[Vm-dev] VM Maker: VMMaker.oscog-eem.3071.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Sep 17 02:50:09 UTC 2021
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3071.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3071
Author: eem
Time: 16 September 2021, 7:49:59.194516 pm
UUID: ae226d69-be9f-4f7a-a138-0c85163277dd
Ancestors: VMMaker.oscog-eem.3070
Allow cFramePointerInUse to be defined at compile time. Some compilers do not use the frame pointer consistently and don't allow overriding their inconsistent use (clang-cl 10).
Clue StackDepthFinder into the implicit literal enumeration fix.
=============== Diff against VMMaker.oscog-eem.3070 ===============
Item was changed:
----- Method: CoInterpreter>>checkIfCFramePointerInUse (in category 'cog jit support') -----
checkIfCFramePointerInUse
<api>
"Necessary because we very much want CStackPointer and CFramePointer to be static/private and grouped
+ with other interpreter variables which will hence be accessed via VarBaseReg on platforms that have one."
- with other interpreter variables which will hence be accessed via VarBaseReg on platforms trhat have one."
^self isCFramePointerInUse: (self addressOf: CFramePointer) _: (self addressOf: CStackPointer)!
Item was changed:
----- Method: CoInterpreter>>enterSmalltalkExecutiveImplementation (in category 'initialization') -----
enterSmalltalkExecutiveImplementation
"Main entry-point into the interpreter at each execution level, where an execution
level is either the start of execution or reentry for a callback. Capture the C stack
pointers so that calls from machine-code into the C run-time occur at this level.
This is the actual implementation, separated from enterSmalltalkExecutive so the
+ simulator can wrap it in an exception handler and hence simulate the Cogit's jump
+ back into C code on interpreting; see ceInvokeInterpret.
+
+ Conceptually, an invocation of interpret exists at each level of execution from the
+ initial invocation through each callback. Entry to each execution level is through
+ this function. It captures the C stack & frame pointers for this level of execution
+ and then either invokes machine code or interpret, depending on whether the
+ current frame (the effective entry-point into Smalltalk execution) is a machine code
+ or interpreted frame. In addition, interpret captures the return address of its caller
+ (this funciton). The Cogit then uses the captured C stack pointers and return
+ address to invoke interpret as if it had been called from this function."
- simulator can wrap it in an exception handler and hence simulate the setjmp/longjmp."
<inline: false>
cogit assertCStackWellAligned.
cogit ceCaptureCStackPointers.
(self isMachineCodeFrame: framePointer) ifTrue:
[self returnToExecutive: false postContextSwitch: true
"NOTREACHED"].
self interpret.
^0!
Item was changed:
----- Method: Cogit class>>declareCVarsIn: (in category 'translation') -----
declareCVarsIn: aCCodeGenerator
| backEnd |
backEnd := CogCompilerClass basicNew.
#( 'coInterpreter' 'objectMemory' 'methodZone' 'objectRepresentation'
'cogBlockMethodSurrogateClass' 'cogMethodSurrogateClass' 'nsSendCacheSurrogateClass'
'threadManager' 'processor' 'lastNInstructions' 'simulatedAddresses' 'ioHighResClock'
'simulatedTrampolines' 'simulatedVariableGetters' 'simulatedVariableSetters'
'processorFrameValid' 'printRegisters' 'printInstructions' 'clickConfirm' 'singleStep'
'codeZoneIsExecutableNotWritable' 'debugAPISelector' 'shortCutTrampolineBlocks'
'perMethodProfile' 'instructionProfile') do:
[:simulationVariableUnusedByRealVM|
aCCodeGenerator removeVariable: simulationVariableUnusedByRealVM].
NewspeakVM ifFalse:
[#( 'selfSendTrampolines' 'dynamicSuperSendTrampolines'
'implicitReceiverSendTrampolines' 'outerSendTrampolines'
'ceEnclosingObjectTrampoline' 'numIRCs' 'indexOfIRC' 'theIRCs') do:
[:variableNotNeededInNormalVM|
aCCodeGenerator removeVariable: variableNotNeededInNormalVM]].
aCCodeGenerator removeConstant: #COGMTVM. "this should be defined at compile time"
"N.B. We *do not* include sq.h; it pulls in conflicting definitions now that sqVirtualMachine.h
declares cointerp's functions, and declares some of them inaccurately for histrical reasons.
We pull in CoInterpreter's api via cointerp.h which is accurate."
aCCodeGenerator
addHeaderFile:'"sqConfig.h"'; "config.h must be first on linux"
addHeaderFile:'<stddef.h>'; "for e.g. offsetof"
addHeaderFile:'<stdio.h>';
addHeaderFile:'<stdlib.h>';
addHeaderFile:'<string.h>';
addHeaderFile:'"sqPlatformSpecific.h"'; "e.g. solaris overrides things for sqCogStackAlignment.h"
addHeaderFile:'"sqMemoryAccess.h"';
addHeaderFile:'"sqCogStackAlignment.h"';
addHeaderFile:'"dispdbg.h"'; "must precede cointerp.h & cogit.h otherwise NoDbgRegParms gets screwed up"
addHeaderFile:'"cogmethod.h"'.
NewspeakVM ifTrue:
[aCCodeGenerator addHeaderFile:'"nssendcache.h"'].
aCCodeGenerator
addHeaderFile:'#if COGMTVM';
addHeaderFile:'"cointerpmt.h"';
addHeaderFile:'#else';
addHeaderFile:'"cointerp.h"';
addHeaderFile:'#endif';
addHeaderFile:'"cogit.h"'.
aCCodeGenerator
var: #ceGetFP
declareC: 'usqIntptr_t (*ceGetFP)(void)';
var: #ceGetSP
declareC: 'usqIntptr_t (*ceGetSP)(void)';
var: #ceCaptureCStackPointers
declareC: 'void (*ceCaptureCStackPointers)(void)';
var: #ceInvokeInterpret
declareC: 'void (*ceInvokeInterpret)(void)';
var: #ceEnterCogCodePopReceiverReg
declareC: 'void (*ceEnterCogCodePopReceiverReg)(void)';
var: #realCEEnterCogCodePopReceiverReg
declareC: 'void (*realCEEnterCogCodePopReceiverReg)(void)';
var: #ceCallCogCodePopReceiverReg
declareC: 'void (*ceCallCogCodePopReceiverReg)(void)';
var: #realCECallCogCodePopReceiverReg
declareC: 'void (*realCECallCogCodePopReceiverReg)(void)';
var: #ceCallCogCodePopReceiverAndClassRegs
declareC: 'void (*ceCallCogCodePopReceiverAndClassRegs)(void)';
var: #realCECallCogCodePopReceiverAndClassRegs
declareC: 'void (*realCECallCogCodePopReceiverAndClassRegs)(void)';
var: #postCompileHook
declareC: 'void (*postCompileHook)(CogMethod *)';
var: #openPICList declareC: 'CogMethod *openPICList = 0';
var: #maxMethodBefore type: #'CogBlockMethod *';
var: 'enumeratingCogMethod' type: #'CogMethod *'.
aCCodeGenerator
var: #ceTryLockVMOwner
declareC: '#if COGMTVM\usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t)\#endif'.
backEnd numICacheFlushOpcodes > 0 ifTrue:
[aCCodeGenerator
var: #ceFlushICache
declareC: 'static void (*ceFlushICache)(usqIntptr_t from, usqIntptr_t to)'].
aCCodeGenerator
var: #ceFlushDCache
declareC: '#if DUAL_MAPPED_CODE_ZONE\static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to)\#endif';
var: #codeToDataDelta
+ declareC: '#if DUAL_MAPPED_CODE_ZONE\static sqInt codeToDataDelta\#else\# define codeToDataDelta 0\#endif';
+ var: #cFramePointerInUse
+ declareC: '#if !!defined(cFramePointerInUse)\sqInt cFramePointerInUse\#endif'.
- declareC: '#if DUAL_MAPPED_CODE_ZONE\static sqInt codeToDataDelta\#else\# define codeToDataDelta 0\#endif'.
aCCodeGenerator
declareVar: 'aMethodLabel' type: #'AbstractInstruction'; "Has to come lexicographically before backEnd & methodLabel"
var: #backEnd declareC: 'AbstractInstruction * const backEnd = &aMethodLabel';
var: #methodLabel declareC: 'AbstractInstruction * const methodLabel = &aMethodLabel'.
self declareC: #(abstractOpcodes stackCheckLabel
blockEntryLabel blockEntryNoContextSwitch
stackOverflowCall sendMiss
entry noCheckEntry selfSendEntry dynSuperEntry
fullBlockNoContextSwitchEntry fullBlockEntry
picMNUAbort picInterpretAbort endCPICCase0 endCPICCase1 cPICEndOfCodeLabel)
as: #'AbstractInstruction *'
in: aCCodeGenerator.
aCCodeGenerator
declareVar: #cPICPrototype type: #'CogMethod *';
declareVar: #blockStarts type: #'BlockStart *';
declareVar: #fixups type: #'BytecodeFixup *';
declareVar: #methodZoneBase type: #usqInt.
aCCodeGenerator
var: #ordinarySendTrampolines
declareC: 'sqInt ordinarySendTrampolines[NumSendTrampolines]';
var: #superSendTrampolines
declareC: 'sqInt superSendTrampolines[NumSendTrampolines]'.
BytecodeSetHasDirectedSuperSend ifTrue:
[aCCodeGenerator
var: #directedSuperSendTrampolines
declareC: 'sqInt directedSuperSendTrampolines[NumSendTrampolines]';
var: #directedSuperBindingSendTrampolines
declareC: 'sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]'].
NewspeakVM ifTrue:
[aCCodeGenerator
var: #selfSendTrampolines
declareC: 'sqInt selfSendTrampolines[NumSendTrampolines]';
var: #dynamicSuperSendTrampolines
declareC: 'sqInt dynamicSuperSendTrampolines[NumSendTrampolines]';
var: #implicitReceiverSendTrampolines
declareC: 'sqInt implicitReceiverSendTrampolines[NumSendTrampolines]';
var: #outerSendTrampolines
declareC: 'sqInt outerSendTrampolines[NumSendTrampolines]'].
aCCodeGenerator
addConstantForBinding: self bindingForNumTrampolines;
var: #trampolineAddresses
declareC: 'static char *trampolineAddresses[NumTrampolines*2]';
var: #objectReferencesInRuntime
declareC: 'static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]';
var: #labelCounter
type: #int;
var: #traceFlags
declareC: 'int traceFlags = 8 /* prim trace log on by default */';
var: #cStackAlignment
declareC: 'const int cStackAlignment = STACK_ALIGN_BYTES'.
aCCodeGenerator
declareVar: #minValidCallAddress type: #'usqIntptr_t'.
aCCodeGenerator vmClass generatorTable ifNotNil:
[:bytecodeGenTable|
aCCodeGenerator
var: #generatorTable
declareC: 'static BytecodeDescriptor generatorTable[', bytecodeGenTable size printString, ']',
(self tableInitializerFor: bytecodeGenTable
in: aCCodeGenerator)].
"In C the abstract opcode names clash with the Smalltalk generator syntactic sugar.
Most of the syntactic sugar is inlined, but alas some remains. Rename the syntactic
sugar to avoid the clash."
(self organization listAtCategoryNamed: #'abstract instructions') do:
[:s|
aCCodeGenerator addSelectorTranslation: s to: 'g', (aCCodeGenerator cFunctionNameFor: s)].
aCCodeGenerator addSelectorTranslation: #halt: to: 'haltmsg'.
self declareFlagVarsAsByteIn: aCCodeGenerator!
Item was changed:
----- Method: Cogit>>generateStackPointerCapture (in category 'initialization') -----
generateStackPointerCapture
"Generate a routine ceCaptureCStackPointers that will capture the C stack pointer,
and, if it is in use, the C frame pointer. These are used in trampolines to call
run-time routines in the interpreter from machine-code."
+ self cppIf: #cFramePointerInUse defined
+ ifTrue:
+ [self assertCStackWellAligned.
+ self generateCaptureCStackPointers: cFramePointerInUse]
+ ifFalse:
+ [| oldMethodZoneBase oldTrampolineTableIndex |
+ cFramePointerInUse := false. "For the benefit of the following assert, assume the minimum at first."
+ self assertCStackWellAligned.
+ oldMethodZoneBase := methodZoneBase.
+ oldTrampolineTableIndex := trampolineTableIndex.
+ self generateCaptureCStackPointers: true.
+ self perform: #ceCaptureCStackPointers.
+ (cFramePointerInUse := coInterpreter checkIfCFramePointerInUse) ifFalse:
+ [methodZoneBase := oldMethodZoneBase.
+ trampolineTableIndex := oldTrampolineTableIndex.
+ self generateCaptureCStackPointers: false]].
- | oldMethodZoneBase oldTrampolineTableIndex |
- cFramePointerInUse := false. "For the benefit of the following assert, assume the minimum at first."
- self assertCStackWellAligned.
- oldMethodZoneBase := methodZoneBase.
- oldTrampolineTableIndex := trampolineTableIndex.
- self generateCaptureCStackPointers: true.
- self perform: #ceCaptureCStackPointers.
- (cFramePointerInUse := coInterpreter checkIfCFramePointerInUse) ifFalse:
- [methodZoneBase := oldMethodZoneBase.
- trampolineTableIndex := oldTrampolineTableIndex.
- self generateCaptureCStackPointers: false].
self ensureWritableCodeZone.
self assertCStackWellAligned!
Item was added:
+ ----- Method: StackDepthFinder>>pushSpecialConstant: (in category 'instruction decoding implicit literals') -----
+ pushSpecialConstant: value
+ ^self pushConstant: value!
Item was added:
+ ----- Method: StackDepthFinder>>sendSpecial:numArgs: (in category 'instruction decoding implicit literals') -----
+ sendSpecial: aSymbol numArgs: numArgs
+ ^self send: aSymbol super: false numArgs: numArgs!
More information about the Vm-dev
mailing list