[Vm-dev] VM Maker: VMMaker.oscog-eem.1847.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Apr 26 15:52:53 UTC 2016
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1847.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1847
Author: eem
Time: 26 April 2016, 8:49:48.651885 am
UUID: cc80350d-f8a9-47e6-960f-a0e31e20d725
Ancestors: VMMaker.oscog-cb.1846
primitiveVoidVMStateForMethod: ensureAllContextsWithMethodHaveBytecodePCs: should widow contexts, otherwise "separated" but not yet widowed contexts may persist..
Cogit: reorder annotation constants to simplify isPCMappedAnnotation:.
Simulation: fix receivers of integerObjectOf: in recent multiply prim changes.
=============== Diff against VMMaker.oscog-cb.1846 ===============
Item was changed:
----- Method: CoInterpreter>>ensureAllContextsWithMethodHaveBytecodePCs: (in category 'frame access') -----
ensureAllContextsWithMethodHaveBytecodePCs: methodObj
"Map all native pcs to bytecoded pcs in all contexts on methodObj.
Used to implement primitiveVoidVMStateForMethod."
objectMemory allObjectsDo:
[:oop|
((objectMemory isContextNonImm: oop)
and: [(objectMemory fetchPointer: MethodIndex ofObject: oop) = methodObj]) ifTrue:
[(self isMarriedOrWidowedContext: oop)
ifTrue:
+ "Since any machine-code frame activations of the method have been divorced
+ there should only be interpreted activations of marriecd contexts."
+ [(self isWidowedContext: oop) ifFalse:
+ [self deny: (self isMachineCodeFrame: (self frameOfMarriedContext: oop))]]
- [(self checkIsStillMarriedContext: oop currentFP: stackPage headFP) ifTrue:
- [self assert: (self isMachineCodeFrame: (self frameOfMarriedContext: oop)) not]]
ifFalse:
[self ensureContextHasBytecodePC: oop]]]!
Item was changed:
----- Method: Cogit class>>initializeAnnotationConstants (in category 'class initialization') -----
initializeAnnotationConstants
"These form the method map for a cog method. The map defines which addresses
in a machine code method are ones with important functions, such as being a send
site or being a reference to a heap object. Each annotated instruction has a byte
in the map, and each byte in the map has two parts. In the least signficant bits are
a distance in codeGranularity units from the start of the method or the previous
map entry, except for the IsAnnotationExtension type. In the most signficant bits
are the type of annotation at the point reached. A null byte ends the map. The
first mapped location is a distance from the cmNoCheckEntryOffset.
The map occurs at the end of a method (*), in reverse, so that its start is found
by adding the method's block size. If the distance between two mapped
instructions will not fit in the displacement field then one or more displacement
entries are placed in the map to bridge the gap. There is a * 32 displacement
units type for spanning large gaps. The displacements are in codeGranularity
units so that processors like e.g. ARM, with 4-byte instructions, do not have overly
large maps. In [practice maps are very compact, but they should be as quick to
navigate as possible, and hence be as compact as possible.
There is only one kind of call annotation that serves for all calls from machine
code. There are several kinds of call, sends, super sends, calls of the generated
run-time, and direct calls of primitive functions in the interpreter. These need
different treatment at different times. For example, when the send cache is
flushed or the method zone is shrunk some sends must be unlinked and some
sends must be relocated. But to be able to parse bytecoded methods and match
their pcs with corresponding machine code pcs the map needs to differentiate
between sends and run-time calls.
Sends can be distinguished from run-time or direct primitive calls based on address;
only sends have their target between methodZoneBase and methodZone freeStart.
We used to distinguish normal sends from super sends based on alignment of
entry-point, because normal sends link to the checked entry-point, whereas super sends
link to the unchecked entry-point, and both entry points have different alignments.
But now we use the IsAnnotationExtension to label sends other than normal sends.
For these ``exotic'' sends there is both an IsAnnotationExtension annotation and an
IsSendCall annotation.
While run-time calls can be distinguished from direct primitive calls on the basis
of address there is no need to do so. They are merely calls to locations that
don't move during method zone compaction.
Absolute PC references are used for method references and counter references.
These are references from within a particular method to absolute pcs in that same
method that must be relocated when the method moves."
"self initializeAnnotationConstants"
AnnotationShift := 5.
IsDisplacementX2N := 0. "N.B. A 0 byte ends the map"
IsAnnotationExtension := 1. "Used to extend IsSendCall with different codes for exotic send types."
IsObjectReference := 2.
IsAbsPCReference := 3.
+ IsRelativeCall := 4.
+ HasBytecodePC := 5.
- HasBytecodePC := 4.
- IsRelativeCall := 5.
IsNSSendCall := NewspeakVM ifTrue: [6].
IsSendCall := 7.
"These are formed by combining IsSendCall and IsAnnotationExtension annotations."
IsSuperSend := 8.
IsDirectedSuperSend := 9.
IsNSSelfSend := NewspeakVM ifTrue: [10].
IsNSDynamicSuperSend := NewspeakVM ifTrue: [11].
IsNSImplicitReceiverSend := NewspeakVM ifTrue: [12].
DisplacementMask := (1 << AnnotationShift) - 1.
DisplacementX2N := IsDisplacementX2N << AnnotationShift.
FirstAnnotation := IsObjectReference << AnnotationShift.
MaxX2NDisplacement := DisplacementMask << AnnotationShift.
MapEnd := 0.
AnnotationConstantNames := #( IsDisplacementX2N
IsAnnotationExtension
IsObjectReference
IsAbsPCReference
HasBytecodePC
IsRelativeCall
IsNSSendCall
IsSendCall
IsSuperSend
IsDirectedSuperSend
IsNSSelfSend
IsNSDynamicSuperSend
IsNSImplicitReceiverSend).
AnnotationsWithBytecodePCs := #(HasBytecodePC
IsNSSendCall
IsSendCall
IsSuperSend
IsDirectedSuperSend
IsNSSelfSend
IsNSDynamicSuperSend
IsNSImplicitReceiverSend)!
Item was changed:
----- Method: Cogit>>isPCMappedAnnotation: (in category 'method map') -----
isPCMappedAnnotation: annotation
+ "See Cogit class>>initializeAnnotationConstants"
<inline: true>
+ ^annotation >= HasBytecodePC!
- ^annotation >= IsSendCall
- or: [annotation = HasBytecodePC
- or: [NewspeakVM and: [annotation = IsNSSendCall]]]!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveMultiply (in category 'arithmetic integer primitives') -----
primitiveMultiply
| integerRcvr integerArg integerResult overflow |
integerRcvr := self stackIntegerValue: 1.
integerArg := self stackIntegerValue: 0.
self successful ifTrue:
[overflow := integerRcvr > 0
ifTrue: [integerArg > 0
ifTrue: [integerRcvr > (objectMemory maxSmallInteger / integerArg)]
ifFalse: [integerArg < (objectMemory minSmallInteger / integerRcvr)]]
ifFalse: [integerArg > 0
ifTrue: [integerRcvr < (objectMemory minSmallInteger / integerArg)]
ifFalse: [(integerRcvr < 0) and: [integerArg < (objectMemory maxSmallInteger / integerRcvr)]]].
overflow
ifTrue: [self primitiveFail]
ifFalse:
[integerResult := integerRcvr * integerArg.
+ self pop: 2 thenPush: (objectMemory integerObjectOf: integerResult)]]!
- self pop: 2 thenPush: (self integerObjectOf: integerResult)]]!
Item was changed:
----- Method: StackInterpreter>>bytecodePrimMultiply (in category 'common selector sends') -----
bytecodePrimMultiply
| rcvr arg result overflow oop |
rcvr := self internalStackValue: 1.
arg := self internalStackValue: 0.
(objectMemory areIntegers: rcvr and: arg)
ifTrue: [rcvr := objectMemory integerValueOf: rcvr.
arg := objectMemory integerValueOf: arg.
overflow := rcvr > 0
ifTrue: [arg > 0
ifTrue: [rcvr > (objectMemory maxSmallInteger / arg)]
ifFalse: [arg < (objectMemory minSmallInteger / rcvr)]]
ifFalse: [arg > 0
ifTrue: [rcvr < (objectMemory minSmallInteger / arg)]
ifFalse: [(rcvr < 0) and: [arg < (objectMemory maxSmallInteger / rcvr)]]].
overflow
ifFalse:
[result := rcvr * arg.
+ oop := objectMemory integerObjectOf: result.
- oop := self integerObjectOf: result.
self internalPop: 2 thenPush: oop.
^self fetchNextBytecode "success"]]
ifFalse: [self initPrimCall.
self externalizeIPandSP.
self primitiveFloatMultiply: rcvr byArg: arg.
self internalizeIPandSP.
self successful ifTrue: [^ self fetchNextBytecode "success"]].
messageSelector := self specialSelector: 8.
argumentCount := 1.
self normalSend!
More information about the Vm-dev
mailing list