[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