[Vm-dev] VM Maker: VMMaker.oscog-eem.314.mcz
Eliot Miranda
eliot.miranda at gmail.com
Wed Jul 31 00:43:41 UTC 2013
On Mon, Jul 29, 2013 at 3:22 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>
> On 30 July 2013 00:14, <commits at source.squeak.org> wrote:
> >
> > Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> > http://source.squeak.org/VMMaker/VMMaker.oscog-eem.314.mcz
> >
> > ==================== Summary ====================
> >
> > Name: VMMaker.oscog-eem.314
> > Author: eem
> > Time: 29 July 2013, 3:13:51.976 pm
> > UUID: e8cba0d1-78b9-4058-820f-62d6e02e180b
> > Ancestors: VMMaker.oscog-eem.312
> >
> > Fix bug in transferTo:(from:) when doing a code compaction when
> > ensuring there is a machine code method when switching to a
> > process whose context has a machine code pc.
> >
>
> That, i hope, was the reason of smallinteger popping out of nowhere on
> stack :)
>
<blush>I think so</blush>. Well, I hope so. Let me know :-)
> >
> > Add an assert to commenceCogCompiledCodeCompaction to catch
> > the actual bug (pushing the instructionPointer twice).
> >
> > Improve inlining via inlineSend:directReturn:exitVar:in: by refactoring
> > argAssignmentsFor:args:in:'s innards. Now global variables are
> > inlined if they are only read within the code being inlined.
> >
> > Implement warningat in term of warning so one only has to remember
> > to set a breakpoint in warning, not both.
> >
> > =============== Diff against VMMaker.oscog-eem.312 ===============
> >
> > Item was changed:
> > ----- Method: CoInterpreter>>commenceCogCompiledCodeCompaction (in
> category 'process primitive support') -----
> > commenceCogCompiledCodeCompaction
> > | startTime |
> > <var: #startTime type: #usqLong>
> > cogCompiledCodeCompactionCalledFor := false.
> > cogit recordEventTrace ifTrue:
> > [self recordTrace: TraceCodeCompaction thing:
> TraceCodeCompaction source: 0].
> > cogit recordPrimTrace ifTrue:
> > [self fastLogPrim: TraceCodeCompaction].
> > startTime := self ioUTCMicrosecondsNow.
> >
> > "This can be called in a number of circumstances. The
> instructionPointer
> > may contain a native pc that must be relocated. There may
> already be a
> > pushed instructionPointer on stack. Clients ensure that
> instructionPointer
> > is 0 if it should not be pushed and/or relocated. Pushing
> twice is a mistake
> > because only the top one will be relocated."
> > instructionPointer ~= 0 ifTrue:
> > + ["better not have already been pushed"
> > + self assert: self stackTop asUnsignedInteger ~=
> instructionPointer.
> > + self push: instructionPointer.
> > - [self push: instructionPointer.
> > self externalWriteBackHeadStackPointer].
> > self assertValidStackedInstructionPointers: #'__LINE__'.
> > cogit compactCogCompiledCode.
> > instructionPointer ~= 0 ifTrue:
> > [instructionPointer := self popStack.
> > self externalWriteBackHeadStackPointer].
> > self assertValidStackedInstructionPointers: #'__LINE__'.
> >
> > statCodeCompactionCount := statCodeCompactionCount + 1.
> > statCodeCompactionUsecs := statCodeCompactionUsecs + (self
> ioUTCMicrosecondsNow - startTime).
> >
> > objectMemory checkForLeaks ~= 0 ifTrue:
> > [objectMemory clearLeakMapAndMapAccessibleObjects.
> > self assert: (self checkCodeIntegrity: false)]!
> >
> > Item was changed:
> > ----- Method: CoInterpreter>>transferTo:from: (in category 'process
> primitive support') -----
> > transferTo: newProc from: sourceCode
> > "Record a process to be awoken on the next interpreter cycle.
> > + Reimplement to record the source of the switch for debugging,
> > + and to cope with possible code compaction in makeBaseFrameFor:."
> > + | activeContext sched oldProc |
> > - Reimplement to record the source of the switch for debugging."
> > <inline: false>
> > self recordContextSwitchFrom: self activeProcess in: sourceCode.
> > + statProcessSwitch := statProcessSwitch + 1.
> > + self push: instructionPointer.
> > + self externalWriteBackHeadFramePointers.
> > + self assertValidExecutionPointe: instructionPointer r:
> framePointer s: stackPointer.
> > + "ensureMethodIsCogged: in makeBaseFrameFor: in
> > + externalSetStackPageAndPointersForSuspendedContextOfProcess:
> > + below may do a code compaction. Nil instructionPointer to avoid
> it getting pushed twice."
> > + instructionPointer := 0.
> > + sched := self schedulerPointer.
> > + oldProc := objectMemory fetchPointer: ActiveProcessIndex
> ofObject: sched.
> > + activeContext := self ensureFrameIsMarried: framePointer SP:
> stackPointer.
> > + objectMemory storePointer: SuspendedContextIndex ofObject:
> oldProc withValue: activeContext.
> > + objectMemory storePointer: ActiveProcessIndex ofObject: sched
> withValue: newProc.
> > + objectMemory storePointerUnchecked: MyListIndex ofObject:
> newProc withValue: objectMemory nilObject.
> > + self
> externalSetStackPageAndPointersForSuspendedContextOfProcess: newProc!
> > - super transferTo: newProc!
> >
> > Item was changed:
> > ----- Method: StackInterpreter class>>preambleCCode (in category
> 'translation') -----
> > preambleCCode
> > ^
> > '/* Disable Intel compiler inlining of warning which is used for
> breakpoints */
> > #pragma auto_inline off
> > void
> > warning(char *s) { /* Print an error message but don''t exit. */
> > printf("\n%s\n", s);
> > }
> > void
> > warningat(char *s, int l) { /* ditto with line number. */
> > + #if 0
> > + printf("\n%s %d\n", s, l);
> > + #else /* use alloca to call warning so one does not have to remember
> to set two breakpoints... */
> > + char *sl = alloca(strlen(s) + 16);
> > + sprintf(sl, "%s %d", s, l);
> > + warning(sl);
> > + #endif
> > - printf("\n%s %d\n", s,l);
> > }
> > #pragma auto_inline on
> >
> > void
> > invalidCompactClassError(char *s) { /* Print a compact class index
> error message and exit. */
> > printf("\nClass %s does not have the required compact class
> index\n", s);
> > exit(-1);
> > }
> >
> > /*
> > * Define sigsetjmp and siglongjmp to be the most minimal
> setjmp/longjmp available on the platform.
> > */
> > #if WIN32
> > # define sigsetjmp(jb,ssmf) setjmp(jb)
> > # define siglongjmp(jb,v) longjmp(jb,v)
> > #else
> > # define sigsetjmp(jb,ssmf) _setjmp(jb)
> > # define siglongjmp(jb,v) _longjmp(jb,v)
> > #endif
> > '!
> >
> > Item was changed:
> > ----- Method: TMethod>>argAssignmentsFor:args:in: (in category
> 'inlining') -----
> > argAssignmentsFor: meth args: argList in: aCodeGen
> > "Return a collection of assignment nodes that assign the given
> argument expressions to the formal parameter variables of the given method."
> > "Optimization: If the actual parameters are either constants or
> local variables in the target method (the receiver), substitute them
> directly into the body of meth. Note that global variables cannot be
> subsituted because the inlined method might depend on the exact ordering of
> side effects to the globals."
> >
> > | stmtList substitutionDict |
> > stmtList := OrderedCollection new: 100.
> > substitutionDict := Dictionary new: 100.
> > meth args with: argList do:
> > [ :argName :exprNode |
> > + (self isNode: exprNode substitutableFor: argName
> inMethod: meth in: aCodeGen)
> > - (self isSubstitutableNode: exprNode intoMethod: meth in:
> aCodeGen)
> > ifTrue:
> > [substitutionDict at: argName put:
> exprNode.
> > locals remove: argName]
> > ifFalse:
> > [stmtList add: (TAssignmentNode new
> >
> setVariable: (TVariableNode new setName: argName)
> >
> expression: exprNode copy)]].
> > meth parseTree: (meth parseTree bindVariablesIn:
> substitutionDict).
> > ^stmtList!
> >
> > Item was added:
> > + ----- Method: TMethod>>isNode:substitutableFor:inMethod:in: (in
> category 'inlining') -----
> > + isNode: aNode substitutableFor: argName inMethod: targetMeth in:
> aCodeGen
> > + "Answer true if the given parameter node is either a constant, a
> local variable, or a formal parameter of the receiver. Such parameter nodes
> may be substituted directly into the body of the method during inlining.
> Note that global variables cannot be subsituted into methods with possible
> side effects (i.e., methods that may assign to global variables) because
> the inlined method might depend on having the value of the global variable
> captured when it is passed in as an argument."
> > +
> > + | var |
> > + aNode isConstant ifTrue: [^true].
> > +
> > + aNode isVariable ifTrue:
> > + [var := aNode name.
> > + ((locals includes: var) or: [args includes: var])
> ifTrue: [^true].
> > + (#(self true false nil) includes: var) ifTrue: [^true].
> > + "We can substitute any variable provided it is only read
> in the method being inlined."
> > + (targetMeth isComplete
> > + and: [targetMeth parseTree noneSatisfy:
> > + [:node|
> > + node isAssignment and: [node variable
> name = argName]]]) ifTrue:
> > + [^true].
> > + (targetMeth maySubstituteGlobal: var in: aCodeGen)
> ifTrue: [^true]].
> > +
> > + "For now allow literal blocks to be substituted. They better be
> accessed only
> > + with value[:value:*] messages though!!"
> > + aNode isStmtList ifTrue: [^true].
> > +
> > + "scan expression tree; must contain only constants, builtin ops,
> and inlineable vars"
> > + aNode nodesDo: [ :node |
> > + node isSend ifTrue: [
> > + node isBuiltinOperator ifFalse: [^false].
> > + ].
> > + node isVariable ifTrue: [
> > + var := node name.
> > + ((locals includes: var) or:
> > + [(args includes: var) or:
> > + [(#(self true false nil) includes: var) or:
> > + [targetMeth maySubstituteGlobal: var in:
> aCodeGen]]]) ifFalse: [^false].
> > + ].
> > + (node isConstant or: [node isVariable or: [node
> isSend]]) ifFalse: [^false].
> > + ].
> > +
> > + ^ true!
> >
>
>
>
> --
> Best regards,
> Igor Stasenko.
>
--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20130730/c072c8c8/attachment.htm
More information about the Vm-dev
mailing list