[Vm-dev] VM Maker: VMMaker.oscog-rmacnak.1375.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Jun 23 05:09:25 UTC 2015


Ryan Macnak uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-rmacnak.1375.mcz

==================== Summary ====================

Name: VMMaker.oscog-rmacnak.1375
Author: rmacnak
Time: 22 June 2015, 10:07:47.302 pm
UUID: 2834a848-0c6d-4c29-bd1e-a43ad70450d9
Ancestors: VMMaker.oscog-cb.1374

Do proper lookups for implicit receiver and outer send misses from cogged code.

=============== Diff against VMMaker.oscog-cb.1374 ===============

Item was changed:
  ----- Method: CoInterpreter>>ceImplicitReceiverSend:receiver: (in category 'trampolines') -----
  ceImplicitReceiverSend: cacheAddress receiver: methodReceiver
  	"An implicit receiver send cache missed."
+ 	| nsSendCache methodReceiverClassTag cogMethod errSelIdx |
- 	| nsSendCache methodMixin numArgs selector implicitReceiver cogMethod irClassTag mrClassTag errSelIdx |
  	<api>
  	<option: #NewspeakVM>
  	<inline: false>
  	<var: #nsSendCache type: #'NSSendCache *'>
  	<var: #cogMethod type: #'CogMethod *'>
  
  	cogit assertCStackWellAligned.
  	self assert: (objectMemory addressCouldBeOop: methodReceiver).
+ 	self deny: (objectMemory isOopForwarded: methodReceiver).
  
  	nsSendCache := self cCoerceSimple: cacheAddress to: #'NSSendCache *'.
+ 	messageSelector := nsSendCache selector.
+ 	argumentCount := nsSendCache numArgs.
+ 	method := (self mframeHomeMethod: framePointer) methodObject.
- 	selector := nsSendCache selector.
- 	numArgs := nsSendCache numArgs.
- 	methodMixin := self mMethodClass.
  
+ 	self assert: (self stackValue: argumentCount + 1 "ret addr") = methodReceiver.
- 	implicitReceiver := self
- 		implicitReceiverFor: methodReceiver
- 		mixin: methodMixin
- 		implementing: selector.
  
+ 	methodReceiverClassTag := objectMemory fetchClassTagOf: methodReceiver.
- 	self assert: (self stackValue: numArgs + 1 "ret val") = methodReceiver.
- 	self stackValue: numArgs + 1 "ret val " put: implicitReceiver.
- 	"Replace the methodReceiver on the stack with the implicitReceiver. When the cache has
- 	a hit, we don't care that the value on the stack is wrong because the compiled callee will
- 	use the value in ReceiverResultReg to build its frame. But the interpreter will use
- 	stack(numArgs)."
  
+ 	(self
+ 		inlineLookupInNSMethodCacheSel: messageSelector
+ 		classTag: methodReceiverClassTag
+ 		method: method
+ 		lookupRule: LookupRuleImplicit)
+ 			ifTrue:
+ 				[localAbsentReceiverOrZero = 0
+ 					ifTrue: [localAbsentReceiver := methodReceiver]
+ 					ifFalse: [localAbsentReceiver := localAbsentReceiverOrZero].
+ 				"check for coggability because method is in the cache"
+ 				self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector]
+ 			ifFalse:
+ 				[self deny: (objectMemory isOopForwarded: messageSelector).
+ 				self deny: (objectMemory isForwardedClassTag: methodReceiverClassTag).
+ 				lkupClassTag := methodReceiverClassTag.
+ 				errSelIdx := self lookupImplicitReceiverSendNoMNU: methodReceiver.
+ 				errSelIdx ~= 0 ifTrue:
+ 					[self assert: errSelIdx == SelectorDoesNotUnderstand.
+ 					self handleMNU: errSelIdx 
+ 						InMachineCodeTo: methodReceiver
+ 						classForMessage: (objectMemory classForClassTag: methodReceiverClassTag).
+ 					self unreachable].
+ 				self addNewMethodToNSCache: LookupRuleImplicit].
- 	mrClassTag := objectMemory fetchClassTagOf: methodReceiver.
- 	irClassTag := objectMemory fetchClassTagOf: implicitReceiver.
- 	argumentCount := numArgs.
  
