Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.422.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.422 Author: eem Time: 1 October 2013, 6:00:00.977 pm UUID: b892d1f0-5b73-4fe6-9cc6-5ac122276de6 Ancestors: VMMaker.oscog-eem.421
Fix bad slip in CoInterpreter>>mapVMRegisters.
Fix alignment of fake block headers. Use self AlignmentNops: (methodZone roundUpLength: 1) instead of self AlignmentNops: (self sizeof: CogBlockMethod).
Refactor genPushReceiverVariable: to eliminate genSSPushSlot:reg:.
Get ceNewArraySlotSize: to use faster Spur allocation.
More protocol added to CogObjectRepresentationFor[NBit]Spur.
Make checkIfValidObjectRef:pc:cogMethod: distinguish between linked and unlinked sends.
Clue SpurMemoryManager>>checkHeapIntegrity into CogMethods.
Do some plumbing work for heapMapAtWord:[Put:].
More isIntegerObject: => isImmediate:, isNonIntegerObject: => isNonImmediate:.
Bootstrap proceeds to first compilation of something containing special selector class.
=============== Diff against VMMaker.oscog-eem.421 ===============
Item was changed: ----- Method: CoInterpreter>>ceNewArraySlotSize: (in category 'trampolines') ----- ceNewArraySlotSize: slotSize <api> + objectMemory hasSpurMemoryManagerAPI ifTrue: + [| obj | + obj := objectMemory + eeInstantiateClassIndex: ClassArrayCompactIndex + format: objectMemory arrayFormat + numSlots: slotSize. + objectMemory fillObj: obj numSlots: slotSize with: objectMemory nilObject. + ^obj]. + ^objectMemory + eeInstantiateAndInitializeClass: (objectMemory splObj: ClassArray) + indexableSize: slotSize! - ^objectMemory eeInstantiateAndInitializeClass: (objectMemory splObj: ClassArray) indexableSize: slotSize!
Item was changed: ----- Method: CoInterpreter>>checkStackIntegrity (in category 'object memory support') ----- checkStackIntegrity "Perform an integrity/leak check using the heapMap. Assume clearLeakMapAndMapAccesibleObjects has set a bit at each object's header. Scan all objects accessible from the stack checking that every pointer points to a header. Answer if no dangling pointers were detected." | ok | <inline: false> <var: #thePage type: #'StackPage *'> <var: #theSP type: #'char *'> <var: #theFP type: #'char *'> <var: #callerFP type: #'char *'> <var: #frameRcvrOffset type: #'char *'> <var: #cogMethod type: #'CogMethod *'> ok := true. 0 to: numStackPages - 1 do: [:i| | thePage theSP theFP frameRcvrOffset callerFP oop | thePage := stackPages stackPageAt: i. (stackPages isFree: thePage) ifFalse: [thePage = stackPage ifTrue: [theSP := stackPointer. theFP := framePointer] ifFalse: [theSP := thePage headSP. theFP := thePage headFP]. "Skip the instruction pointer on top of stack of inactive pages." thePage = stackPage ifFalse: [theSP := theSP + BytesPerWord]. [frameRcvrOffset := self frameReceiverOffset: theFP. [theSP <= frameRcvrOffset] whileTrue: [oop := stackPages longAt: theSP. + ((objectMemory isNonImmediate: oop) - ((objectMemory isNonIntegerObject: oop) and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue: [self printFrameThing: 'object leak in frame temp' at: theSP; cr. ok := false]. theSP := theSP + BytesPerWord]. (self frameHasContext: theFP) ifTrue: [oop := self frameContext: theFP. + ((objectMemory isImmediate: oop) - ((objectMemory isIntegerObject: oop) or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue: [self printFrameThing: 'object leak in frame ctxt' at: theFP + FoxThisContext; cr. ok := false]. (oop = objectMemory nilObject or: [objectMemory isContext: oop]) ifFalse: [self printFrameThing: 'frame ctxt should be context' at: theFP + FoxThisContext; cr. ok := false]]. (self isMachineCodeFrame: theFP) ifTrue: [| cogMethod | cogMethod := self mframeHomeMethod: theFP. (self heapMapAtWord: (self pointerForOop: cogMethod)) = 0 ifTrue: [self printFrameThing: 'object leak in mframe mthd' at: theFP + FoxMethod; cr. ok := false]] ifFalse: [oop := self iframeMethod: theFP. + ((objectMemory isImmediate: oop) - ((objectMemory isIntegerObject: oop) or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue: [self printFrameThing: 'object leak in iframe mthd' at: theFP + FoxMethod; cr. ok := false]]. (callerFP := self frameCallerFP: theFP) ~= 0] whileTrue: [theSP := theFP + FoxCallerSavedIP + BytesPerWord. theFP := callerFP]. theSP := theFP + FoxCallerSavedIP + BytesPerWord. [theSP <= thePage baseAddress] whileTrue: [oop := stackPages longAt: theSP. + ((objectMemory isNonImmediate: oop) - ((objectMemory isNonIntegerObject: oop) and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue: [self printFrameThing: 'object leak in frame arg' at: theSP; cr. ok := false]. theSP := theSP + BytesPerWord]]]. ^ok!
Item was changed: ----- Method: CoInterpreter>>mapVMRegisters (in category 'object memory support') ----- mapVMRegisters "Map the oops in the interpreter's vm ``registers'' to their new values during garbage collection or a become: operation." "Assume: All traced variables contain valid oops. N.B. Don't trace messageSelector and lkupClass; these are ephemeral, live only during message lookup and because createActualMessageTo will not cause a GC these cannot change during message lookup." | mapInstructionPointer | (objectMemory shouldRemapObj: method) ifTrue: ["i.e. interpreter instructionPointer in method as opposed to machine code?" (mapInstructionPointer := instructionPointer > method) ifTrue: [instructionPointer := instructionPointer - method]. "*rel to method" method := objectMemory remapObj: method. mapInstructionPointer ifTrue: [instructionPointer := instructionPointer + method]]. "*rel to method" + (objectMemory shouldRemapOop: newMethod) ifTrue: "maybe oop due to object-as-method" + [newMethod := objectMemory remapObj: newMethod]! - (objectMemory shouldRemapOop: newMethod) ifFalse: "maybe oop due to object-as-method" - [newMethod := objectMemory remap: newMethod]!
Item was changed: ----- Method: CoInterpreterPrimitives>>primitiveClone (in category 'object access primitives') ----- primitiveClone "Return a shallow copy of the receiver. Special-case non-single contexts (because of context-to-stack mapping). Can't fail for contexts cuz of image context instantiation code (sigh). Special case CompiledMerhods since the copy mustn't refer to CogMethod if receiver has been cogged."
| rcvr newCopy objHeader | rcvr := self stackTop. + (objectMemory isImmediate: rcvr) - (objectMemory isIntegerObject: rcvr) ifTrue: [newCopy := rcvr] ifFalse: [objHeader := objectMemory baseHeader: rcvr. (objectMemory isContextHeader: objHeader) ifTrue: [newCopy := self cloneContext: rcvr] ifFalse: [newCopy := objectMemory clone: rcvr]. newCopy = 0 ifTrue: [^self primitiveFailFor: PrimErrNoMemory]. (objectMemory isCompiledMethodHeader: objHeader) ifTrue: ["use stackTop since GC may have moved rcvr" self rawHeaderOf: newCopy put: (self headerOf: self stackTop)]]. self pop: 1 thenPush: newCopy!
Item was added: + ----- Method: CogObjectRepresentationFor32BitSpur>>genRemoveSmallIntegerTagsInScratchReg: (in category 'compile abstract instructions') ----- + genRemoveSmallIntegerTagsInScratchReg: scratchReg + cogit SubCq: 1 R: scratchReg. + ^0!
Item was added: + ----- Method: CogObjectRepresentationFor32BitSpur>>genSetSmallIntegerTagsIn: (in category 'compile abstract instructions') ----- + genSetSmallIntegerTagsIn: scratchReg + cogit OrCq: 1 R: scratchReg. + ^0!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>checkValidInlineCacheTag: (in category 'debug support') ----- + checkValidInlineCacheTag: classIndexOrTagPattern + ^classIndexOrTagPattern <= objectMemory tagMask + or: [(objectMemory classAtIndex: classIndexOrTagPattern) notNil]!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>checkValidObjectReference: (in category 'debug support') ----- + checkValidObjectReference: anOop + ^(objectMemory isImmediate: anOop) + or: [(objectMemory heapMapAtWord: (self pointerForOop: anOop)) ~= 0]!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>genRemoveSmallIntegerTagsInScratchReg: (in category 'compile abstract instructions') ----- + genRemoveSmallIntegerTagsInScratchReg: scratchReg + self subclassResponsibility!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>genSetSmallIntegerTagsIn: (in category 'compile abstract instructions') ----- + genSetSmallIntegerTagsIn: scratchReg + self subclassResponsibility!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>genStoreImmediateInSourceReg:slotIndex:destReg: (in category 'compile abstract instructions') ----- + genStoreImmediateInSourceReg: sourceReg slotIndex: index destReg: destReg + cogit MoveR: sourceReg + Mw: index * objectMemory wordSize + objectMemory baseHeaderSize + r: destReg. + ^0!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>genStoreSourceReg:slotIndex:destReg:scratchReg: (in category 'compile abstract instructions') ----- + genStoreSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg + | jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRemembered mask rememberedBitByteOffset | + <var: #jmpImmediate type: #'AbstractInstruction *'> + <var: #jmpDestYoung type: #'AbstractInstruction *'> + <var: #jmpSourceOld type: #'AbstractInstruction *'> + <var: #jmpAlreadyRemembered type: #'AbstractInstruction *'> + "do the store" + cogit MoveR: sourceReg + Mw: index * objectMemory wordSize + objectMemory baseHeaderSize + r: destReg. + "now the check. Is value stored an integer? If so we're done" + cogit MoveR: sourceReg R: scratchReg. + cogit AndCq: objectMemory tagMask R: scratchReg. + jmpImmediate := cogit JumpNonZero: 0. + "Get the old/new boundary in scratchReg" + cogit MoveAw: objectMemory newSpaceLimitAddress R: scratchReg. + "Is target young? If so we're done" + cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg - scratchReg" + jmpDestYoung := cogit JumpBelow: 0. + "Is value stored old? If so we're done." + cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := sourceReg - scratchReg" + jmpSourceOld := cogit JumpAboveOrEqual: 0. + "value is young and target is old. + Need to remember this only if the remembered bit is not already set. + Test the remembered bit. Only need to fetch the byte containing it, + which reduces the size of the mask constant." + rememberedBitByteOffset := jmpSourceOld isBigEndian + ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)] + ifFalse:[objectMemory rememberedBitShift // 8]. + mask := 1 << (objectMemory rememberedBitShift \ 8). + cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg. + cogit AndCq: mask R: scratchReg. + jmpAlreadyRemembered := cogit JumpNonZero: 0. + "Remembered bit is not set. Call store check to insert dest into remembered table." + self assert: destReg == ReceiverResultReg. + cogit CallRT: cogit ceStoreCheckTrampoline. + jmpImmediate jmpTarget: + (jmpDestYoung jmpTarget: + (jmpSourceOld jmpTarget: + (jmpAlreadyRemembered jmpTarget: + cogit Label))). + ^0!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>hasValidHeaderPostGC: (in category 'garbage collection') ----- + hasValidHeaderPostGC: cogMethod + <var: #cogMethod type: #'CogMethod *'> + <inline: true> + ^cogMethod objectHeader = objectMemory nullHeaderForMachineCodeMethod!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>inlineCacheTagForInstance: (in category 'in-line cacheing') ----- + inlineCacheTagForInstance: oop + "c.f. getInlineCacheClassTagFrom:into:" + (objectMemory isImmediate: oop) ifTrue: + [(objectMemory isIntegerObject: oop) ifTrue: + [^objectMemory integerObjectOf: 0]. "the SmallInteger tag" + ^oop bitAnd: objectMemory tagMask]. "the other tags" + ^objectMemory classIndexOf: oop!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>inlineCacheTagIsYoung: (in category 'in-line cacheing') ----- + inlineCacheTagIsYoung: anInteger + "classIndices are not objects, heh, heh, heh..." + ^false!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>isImmediate: (in category 'object representation') ----- + isImmediate: oop + ^objectMemory isImmediate: oop!
Item was added: + ----- Method: CogObjectRepresentationForSpur>>slotOffsetOfInstVarIndex: (in category 'compile abstract instructions') ----- + slotOffsetOfInstVarIndex: index + ^index * objectMemory wordSize + objectMemory baseHeaderSize!
Item was removed: - ----- Method: CogObjectRepresentationForSqueakV3>>genSSPushSlot:reg: (in category 'compile abstract instructions') ----- - genSSPushSlot: index reg: baseReg - ^cogit ssPushBase: baseReg offset: (self slotOffsetOfInstVarIndex: index)!
Item was added: + ----- Method: CogVMSimulator>>heapMapAtWord: (in category 'debug support') ----- + heapMapAtWord: address + ^objectMemory heapMap heapMapAtWord: address asUnsignedInteger!
Item was added: + ----- Method: CogVMSimulator>>heapMapAtWord:Put: (in category 'debug support') ----- + heapMapAtWord: address Put: aBit + ^objectMemory heapMap heapMapAtWord: address asUnsignedInteger Put: aBit!
Item was changed: ----- Method: CogVMSimulator>>utilitiesMenu: (in category 'UI') ----- utilitiesMenu: aMenuMorph aMenuMorph add: 'toggle transcript' action: #toggleTranscript; addLine; add: 'print ext head frame' action: #printExternalHeadFrame; add: 'print int head frame' action: #printHeadFrame; add: 'print mc/cog frame' action: [self printFrame: cogit processor fp WithSP: cogit processor sp]; add: 'short print ext frame & callers' action: [self shortPrintFrameAndCallers: framePointer]; add: 'short print int frame & callers' action: [self shortPrintFrameAndCallers: localFP]; add: 'short print mc/cog frame & callers' action: [self shortPrintFrameAndCallers: cogit processor fp]; add: 'long print ext frame & callers' action: [self printFrameAndCallers: framePointer SP: stackPointer]; add: 'long print int frame & callers' action: [self printFrameAndCallers: localFP SP: localSP]; add: 'long print mc/cog frame & callers' action: [self printFrameAndCallers: cogit processor fp SP: cogit processor sp]; add: 'print frame...' action: [(self promptHex: 'print frame') ifNotNil: [:fp| self printFrame: fp]]; add: 'print call stack' action: #printCallStack; + add: 'print stack call stack' action: #printStackCallStack; add: 'print call stack of...' action: [(self promptHex: 'context or process oop') ifNotNil: [:obj| self printCallStackOf: obj]]; add: 'print all stacks' action: #printAllStacks; addLine; add: 'print registers' action: [cogit processor printRegistersOn: transcript]; add: 'disassemble method/trampoline...' action: [(self promptHex: 'pc') ifNotNil: [:pc| cogit disassembleCodeAt: pc]]; add: 'disassemble method/trampoline at pc' action: [cogit disassembleCodeAt: cogit processor pc]; add: 'disassemble ext head frame method' action: [cogit disassembleMethod: (self frameMethod: framePointer)]; add: 'print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self printOop: oop]]; add: 'long print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self longPrintOop: oop]]; addLine; add: 'inspect object memory' target: objectMemory action: #inspect; add: 'inspect cointerpreter' action: #inspect; add: 'inspect cogit' target: cogit action: #inspect; add: 'inspect method zone' target: cogit methodZone action: #inspect. self isThreadedVM ifTrue: [aMenuMorph add: 'inspect thread manager' target: self threadManager action: #inspect]. aMenuMorph addLine; add: 'print cog methods' target: cogMethodZone action: #printCogMethods; add: 'print trampoline table' target: cogit action: #printTrampolineTable; add: 'report recent instructions' target: cogit action: #reportLastNInstructions; add: 'set break pc...' action: [(self promptHex: 'break pc') ifNotNil: [:bpc| cogit breakPC: bpc]]; add: (cogit singleStep ifTrue: ['no single step'] ifFalse: ['single step']) action: [cogit singleStep: cogit singleStep not]; add: (cogit printRegisters ifTrue: ['no print registers each instruction'] ifFalse: ['print registers each instruction']) action: [cogit printRegisters: cogit printRegisters not]; add: (cogit printInstructions ifTrue: ['no print instructions each instruction'] ifFalse: ['print instructions each instruction']) action: [cogit printInstructions: cogit printInstructions not]; addLine; add: 'set break count...' action: [|s| s := UIManager default request: 'break count (dec)'. s notEmpty ifTrue: [breakCount := Integer readFrom: s readStream]]; add: 'set break selector...' action: [|s| s := UIManager default request: 'break selector'. s notEmpty ifTrue: [self setBreakSelector: s]]; add: 'set break block...' action: [|s| s := UIManager default request: 'break selector'. s notEmpty ifTrue: [self setBreakBlockFromString: s]]; add: (printBytecodeAtEachStep ifTrue: ['no print bytecode each bytecode'] ifFalse: ['print bytecode each bytecode']) action: [self ensureDebugAtEachStepBlock. printBytecodeAtEachStep := printBytecodeAtEachStep not]; add: (printFrameAtEachStep ifTrue: ['no print frame each bytecode'] ifFalse: ['print frame each bytecode']) action: [self ensureDebugAtEachStepBlock. printFrameAtEachStep := printFrameAtEachStep not]. ^aMenuMorph!
Item was changed: ----- Method: Cogit>>addCogMethodsToHeapMap (in category 'debugging') ----- addCogMethodsToHeapMap <api> "Perform an integrity/leak check using the heapMap. Set a bit at each cog method's header." | cogMethod | <var: #cogMethod type: #'CogMethod *'> cogMethod := self cCoerceSimple: methodZoneBase to: #'CogMethod *'. [cogMethod < methodZone limitZony] whileTrue: [cogMethod cmType = CMMethod ifTrue: + [coInterpreter heapMapAtWord: cogMethod Put: 1]. - [self heapMapAtWord: cogMethod Put: 1]. cogMethod := methodZone methodAfter: cogMethod]!
Item was changed: ----- Method: Cogit>>checkIfValidObjectRef:pc:cogMethod: (in category 'garbage collection') ----- checkIfValidObjectRef: annotation pc: mcpc cogMethod: cogMethod <var: #mcpc type: #'char *'> annotation = IsObjectReference ifTrue: [| literal | literal := backEnd literalBeforeFollowingAddress: mcpc asInteger. (objectRepresentation checkValidObjectReference: literal) ifFalse: [self print: 'object ref leak in CM '; printHex: cogMethod asInteger; print: ' @ '; printHex: mcpc asInteger; cr. ^1]]. (self isSendAnnotation: annotation) ifTrue: + [| entryPoint selectorOrCacheTag | + entryPoint := backEnd callTargetFromReturnAddress: mcpc asInteger. + selectorOrCacheTag := backEnd inlineCacheTagAt: mcpc asInteger. + entryPoint > methodZoneBase + ifTrue: "linked send, cacheTag is a cacheTag" + [(objectRepresentation checkValidInlineCacheTag: selectorOrCacheTag) ifFalse: + [self print: 'cache tag leak in CM '; printHex: cogMethod asInteger; print: ' @ '; printHex: mcpc asInteger; cr. + ^1]] + ifFalse: "unlinked send; cacheTag is a selector" + [(objectRepresentation checkValidObjectReference: selectorOrCacheTag) ifFalse: + [self print: 'selector leak in CM '; printHex: cogMethod asInteger; print: ' @ '; printHex: mcpc asInteger; cr. + ^1]]]. - [| cacheTag | - cacheTag := backEnd inlineCacheTagAt: mcpc asInteger. - (objectRepresentation checkValidInlineCacheTag: cacheTag) ifFalse: - [self print: 'cache tag/selector leak in CM '; printHex: cogMethod asInteger; print: ' @ '; printHex: mcpc asInteger; cr. - ^1]]. ^0 "keep scanning"!
Item was changed: ----- Method: Cogit>>compileBlockEntry: (in category 'compile abstract instructions') ----- compileBlockEntry: blockStart "Compile a block's entry. This looks like a dummy CogBlockMethod header (for frame parsing) followed by either a frame build, if a frame is required, or nothing. The CogMethodHeader's objectHeader field is a back pointer to the method, but this can't be filled in until code generation." <var: #blockStart type: #'BlockStart *'> + "Block method headers must be aligned on the correct boundary, just like non-block method headers." + self AlignmentNops: (methodZone roundUpLength: 1). - self AlignmentNops: (self sizeof: CogBlockMethod). blockStart fakeHeader: self Label. (self sizeof: CogBlockMethod) caseOf: { [2 * BytesPerWord] "ObjectMemory" -> [self Fill32: 0. "gets filled in later with the homeOffset and startpc" self Fill32: 0]. "gets filled in later with numArgs et al" [3 * BytesPerWord] "Spur" -> [self Fill32: 0. "gets filled in later with the homeOffset and startpc" self Fill32: 0. "is left fallow" self Fill32: 0]. "gets filled in later with numArgs et al" }. blockStart entryLabel: self Label. needsFrame ifTrue: [self compileBlockFrameBuild: blockStart. self recordBlockTrace ifTrue: [self CallRT: ceTraceBlockActivationTrampoline]] ifFalse: [self compileBlockFramelessEntry: blockStart]!
Item was added: + ----- Method: Spur32BitCoMemoryManager>>clearLeakMapAndMapAccessibleObjects (in category 'debug support') ----- + clearLeakMapAndMapAccessibleObjects + "Perform an integrity/leak check using the heapMap. Set a bit at each object's header. + Override to set a bit at each Cog method" + super clearLeakMapAndMapAccessibleObjects. + cogit addCogMethodsToHeapMap!
Item was added: + ----- Method: Spur32BitCoMemoryManager>>newSpaceLimitAddress (in category 'trampoline support') ----- + newSpaceLimitAddress + <api> + <returnTypeC: #usqInt> + ^self cCode: [(self addressOf: newSpaceLimit) asUnsignedInteger] + inSmalltalk: [cogit simulatedReadWriteVariableAddress: #newSpaceLimit in: self]!
Item was added: + ----- Method: Spur32BitMMLECoSimulator>>heapMapAtWord: (in category 'debug support') ----- + heapMapAtWord: address + ^heapMap heapMapAtWord: address!
Item was changed: ----- Method: SpurMemoryManager>>checkHeapIntegrity (in category 'debug support') ----- checkHeapIntegrity "Perform an integrity/leak check using the heapMap. Assume clearLeakMapAndMapAccessibleObjects has set a bit at each object's header. Scan all objects in the heap checking that every pointer points to a header. Scan the rootTable, remapBuffer and extraRootTable checking that every entry is a pointer to a header. Check that the number of roots is correct and that all rootTable entries have their rootBit set. Answer if all checks pass." | prevObj prevPrevObj ok numRememberedRootsInHeap | <inline: false> ok := true. numRememberedRootsInHeap := 0. self allHeapEntitiesDo: [:obj| | containsYoung fieldOop classIndex classOop | (self isFreeObject: obj) ifFalse: [containsYoung := false. (self isRemembered: obj) ifTrue: [numRememberedRootsInHeap := numRememberedRootsInHeap + 1. (scavenger isInRememberedTable: obj) ifFalse: [coInterpreter print: 'remembered object '; printHex: obj; print: ' is not in remembered table'; cr. self eek. ok := false]]. (self isForwarded: obj) ifTrue: [fieldOop := self fetchPointer: 0 ofMaybeForwardedObject: obj. (heapMap heapMapAtWord: (self pointerForOop: fieldOop)) = 0 ifTrue: [coInterpreter print: 'object leak in forwarder '; printHex: obj; print: ' to unmapped '; printHex: fieldOop; cr. self eek. ok := false]. (self isYoung: fieldOop) ifTrue: [containsYoung := true]] ifFalse: [classOop := self classAtIndex: (classIndex := self classIndexOf: obj). (classOop isNil or: [classOop = nilObj]) ifTrue: [coInterpreter print: 'object leak in '; printHex: obj; print: ' invalid class index '; printHex: classIndex; print: ' -> '; print: (classOop ifNil: ['nil'] ifNotNil: ['nilObj']); cr. self eek. ok := false]. self baseHeaderSize to: (self lastPointerOf: obj) by: BytesPerOop do: [:ptr| fieldOop := self longAt: obj + ptr. (self isNonImmediate: fieldOop) ifTrue: [| fi | fi := ptr - self baseHeaderSize / self wordSize. (fieldOop bitAnd: self wordSize - 1) ~= 0 ifTrue: [coInterpreter print: 'misaligned oop in '; printHex: obj; print: ' @ '; printNum: fi; print: ' = '; printHex: fieldOop; cr. self eek. ok := false] ifFalse: [(heapMap heapMapAtWord: (self pointerForOop: fieldOop)) = 0 ifTrue: [coInterpreter print: 'object leak in '; printHex: obj; print: ' @ '; printNum: fi; print: ' = '; printHex: fieldOop; cr. self eek. ok := false]. + "don't be misled by CogMethods; they appear to be young, but they're not" + ((self isYoung: fieldOop) and: [fieldOop >= startOfMemory]) ifTrue: - (self isYoung: fieldOop) ifTrue: [containsYoung := true]]]]]. (containsYoung and: [(self isYoung: obj) not]) ifTrue: [(self isRemembered: obj) ifFalse: [coInterpreter print: 'unremembered object '; printHex: obj; print: ' contains young oop(s)'; cr. self eek. ok := false]]]. prevPrevObj := prevObj. prevObj := obj]. numRememberedRootsInHeap ~= scavenger rememberedSetSize ifTrue: [coInterpreter print: 'root count mismatch. #heap roots '; printNum: numRememberedRootsInHeap; print: '; #roots '; printNum: scavenger rememberedSetSize; cr. self eek. "But the system copes with overflow..." self flag: 'no support for remembered set overflow yet'. "ok := rootTableOverflowed and: [needGCFlag]"]. scavenger rememberedSetWithIndexDo: [:obj :i| (obj bitAnd: self wordSize - 1) ~= 0 ifTrue: [coInterpreter print: 'misaligned oop in rootTable @ '; printNum: i; print: ' = '; printHex: obj; cr. self eek. ok := false] ifFalse: [(heapMap heapMapAtWord: (self pointerForOop: obj)) = 0 ifTrue: [coInterpreter print: 'object leak in remembered set @ '; printNum: i; print: ' = '; printHex: obj; cr. self eek. ok := false] ifFalse: [(self isYoung: obj) ifTrue: [coInterpreter print: 'non-root in remembered set @ '; printNum: i; print: ' = '; printHex: obj; cr. self eek. ok := false]]]]. self flag: 'no support for remap buffer yet'. "1 to: remapBufferCount do: [:ri| obj := remapBuffer at: ri. (obj bitAnd: self wordSize - 1) ~= 0 ifTrue: [coInterpreter print: 'misaligned remapRoot @ '; printNum: ri; print: ' = '; printHex: obj; cr. self eek. ok := false] ifFalse: [(heapMap heapMapAtWord: (self pointerForOop: obj)) = 0 ifTrue: [coInterpreter print: 'object leak in remapRoots @ '; printNum: ri; print: ' = '; printHex: obj; cr. self eek. ok := false]]]." self flag: 'no support for extraRoots yet'. "1 to: extraRootCount do: [:ri| obj := (extraRoots at: ri) at: 0. (obj bitAnd: self wordSize - 1) ~= 0 ifTrue: [coInterpreter print: 'misaligned extraRoot @ '; printNum: ri; print: ' => '; printHex: obj; cr. self eek. ok := false] ifFalse: [(heapMap heapMapAtWord: (self pointerForOop: obj)) = 0 ifTrue: [coInterpreter print: 'object leak in extraRoots @ '; printNum: ri; print: ' => '; printHex: obj; cr. self eek. ok := false]]]." ^ok!
Item was changed: ----- Method: SpurMemoryManager>>isIntegerObject: (in category 'object testing') ----- isIntegerObject: oop "This list records the valid senders of isIntegerObject: as we replace uses of isIntegerObject: by isImmediate: where appropriate." | sel | sel := thisContext sender method selector. (#( DoIt DoItIn: on:do: "from the debugger" makeBaseFrameFor: quickFetchInteger:ofObject: frameOfMarriedContext: objCouldBeClassObj: isMarriedOrWidowedContext: shortPrint: bytecodePrimAt bytecodePrimAtPut commonAt: commonAtPut: loadFloatOrIntFrom: positive32BitValueOf: primitiveExternalCall checkedIntegerValueOf: bytecodePrimAtPut commonAtPut: primitiveVMParameter checkIsStillMarriedContext:currentFP: displayBitsOf:Left:Top:Right:Bottom: fetchStackPointerOf: primitiveContextAt primitiveContextAtPut subscript:with:storing:format: printContext: compare31or32Bits:equal: signed64BitValueOf: primDigitMultiply:negative: digitLength: isNegativeIntegerValueOf: magnitude64BitValueOf: primitiveMakePoint primitiveAsCharacter primitiveInputSemaphore baseFrameReturn primitiveExternalCall primDigitCompare: isLiveContext: numPointerSlotsOf: fileValueOf: loadBitBltDestForm fetchIntOrFloat:ofObject:ifNil: fetchIntOrFloat:ofObject: loadBitBltSourceForm loadPoint:from: primDigitAdd: primDigitSubtract: positive64BitValueOf: digitBitLogic:with:opIndex: signed32BitValueOf: isNormalized: primDigitDiv:negative: bytesOrInt:growTo: primitiveNewMethod isCogMethodReference: functionForPrimitiveExternalCall: genSpecialSelectorArithmetic + genSpecialSelectorComparison + ensureContextHasBytecodePC: + instVar:ofContext:) includes: sel) ifFalse: - genSpecialSelectorComparison) includes: sel) ifFalse: [self halt]. ^(oop bitAnd: 1) ~= 0!
Item was changed: ----- Method: StackInterpreter>>findSelectorOfMethod: (in category 'debug support') ----- + findSelectorOfMethod: methArg + | meth classObj classDict classDictSize methodArray i | + (objectMemory addressCouldBeObj: methArg) ifFalse: - findSelectorOfMethod: meth - | classObj classDict classDictSize methodArray i | - (objectMemory addressCouldBeObj: meth) ifFalse: [^objectMemory nilObject]. + meth := (objectMemory isForwarded: methArg) + ifTrue: [objectMemory followForwarded: methArg] + ifFalse: [methArg]. + (objectMemory isOopCompiledMethod: meth) ifFalse: + [^objectMemory nilObject]. classObj := self methodClassOf: meth. (self addressCouldBeClassObj: classObj) ifTrue: [classDict := objectMemory fetchPointer: MethodDictionaryIndex ofObject: classObj. classDictSize := objectMemory fetchWordLengthOf: classDict. methodArray := objectMemory fetchPointer: MethodArrayIndex ofObject: classDict. i := 0. [i <= (classDictSize - SelectorStart)] whileTrue: [meth = (objectMemory fetchPointer: i ofObject: methodArray) ifTrue: [^(objectMemory fetchPointer: i + SelectorStart ofObject: classDict)]. i := i + 1]]. ^objectMemory nilObject!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genPushReceiverVariable: (in category 'bytecode generators') ----- genPushReceiverVariable: index <inline: false> self ensureReceiverResultRegContainsSelf. + ^self ssPushBase: ReceiverResultReg + offset: (objectRepresentation slotOffsetOfInstVarIndex: index)! - ^objectRepresentation genSSPushSlot: index reg: ReceiverResultReg!
vm-dev@lists.squeakfoundation.org