Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.577.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.577 Author: eem Time: 6 January 2014, 1:53:51.172 pm UUID: 8788f091-6817-480e-9bda-13ae360eeeb7 Ancestors: VMMaker.oscog-eem.576
Clean-up accessorDepth code for SqueakV3 VMs. Don't include accessor depth in SqueakV3 vm's named primitives. Do a better job of dead code removal with and: and or: chains. Don't generate primitiveAccessorDepthTable in SqueakV3 VMs. Copy the hasSpurMemoryManagerAPI methods to the class-side.
=============== Diff against VMMaker.oscog-eem.576 ===============
Item was changed: ----- Method: CCodeGenerator>>emitExportsNamed:pluginName:on: (in category 'C code generator') ----- emitExportsNamed: exportsNamePrefix pluginName: pluginName on: aStream "Store all the exported primitives in the form used by the internal named prim system." + | nilVMClass excludeDepth | - | nilVMClass | (nilVMClass := vmClass isNil) ifTrue: [vmClass := StackInterpreter]. + "Don't include the depth in the vm's named primitives if the vm is non-Spur." + excludeDepth := exportsNamePrefix = 'vm' + and: [pluginName isEmpty + and: [vmClass objectMemoryClass hasSpurMemoryManagerAPI not]]. aStream cr; cr; nextPutAll: 'void* '; nextPutAll: exportsNamePrefix; nextPutAll: '_exports[][3] = {'. (self sortStrings: self exportedPrimitiveNames) do: [:primName| + aStream cr; tab; + nextPutAll: '{"'; - aStream cr; - nextPutAll:' {"'; nextPutAll: pluginName; nextPutAll: '", "'; nextPutAll: primName. + excludeDepth ifFalse: + [(self accessorDepthForSelector: primName asSymbol) ifNotNil: + [:depth| "store the accessor depth in a hidden byte immediately after the primName" + self assert: depth < 128. + aStream + nextPutAll: '\000'; + nextPutAll: ((depth bitAnd: 255) printStringBase: 8 nDigits: 3)]]. - (self accessorDepthForSelector: primName asSymbol) ifNotNil: - [:depth| "store the accessor depth in a hidden byte immediately after the primName" - self assert: depth < 128. - aStream - nextPutAll: '\000'; - nextPutAll: ((depth bitAnd: 255) printStringBase: 8 nDigits: 3)]. aStream + nextPutAll: '", (void*)'; - nextPutAll:'", (void*)'; nextPutAll: primName; + nextPutAll: '},']. + aStream cr; tab; nextPutAll: '{NULL, NULL, NULL}'; cr; nextPutAll: '};'; cr. - nextPutAll:'},']. - aStream cr; tab; nextPutAll:'{NULL, NULL, NULL}'; cr; nextPutAll: '};'; cr. nilVMClass ifTrue: [vmClass := nil]!
Item was changed: ----- Method: CCodeGenerator>>nilOrBooleanConstantReceiverOf: (in category 'utilities') ----- nilOrBooleanConstantReceiverOf: aNode "Answer nil or the boolean constant that is the receiver of the given message send. Used to suppress conditional code when the condition is a translation-time constant."
| val receiver argument | generateDeadCode ifTrue:[^nil]. ((self isConstantNode: aNode valueInto: [:v| val := v]) and: [#(true false) includes: val]) ifTrue: [^val]. aNode isSend ifTrue: [((#(or: and:) includes: aNode selector) and: [aNode args last isStmtList and: [aNode args last statements size = 1]]) ifTrue: [(self nilOrBooleanConstantReceiverOf: aNode receiver) ifNotNil: [:rcvr| + ((rcvr == false and: [aNode selector == #and:]) + or: [rcvr == true and: [aNode selector == #or:]]) ifTrue: + [^rcvr]. (self nilOrBooleanConstantReceiverOf: aNode args last statements first) ifNotNil: [:arg| ^rcvr perform: aNode selector with: [arg]]]]. ((#(= ~= < > <= >=) includes: aNode selector) and: [(self isConstantNode: aNode receiver valueInto: [:v| receiver := v]) and: [receiver isInteger and: [(self isConstantNode: aNode args first valueInto: [:v| argument := v]) and: [argument isInteger]]]]) ifTrue: [^receiver perform: aNode selector with: argument]]. ^nil!
Item was added: + ----- Method: ObjectMemory class>>hasSpurMemoryManagerAPI (in category 'api chacterization') ----- + hasSpurMemoryManagerAPI + ^false!
Item was added: + ----- Method: SpurMemoryManager class>>hasSpurMemoryManagerAPI (in category 'api characterization') ----- + hasSpurMemoryManagerAPI + ^true!
Item was changed: ----- Method: StackInterpreter class>>declareCVarsIn: (in category 'translation') ----- declareCVarsIn: aCCodeGenerator self class == thisContext methodClass ifFalse: [^self]. "Don't duplicate decls in subclasses" aCCodeGenerator addHeaderFile:'<stddef.h> /* for e.g. alloca */'; addHeaderFile:'<setjmp.h>'; addHeaderFile:'"vmCallback.h"'; addHeaderFile:'"sqMemoryFence.h"'; addHeaderFile:'"dispdbg.h"'. self declareInterpreterVersionIn: aCCodeGenerator defaultName: 'Stack'. aCCodeGenerator var: #interpreterProxy type: #'struct VirtualMachine*'. aCCodeGenerator declareVar: #sendTrace type: 'volatile int'; declareVar: #byteCount type: 'unsigned long'. "These need to be pointers or unsigned." self declareC: #(instructionPointer method newMethod) as: #usqInt in: aCCodeGenerator. "These are all pointers; char * because Slang has no support for C pointer arithmetic." self declareC: #(localIP localSP localFP stackPointer framePointer stackLimit stackMemory) as: #'char *' in: aCCodeGenerator. self declareC: #(stackPage overflowedPage) as: #'StackPage *' in: aCCodeGenerator. aCCodeGenerator removeVariable: 'stackPages'. "this is an implicit receiver in the translated code." "This defines bytecodeSetSelector as 0 if MULTIPLEBYTECODESETS is not defined, for the benefit of the interpreter on slow machines." aCCodeGenerator addConstantForBinding: (self bindingOf: #MULTIPLEBYTECODESETS). MULTIPLEBYTECODESETS == false ifTrue: [aCCodeGenerator removeVariable: 'extA'; removeVariable: 'extB'; removeVariable: 'bytecodeSetSelector']. aCCodeGenerator var: #methodCache declareC: 'long methodCache[MethodCacheSize + 1 /* ', (MethodCacheSize + 1) printString, ' */]'. aCCodeGenerator var: #atCache declareC: 'sqInt atCache[AtCacheTotalSize + 1 /* ', (AtCacheTotalSize + 1) printString, ' */]'. aCCodeGenerator var: #primitiveTable declareC: 'void (*primitiveTable[MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */])(void) = ', self primitiveTableString. self primitiveTable do: [:symbolOrNot| (symbolOrNot isSymbol and: [symbolOrNot ~~ #primitiveFail]) ifTrue: [(aCCodeGenerator methodNamed: symbolOrNot) ifNotNil: [:tMethod| tMethod returnType: #void]]]. + self objectMemoryClass hasSpurMemoryManagerAPI + ifTrue: + [aCCodeGenerator + var: #primitiveAccessorDepthTable + type: 'signed char' + sizeString: 'MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */' + array: self primitiveAccessorDepthTable] + ifFalse: + [aCCodeGenerator removeVariable: #primitiveAccessorDepthTable]. - self objectMemoryClass basicNew hasSpurMemoryManagerAPI ifTrue: - [aCCodeGenerator - var: #primitiveAccessorDepthTable - type: 'signed char' - sizeString: 'MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */' - array: self primitiveAccessorDepthTable]. aCCodeGenerator var: #primitiveFunctionPointer declareC: 'void (*primitiveFunctionPointer)()'. aCCodeGenerator var: #externalPrimitiveTable declareC: 'void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* ', (MaxExternalPrimitiveTableSize + 1) printString, ' */])(void)'. aCCodeGenerator var: #showSurfaceFn type: #'void *'. aCCodeGenerator var: #jmpBuf declareC: 'jmp_buf jmpBuf[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]'. aCCodeGenerator var: #suspendedCallbacks declareC: 'usqInt suspendedCallbacks[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]'. aCCodeGenerator var: #suspendedMethods declareC: 'usqInt suspendedMethods[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]'. aCCodeGenerator var: #interruptCheckChain declareC: 'void (*interruptCheckChain)(void) = 0'. aCCodeGenerator var: #breakSelector type: #'char *'; var: #breakSelectorLength declareC: 'sqInt breakSelectorLength = -1'.
self declareCAsUSqLong: #(nextPollUsecs nextWakeupUsecs longRunningPrimitiveGCUsecs longRunningPrimitiveStartUsecs longRunningPrimitiveStopUsecs) in: aCCodeGenerator. aCCodeGenerator var: #nextProfileTick type: #sqLong!
Item was changed: ----- Method: StackInterpreter>>checkForAndFollowForwardedPrimitiveState (in category 'primitive support') ----- checkForAndFollowForwardedPrimitiveState "In Spur a primitive may fail due to encountering a forwarder. On failure check the accessorDepth for the primitive and if non-negative scan the args to the depth, following any + forwarders. Answer if any are found so the prim can be retried." + <option: #SpurObjectMemory> - forwarders. Answer if any are found so the prim can be retried.." | primIndex accessorDepth found | self assert: self successful not. found := false. primIndex := self primitiveIndexOf: newMethod. self assert: (self cCode: [primitiveFunctionPointer = (self functionPointerFor: primIndex inClass: objectMemory nilObject)] inSmalltalk: [((primitiveFunctionPointer isInteger and: [primitiveFunctionPointer >= 1000]) ifTrue: [#primitiveExternalCall] ifFalse: [primitiveFunctionPointer]) = (self functionPointerFor: primIndex inClass: objectMemory nilObject)]). self assert: argumentCount = (self argumentCountOf: newMethod). accessorDepth := (primIndex = 117 and: [primitiveFunctionPointer ~~ #primitiveExternalCall]) ifTrue: [self primitiveAccessorDepthForExternalPrimitiveMethod: newMethod] ifFalse: [primitiveAccessorDepthTable at: primIndex]. accessorDepth < 0 ifTrue: [^false]. 0 to: argumentCount do: [:index| | oop | oop := self stackValue: index. (objectMemory isNonImmediate: oop) ifTrue: [(objectMemory isForwarded: oop) ifTrue: [self assert: index < argumentCount. "receiver should have been caught at send time." found := true. oop := objectMemory followForwarded: oop. self stackValue: index put: oop]. ((objectMemory hasPointerFields: oop) and: [objectMemory followForwardedObjectFields: oop toDepth: accessorDepth]) ifTrue: [found := true]]]. ^found!
vm-dev@lists.squeakfoundation.org