+ 	"Fix stacked receiver."
+ 	self stackValue: argumentCount + 1 "ret addr" put: localAbsentReceiver.
- 	(self lookupInMethodCacheSel: selector classTag: irClassTag)
- 		ifTrue: ["check for coggability because method is in the cache"
- 			self ifAppropriateCompileToNativeCode: newMethod selector: selector]
- 		ifFalse: [
- 			(objectMemory isOopForwarded: selector) ifTrue:
- 				[self error: 'Selector should have fixed by mapObjectReferencesInMachineCodeForBecome'].
- 			(objectMemory isForwardedClassTag: irClassTag) ifTrue:
- 				[self error: 'Implicit receiver lookup should have followed fowarded objects'].
- 			messageSelector := selector.
- 			(errSelIdx := self lookupMethodNoMNUEtcInClass: (objectMemory classForClassTag: irClassTag)) ~= 0
- 				ifTrue: [[self handleMNU: errSelIdx InMachineCodeTo: implicitReceiver classForMessage: (objectMemory classForClassTag: irClassTag).
- 						self error: 'UNREACHABLE3']]].
  
  	(self maybeMethodHasCogMethod: newMethod) 
  		ifTrue: [
  			cogMethod := self cogMethodOf: newMethod.
  			cogMethod selector = objectMemory nilObject
+ 				ifTrue: [cogit setSelectorOf: cogMethod to: messageSelector]
- 				ifTrue: [cogit setSelectorOf: cogMethod to: selector]
  				ifFalse: ["Deal with anonymous accessors, e.g. in Newspeak.
  					The cogMethod may not have the
  					correct selector. If not, try and compile a new method
  					with the correct selector."
+ 					cogMethod selector ~= messageSelector ifTrue: [
+ 							(cogit cog: newMethod selector: messageSelector)
- 					cogMethod selector ~= selector ifTrue: [
- 							(cogit cog: newMethod selector: selector)
  								ifNotNil: [:newCogMethod | cogMethod := newCogMethod]]].
+ 			cogMethod selector = messageSelector
- 			cogMethod selector = selector
  				ifTrue:
  					[cogit
  						linkNSSendCache: nsSendCache 
+ 						classTag: methodReceiverClassTag
+ 						enclosingObject: localAbsentReceiverOrZero
- 						classTag: mrClassTag
- 						enclosingObject: (implicitReceiver = methodReceiver
- 							ifTrue: [0] ifFalse: [implicitReceiver])
  						target: cogMethod
  						caller: self mframeHomeMethodExport]
  				ifFalse: ["Out of code memory. Fall through to interpret."].
  			instructionPointer := self popStack.
  			self executeNewMethod.
+ 			self unreachable].
- 			self error: 'UNREACHABLE 1'].
  	instructionPointer := self popStack.
  	self interpretMethodFromMachineCode.
+ 	self unreachable.!
- 	self error: 'UNREACHABLE 2'.
- 	^nil!

Item was changed:
  ----- Method: CoInterpreter>>ceOuterSend:receiver: (in category 'trampolines') -----
  ceOuterSend: cacheAddress receiver: methodReceiver
  	"An outer send cache missed."
+ 	| nsSendCache depth methodReceiverClassTag cogMethod errSelIdx |
- 	| nsSendCache methodMixin numArgs selector depth enclosingObject cogMethod eoClassTag mrClassTag errSelIdx |
  	<api>
  	<option: #NewspeakVM>
  	<inline: false>
  	<var: #nsSendCache type: #'NSSendCache *'>
  	<var: #cogMethod type: #'CogMethod *'>
  
  	cogit assertCStackWellAligned.
  	self assert: (objectMemory addressCouldBeOop: methodReceiver).
+ 	self deny: (objectMemory isOopForwarded: methodReceiver).
  
  	nsSendCache := self cCoerceSimple: cacheAddress to: #'NSSendCache *'.
+ 	messageSelector := nsSendCache selector.
+ 	argumentCount := nsSendCache numArgs.
- 	selector := nsSendCache selector.
- 	numArgs := nsSendCache numArgs.
  	depth := nsSendCache depth.
+ 	method := (self mframeHomeMethod: framePointer) methodObject.
- 	methodMixin := self mMethodClass.
  
+ 	self assert: (self stackValue: argumentCount + 1 "ret addr") = methodReceiver.
- 	enclosingObject := self
- 		enclosingObjectAt: depth
- 		withObject: methodReceiver
- 		withMixin: methodMixin.
  
+ 	methodReceiverClassTag := objectMemory fetchClassTagOf: methodReceiver.
- 	self assert: (self stackValue: numArgs + 1 "ret val") = methodReceiver.
- 	self stackValue: numArgs + 1 "ret val " put: enclosingObject.
- 	"Replace the methodReceiver on the stack with the enclosingObject. When the cache has
- 	a hit, we don't care that the value on the stack is wrong because the compiled callee will
- 	use the value in ReceiverResultReg to build its frame. But the interpreter will use
- 	stack(numArgs)."
  
