[Vm-dev] VM Maker: VMMaker.oscog-eem.1367.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Jun 20 03:26:52 UTC 2015


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1367.mcz

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

Name: VMMaker.oscog-eem.1367
Author: eem
Time: 19 June 2015, 8:24:51.209 pm
UUID: 5d5685bb-29fe-4d36-8ff2-df498dd8cc47
Ancestors: VMMaker.oscog-eem.1366

Fix PIC parsing for out-of-line literals.  Add an
assert to the closed PIC prototype code to 
check all PIC parameters are accessible.
Add a containsAddress: to abstract away the
test for a target within the PIC.

Make the OOLL [store]classRef[:]InClosedPICAt:
code 64-bit aware.

Fix method header printing for PICs.

=============== Diff against VMMaker.oscog-eem.1366 ===============

Item was added:
+ ----- Method: CogMethod>>containsAddress: (in category 'testing') -----
+ containsAddress: address
+ 	<inline: true>
+ 	^self asUnsignedInteger <= address asUnsignedInteger
+ 	  and: [self asUnsignedInteger + self blockSize >= address asUnsignedInteger]!

Item was added:
+ ----- Method: CogMethodSurrogate>>containsAddress: (in category 'testing') -----
+ containsAddress: address
+ 	"Simulation only; N.B. this will error if used on block method surrogates."
+ 	^address <= address asUnsignedInteger
+ 	  and: [address + self blockSize >= address asUnsignedInteger]!

Item was changed:
  ----- Method: Cogit>>cPICHasFreedTargets: (in category 'in-line cacheing') -----
  cPICHasFreedTargets: cPIC
  	<var: #cPIC type: #'CogMethod *'>
  	| pc entryPoint targetMethod |
  	<var: #targetMethod type: #'CogMethod *'>
  	pc := cPIC asInteger + firstCPICCaseOffset.
  	1 to: cPIC cPICNumCases do:
  		[:i|
  		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
  		"Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC"
+ 		(cPIC containsAddress: entryPoint) ifFalse:
- 		(entryPoint < cPIC asInteger
- 		 or: [entryPoint > (cPIC asInteger + cPIC blockSize)]) ifTrue:
  			[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.
  			 self assert: (targetMethod cmType = CMMethod or: [targetMethod cmType = CMFree]).
  			 targetMethod cmType = CMFree ifTrue:
  				[^true]].
  		pc := pc + cPICCaseSize].
  	^false!

Item was added:
+ ----- Method: Cogit>>cPICPrototypeCaseOffset (in category 'in-line cacheing') -----
+ cPICPrototypeCaseOffset
+ 	"Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in the middle of the zone."
+ 	^methodZoneBase + methodZone youngReferrers / 2 -  16rCA5E10!

Item was changed:
  ----- Method: Cogit>>closedPICRefersToUnmarkedObject: (in category 'garbage collection') -----
  closedPICRefersToUnmarkedObject: cPIC
  	"Answer if the ClosedPIC refers to any unmarked objects or freed/freeable target methods,
  	 applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to determine if freed/freeable."
  	<var: #cPIC type: #'CogMethod *'>
+ 	| pc offsetToLiteral object entryPoint targetMethod |
- 	| pc offsetToLiteral offsetToJump object entryPoint targetMethod |
  	<var: #targetMethod type: #'CogMethod *'>
  	(objectMemory isImmediate: cPIC selector) ifFalse:
  		[(objectMemory isMarked: cPIC selector) ifFalse:
  			[^true]].
  	pc := cPIC asInteger + firstCPICCaseOffset.
  	"First jump is unconditional; subsequent ones are conditional"
  	offsetToLiteral := backEnd jumpLongByteSize.
