'From Squeak3.11alpha of 6 December 2011 [latest update: #11804] on 10 December 2011 at 7:35:34 pm'! !SystemTracer2 methodsFor: 'private' stamp: 'dtl 12/7/2011 22:57'! writeAndTrace: object "Write the image representation of me on byteStream at my oop, and add my not-yet-seen fields to traceQueue." | lengthAndHeaderSize oop byteSize byteBuffer | lengthAndHeaderSize := self lengthAndHeaderSizeFor: object. oop := oopMap at: object ifAbsent: [object isNil ifTrue: [nilOop] ifFalse: [self halt: 'oop should have been added to oopMap when object was add to traceQueue']]. "Write header" byteStream position: oop - ((lengthAndHeaderSize second - 1) * wordSize). byteStream nextPutAll: (self headersFor: object class classOop: (self reserve: object class from: object field: -1 "class field") hash: (self identityHashFor: object) numFields: (self fixedPlusIndexableSizeFor: object) ). "Write fields" (object class isPointers or: [object class == CompiledMethod]) ifTrue: [ object class == BlockClosure ifTrue: [ | startpc diff | "Adjust startpc of a BlockClosure to account for possibly different width of word-sized instance variables and header in its enclosing compiled method." startpc := object startpc. diff := self wordSize - Smalltalk wordSize. object instVarAt: 2 put: (object startpc + (object outerContext method numLiterals + 1 * diff)). byteStream nextPutAll: (self object: object allFieldsWithIndex: [:val :i | self reserve: val from: object field: i] collect: WordArray). object instVarAt: 2 put: startpc ] ifFalse: [ byteStream nextPutAll: (self object: object allFieldsWithIndex: [:val :i | self reserve: val from: object field: i] collect: WordArray) ] ] ifFalse: [ "isBits" byteStream nextPutAll: object. object class isBytes ifTrue: [ "fill bytes unused in last word" 1 to: (wordSize-1) - (object basicSize + (wordSize-1) \\ wordSize) do: [:i | byteStream nextPut: 0]] ifFalse: [(wordSize = 8 and: [object basicSize odd]) ifTrue: [ "fill word unused in last long8" byteStream nextPutAll: (WordArray with: 0)]]. ]. object class == CompiledMethod ifTrue: [ byteSize := object basicSize - object initialPC + 1. byteBuffer := ByteArray new: byteSize. byteBuffer replaceFrom: 1 to: byteSize with: object startingAt: object initialPC. "intermediate ByteArray needed since byteStream (a file) cannot putAll from a subclass of ByteArray (CompiledMethod)" byteStream nextPutAll: byteBuffer. "fill bytes unused in last word" 1 to: (wordSize-1) - (byteBuffer size + (wordSize-1) \\ wordSize) do: [:i | byteStream nextPut: 0]. ]. "Double check that fields take up expected size" byteStream position = (oop + (lengthAndHeaderSize first * wordSize)) ifFalse: [ self error: 'object size discrepency']. ^ oop! !