+ 	(self
+ 		inlineLookupInNSMethodCacheSel: messageSelector
+ 		classTag: methodReceiverClassTag
+ 		method: method
+ 		lookupRule: depth)
+ 			ifTrue:
+ 				[localAbsentReceiverOrZero = 0
+ 					ifTrue: [localAbsentReceiver := methodReceiver]
+ 					ifFalse: [localAbsentReceiver := localAbsentReceiverOrZero].
+ 				"check for coggability because method is in the cache"
+ 				self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector]
+ 			ifFalse:
+ 				[self deny: (objectMemory isOopForwarded: messageSelector).
+ 				self deny: (objectMemory isForwardedClassTag: methodReceiverClassTag).
+ 				lkupClassTag := methodReceiverClassTag.
+ 				errSelIdx := self lookupOuterSendNoMNU: methodReceiver depth: depth.
+ 				errSelIdx ~= 0 ifTrue:
+ 					[self assert: errSelIdx == SelectorDoesNotUnderstand.
+ 					self handleMNU: errSelIdx 
+ 						InMachineCodeTo: methodReceiver
+ 						classForMessage: (objectMemory classForClassTag: methodReceiverClassTag).
+ 					self unreachable].
+ 				self addNewMethodToNSCache: depth].
- 	mrClassTag := objectMemory fetchClassTagOf: methodReceiver.
- 	eoClassTag := objectMemory fetchClassTagOf: enclosingObject.
- 	argumentCount := numArgs.
  
+ 	"Fix stacked receiver."
+ 	self stackValue: argumentCount + 1 "ret addr" put: localAbsentReceiver.
- 	(self lookupInMethodCacheSel: selector classTag: eoClassTag)
- 		ifTrue: ["check for coggability because method is in the cache"
- 			self ifAppropriateCompileToNativeCode: newMethod selector: selector]
- 		ifFalse: [
- 			(objectMemory isOopForwarded: selector) ifTrue:
- 				[self error: 'Selector should have fixed by mapObjectReferencesInMachineCodeForBecome'].
- 			(objectMemory isForwardedClassTag: eoClassTag) ifTrue:
- 				[self error: 'Implicit receiver lookup should have followed fowarded objects'].
- 			messageSelector := selector.
- 			(errSelIdx := self lookupMethodNoMNUEtcInClass: (objectMemory classForClassTag: eoClassTag)) ~= 0
- 				ifTrue: [[self handleMNU: errSelIdx InMachineCodeTo: enclosingObject classForMessage: (objectMemory classForClassTag: eoClassTag).
- 						self error: 'UNREACHABLE3']]].
  
  	(self maybeMethodHasCogMethod: newMethod) 
  		ifTrue: [
  			cogMethod := self cogMethodOf: newMethod.
  			cogMethod selector = objectMemory nilObject
+ 				ifTrue: [cogit setSelectorOf: cogMethod to: messageSelector]
- 				ifTrue: [cogit setSelectorOf: cogMethod to: selector]
  				ifFalse: ["Deal with anonymous accessors, e.g. in Newspeak.
  					The cogMethod may not have the
  					correct selector. If not, try and compile a new method
  					with the correct selector."
+ 					cogMethod selector ~= messageSelector ifTrue: [
+ 							(cogit cog: newMethod selector: messageSelector)
- 					cogMethod selector ~= selector ifTrue: [
- 							(cogit cog: newMethod selector: selector)
  								ifNotNil: [:newCogMethod | cogMethod := newCogMethod]]].
+ 			cogMethod selector = messageSelector
- 			cogMethod selector = selector
  				ifTrue:
  					[cogit
  						linkNSSendCache: nsSendCache 
+ 						classTag: methodReceiverClassTag
+ 						enclosingObject: localAbsentReceiverOrZero
- 						classTag: mrClassTag
- 						enclosingObject: enclosingObject
  						target: cogMethod
  						caller: self mframeHomeMethodExport]
  				ifFalse: ["Out of code memory. Fall through to interpret."].
  			instructionPointer := self popStack.
  			self executeNewMethod.
+ 			self unreachable].
- 			self error: 'UNREACHABLE 1'].
  	instructionPointer := self popStack.
  	self interpretMethodFromMachineCode.
+ 	self unreachable.!
- 	self error: 'UNREACHABLE 2'.
- 	^nil!

