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

commits at source.squeak.org commits at source.squeak.org
Thu Aug 12 17:56:28 UTC 2021


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

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

Name: VMMaker.oscog-eem.3034
Author: eem
Time: 12 August 2021, 10:56:19.010201 am
UUID: 3ea0aaa2-20e4-4c02-b448-c3e708578e16
Ancestors: VMMaker.oscog-eem.3033

CogARMv8Compiler: Make sure the generated cache flush code flushes the range (startAddress to endAddress], i.e. never flush endAddress, only addresses less than endAddress.  Flushing endAddress can cause a segmentation violation if the endAddress is on an empty page.

Have Symbol simulate & for expressions such as
	self cppIf: #__APPLE__ & #__MACH__
		ifFalse: ...

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

Item was changed:
  ----- Method: CogARMv8Compiler>>generateDCacheFlush (in category 'inline cacheing') -----
  generateDCacheFlush
  	"Use the DC instruction to implement ceFlushDCache(void *start, void *end); see flushDCacheFrom:to:.
  	 If there is a dual mapped zone then clean data via DC_CVAU as address + codeToDataDelta,
  	 then invalidate data at address via CIVAC."
  
  	"D4.4.7		About cache maintenance in AArch64 state													D4-2478
  
  		Terminology for Clean, Invalidate, and Clean and Invalidate instructions									D4-2479
  		...
  		-	For instructions operating by VA, the following conceptual points are defined:						D4-2480
  		Point of Unification (PoU)							
  			The PoU for a PE is the point by which the instruction and data caches and the translation table walks of that
  			PE are guaranteed to see the same copy of a memory location. In many cases, the Point of Unification is the
  			point in a uniprocessor memory system by which the instruction and data caches and the translation table
  			walks have merged.
  
  			The PoU for an Inner Shareable shareability domain is the point by which the instruction and data caches
  			and the translation table walks of all the PEs in that Inner Shareable shareability domain are guaranteed to
  			see the same copy of a memory location. Defining this point permits self-modifying software to ensure future
  			instruction fetches are associated with the modified version of the software by using the standard correctness
  			policy of:
  				1. Clean data cache entry by address.
  				2. Invalidate instruction cache entry by address.
  
  		Example code for cache maintenance instructions D4-2490 - D4-2491"
  	self cppIf: #__APPLE__ & #__MACH__
  		ifFalse:
  			[| mask loop |
  			self assert: cogit getCodeToDataDelta ~= 0.
  			"Mask is large enough to encompass the method zone and has the correct minimum alignment."
  			mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self dataCacheLineLength.
  
  			"Since this is used from C code we must use only caller-saved registers.
  			 C arg registers 2 & 3 are such a convenient pair of caller-saved registers."
  			cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"
  			cogit AddCq: cogit getCodeToDataDelta R: CArg2Reg R: CArg3Reg.
  			loop := cogit Label.
  			"see concretizeDataCacheControl"
  			cogit gen: DC operand: CArg3Reg operand: DC_CVAU.	"clean (flush) address + codeToDataDelta"
  			cogit gen: DC operand: CArg2Reg operand: DC_CIVAC.	"invalidate address"
  			cogit
  				AddCq: self dataCacheLineLength R: CArg2Reg;
  				AddCq: self dataCacheLineLength R: CArg3Reg;
  				CmpR: CArg1Reg R: CArg2Reg;
+ 				JumpBelow: loop.
- 				JumpBelowOrEqual: loop.
  			cogit RetN: 0]!