- 	offsetToJump := literalsManager literalBytesFollowingJumpInClosedPIC.
  	1 to: cPIC cPICNumCases do:
  		[:i|
  		objectRepresentation inlineCacheTagsMayBeObjects ifTrue:
  			[object := literalsManager classRefInClosedPICAt: pc - offsetToLiteral.
  			 ((objectRepresentation couldBeObject: object)
  			  and: [(objectMemory isMarked: object) not]) ifTrue:
  				[^true]].
  		object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.
  		((objectRepresentation couldBeObject: object)
  		 and: [(objectMemory isMarked: object) not]) ifTrue:
  			[^true].
+ 		offsetToLiteral := backEnd jumpLongConditionalByteSize.
+ 		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
- 		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc - offsetToJump.
  		"Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC"
  		self assert: (entryPoint > methodZoneBase and: [entryPoint < methodZone freeStart]).
+ 		(cPIC containsAddress: entryPoint) ifFalse:
- 		(entryPoint asUnsignedInteger < cPIC asUnsignedInteger
- 		 or: [entryPoint asUnsignedInteger > (cPIC asUnsignedInteger + cPIC blockSize) asUnsignedInteger]) ifTrue:
  			[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.
  			 self assert: (targetMethod cmType = CMMethod
  						or: [targetMethod cmType = CMFree]).
  			 (self markAndTraceOrFreeCogMethod: targetMethod
  				  firstVisit: targetMethod asUnsignedInteger > pc asUnsignedInteger) ifTrue:
  				[^true]].
- 		offsetToLiteral := backEnd jumpLongConditionalByteSize.
- 		offsetToJump := literalsManager literalBytesFollowingBranchInClosedPIC.
  		pc := pc + cPICCaseSize].
  	^false!

Item was changed:
  ----- Method: Cogit>>compileClosedPICPrototype (in category 'in-line cacheing') -----
  compileClosedPICPrototype
  	"Compile the abstract instructions for a full closed PIC used to initialize closedPICSize.
  	 The loads into SendNumArgsReg are those for optional method objects which may be
  	 used in MNU cases."
  	<inline: true>
  	| numArgs jumpNext |
  	<var: #jumpNext type: #'AbstractInstruction *'>
  	numArgs := 0.
  	self compilePICAbort: numArgs.
  	jumpNext := self compileCPICEntry.
  	self MoveUniqueCw: 16r5EAF00D R: SendNumArgsReg.
+ 	self DumpJumpLong: self cPICPrototypeCaseOffset + 16rCA5E10.
- 	self DumpJumpLong: methodZoneBase + 16rCA5E10.
  	jumpNext jmpTarget: (endCPICCase0 := self Label).
  	1 to: numPICCases - 1 do:
  		[:h|
  		self CmpCw: 16rBABE1F15+h R: TempReg.
  		self MoveUniqueCw: 16rBADA550 + h R: SendNumArgsReg.
+ 		self DumpJumpLongZero: self cPICPrototypeCaseOffset + 16rCA5E10 + (h * 16).
- 		self DumpJumpLongZero: 16rCA5E10 + (h * 16).
  		h = 1 ifTrue:
  			[endCPICCase1 := self Label]].
  	self MoveCw: methodLabel address R: ClassReg.
  	self JumpLong: (self cPICMissTrampolineFor: numArgs).
  	^0!

Item was added:
+ ----- Method: Cogit>>expectedClosedPICPrototype: (in category 'garbage collection') -----
+ expectedClosedPICPrototype: cPIC
+ 	"Answer 0 if the ClosedPIC is as expected from compileClosedPICPrototype,
+ 	 otherwise answer an error code identifying the first discrepancy found."
+ 	<var: #cPIC type: #'CogMethod *'>
+ 	| pc offsetToLiteral object entryPoint |
+ 	pc := cPIC asInteger + firstCPICCaseOffset.
+ 	"First jump is unconditional; subsequent ones are conditional"
+ 	offsetToLiteral := backEnd jumpLongByteSize.
+ 	1 to: numPICCases do:
+ 		[:i|
+ 		i > 1 ifTrue:
+ 			[object := literalsManager classRefInClosedPICAt: pc - offsetToLiteral.
+ 			 object = (16rBABE1F15 + i - 1) ifFalse:
+ 				[^1]].
+ 		object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.
+ 		object = (i = 1
+ 					ifTrue: [16r5EAF00D]
+ 					ifFalse: [16rBADA550 + i - 1]) ifFalse:
+ 			[^2].
+ 		offsetToLiteral := backEnd jumpLongConditionalByteSize.
+ 		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
+ 		entryPoint = (self cPICPrototypeCaseOffset + 16rCA5E10 + (i - 1 * 16)) ifFalse:
+ 				[^3].
+ 		pc := pc + cPICCaseSize].
+ 	pc := pc - cPICCaseSize.
+ 	entryPoint := backEnd jumpLongTargetBeforeFollowingAddress: pc + cPICEndSize.
+ 	entryPoint = (self cPICMissTrampolineFor: 0) ifFalse:
+ 		[^4].
+ 	^0!

