Eliot Miranda uploaded a new version of Cog to project VM Maker: http://source.squeak.org/VMMaker/Cog-eem.183.mcz
==================== Summary ====================
Name: Cog-eem.183 Author: eem Time: 9 August 2014, 11:29:12.516 am UUID: f37551e3-a5fa-4344-b65c-f2496bd47800 Ancestors: Cog-eem.182
Bootstrap needs to adjust pcs in contexts and closures on methods that have primitives.
=============== Diff against Cog-eem.182 ===============
Item was changed: Object subclass: #SpurBootstrap + instanceVariableNames: 'oldHeap newHeap oldHeapSize newHeapSize oldHeapNumObjs newHeapNumObjs map reverseMap classToIndex oldInterpreter lastClassTablePage literalMap methodClasses installedPrototypes sizeSym rehashSym classMetaclass imageTypes classMethodContextIndex classBlockClosureIndex' - instanceVariableNames: 'oldHeap newHeap oldHeapSize newHeapSize oldHeapNumObjs newHeapNumObjs map reverseMap classToIndex oldInterpreter lastClassTablePage literalMap methodClasses installedPrototypes sizeSym rehashSym classMetaclass imageTypes' classVariableNames: 'ImageHeaderFlags ImageName ImageScreenSize TransformedImage' poolDictionaries: 'VMObjectIndices' category: 'Cog-Bootstrapping'!
!SpurBootstrap commentStamp: 'eem 9/11/2013 05:45' prior: 0! SpurBootstrap bootstraps an image in SpurMemoryManager format from a Squeak V3 + closures format.
e.g. (SpurBootstrap32 new on: '/Users/eliot/Cog/startreader.image') transform; launch
Bootstrap issues: - should it implement a deterministic Symbol identityHash? This means set a Symbol's identityHash at instance creation time based on its string hash so that e.g. MethodDIctionary instances have a deterministic order and don't need to be rehashed on load. - should it collapse ContextPart and MethodContext down onto Context (and perhaps eliminate BlockContext)?
Instance Variables classToIndex: <Dictionary> lastClassTablePage: <Integer> map: <Dictionary> methodClasses: <Set> newHeap: <SpurMemoryManager> oldHeap: <NewObjectMemory> oldInterpreter: <StackInterpreterSimulator> reverseMap: <Dictionary> symbolMap: <Dictionary>
classToIndex - oldClass to new classIndex map
lastClassTablePage - oop in newHeap of last classTable page. U<sed in validation to filter-out class table.
methodClasses - cache of methodClassAssociations for classes in which modified methods are installed
map - oldObject to newObject map
newHeap - the output, bootstrapped image
oldHeap - the input, image
oldInterpreter - the interpreter associated with oldHeap, needed for a hack to grab WeakArray
reverseMap - newObject to oldObject map
symbolMap - symbol toi symbol oop in oldHeap, used to map prototype methdos to methods in oldHeap!
Item was changed: ----- Method: SpurBootstrap>>defineKnownClassIndices (in category 'class indices') ----- defineKnownClassIndices "The classTable is laid out - to make it easy to map immediates to classes; the tag pattern of an immediate is its class index. hence there are two entries for SmallInteger - to assign small indices to well-known classes such as Array, Message et al - to leave plenty of room for new known classes; hence the first page contains only well-known classes - to enable overlaps and avoid conflicts with indices in the specialObjectsArray (?really? eem) - to provide a WeakArray pun for the pages of the table itself so that these do not show up as instances of WeakArray" | classMethodContext classBlockClosure classMessage "no api method for these" | classMessage := oldHeap splObj: (VMObjectIndices bindingOf: #ClassMessage) value. classMethodContext := oldHeap splObj: (VMObjectIndices bindingOf: #ClassMethodContext) value. classBlockClosure := oldHeap splObj: (VMObjectIndices bindingOf: #ClassBlockClosure) value. "c.f. SpurMemoryManager class>>intializeCompactClassIndices". classToIndex keysDo: [:oldClass| self assert: (oldInterpreter addressCouldBeClassObj: oldClass)]. classToIndex at: oldHeap classSmallInteger put: 1; "N.B. must fill-in index 3 manually" at: oldHeap classCharacter put: 2; "at: oldHeap classSmallInteger put: 3" "N.B. must fill-in index 3 manually" "leave room for up to 15 tagged classes" "leave room for up to 16 puns" at: oldHeap classLargeNegativeInteger put: 32; at: oldHeap classLargePositiveInteger put: 33; at: oldHeap classFloat put: 34;
at: "oldHeap" classMessage put: 35; + at: "oldHeap" classMethodContext put: (classMethodContextIndex := 36); + at: "oldHeap" classBlockClosure put: (classBlockClosureIndex := 37); - at: "oldHeap" classMethodContext put: 36; - at: "oldHeap" classBlockClosure put: 37;
at: oldHeap classSemaphore put: 48; "at: oldHeap classMutex put: 49; see below"
at: oldHeap classByteArray put: 50; at: oldHeap classArray put: 51; at: oldHeap classString put: 52; at: oldHeap classBitmap put: 53; at: oldHeap classPoint put: 54.
{{oldHeap classMutex. 49}. {oldHeap classExternalAddress. 128}. {oldHeap classExternalData. 129}. {oldHeap classExternalFunction. 130}. {oldHeap classExternalLibrary. 131}. {oldHeap classExternalStructure. 132}. {oldHeap classAlien. 133}. {oldHeap classUnsafeAlien. 134}} do: [:pair| [:oop :index| oop ~= oldHeap nilObject ifTrue: [classToIndex at: oop put: index]] valueWithArguments: pair].
classToIndex keysDo: [:oldClass| self assert: (oldInterpreter addressCouldBeClassObj: oldClass)]!
Item was changed: ----- Method: SpurBootstrap>>fillInObjects (in category 'bootstrap image') ----- fillInObjects oldHeap allObjectsDo: [:oldObj| (map at: oldObj ifAbsent: nil) ifNotNil: + [:newObj| | format classIndex | + format := newHeap formatOf: newObj. + (newHeap isPointersFormat: format) + ifTrue: + [((newHeap isIndexableFormat: format) + and: [(classIndex := newHeap classIndexOf: newObj) <= classBlockClosureIndex + and: [classIndex >= classMethodContextIndex]]) + ifTrue: [self fillInPointerObjectWithPC: newObj from: oldObj] + ifFalse: [self fillInPointerObject: newObj from: oldObj]] - [:newObj| - (newHeap isCompiledMethod: newObj) - ifTrue: [self fillInCompiledMethod: newObj from: oldObj] ifFalse: + [(newHeap isCompiledMethodFormat: format) + ifTrue: [self fillInCompiledMethod: newObj from: oldObj] - [(newHeap isPointersNonImm: newObj) - ifTrue: [self fillInPointerObject: newObj from: oldObj] ifFalse: [self fillInBitsObject: newObj from: oldObj]]]]!
Item was added: + ----- Method: SpurBootstrap>>fillInPointerObjectWithPC:from: (in category 'bootstrap image') ----- + fillInPointerObjectWithPC: newObj from: oldObj + "Fill-in a newObj with appropriately mapped contents from oldObj. + If the object has a pc and its method has a primitive, increment the + pc by the size of the callPrimitive: bytecode." + | method | + self fillInPointerObject: newObj from: oldObj. + (newHeap classIndexOf: newObj) = classBlockClosureIndex ifTrue: + [method := oldHeap + fetchPointer: MethodIndex + ofObject: (oldHeap + fetchPointer: ClosureOuterContextIndex + ofObject: oldObj). + (oldInterpreter primitiveIndexOf: method) > 0 ifTrue: + [self incrementPCField: ClosureStartPCIndex ofObject: newObj by: 3]]. + (newHeap classIndexOf: newObj) = classMethodContextIndex ifTrue: + [method := oldHeap + fetchPointer: MethodIndex + ofObject: oldObj. + (oldInterpreter primitiveIndexOf: method) > 0 ifTrue: + [self incrementPCField: InstructionPointerIndex ofObject: newObj by: 3]].!
Item was added: + ----- Method: SpurBootstrap>>incrementPCField:ofObject:by: (in category 'bootstrap image') ----- + incrementPCField: fieldIndex ofObject: newObj by: n + | value | + value := newHeap fetchPointer: fieldIndex ofObject: newObj. + (newHeap isIntegerObject: value) + ifTrue: + [newHeap + storePointerUnchecked: fieldIndex + ofObject: newObj + withValue: (newHeap integerObjectOf: n + (newHeap integerValueOf: value))] + ifFalse: + [self assert: value = newHeap nilObject]!
vm-dev@lists.squeakfoundation.org