[Vm-dev] VM Maker: VMMaker-dtl.392.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Jan 13 01:41:35 UTC 2017


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.392.mcz

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

Name: VMMaker-dtl.392
Author: dtl
Time: 12 January 2017, 8:34:22.25 pm
UUID: 7c31d31d-9de0-4f45-89e2-6caa1886f12f
Ancestors: VMMaker-dtl.391

VMMaker 4.16.3

Support very early images in which method context copy fails due to stack pointer not yet adjusted to position. For these images, disable stack limit bounds check. Based on SqueakJS implementation as described below.

From: Bert Freudenberg <bert at freudenbergs.de>
Date: Wed, 11 Jan 2017 17:10:24 +0100
To: The general-purpose Squeak developers list <squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Backward image and VM compatibility

Some early images fill the context stack before advancing its stack pointer. I have a flag to allow that, it's pretty certainly used in primitive 61. Normally the VM does not allow access beyond the SP because there is garbage there (stack pops do not nil out the context slot):

https://github.com/bertfreudenberg/SqueakJS/search?q=allowAccessBeyondSP

But since the regular VM does not allow it, no image (except the really old ones) ever does it, so I just leave the flag enabled whenever "oldPrims" is in effect ;) Would be better if we could come up with a better way to identify these images.

=============== Diff against VMMaker-dtl.391 ===============

Item was changed:
  Interpreter subclass: #ContextInterpreter
+ 	instanceVariableNames: 'activeContext theHomeContext method receiver instructionPointer stackPointer localIP localSP localHomeContext localReturnContext localReturnValue messageSelector currentBytecode primitiveIndex primitiveFunctionPointer methodCache atCache lkupClass reclaimableContextCount nextPollTick nextWakeupTick lastTick interruptPending savedWindowSize fullScreenFlag deferDisplayUpdates pendingFinalizationSignals compilerInitialized compilerHooks extraVMMemory newNativeMethod methodClass receiverClass interpreterVersion imageFormatVersionNumber interpreterProxy showSurfaceFn interruptCheckCounter interruptCheckCounterFeedBackReset interruptChecksEveryNms externalPrimitiveTable globalSessionID jmpBuf jmpDepth jmpMax suspendedCallbacks suspendedMethods imageFormatInitialVersion allowAccessBeyondSP'
- 	instanceVariableNames: 'activeContext theHomeContext method receiver instructionPointer stackPointer localIP localSP localHomeContext localReturnContext localReturnValue messageSelector currentBytecode primitiveIndex primitiveFunctionPointer methodCache atCache lkupClass reclaimableContextCount nextPollTick nextWakeupTick lastTick interruptPending savedWindowSize fullScreenFlag deferDisplayUpdates pendingFinalizationSignals compilerInitialized compilerHooks extraVMMemory newNativeMethod methodClass receiverClass interpreterVersion imageFormatVersionNumber interpreterProxy showSurfaceFn interruptCheckCounter interruptCheckCounterFeedBackReset interruptChecksEveryNms externalPrimitiveTable globalSessionID jmpBuf jmpDepth jmpMax suspendedCallbacks suspendedMethods imageFormatInitialVersion'
  	classVariableNames: 'BlockArgumentCountIndex BytecodeTable CacheProbeMax CallerIndex CompilerHooksSize DirBadPath DirEntryFound DirNoMoreEntries DoBalanceChecks HomeIndex InitialIPIndex MaxJumpBuf MessageDictionaryIndex MethodCacheNative TempFrameStart'
  	poolDictionaries: 'VMMethodCacheConstants VMSqueakV3BytecodeConstants'
  	category: 'VMMaker-Interpreter'!
  
  !ContextInterpreter commentStamp: '<historical>' prior: 0!
  This class is a complete implementation of the Smalltalk-80 virtual machine, derived originally from the Blue Book specification but quite different in some areas.
  
  It has been modernized with 32-bit pointers, better management of Contexts, and attention to variable use that allows the CCodeGenerator (qv) to keep, eg, the instruction pointer and stack pointer in registers as well as keeping most simple variables in a global array that seems to improve performance for most platforms.
  
  In addition to SmallInteger arithmetic and Floats, it supports logic on 32-bit PositiveLargeIntegers, thus allowing it to simulate itself much more effectively than would otherwise be the case.
  
  NOTE:  Here follows a list of things to be borne in mind when working on this code, or when making changes for the future.
  
  1.  There are a number of things that should be done the next time we plan to release a copletely incompatible image format.  These include unifying the instanceSize field of the class format word -- see instantiateClass:indexableSize:, and unifying the bits of the method primitive index (if we decide we need more than 512, after all) -- see primitiveIndexOf:.  Also, contexts should be given a special format code (see next item).
  
  2.  There are several fast checks for contexts (see isContextHeader: and isMethodContextHeader:) which will fail if the compact class indices of BlockContext or MethodContext change.  This is necessary because the oops may change during a compaction when the oops are being adjusted.  It's important to be aware of this when writing a new image using the systemTracer.  A better solution would be to reserve one of the format codes for Contexts only.
  
  3.  We have made normal files tolerant to size and positions up to 32 bits.  This has not been done for async files, since they are still experimental.  The code in size, at: and at:put: should work with sizes and indices up to 31 bits, although I have not tested it (di 12/98); it might or might not work with 32-bit sizes.
  
  4.  Note that 0 is used in a couple of places as an impossible oop.  This should be changed to a constant that really is impossible (or perhaps there is code somewhere that guarantees it --if so it should be put in this comment).  The places include the method cache and the at cache. !