Item was changed:
  ----- Method: Cogit>>generateClosedPICPrototype (in category 'initialization') -----
  generateClosedPICPrototype
  	"Generate the prototype ClosedPIC to determine how much space as full PIC takes.
  	 When we first allocate a closed PIC it only has one or two cases and we want to grow it.
  	 So we have to determine how big a full one is before hand."
+ 	| cPIC |
+ 	<var: 'cPIC' type: #'CogMethod *'>
  	numPICCases := 6.
  	"stack allocate the various collections so that they
  	 are effectively garbage collected on return."
  	self allocateOpcodes: numPICCases * 9 bytecodes: 0.
  	methodLabel address: methodZoneBase; dependent: nil. "for pc-relative MoveCw: cPIC R: ClassReg"
  	self compileClosedPICPrototype.
  	self computeMaximumSizes.
+ 	cPIC := (self cCoerceSimple: methodZoneBase to: #'CogMethod *').
  	closedPICSize := (self sizeof: CogMethod) + (self generateInstructionsAt: methodZoneBase + (self sizeof: CogMethod)).
+ 	self outputInstructionsAt: methodZoneBase + (self sizeof: CogMethod).
  	firstCPICCaseOffset := endCPICCase0 address - methodZoneBase.
  	cPICCaseSize := endCPICCase1 address - endCPICCase0 address.
  	cPICEndSize := closedPICSize - (numPICCases - 1 * cPICCaseSize + firstCPICCaseOffset).
  	closedPICSize := methodZone roundUpLength: closedPICSize.
+ 	self assert: picInterpretAbort address = (methodLabel address + self picInterpretAbortOffset).
+ 	self assert: (self expectedClosedPICPrototype: cPIC) = 0
- 	self assert: picInterpretAbort address = (methodLabel address + self picInterpretAbortOffset)
  	"self cCode: ''
  		inSmalltalk:
+ 			[self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: methodZoneBase + closedPICSize - 1.
- 			[| end |
- 			 end := self outputInstructionsAt: methodZoneBase + headerSize.
- 			 self disassembleFrom: methodZoneBase + headerSize to: end - 1.
  			 self halt]"!

Item was changed:
  ----- Method: Cogit>>noTargetsFreeInClosedPIC: (in category 'compaction') -----
  noTargetsFreeInClosedPIC: cPIC
  	"Answerr if all targets in the PIC are in-use methods."
  	<var: #cPIC type: #'CogMethod *'>
  	| pc entryPoint targetMethod |
  	<var: #targetMethod type: #'CogMethod *'>
  	pc := cPIC asInteger + firstCPICCaseOffset.
  	1 to: cPIC cPICNumCases do:
  		[:i|
  		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
  		"Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC"
+ 		(cPIC containsAddress: entryPoint) ifFalse:
- 		(entryPoint < cPIC asInteger
- 		 or: [entryPoint > (cPIC asInteger + cPIC blockSize)]) ifTrue:
  			[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.
  			 targetMethod cmType ~= CMMethod ifTrue:
  				[^false]].
  		i < cPIC cPICNumCases ifTrue:
  			[pc := pc + cPICCaseSize]].
  	^true!

Item was removed:
- ----- Method: Cogit>>pc:isWithinMethod: (in category 'disassembly') -----
- pc: address isWithinMethod: cogMethod
- 	<api>
- 	<var: #address type: #'char *'>
- 	<var: #cogMethod type: #'CogMethod *'>
- 	^address asInteger
- 		between: cogMethod asInteger + (self sizeof: CogMethod)
- 		and: cogMethod asInteger + cogMethod blockSize!

Item was changed:
  ----- Method: Cogit>>printMethodHeader:on: (in category 'disassembly') -----
  printMethodHeader: cogMethod on: aStream
  	<doNotGenerate>
  	self cCode: ''
  		inSmalltalk:
  			[cogMethod isInteger ifTrue:
  				[^self printMethodHeader: (self cogMethodOrBlockSurrogateAt: cogMethod) on: aStream]].
  	aStream ensureCr.
  	cogMethod asInteger printOn: aStream base: 16.
- 	aStream crtab.
  	cogMethod cmType = CMMethod ifTrue:
+ 		[aStream crtab; nextPutAll: 'objhdr: '.
- 		[aStream nextPutAll: 'objhdr: '.
  		cogMethod objectHeader printOn: aStream base: 16].
  	cogMethod cmType = CMBlock ifTrue:
  		[aStream nextPutAll: 'homemth: '.
  		cogMethod cmHomeMethod asUnsignedInteger printOn: aStream base: 16.
  		aStream crtab; nextPutAll: 'startpc: '; print: cogMethod startpc].
  	aStream
  		crtab; nextPutAll: 'nArgs: ';	print: cogMethod cmNumArgs;
  		tab;    nextPutAll: 'type: ';	print: cogMethod cmType.
  	(cogMethod cmType ~= 0 and: [cogMethod cmType ~= CMBlock]) ifTrue:
  		[aStream crtab; nextPutAll: 'blksiz: '.
  		cogMethod blockSize printOn: aStream base: 16.
+ 		cogMethod cmType = CMMethod ifTrue:
+ 			[aStream crtab; nextPutAll: 'method: '.
+ 			 cogMethod methodObject printOn: aStream base: 16.
+ 			 aStream crtab; nextPutAll: 'mthhdr: '.
+ 			 cogMethod methodHeader printOn: aStream base: 16].
- 		aStream crtab; nextPutAll: 'method: '.
- 		cogMethod methodObject printOn: aStream base: 16.
- 		aStream crtab; nextPutAll: 'mthhdr: '.
- 		cogMethod methodHeader printOn: aStream base: 16.
  		aStream crtab; nextPutAll: 'selctr: '.
  		cogMethod selector printOn: aStream base: 16.
  		(coInterpreter lookupAddress: cogMethod selector) ifNotNil:
  			[:string| aStream nextPut: $=; nextPutAll: string].
+ 		cogMethod cmType = CMMethod ifTrue:
+ 			[aStream crtab; nextPutAll: 'blkentry: '.
+ 			 cogMethod blockEntryOffset printOn: aStream base: 16.
+ 			 cogMethod blockEntryOffset ~= 0 ifTrue:
+ 				[aStream nextPutAll: ' => '.
+ 				 cogMethod asInteger + cogMethod blockEntryOffset printOn: aStream base: 16]]].
- 		aStream crtab; nextPutAll: 'blkentry: '.
- 		cogMethod blockEntryOffset printOn: aStream base: 16.
- 		cogMethod blockEntryOffset ~= 0 ifTrue:
- 			[aStream nextPutAll: ' => '.
- 			 cogMethod asInteger + cogMethod blockEntryOffset printOn: aStream base: 16]].
  	cogMethod cmType = CMClosedPIC
  		ifTrue:
  			[aStream crtab; nextPutAll: 'cPICNumCases: '.
  			 cogMethod cPICNumCases printOn: aStream base: 16.]
  		ifFalse:
  			[aStream crtab; nextPutAll: 'stackCheckOffset: '.
  			 cogMethod stackCheckOffset printOn: aStream base: 16.
  			 cogMethod stackCheckOffset > 0 ifTrue:
  				[aStream nextPut: $/.
  				 cogMethod asInteger + cogMethod stackCheckOffset printOn: aStream base: 16].
  			cogMethod cmType = CMBlock
  				ifTrue:
  					[aStream
  						crtab;
  						nextPutAll: 'cbUsesInstVars ';
  						nextPutAll: (cogMethod cbUsesInstVars ifTrue: ['yes'] ifFalse: ['no'])]
  				ifFalse:
  					[aStream
  						crtab;
  						nextPutAll: 'cmRefersToYoung: ';
  						nextPutAll: (cogMethod cmRefersToYoung ifTrue: ['yes'] ifFalse: ['no'])].
  			cogMethod cmType = CMMethod ifTrue:
  				[([cogMethod nextMethodOrIRCs] on: MessageNotUnderstood do: [:ex| nil]) ifNotNil:
  					[:nmoircs| aStream crtab; nextPutAll: 'nextMethodOrIRCs: '.
  						nmoircs = 0 ifTrue: [aStream print: nmoircs] ifFalse: [coInterpreter printHex: nmoircs]].
  				 ([cogMethod counters] on: MessageNotUnderstood do: [:ex| nil]) ifNotNil:
  					[:cntrs| aStream crtab; nextPutAll: 'counters: '.
  						cntrs = 0 ifTrue: [aStream print: cntrs] ifFalse: [coInterpreter printHex: cntrs]]]].
  	aStream cr; flush!

Item was changed:
  ----- Method: Cogit>>relocateCallsInClosedPIC: (in category 'compaction') -----
  relocateCallsInClosedPIC: cPIC
  	<var: #cPIC type: #'CogMethod *'>
  	| delta pc entryPoint targetMethod |
  	<var: #targetMethod type: #'CogMethod *'>
  	delta := cPIC objectHeader.
  	self assert: (backEnd callTargetFromReturnAddress: cPIC asInteger + missOffset)
  					= (self picAbortTrampolineFor: cPIC cmNumArgs).
  	backEnd relocateCallBeforeReturnPC: cPIC asInteger + missOffset by: delta negated.
  
  	pc := cPIC asInteger + firstCPICCaseOffset.
  	1 to: cPIC cPICNumCases do:
  		[:i|
  		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
  		"Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC"
+ 		(cPIC containsAddress: entryPoint) ifFalse:
- 		(entryPoint < cPIC asInteger
- 		 or: [entryPoint > (cPIC asInteger + cPIC blockSize)]) ifTrue:
  			[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.
  			 self assert: targetMethod cmType = CMMethod.
  			 literalsManager
  				cPICCase: i
  				relocateJumpLongBefore: pc
  				by: (delta - targetMethod objectHeader) negated].
  		pc := pc + cPICCaseSize].
  	self assert: cPIC cPICNumCases > 0.
  	pc := pc - cPICCaseSize.
  	"Finally relocate the load of the PIC and the jump to the overflow routine ceCPICMiss:receiver:"
  	backEnd relocateMethodReferenceBeforeAddress: pc + backEnd loadPICLiteralByteSize by: delta.
  	backEnd relocateJumpLongBeforeFollowingAddress: pc + cPICEndSize by: delta negated!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>classRefInClosedPICAt: (in category 'garbage collection') -----
+ classRefInClosedPICAt: address
- classRefInClosedPICAt: mcpc
  	<inline: true>
+ 	"If inline cache tags are not objects they will be 32-bit values."
+ 	^objectRepresentation inlineCacheTagsMayBeObjects
+ 		ifTrue: [objectMemory long32At: address - 4]
+ 		ifFalse: [objectMemory longAt: address - objectMemory bytesPerOop]!
- 	^objectMemory longAt: mcpc - objectMemory bytesPerOop!

Item was removed:
- ----- Method: OutOfLineLiteralsManager>>literalBytesFollowingBranchInClosedPIC (in category 'garbage collection') -----
- literalBytesFollowingBranchInClosedPIC
- 	<inline: true>
- 	"With Spur the class tag is always 32-bits and the literal is bytesPerOop.
- 	 With V3 the class and literal are both bytesPerOop."
- 	^objectRepresentation inlineCacheTagsMayBeObjects
- 		ifTrue: [objectMemory bytesPerOop * 2]
- 		ifFalse: [objectMemory bytesPerOop + 4]!

Item was removed:
- ----- Method: OutOfLineLiteralsManager>>literalBytesFollowingJumpInClosedPIC (in category 'garbage collection') -----
- literalBytesFollowingJumpInClosedPIC
- 	<inline: true>
- 	^objectMemory bytesPerOop!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>objRefInClosedPICAt: (in category 'garbage collection') -----
+ objRefInClosedPICAt: address
- objRefInClosedPICAt: mcpc
  	<inline: true>
+ 	^objectMemory longAt: address!
- 	^objectMemory longAt: mcpc!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>storeClassRef:inClosedPICAt: (in category 'garbage collection') -----
  storeClassRef: classObj inClosedPICAt: address
  	<var: #address type: #usqInt>
  	<inline: true>
+ 	"If inline cache tags are not objects they will be 32-bit values."
+ 	objectRepresentation inlineCacheTagsMayBeObjects
+ 		ifTrue: [objectMemory long32At: address - 4 put: classObj]
+ 		ifFalse: [objectMemory longAt: address - objectMemory bytesPerOop]!
- 	objectMemory longAt: address - objectMemory bytesPerOop put: classObj!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>storeObjRef:inClosedPICAt: (in category 'garbage collection') -----
  storeObjRef: literal inClosedPICAt: address
  	<var: #address type: #usqInt>
  	<inline: true>
  	objectMemory longAt: address put: literal!

Item was changed:
  ----- Method: SistaStackToRegisterMappingCogit>>populate:withPICInfoFor:firstCacheTag: (in category 'method introspection') -----
  populate: tuple withPICInfoFor: cPIC firstCacheTag: firstCacheTag
  	"Populate tuple (which must be large enough) with the ClosedPIC's target method class pairs.
  	 The first entry in tuple contains the bytecode pc for the send, so skip the tuple's first field."
  	<var: #cPIC type: #'CogMethod *'>
  	| pc cacheTag classOop entryPoint targetMethod value |
  	<var: #targetMethod type: #'CogMethod *'>
  	pc := cPIC asInteger + firstCPICCaseOffset.
  	1 to: cPIC cPICNumCases do:
  		[:i|
  		cacheTag := i = 1
  						ifTrue: [firstCacheTag]
  						ifFalse: [backEnd literalBeforeFollowingAddress: pc
  																		- backEnd jumpLongConditionalByteSize
  																		- backEnd loadLiteralByteSize].
  		classOop := objectRepresentation classForInlineCacheTag: cacheTag.
  		objectMemory storePointer: i * 2 - 1 ofObject: tuple withValue: classOop.
  		entryPoint := literalsManager cPICCase: i jumpTargetBefore: pc.
  		"Find target from jump.  A jump to the MNU entry-point should collect #doesNotUnderstand:"
+ 		(cPIC containsAddress: entryPoint)
- 		(entryPoint asUnsignedInteger < cPIC asUnsignedInteger
- 		 or: [entryPoint asUnsignedInteger > (cPIC asUnsignedInteger + cPIC blockSize) asUnsignedInteger])
  			ifTrue:
+ 				[value := objectMemory splObj: SelectorDoesNotUnderstand]
+ 			ifFalse:
  				[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.
  				 self assert: targetMethod cmType = CMMethod.
+ 				 value := targetMethod methodObject].
- 				 value := targetMethod methodObject]
- 			ifFalse:
- 				[value := objectMemory splObj: SelectorDoesNotUnderstand].
  		objectMemory storePointer: i * 2 ofObject: tuple withValue: value.
  		pc := pc + cPICCaseSize]!



More information about the Vm-dev mailing list