Item was removed:
- ----- Method: CoInterpreter>>implicitReceiverFor:mixin:implementing: (in category 'newspeak bytecode support') -----
- implicitReceiverFor: methodReceiver mixin: methodMixin implementing: selector
- 	"This is used to implement implicit receiver sends in Newspeak. Find the nearest
- 	 lexically-enclosing implementation of selector by searching up the static chain of the
- 	 method's receiver, starting at mixin's application. This implementation is derived from
- 
- 	<ContextPart> implicitReceiverFor: methodReceiver <Object>
- 					in: methodMixin <Mixin>
- 					implementing: selector <Symbol> ^<Object>"
- 
- 	<api>
- 	<option: #NewspeakVM>
- 	cogit breakOnImplicitReceiver ifTrue:
- 		[self sendBreakpoint: selector receiver: nil].
- 	^super implicitReceiverFor: methodReceiver mixin: methodMixin implementing: selector!

Item was added:
+ ----- Method: CoInterpreter>>lookupImplicitReceiverSendNoMNU: (in category 'message sending') -----
+ lookupImplicitReceiverSendNoMNU: methodReceiver
+ 	"Do the full lookup for an implicit receiver send.
+ 	IN: messageSelector
+ 	IN: argumentCount
+ 	OUT: localAbsentReceiver
+ 	OUT: localAbsentReceiverOrZero
+ 	OUT: newMethod
+ 	OUT: primitiveIndex
+ 	RESULT: 0 or SelectorDoesNotUnderstand"
+ 
+ 	| candidateReceiver candidateMixin candidateMixinApplication dictionary found |
+ 	messageSelector := objectMemory followMaybeForwarded: messageSelector.
+ 	candidateReceiver := methodReceiver.
+ 	self deny: (objectMemory isForwarded: method).
+ 	candidateMixin := self methodClassOf: method.
+ 	localAbsentReceiverOrZero := 0.
+ 	[self deny: (objectMemory isForwarded: candidateMixin).
+ 	self deny: (objectMemory isForwarded: candidateReceiver).
+ 	candidateMixinApplication := self
+ 		findApplicationOfTargetMixin: candidateMixin
+ 		startingAtBehavior: (objectMemory fetchClassOf: candidateReceiver).
+ 	self deny: (candidateMixinApplication = 0).
+ 	self deny: (candidateMixinApplication = objectMemory nilObject).
+ 	self deny: (objectMemory isForwarded: candidateMixinApplication).
+ 	self assert: (self addressCouldBeClassObj: candidateMixinApplication).
+ 	dictionary := objectMemory followObjField: MethodDictionaryIndex ofObject: candidateMixinApplication.
+ 	found := self lookupMethodInDictionary: dictionary.
+ 	found ifTrue:
+ 		[localAbsentReceiver := candidateReceiver.
+ 		^self lookupLexicalNoMNU: messageSelector from: candidateMixin rule: LookupRuleImplicit].
+ 	candidateMixin := objectMemory followObjField: EnclosingMixinIndex ofObject: candidateMixin.
+ 	self deny: (objectMemory isForwarded: candidateMixin).
+ 	candidateMixin = objectMemory nilObject]
+ 		whileFalse:
+ 			[localAbsentReceiverOrZero := candidateReceiver := objectMemory followObjField: EnclosingObjectIndex ofObject: candidateMixinApplication].
+ 	"There is no lexically visible method, so the implicit receiver is the method receiver."
+ 	localAbsentReceiverOrZero := 0.
+ 	localAbsentReceiver := methodReceiver.
+ 	lkupClass := objectMemory fetchClassOf: methodReceiver. "For use by MNU"
+ 	^self lookupProtectedNoMNU: messageSelector startingAt: lkupClass rule: LookupRuleImplicit.!

Item was added:
+ ----- Method: CoInterpreter>>lookupLexicalNoMNU:from:rule: (in category 'message sending') -----
+ lookupLexicalNoMNU: selector from: mixin rule: rule
+ 	"A shared part of the lookup for implicit receiver sends that found a lexically visible
+ 	method, and self and outer sends."
+ 	| receiverClass mixinApplication dictionary found |
+ 	receiverClass := objectMemory fetchClassOf: localAbsentReceiver.
+ 	mixinApplication := self findApplicationOfTargetMixin: mixin startingAtBehavior: receiverClass.
+ 	dictionary := objectMemory followObjField: MethodDictionaryIndex ofObject: mixinApplication.
+ 	found := self lookupMethodInDictionary: dictionary.
+ 	(found and: [(self accessModifierOfMethod: newMethod) = AccessModifierPrivate])
+ 		ifTrue: [^0].
+ 	^self lookupProtectedNoMNU: selector startingAt: receiverClass rule: rule
+ !