Item was changed:
  ----- Method: ContextInterpreter>>interpret (in category 'interpreter shell') -----
  interpret
  	"This is the main interpreter loop. It normally loops forever, fetching and executing bytecodes. When running in the context of a browser plugin VM, however, it must return control to the browser periodically. This should done only when the state of the currently running Squeak thread is safely stored in the object heap. Since this is the case at the moment that a check for interrupts is performed, that is when we return to the browser if it is time to do so. Interrupt checks happen quite frequently."
  
  	<inline: false> "should not be inlined into any senders"
  	self initializeImageFormatVersion.
  	self updatePrimitiveTable..
+ 	allowAccessBeyondSP := self useOldPrimitives. "some old images must disable stack bounds check"
  	self browserPluginInitialiseIfNeeded. "record entry time when running as a browser plug-in"
  	self internalizeIPandSP.
  	self fetchNextBytecode.
  	[true] whileTrue: [self dispatchOn: currentBytecode in: BytecodeTable].
  	localIP := localIP - 1.  "undo the pre-increment of IP before returning"
  	self externalizeIPandSP.
  !

Item was added:
+ ----- Method: ContextInterpreter>>shouldBoundAccessWithinStackFor:withFormat: (in category 'array primitive support') -----
+ shouldBoundAccessWithinStackFor: header withFormat: format
+ 	"Answer true if header describes a context object for which array access should
+ 	not extend beyond the stack pointer, unless allowAccessBeyondSP has been
+ 	set true.
+ 
+ 	The allowAccessBeyondSP flag is set if we are running an older image, whiich
+ 	in some cases may require copying method contexts prior to setting the stack
+ 	pointer to its proper position. The normal setting for allowAccessBeyondSP is
+ 	false, which prevents improper accesses beyond stack boundaries."
+ 
+ 	<inline: true>
+ 	^ (format = 3
+ 		and: [allowAccessBeyondSP not])
+ 			and: [self isContextHeader: header]
+ !

Item was changed:
  ----- Method: ContextInterpreter>>stObject:at: (in category 'array primitive support') -----
  stObject: array at: index
  	"Return what ST would return for <obj> at: index."
  
  	| hdr fmt totalLength fixedFields stSize |
- 	<inline: false>
  	hdr := objectMemory baseHeader: array.
  	fmt := (hdr >> 8) bitAnd: 16rF.
  	totalLength := objectMemory lengthOf: array baseHeader: hdr format: fmt.
  	fixedFields := objectMemory fixedFieldsOf: array format: fmt length: totalLength.
+ 	(self shouldBoundAccessWithinStackFor: hdr withFormat: fmt)
- 	(fmt = 3 and: [self isContextHeader: hdr])
  		ifTrue: [stSize := self fetchStackPointerOf: array]
  		ifFalse: [stSize := totalLength - fixedFields].
  	((objectMemory oop: index isGreaterThanOrEqualTo: 1)
  			and: [objectMemory oop: index isLessThanOrEqualTo: stSize])
  		ifTrue: [^ self subscript: array with: (index + fixedFields) format: fmt]
  		ifFalse: [self primitiveFail.  ^ 0].!

Item was changed:
  ----- Method: ContextInterpreter>>stObject:at:put: (in category 'array primitive support') -----
  stObject: array at: index put: value
  	"Do what ST would return for <obj> at: index put: value."
+ 
  	| hdr fmt totalLength fixedFields stSize |
- 	<inline: false>
  	hdr := objectMemory baseHeader: array.
  	fmt := (hdr >> 8) bitAnd: 16rF.
  	totalLength := objectMemory lengthOf: array baseHeader: hdr format: fmt.
  	fixedFields := objectMemory fixedFieldsOf: array format: fmt length: totalLength.
+ 	(self shouldBoundAccessWithinStackFor: hdr withFormat: fmt)
- 	(fmt = 3 and: [self isContextHeader: hdr])
  		ifTrue: [stSize := self fetchStackPointerOf: array]
  		ifFalse: [stSize := totalLength - fixedFields].
  	((objectMemory oop: index isGreaterThanOrEqualTo: 1)
  			and: [objectMemory oop: index isLessThanOrEqualTo: stSize])
  		ifTrue: [self subscript: array with: (index + fixedFields) storing: value format: fmt]
  		ifFalse: [self primitiveFail]!

Item was changed:
  ----- Method: ContextInterpreter>>stSizeOf: (in category 'array primitive support') -----
  stSizeOf: oop
  	"Return the number of indexable fields in the given object. (i.e., what Smalltalk would return for <obj> size)."
  	"Note: Assume oop is not a SmallInteger!!"
  
  	| hdr fmt totalLength fixedFields |
- 	<inline: false>
  	hdr := objectMemory baseHeader: oop.
  	fmt := (hdr >> 8) bitAnd: 16rF.
  	totalLength := objectMemory lengthOf: oop baseHeader: hdr format: fmt.
  	fixedFields := objectMemory fixedFieldsOf: oop format: fmt length: totalLength.
+ 	(self shouldBoundAccessWithinStackFor: hdr withFormat: fmt)
- 	(fmt = 3 and: [self isContextHeader: hdr])
  		ifTrue: [^ self fetchStackPointerOf: oop]
  		ifFalse: [^ totalLength - fixedFields]!

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.16.3'!
- 	^'4.16.2'!



More information about the Vm-dev mailing list