Item was changed:
  ----- Method: CogARMv8Compiler>>generateICacheFlush (in category 'inline cacheing') -----
  generateICacheFlush
  	"Use DC VAUC, DSB, IC IVAU, and ISB instructions to implement ceFlushICache(void *start, void *end); see flushICacheFrom:to:.
  	 One might think that if there is a dual zone then data at address + codeToDataDelta must be cleaned,
  	 but this isn't the case.  All we need to do is clean data at address via DC VAUC and instructions via IC IVAU."
  
  	"B2.2.5		Concurrent modification and execution of instructions											B2-112
  
  		...to avoid UNPREDICTABLE or CONSTRAINED UNPREDICTABLE behavior, instruction modifications must be explicitly synchronized before they are executed. The required synchronization is as follows:
  
  		1.	No PE must be executing an instruction when another PE is modifying that instruction.
  
  		2.	To ensure that the modified instructions are observable, a PE that is writing the instructions must issue the following sequence of instructions and operations:
  
  			; Coherency example for data and instruction accesses within the same Inner Shareable domain.
  			; enter this code with <Wt> containing a new 32-bit instruction, to be held in Cacheable space at a location pointed to by Xn.
  
  			STR Wt, [Xn]
  			DC CVAU, Xn		; Clean data cache by VA to point of unification (PoU)
  			DSB ISH			; Ensure visibility of the data cleaned from cache
  			IC IVAU, Xn			; Invalidate instruction cache by VA to PoU
  			DSB ISH
  
  			Note
  			 -	The DC CVAU operation is not required if the area of memory is either Non-cacheable or Write-Through Cacheable.
  			 -	If the contents of physical memory differ between the mappings, changing the mapping of VAs to PAs can cause
  				the instructions to be concurrently modified by one PE and executed by another PE. If the modifications affect
  				instructions other than those listed as being acceptable for modification, synchronization must be used to avoid
  				UNPREDICTABLE or CONSTRAINED UNPREDICTABLE behavior.
  
  		3.	In a multiprocessor system, the IC IVAU is broadcast to all PEs within the Inner Shareable domain of the PE running this sequence.
  			However, when the modified instructions are observable, each PE that is executing the modified instructions must issue the following
  			instruction to ensure execution of the modified instructions:
  
  			ISB					; Synchronize fetched instruction stream"
  
  	"D4.4.7		About cache maintenance in AArch64 state													D4-2478
  
  		Terminology for Clean, Invalidate, and Clean and Invalidate instructions									D4-2479
  		...
  		-	For instructions operating by VA, the following conceptual points are defined:						D4-2480
  		Point of Unification (PoU)							
  			The PoU for a PE is the point by which the instruction and data caches and the translation table walks of that
  			PE are guaranteed to see the same copy of a memory location. In many cases, the Point of Unification is the
  			point in a uniprocessor memory system by which the instruction and data caches and the translation table
  			walks have merged.
  
  			The PoU for an Inner Shareable shareability domain is the point by which the instruction and data caches
  			and the translation table walks of all the PEs in that Inner Shareable shareability domain are guaranteed to
  			see the same copy of a memory location. Defining this point permits self-modifying software to ensure future
  			instruction fetches are associated with the modified version of the software by using the standard correctness
  			policy of:
  				1. Clean data cache entry by address.
  				2. Invalidate instruction cache entry by address.
  
  		Example code for cache maintenance instructions D4-2490 - D4-2491"
  	self cppIf: #__APPLE__ & #__MACH__
  		ifFalse:
  			[| mask loop |
  			"See concretizeCacheControlOp1:CRm:Op2: & 
  			 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100403_0200_00_en/lau1443435580346.html"
  			self dataCacheFlushRequired ifTrue: "CTR_EL0.IDC is zero; must clean data cache to point of unification."
  				["Since this is used from C code we must use only caller-saved registers.
  				  C arg registers 2 & 3 are as such a convenient pair of caller-saved registers."
  				 "Mask is large enough to encompass the method zone and has the correct minimum alignment."
  				 mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self dataCacheLineLength.
  				 cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"
  	
  				 loop := cogit Label.
  				 "see concretizeDataCacheControl"
  				 cogit
  					gen: DC operand: CArg2Reg operand: DC_CVAU;		"clean (flush) address"
  					AddCq: self dataCacheLineLength R: CArg2Reg;
  					CmpR: CArg1Reg R: CArg2Reg;
+ 					JumpBelow: loop].
- 					JumpBelowOrEqual: loop].
  
  			cogit gen: DSB operand: DSB_ISH operand: DSB_ALL.		"Ensure visibility of the data cleaned from cache"
  
  			self instructionCacheFlushRequired ifTrue: "CTR_EL0.DIC is zero; must clean instruction cache to point of unification."
  				["Mask is large enough to encompass the method zone and has the correct minimum alignment."
  				 mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self instructionCacheLineLength.
  				 cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"
  	
  				 loop := cogit Label.
  				 "see concretizeDataCacheControl"
  				 cogit
  					gen: IC operand: CArg2Reg operand: IC_IVAU;		"clean (flush) address"
  					AddCq: self instructionCacheLineLength R: CArg2Reg;
  					CmpR: CArg1Reg R: CArg2Reg;
+ 					JumpBelow: loop.
- 					JumpBelowOrEqual: loop.
  
  				 cogit gen: DSB operand: DSB_ISH operand: DSB_ALL].
  
  			cogit
  				gen: ISB;
  				RetN: 0]!

Item was added:
+ ----- Method: Symbol>>& (in category '*VMMaker-interpreter simulator') -----
+ & aSymbol
+ 	^(VMClass valueOfSymbol: self) & (VMClass valueOfSymbol: aSymbol)!

Item was added:
+ ----- Method: VMClass class>>valueOfSymbol: (in category 'simulation') -----
+ valueOfSymbol: value
+ 	^(self bindingOf: value)
+ 		ifNil: [InitializationOptions at: value ifAbsent: [false]]
+ 		ifNotNil: [:binding| binding value]!

Item was changed:
  ----- Method: VMClass>>cppIf:ifTrue:ifFalse: (in category 'translation support') -----
  cppIf: conditionBlockOrSymbolValue ifTrue: trueExpressionOrBlock ifFalse: falseExpressionOrBlockOrNil
  	"When translated, produces #if (condition) #else #endif CPP directives.
  	 Example usage:
  
  		self cppIf: [BytesPerWord = 8]
  			ifTrue: [self doSomethingFor64Bit]
  			ifFalse: [self doSomethingFor32Bit]
  		self cppIf: BytesPerWord = 8
  			ifTrue: [self doSomethingFor64Bit]
  			ifFalse: [self doSomethingFor32Bit]
  		self cppIf: #A_GLOBAL
  			ifTrue: [self doSomethingFor64Bit]
  			ifFalse: [self doSomethingFor32Bit]"
  	<doNotGenerate>
  	^(conditionBlockOrSymbolValue value
  		ifNil: [false]
  		ifNotNil: [:value|
  			value isInteger
  				ifTrue: [value ~= 0]
  				ifFalse:
  					[value isSymbol
+ 						ifTrue: [self class valueOfSymbol: value]
- 						ifTrue: [(self class bindingOf: value)
- 									ifNil: [InitializationOptions at: value ifAbsent: [false]]
- 									ifNotNil: [:binding| binding value]]
  						ifFalse: [value]]])
  		ifTrue: trueExpressionOrBlock
  		ifFalse: falseExpressionOrBlockOrNil!



More information about the Vm-dev mailing list