Item was added:
+ ----- Method: CoInterpreter>>lookupOuterSendNoMNU:depth: (in category 'message sending') -----
+ lookupOuterSendNoMNU: methodReceiver depth: depth
+ 	"Do the full lookup for a self or outer send.
+ 	IN: messageSelector
+ 	IN: argumentCount
+ 	OUT: localAbsentReceiver
+ 	OUT: localAbsentReceiverOrZero
+ 	OUT: newMethod
+ 	OUT: primitiveIndex
+ 	RESULT: 0 or SelectorDoesNotUnderstand"
+ 
+ 	| targetMixin count mixinApplication |
+ 	localAbsentReceiver := methodReceiver.
+ 	localAbsentReceiverOrZero := 0.
+ 	targetMixin := self methodClassOf: method.
+ 	count := 0.
+ 	[count < depth] whileTrue:
+ 		[count := count + 1.
+ 		mixinApplication := self
+ 			findApplicationOfTargetMixin: targetMixin
+ 			startingAtBehavior: (objectMemory fetchClassOf: localAbsentReceiver).
+ 		localAbsentReceiverOrZero := localAbsentReceiver := objectMemory followObjField: EnclosingObjectIndex ofObject: mixinApplication.
+ 		targetMixin := objectMemory followObjField: EnclosingMixinIndex ofObject: targetMixin].
+ 	^self lookupLexicalNoMNU: messageSelector from: targetMixin rule: depth!

Item was added:
+ ----- Method: CoInterpreter>>lookupProtectedNoMNU:startingAt:rule: (in category 'message sending') -----
+ lookupProtectedNoMNU: selector startingAt: mixinApplication rule: rule
+ 	"A shared part of the lookup for self, outer or implicit receiver sends that did not find a
+ 	private lexically visible method, and (Newspeak) super sends."
+ 	| lookupClass dictionary found |
+ 	lookupClass := mixinApplication.
+ 	[lookupClass = objectMemory nilObject] whileFalse:
+ 		[dictionary := objectMemory followObjField: MethodDictionaryIndex ofObject: lookupClass.
+ 		found := self lookupMethodInDictionary: dictionary.
+ 		(found and: [(self accessModifierOfMethod: newMethod) ~= AccessModifierPrivate])
+ 			ifTrue: [^0].
+ 		lookupClass := self superclassOf: lookupClass].
+ 	^SelectorDoesNotUnderstand!

Item was added:
+ ----- Method: CoInterpreter>>unreachable (in category 'cog jit support') -----
+ unreachable
+ 	self error: 'UNREACHABLE'.!

Item was removed:
- ----- Method: StackInterpreter>>implicitReceiverFor:mixin:implementing: (in category 'newspeak bytecode support') -----
- implicitReceiverFor: methodReceiver mixin: methodMixin implementing: selector
- 	"This is used to implement implicit receiver sends in Newspeak. Find the nearest
- 	 lexically-enclosing implementation of selector by searching up the static chain of the
- 	 method's receiver, starting at mixin's application. This implementation is derived from
- 
- 	<ContextPart> implicitReceiverFor: methodReceiver <Object>
- 					in: methodMixin <Mixin>
- 					implementing: selector <Symbol> ^<Object>"
- 	<api>
- 	<option: #NewspeakVM>
- 	| candidateReceiver candidateMixin candidateMixinApplication dictionary found |
- 	self deny: (objectMemory isOopForwarded: methodReceiver).
- 	self deny: (objectMemory isForwarded: methodMixin).
- 	"messageSelector is an implicit parameter of lookupMethodInDictionary:"
- 	messageSelector := objectMemory followMaybeForwarded: selector.
- 	candidateReceiver := methodReceiver.
- 	candidateMixin := methodMixin.
- 	[candidateMixinApplication := self
- 		findApplicationOfTargetMixin: candidateMixin
- 		startingAtBehavior: (objectMemory fetchClassOf: candidateReceiver).
- 	 self deny: (candidateMixinApplication = objectMemory nilObject).
- 	 dictionary := objectMemory followObjField: MethodDictionaryIndex ofObject: candidateMixinApplication.
- 	 found := self lookupMethodInDictionary: dictionary.
- 	 found ifTrue: [^candidateReceiver].
- 	 candidateMixin := objectMemory followObjField: EnclosingMixinIndex ofObject: candidateMixin.
- 	 candidateMixin = objectMemory nilObject]
- 		whileFalse:
- 			[candidateReceiver := objectMemory followObjField: EnclosingObjectIndex ofObject: candidateMixinApplication].
- 	^methodReceiver!



More information about the Vm-dev mailing list