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

commits at source.squeak.org commits at source.squeak.org
Tue Apr 21 02:52:32 UTC 2015


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

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

Name: VMMaker.oscog-eem.1229
Author: eem
Time: 20 April 2015, 7:50:05.213 pm
UUID: 9265e9ce-f37e-4bd0-9d85-e266d05f6628
Ancestors: VMMaker.oscog-eem.1228

CogARMCompiler:
Fix updating of call and jump instructions by splitting the
call/jump update from the callfull/jumpfull update.  Rename
the operand extractor to
extract32BitOperandFrom4InstructionsPreceeding: and add
insert32BitOperand:into4InstructionsPreceeding: to go with.
Use these to update instructions.

Modify machineCode array to be array of longs. Refactor
machine code output so that CogARMCompiler can spit
out words while the x86 dribbles bytes.

Avoid annotating the absolute CallFull/JumpFull instructions
so that the update is simplified.

Now the system survives a code compaction on ARM
although it doesn't continue for long there-after.

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

Item was added:
+ ----- Method: CogARMCompiler class>>instVarNamesAndTypesForTranslationDo: (in category 'translation') -----
+ instVarNamesAndTypesForTranslationDo: aBinaryBlock
+ 	"enumerate aBinaryBlock with the names and C type strings for the inst vars to include in an AbstractInstruction struct."
+ 	"{CogAbstractInstruction. CogIA32Compiler. CogARMCompiler} do:
+ 		[:c| Transcript print: c; cr. c printTypedefOn: Transcript]"
+ 	(self filteredInstVarNames copyWithout: 'machineCode'), #('machineCode') do:
+ 		[:ivn|
+ 		ivn ~= 'bcpc' ifTrue:
+ 			[aBinaryBlock
+ 				value: ivn
+ 				value: (ivn caseOf: {
+ 							['address']			-> [#'unsigned long'].
+ 							['machineCode']	-> [{#'unsigned long'. '[', self basicNew machineCodeWords printString, ']'}].
+ 							['operands']		-> [{#'unsigned long'. '[', NumOperands, ']'}].
+ 							['dependent']		-> ['struct _AbstractInstruction *']}
+ 						otherwise:
+ 							[#'unsigned char'])]]!

Item was changed:
  ----- Method: CogARMCompiler>>blx: (in category 'ARM convenience instructions') -----
  blx: targetReg
+ 	"Branch&link to the address in targetReg. Return address is in LR
- "Branch&link to the address in targetReg. Return address is in LR
  	BX targetReg"
+ 	<inline: true>
  	^self cond: AL bx: 1 target: targetReg
  !

Item was changed:
  ----- Method: CogARMCompiler>>bx: (in category 'ARM convenience instructions') -----
  bx: targetReg
+ 	"Branch to address in targetReg. BX targetReg"
+ 	<inline: true>
- "Branch to address in targetReg.
- 	BX targetReg"
  	^self cond: AL bx: 0 target: targetReg
  !

Item was added:
+ ----- Method: CogARMCompiler>>callFullTargetFromReturnAddress: (in category 'inline cacheing') -----
+ callFullTargetFromReturnAddress: callSiteReturnAddress
+ 	"Answer the address that the call immediately preceeding callSiteReturnAddress will jump to."
+ 	"this is also used by #jumpLongTargetBeforeFollowingAddress: and so we check for both call and jump related instructions; later on we can use simpler tests once it feels safe to assume we get here always with a call/jump in the proper place"
+ 	| call |
+ 	call := self instructionBeforeAddress: callSiteReturnAddress.
+ 	self assert: ((self instructionIsBX: call) or: [self instructionIsBLX: call]).
+ 	"A Long Call/Jump. Extract the value saved to RISCTempReg from all the instructions before."
+ 	^self extract32BitOperandFrom4InstructionsPreceeding: callSiteReturnAddress - 4!

Item was changed:
  ----- Method: CogARMCompiler>>callTargetFromReturnAddress: (in category 'inline cacheing') -----
  callTargetFromReturnAddress: callSiteReturnAddress
  	"Answer the address that the call immediately preceeding callSiteReturnAddress will jump to."
+ 	"this is also used by #jumpLongTargetBeforeFollowingAddress:."
- 	"this is also used by #jumpLongTargetBeforeFollowingAddress: and so we check for both call and jump related instructions; later on we can use simpler tests once it feels safe to assume we get here always with a call/jump in the proper place"
  	| callDistance call |
  	call := self instructionBeforeAddress: callSiteReturnAddress.
+ 	self assert: ((self instructionIsB: call) or: [self instructionIsBL: call]).
+ 	callDistance := self extractOffsetFromBL: call.
+ 	^callSiteReturnAddress + 4 + callDistance signedIntFromLong!
- 	self assert: call ~= 0. "andeq r0, r0 will not be generated, not even as nops"
- 	((self instructionIsB: call) or:[self instructionIsBL: call])
- 		ifTrue: [ "a short call/jump" callDistance := self extractOffsetFromBL: call.
- 			^callSiteReturnAddress + 4 + callDistance signedIntFromLong].
- 	
- 	((self instructionIsBX: call) or:[self instructionIsBLX: call])
- 		ifTrue:["A Long Call/Jump. Extract the value saved to RISCTempReg from all the instructions before."
- 			^self extractOffsetFromBXAt: callSiteReturnAddress - 4].
- 	self halt
- 	!

Item was changed:
  ----- Method: CogARMCompiler>>concretizeJumpFull (in category 'generate machine code - concretize') -----
  concretizeJumpFull
  	"Will get inlined into concretizeAt: switch."
  	"A JumpFull is used when we need to jump to anywhere in 32bit address space rather than somewhere known to be in code-space. It also must be relocatable and non-varying with the jump range. On ARM this means using the build-long-const + BX sequence."
  	<inline: true>
  	| jumpTarget instrOffset|
  	<var: #jumpTarget type: #'AbstractInstruction *'>
  	jumpTarget := self longJumpTargetAddress.
  	instrOffset := self at: 0 moveCw: jumpTarget intoR: ConcreteIPReg.
  	"bx ConcreteIPReg"
+ 	self machineCodeAt: instrOffset put: (self bx: ConcreteIPReg).
- 	self machineCodeAt: instrOffset put: (self cond: AL bx: 0 target: ConcreteIPReg).
  	^machineCodeSize := instrOffset + 4!

Item was added:
+ ----- Method: CogARMCompiler>>extract32BitOperandFrom4InstructionsPreceeding: (in category 'testing') -----
+ extract32BitOperandFrom4InstructionsPreceeding: addr
+ 	<inline: true>
+ 	^(objectMemory byteAt: addr -4) 
+ 	 + ((objectMemory byteAt: addr - 8) << 8) 
+ 	 + ((objectMemory byteAt: addr - 12) << 16) 
+ 	 + ((objectMemory byteAt: addr - 16) << 24)!

Item was changed:
  ----- Method: CogARMCompiler>>extractOffsetFromBL: (in category 'testing') -----
  extractOffsetFromBL: instr
+ 	"we are told this is a BL <offset> instruction, so work out the offset it encodes"
+ 	<inline: true>
- "we are told this is a BL <offset> instruction, so work out the offset it encodes"
  	| relativeJump |
  	relativeJump := instr bitAnd: 16r00FFFFFF.
  	relativeJump := (relativeJump bitAt: 24) = 1 
  						ifTrue: [((relativeJump bitOr: 16r3F000000) << 2) signedIntFromLong]
  						ifFalse: [relativeJump << 2].
  	^relativeJump!

Item was removed:
- ----- Method: CogARMCompiler>>extractOffsetFromBXAt: (in category 'testing') -----
- extractOffsetFromBXAt: addr
- "this should return the long call/jump target"
- 	^(objectMemory byteAt: addr -4) 
- 		+ ((objectMemory byteAt: addr - 8) << 8) 
- 		+ ((objectMemory byteAt: addr - 12) << 16) 
- 		+ ((objectMemory byteAt: addr - 16) << 24)!

Item was added:
+ ----- Method: CogARMCompiler>>fullCallsAreRelative (in category 'abi') -----
+ fullCallsAreRelative
+ 	"Answer if CallFull and/or JumpFull are relative and hence need relocating on method
+ 	 compation. If so, they are annotated with IsRelativeCall in methods and relocated in
+ 	 relocateIfCallOrMethodReference:mcpc:delta:"
+ 	^false!

Item was added:
+ ----- Method: CogARMCompiler>>initialize (in category 'generate machine code') -----
+ initialize
+ 	"This method intializes the Smalltalk instance.  The C instance is merely a struct and doesn't need initialization."
+ 	<doNotGenerate>
+ 	operands := CArrayAccessor on: (Array new: NumOperands).
+ 	machineCode := CArrayAccessor on: (Array new: self machineCodeWords)!

Item was changed:
  ----- Method: CogARMCompiler>>inlineCacheTagAt: (in category 'inline cacheing') -----
  inlineCacheTagAt: callSiteReturnAddress
  	"Answer the inline cache tag for the return address of a send."
+ 	self assert: (self instructionIsBL: (self instructionBeforeAddress: callSiteReturnAddress)).
+ 	^self extract32BitOperandFrom4InstructionsPreceeding: callSiteReturnAddress - 4!
- 	^self literalBeforeFollowingAddress: callSiteReturnAddress - 4!

Item was added:
+ ----- Method: CogARMCompiler>>insert32BitOperand:into4InstructionsPreceeding: (in category 'testing') -----
+ insert32BitOperand: operand into4InstructionsPreceeding: addr
+ 	<inline: true>
+ 	objectMemory
+ 		byteAt: addr -   4 put: (operand			bitAnd: 16rFF);
+ 		byteAt: addr -   8 put: (operand >>   8	bitAnd: 16rFF);
+ 		byteAt: addr - 12 put: (operand >> 16	bitAnd: 16rFF);
+ 		byteAt: addr - 16 put: (operand >> 24	bitAnd: 16rFF)!

Item was changed:
  ----- Method: CogARMCompiler>>instructionBeforeAddress: (in category 'inline cacheing') -----
  instructionBeforeAddress: followingAddress
  	"Answer the instruction immediately preceeding followingAddress."
+ 	<inline: true>
  	^objectMemory longAt: followingAddress -4!

Item was changed:
  ----- Method: CogARMCompiler>>literalBeforeFollowingAddress: (in category 'inline cacheing') -----
  literalBeforeFollowingAddress: followingAddress
  	"Answer the long constant loaded by a MOV/ORR/ORR/ORR
  	 or MOV/ORR/ORR/ORR/PUSH  sequence, just before this address:"
+ 	^(self instructionIsOR: (self instructionBeforeAddress: followingAddress))
+ 		ifTrue: [self extract32BitOperandFrom4InstructionsPreceeding: followingAddress]
+ 		ifFalse: [self extract32BitOperandFrom4InstructionsPreceeding: followingAddress - 4]!
- 	^(self instructionIsOR: (objectMemory longAt: followingAddress - 4))
- 		ifTrue:
- 			[   ((objectMemory byteAt: followingAddress - 16) << 24)
- 			+  ((objectMemory byteAt: followingAddress - 12) << 16)
- 			+  ((objectMemory byteAt: followingAddress - 8) << 8)
- 			+   (objectMemory byteAt: followingAddress - 4)]
- 		ifFalse:
- 			[   ((objectMemory byteAt: followingAddress - 20) << 24)
- 			+  ((objectMemory byteAt: followingAddress - 16) << 16)
- 			+  ((objectMemory byteAt: followingAddress - 12) << 8)
- 			+   (objectMemory byteAt: followingAddress - 8)]!

Item was changed:
  ----- Method: CogARMCompiler>>machineCodeAt: (in category 'accessing') -----
  machineCodeAt: anOffset
  	"read aWord from machineCode, with little endian"
  	<inline: true>
+ 	^machineCode at: anOffset // 4!
- 	^((machineCode at: anOffset"+0")"<< 0" bitOr: (machineCode at: anOffset + 1) << 8) 
- 		bitOr: ((machineCode at: anOffset + 2) << 16 bitOr: (machineCode at: anOffset + 3) << 24)
- !

Item was changed:
  ----- Method: CogARMCompiler>>machineCodeAt:put: (in category 'accessing') -----
  machineCodeAt: anOffset put: aWord
  	"add aWord to machineCode, with little endian"
  	<inline: true>
+ 	machineCode at: anOffset // 4 put: aWord!
- 	machineCode
- 		at: anOffset + 3 put: (16rFF bitAnd: aWord >> 24);
- 		at: anOffset + 2 put: (16rFF bitAnd: aWord >> 16);
- 		at: anOffset + 1 put: (16rFF bitAnd: aWord >> 8);
- 		at: anOffset"+ 0"put: (16rFF bitAnd: aWord">> 0")!

Item was added:
+ ----- Method: CogARMCompiler>>machineCodeWords (in category 'generate machine code') -----
+ machineCodeWords
+ 	"Answer the maximum number of words of machine code generated for any abstract instruction.
+ 	 e.g. CmpCwR =>
+ 			mov R3, #<addressByte1>, 12
+ 			orr R3, R3, #<addressByte2>, 8
+ 			orr R3, R3, #<addressByte3>, 4
+ 			orr R3, R3, #<addressByte4>, 0
+ 			cmp R?, R3"
+ 	^5!

Item was added:
+ ----- Method: CogARMCompiler>>outputMachineCodeAt: (in category 'inline cacheing') -----
+ outputMachineCodeAt: address
+ 	"By default move machine code a byte at a time
+ 	  Subclasses with coarser granularity can override as desired."
+ 	<inline: true>
+ 	0 to: machineCodeSize - 1 by: 4 do:
+ 		[:j|
+ 		objectMemory longAt: address + j put: (machineCode at: j // 4)]!

Item was changed:
  ----- Method: CogARMCompiler>>relocateCallBeforeReturnPC:by: (in category 'inline cacheing') -----
  relocateCallBeforeReturnPC: retpc by: delta
  	| instr distanceDiv4 |
  	self assert: delta \\ 4 = 0.
  	delta ~= 0 ifTrue:
+ 		[instr := self instructionBeforeAddress: retpc.
+ 		 self assert: ((self instructionIsB: instr) or: [self instructionIsBL: instr]).
- 		[instr := objectMemory longAt: retpc - 4.
  		 distanceDiv4 := instr bitAnd: 16rFFFFFF.
  		 distanceDiv4 := distanceDiv4 + (delta // 4).
  		 objectMemory longAt: retpc - 4 put: ((instr bitAnd: 16rFF000000) bitOr: (delta bitAnd: 16rFFFFFF))]!

Item was changed:
  ----- Method: CogARMCompiler>>relocateMethodReferenceBeforeAddress:by: (in category 'inline cacheing') -----
  relocateMethodReferenceBeforeAddress: pc by: delta
  	"If possible we generate the method address using pc-relative addressing.
  	 If so we don't need to relocate it in code.  So check if pc-relative code was
  	 generated, and if not, adjust a long sequence."
  	| location |
+ 	(self isPCRelativeValueLoad: (self instructionBeforeAddress: pc - 4)) ifFalse:
+ 		[location := self extract32BitOperandFrom4InstructionsPreceeding: pc - 4.
- 	(self isPCRelativeValueLoad: (objectMemory longAt: pc - 8)) ifFalse:
- 		[location :=    ((objectMemory byteAt: pc - 20) << 24)
- 					+  ((objectMemory byteAt: pc - 16) << 16)
- 					+  ((objectMemory byteAt: pc - 12) << 8)
- 					+   (objectMemory byteAt: pc - 8).
  		 location := location + delta.
+ 		 self insert32BitOperand: location into4InstructionsPreceeding: pc - 4]!
- 		objectMemory byteAt: pc - 20 put: (location >> 24 bitAnd: 16rFF).
- 		objectMemory byteAt: pc - 16 put: (location >> 16 bitAnd: 16rFF).
- 		objectMemory byteAt: pc - 12 put: (location >> 8 bitAnd: 16rFF).
- 		objectMemory byteAt: pc - 8 put: (location  bitAnd: 16rFF)]!

Item was changed:
  ----- Method: CogARMCompiler>>rewriteCallFullAt:target: (in category 'inline cacheing') -----
  rewriteCallFullAt: callSiteReturnAddress target: callTargetAddress
  	"Rewrite a callFull instruction to jump to a different target.  This variant
  	 is used to rewrite cached primitive calls.   Answer the extent of the
  	 code change which is used to compute the range of the icache to flush."
+ 	<inline: true>
+ 	^self
+ 		rewriteFullTransferAt: callSiteReturnAddress
+ 		target: callTargetAddress
+ 		expectedInstruction: 16rE12FFF3C!
- 	<var: #callSiteReturnAddress type: #usqInt>
- 	<var: #callTargetAddress type: #usqInt>
- 	"cogit disassembleFrom: callSiteReturnAddress - 40 to: callSiteReturnAddress + 9"
- 
- 	"check that the instruction involved is actually a long jump BX ip (reg 12)
- 	(CogARMCompiler new blx: 12) hex '16rE12FFF3C'"
- 	self assert: (objectMemory longAt:  callSiteReturnAddress - 4) = 16rE12FFF3C .
- 	
- 	"The callTargetAddress is loaded byte by byte."
- 	objectMemory byteAt: callSiteReturnAddress - 20 put: (callTargetAddress >> 24 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 16 put: (callTargetAddress >> 16 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 12 put: (callTargetAddress >> 8 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 8 put: (callTargetAddress  bitAnd: 16rFF).
- 
- 	self assert: (self callTargetFromReturnAddress: callSiteReturnAddress) signedIntToLong = callTargetAddress.
- 	"self cCode: ''
- 		inSmalltalk: [cogit disassembleFrom: callSiteReturnAddress - 20 to: callSiteReturnAddress - 1]."
- 	^20!

Item was added:
+ ----- Method: CogARMCompiler>>rewriteFullTransferAt:target:expectedInstruction: (in category 'inline cacheing') -----
+ rewriteFullTransferAt: callSiteReturnAddress target: callTargetAddress expectedInstruction: expectedInstruction
+ 	"Rewrite a CallFull or JumpFull instruction to transfer to a different target.
+ 	 This variant is used to rewrite cached primitive calls.   Answer the extent
+ 	 of the code change which is used to compute the range of the icache to flush."
+ 	<var: #callSiteReturnAddress type: #usqInt>
+ 	<var: #callTargetAddress type: #usqInt>
+ 	"cogit disassembleFrom: callSiteReturnAddress - 20 to: callSiteReturnAddress - 1"
+ 	self assert: (self instructionBeforeAddress: callSiteReturnAddress) = expectedInstruction.
+ 	self insert32BitOperand: callTargetAddress into4InstructionsPreceeding: callSiteReturnAddress - 4.
+ 	self assert: (self callFullTargetFromReturnAddress: callSiteReturnAddress) signedIntToLong = callTargetAddress.
+ 	^20!

Item was changed:
  ----- Method: CogARMCompiler>>rewriteInlineCacheAt:tag:target: (in category 'inline cacheing') -----
  rewriteInlineCacheAt: callSiteReturnAddress tag: cacheTag target: callTargetAddress
  	"Rewrite an inline cache to call a different target for a new tag.  This variant is used
  	 to link unlinked sends in ceSend:to:numArgs: et al.  Answer the extent of the code
  	 change which is used to compute the range of the icache to flush."
  	
  	"chacheTag contains an oop to the selector which need be loaded before jumping"
  	<var: #callSiteReturnAddress type: #usqInt>
  	<var: #callTargetAddress type: #usqInt>
  	| call callDistance |
- 	"cogit disassembleFrom: callSiteReturnAddress - 40 to: callSiteReturnAddress + 9"
  	false
  		ifTrue: [self assert: callTargetAddress >= cogit minCallAddress]
  		ifFalse: [callTargetAddress >= cogit minCallAddress ifFalse:
  					[self error: 'linking callsite to invalid address']].
  	callDistance := (callTargetAddress - (callSiteReturnAddress + 8 "pc offset"- 4 "return offset")) signedIntToLong.
+ 	self assert: (self isInImmediateJumpRange: callDistance). "we don't support long call updates here"
- 	
- 	self assert: (self isInImmediateJumpRange: callDistance). "we don't support long call updates, yet"
  	call := self bl: callDistance.
+ 	objectMemory longAt: callSiteReturnAddress - 4 put: call.
+ 	self insert32BitOperand: cacheTag into4InstructionsPreceeding: callSiteReturnAddress - 4.
- 	objectMemory longAt:  callSiteReturnAddress - 4 put: call.
- 	
- 	"The cacheTag is loaded byte by byte. Each byte needs to be encoded with minimal right ring rotation. See also #at:moveCw:intoR:"
- 	objectMemory byteAt: callSiteReturnAddress - 20 put: (cacheTag >> 24 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 16 put: (cacheTag >> 16 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 12 put: (cacheTag >> 8 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 8 put: (cacheTag  bitAnd: 16rFF).
- 
  	self assert: (self callTargetFromReturnAddress: callSiteReturnAddress) signedIntToLong = callTargetAddress.
+ 	self assert: (self extract32BitOperandFrom4InstructionsPreceeding: callSiteReturnAddress - 4) = cacheTag.
  	"self cCode: ''
  		inSmalltalk: [cogit disassembleFrom: callSiteReturnAddress - 20 to: callSiteReturnAddress - 1]."
  	^20!

Item was changed:
  ----- Method: CogARMCompiler>>rewriteJumpFullAt:target: (in category 'inline cacheing') -----
  rewriteJumpFullAt: callSiteReturnAddress target: callTargetAddress
  	"Rewrite a full jump instruction to jump to a different target.  This variant
  	 is used to rewrite cached primitive calls.   Answer the extent of the
  	 code change which is used to compute the range of the icache to flush."
+ 	<inline: true>
+ 	^self
+ 		rewriteFullTransferAt: callSiteReturnAddress
+ 		target: callTargetAddress
+ 		expectedInstruction: 16rE12FFF1C!
- 	<var: #callSiteReturnAddress type: #usqInt>
- 	<var: #callTargetAddress type: #usqInt>
- 	"cogit disassembleFrom: callSiteReturnAddress - 40 to: callSiteReturnAddress + 9"
- 
- 	"check that the instruction involved is actually a long jump BX ip (reg 12)
- 	(CogARMCompiler new bx: 12) hex"
- 	self assert: (objectMemory longAt:  callSiteReturnAddress - 4) = 16rE12FFF1C .
- 	
- 	"The callTargetAddress is loaded byte by byte."
- 	objectMemory byteAt: callSiteReturnAddress - 20 put: (callTargetAddress >> 24 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 16 put: (callTargetAddress >> 16 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 12 put: (callTargetAddress >> 8 bitAnd: 16rFF).
- 	objectMemory byteAt: callSiteReturnAddress - 8 put: (callTargetAddress  bitAnd: 16rFF).
- 
- 	self assert: (self callTargetFromReturnAddress: callSiteReturnAddress) signedIntToLong = callTargetAddress.
- 	"self cCode: ''
- 		inSmalltalk: [cogit disassembleFrom: callSiteReturnAddress - 20 to: callSiteReturnAddress - 1]."
- 	^20!

Item was added:
+ ----- Method: CogAbstractInstruction>>fullCallsAreRelative (in category 'abi') -----
+ fullCallsAreRelative
+ 	"Answer if CallFull and/or JumpFull are relative and hence need relocating on method
+ 	 compation. If so, they are annotated with IsRelativeCall in methods and relocated in
+ 	 relocateIfCallOrMethodReference:mcpc:delta:"
+ 	self subclassResponsibility!

Item was changed:
  ----- Method: CogAbstractInstruction>>longJumpTargetAddress (in category 'generate machine code') -----
  longJumpTargetAddress
  	<inline: true> "Since it's an extraction from other methods."
+ 	"This needs to be different from jumpTargetAddress because long jumps can
- 	"This needs to be digfferent from jumpTargetAddress because long jumps can
  	be to absolute addresses and hence we can't assert that the jump target is sane."
  	| jumpTarget |
  	<var: #jumpTarget type: #'AbstractInstruction *'>
  	jumpTarget := cogit cCoerceSimple: (operands at: 0) to: #'AbstractInstruction *'.
  	(self isAnInstruction: jumpTarget) ifTrue:
  		[jumpTarget := cogit cCoerceSimple: jumpTarget address to: #'AbstractInstruction *'].
  	self assert: jumpTarget ~= 0.
  	^jumpTarget!

Item was added:
+ ----- Method: CogAbstractInstruction>>outputMachineCodeAt: (in category 'encoding') -----
+ outputMachineCodeAt: address
+ 	"By default move machine code a byte at a time
+ 	  Subclasses with coarser granularity can override as desired."
+ 	<inline: true>
+ 	0 to: machineCodeSize - 1 do:
+ 		[:j|
+ 		objectMemory byteAt: address + j put: (machineCode at: j)]!

Item was added:
+ ----- Method: CogAbstractInstruction>>rewriteInlineCacheTag:at: (in category 'inline cacheing') -----
+ rewriteInlineCacheTag: cacheTag at: callSiteReturnAddress
+ 	"Rewrite an inline cache with a new tag.  This variant is used
+ 	 by the garbage collector."
+ 	self subclassResponsibility!

Item was added:
+ ----- Method: CogIA32Compiler>>callFullTargetFromReturnAddress: (in category 'inline cacheing') -----
+ callFullTargetFromReturnAddress: callSiteReturnAddress
+ 	"Answer the address the call immediately preceeding callSiteReturnAddress will jump to."
+ 	^self callTargetFromReturnAddress: callSiteReturnAddress!

Item was added:
+ ----- Method: CogIA32Compiler>>fullCallsAreRelative (in category 'abi') -----
+ fullCallsAreRelative
+ 	"Answer if CallFull and/or JumpFull are relative and hence need relocating on method
+ 	 compation. If so, they are annotated with IsRelativeCall in methods and relocated in
+ 	 relocateIfCallOrMethodReference:mcpc:delta:"
+ 	^true!

Item was changed:
  ----- Method: Cogit>>CallFullRT: (in category 'method map') -----
  CallFullRT: callTarget
  	"Big assumption here that calls and jumps look the same as regards their displacement.
  	 This works on at least x86, ARM and x86_64.
  	 CallFull is intended to be for calls anywhere in our address space.
  	 See also Call which calls within our *code* space"
  	<inline: true>
  	<returnTypeC: #'AbstractInstruction *'>
+ 	^backEnd fullCallsAreRelative
+ 		ifTrue: [self annotateCall: (self CallFull: callTarget)]
+ 		ifFalse: [self CallFull: callTarget]!
- 	^self annotateCall: (self CallFull: callTarget)!

Item was changed:
  ----- Method: Cogit>>JumpFullRT: (in category 'method map') -----
  JumpFullRT: callTarget
  	"Big assumption here that calls and jumps look the same as regards their displacement.
  	 This works on at least x86, ARM and x86_64.
  	 JumpFull is intended to be for jumps anywhere in our address space.
  	 See also JumpLong et al. which jump within our *code* space"
  	<inline: true>
  	<returnTypeC: #'AbstractInstruction *'>
+ 	^backEnd fullCallsAreRelative
+ 		ifTrue: [self annotateCall: (self JumpFull: callTarget)]
+ 		ifFalse: [self JumpFull: callTarget]!
- 	^self annotateCall: (self JumpFull: callTarget)!

Item was changed:
  ----- Method: Cogit>>outputInstructionsAt: (in category 'generate machine code') -----
  outputInstructionsAt: startAddress
  	"Store the generated machine code, answering the last address"
  	| absoluteAddress |
  	<var: #abstractInstruction type: #'AbstractInstruction *'>
  	absoluteAddress := startAddress.
  	0 to: opcodeIndex - 1 do:
  		[:i| | abstractInstruction |
  		abstractInstruction := self abstractInstructionAt: i.
  		self assert: abstractInstruction address = absoluteAddress.
+ 		abstractInstruction outputMachineCodeAt: absoluteAddress.
+ 		absoluteAddress := absoluteAddress + abstractInstruction machineCodeSize].
- 		0 to: abstractInstruction machineCodeSize - 1 do:
- 			[:j|
- 			objectMemory byteAt: absoluteAddress put: (abstractInstruction machineCode at: j).
- 			absoluteAddress := absoluteAddress + 1]].
  	^absoluteAddress!



More information about the Vm-dev mailing list