Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2784.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2784
Author: eem
Time: 28 July 2020, 2:38:11.381837 pm
UUID: 5c810cae-a07a-469a-b68a-9a901ca3545c
Ancestors: VMMaker.oscog-eem.2783
StackInterpreter: introspection for the Qwaq Croquet high-priority ticker/tickee mechanism.
VMMaker: Generate ckformat.c to the src directory if ImageFormat is in the image.
=============== Diff against VMMaker.oscog-eem.2783 ===============
Item was added:
+ ----- Method: StackInterpreterPrimitives>>getVMTickeeCallCount (in category 'system control primitives') -----
+ getVMTickeeCallCount
+ ^self cppIf: #VM_TICKER
+ ifTrue: [self positiveMachineIntegerFor: self ioVMTickeeCallCount]
+ ifFalse: [ConstZero]!
Item was added:
+ ----- Method: StackInterpreterPrimitives>>getVMTickerCount (in category 'system control primitives') -----
+ getVMTickerCount
+ ^self cppIf: #VM_TICKER
+ ifTrue: [self positiveMachineIntegerFor: self ioVMTickerCount]
+ ifFalse: [ConstZero]!
Item was added:
+ ----- Method: StackInterpreterPrimitives>>getVMTickerStartUSecs (in category 'system control primitives') -----
+ getVMTickerStartUSecs
+ ^self cppIf: #VM_TICKER
+ ifTrue: [self positive64BitIntegerFor: self ioVMTickerStartUSecs]
+ ifFalse: [ConstZero]!
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveAllVMParameters: (in category 'system control primitives') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveGetVMParameter: (in category 'system control primitives') -----
primitiveGetVMParameter: arg
"See primitiveVMParameter method comment.
N.B. written as a returning case to avoid branch limits in the V3 bytecode set."
arg caseOf: {
[1] -> [^self positiveMachineIntegerFor: objectMemory oldSpaceSize].
[2] -> [^objectMemory integerObjectOf: objectMemory newSpaceSize].
[3] -> [^self positiveMachineIntegerFor: objectMemory totalMemorySize].
[6] -> [^objectMemory integerObjectOf: objectMemory tenuringThreshold].
[7] -> [^objectMemory integerObjectOf: objectMemory statFullGCs].
[8] -> [^objectMemory integerObjectOf: objectMemory statFullGCUsecs + 500 // 1000].
[9] -> [^objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
ifTrue: [objectMemory statScavenges]
ifFalse: [objectMemory statIncrGCs])].
[10] -> [^objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
ifTrue: [objectMemory statScavengeGCUsecs]
ifFalse: [objectMemory statIncrGCUsecs]) + 500 // 1000].
[11] -> [^objectMemory integerObjectOf: objectMemory statTenures].
[12] -> [^ConstZero]. "Was JITTER VM info"
+ [13] -> [^self getVMTickerStartUSecs].
+ [14] -> [^self getVMTickerCount].
+ [15] -> [^self getVMTickeeCallCount].
- [13] -> [^ConstZero]. "Was JITTER VM info"
- [14] -> [^ConstZero]. "Was JITTER VM info"
- [15] -> [^ConstZero]. "Was JITTER VM info"
[16] -> [^self positive64BitIntegerFor: statIdleUsecs].
[17] -> [^(SistaVM and: [self isCog])
ifTrue: [objectMemory floatObjectOf: self getCogCodeZoneThreshold]
ifFalse: [ConstZero]].
[18] -> [^objectMemory hasSpurMemoryManagerAPI
ifTrue: [objectMemory integerObjectOf: objectMemory statCompactionUsecs + 500 // 1000]
ifFalse: [ConstZero]].
[19] -> [^objectMemory hasSpurMemoryManagerAPI
ifTrue: [objectMemory integerObjectOf: objectMemory scavengeThresholdAsExtent]
ifFalse: [ConstZero]].
[20] -> [^objectMemory positive64BitIntegerFor: self ioUTCStartMicroseconds].
[21] -> [^objectMemory integerObjectOf: objectMemory rootTableCount].
[22] -> [^objectMemory integerObjectOf: objectMemory statRootTableOverflows].
[23] -> [^objectMemory integerObjectOf: extraVMMemory].
[24] -> [^objectMemory integerObjectOf: objectMemory shrinkThreshold].
[25] -> [^objectMemory integerObjectOf: objectMemory growHeadroom].
[26] -> [^objectMemory integerObjectOf: self ioHeartbeatMilliseconds].
[27] -> [^objectMemory integerObjectOf: objectMemory statMarkCount].
[28] -> [^objectMemory integerObjectOf: objectMemory statSweepCount].
[29] -> [^objectMemory integerObjectOf: objectMemory statMkFwdCount].
[30] -> [^objectMemory integerObjectOf: objectMemory statCompMoveCount].
[31] -> [^objectMemory integerObjectOf: objectMemory statGrowMemory].
[32] -> [^objectMemory integerObjectOf: objectMemory statShrinkMemory].
[33] -> [^objectMemory integerObjectOf: objectMemory statRootTableCount].
[34] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:"was statAllocationCount"
[objectMemory positive64BitIntegerFor: objectMemory currentAllocatedBytes]].
[35] -> [^objectMemory integerObjectOf: objectMemory statSurvivorCount].
[36] -> [^objectMemory integerObjectOf: (self microsecondsToMilliseconds: objectMemory statGCEndUsecs)].
[37] -> [^objectMemory integerObjectOf: objectMemory statSpecialMarkCount].
[38] -> [^objectMemory integerObjectOf: objectMemory statIGCDeltaUsecs + 500 // 1000].
[39] -> [^objectMemory integerObjectOf: statPendingFinalizationSignals].
[40] -> [^objectMemory integerObjectOf: objectMemory wordSize].
[41] -> [^objectMemory integerObjectOf: self imageFormatVersion].
[42] -> [^objectMemory integerObjectOf: numStackPages].
[43] -> [^objectMemory integerObjectOf: desiredNumStackPages].
[44] -> [^objectMemory integerObjectOf: objectMemory edenBytes].
[45] -> [^objectMemory integerObjectOf: desiredEdenBytes].
[46] -> [^self getCogCodeSize].
[47] -> [^self getDesiredCogCodeSize].
[48] -> [^self getCogVMFlags].
[49] -> [^objectMemory integerObjectOf: self ioGetMaxExtSemTableSize].
[52] -> [^objectMemory integerObjectOf: objectMemory rootTableCapacity].
[53] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:
[objectMemory integerObjectOf: objectMemory numSegments]].
[54] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:
[objectMemory integerObjectOf: objectMemory freeSize]].
[55] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:
[objectMemory floatObjectOf: objectMemory getHeapGrowthToSizeGCRatio]].
[56] -> [^self positive64BitIntegerFor: statProcessSwitch].
[57] -> [^self positive64BitIntegerFor: statIOProcessEvents].
[58] -> [^self positive64BitIntegerFor: statForceInterruptCheck].
[59] -> [^self positive64BitIntegerFor: statCheckForEvents].
[60] -> [^self positive64BitIntegerFor: statStackOverflow].
[61] -> [^self positive64BitIntegerFor: statStackPageDivorce].
[62] -> [^self getCodeCompactionCount].
[63] -> [^self getCodeCompactionMSecs].
[64] -> [^self getCogMethodCount].
[65] -> [^self getCogVMFeatureFlags].
[66] -> [^objectMemory integerObjectOf: self stackPageByteSize].
[67] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:
[self positiveMachineIntegerFor: objectMemory maxOldSpaceSize]].
[68] -> [^objectMemory floatObjectOf: stackPages statAverageLivePagesWhenMapping].
[69] -> [^objectMemory integerObjectOf: stackPages statMaxPageCountWhenMapping].
[70] -> [^objectMemory integerObjectOf: self vmProxyMajorVersion].
[71] -> [^objectMemory integerObjectOf: self vmProxyMinorVersion].
[72] -> [^objectMemory integerObjectOf: objectMemory statMarkUsecs + 500 // 1000].
[73] -> [^objectMemory integerObjectOf: objectMemory statSweepUsecs + 500 // 1000].
[74] -> [^objectMemory hasSpurMemoryManagerAPI ifTrue:
[objectMemory integerObjectOf: objectMemory statMaxAllocSegmentTime + 500 // 1000]].
[75] -> [^objectMemory booleanObjectOf: self primitiveDoMixedArithmetic] }
otherwise: [^nil]!
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveVMParameter (in category 'system control primitives') -----
primitiveVMParameter
"Behaviour depends on argument count:
0 args: return an Array of VM parameter values;
1 arg: return the indicated VM parameter;
2 args: set the VM indicated parameter.
VM parameters are numbered as follows:
1 end (v3)/size(Spur) of old-space (0-based, read-only)
2 end (v3)/size(Spur) of young/new-space (read-only)
3 end (v3)/size(Spur) of heap (read-only)
4 nil (was allocationCount (read-only))
5 nil (was allocations between GCs (read-write)
6 survivor count tenuring threshold (read-write)
7 full GCs since startup (read-only)
8 total milliseconds in full GCs since startup (read-only)
9 incremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)
10 total milliseconds in incremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)
11 tenures of surving objects since startup or reset (read-write)
+ 12-20 were specific to ikp's JITTER VM, now 12 16 open for use
+ 13 if started, the start time in utc microseconds of the high-priority ticker
+ 14 if started, the number of checkHighPriorityTickees calls
+ 15 if started, the number of tickee calls from checkHighPriorityTickees
- 12-20 were specific to ikp's JITTER VM, now 12-15 are open for use
16 total microseconds at idle since start-up (if non-zero)
17 fraction of the code zone to use (Sista only; used to control code zone use to preserve sendAndBranchData on counter tripped callback)
18 total milliseconds in compaction phase of full GC since start-up (Spur only)
19 scavenge threshold, the effective size of eden. When eden fills to the threshold a scavenge is scheduled. Newer Spur VMs only.
20 utc microseconds at VM start-up (actually at time initialization, which precedes image load).
21 root/remembered table size (occupancy) (read-only)
22 root table overflows since startup (read-only)
23 bytes of extra memory to reserve for VM buffers, plugins, etc (stored in image file header).
24 memory threshold above which shrinking object memory (rw)
25 memory headroom when growing object memory (rw)
26 interruptChecksEveryNms - force an ioProcessEvents every N milliseconds (rw)
27 number of times mark loop iterated for current IGC/FGC (read-only) includes ALL marking
28 number of times sweep loop iterated for current IGC/FGC (read-only)
29 number of times make forward loop iterated for current IGC/FGC (read-only)
30 number of times compact move loop iterated for current IGC/FGC (read-only)
31 number of grow memory requests (read-only)
32 number of shrink memory requests (read-only)
33 number of root table entries used for current IGC/FGC (read-only)
34 Spur: bytes allocated in total since start-up or reset (read-write) (Used to be number of allocations done before current IGC/FGC (read-only))
35 number of survivor objects after current IGC/FGC (read-only)
36 millisecond clock when current IGC/FGC completed (read-only)
37 number of marked objects for Roots of the world, not including Root Table entries for current IGC/FGC (read-only)
38 milliseconds taken by current IGC (read-only)
39 Number of finalization signals for Weak Objects pending when current IGC/FGC completed (read-only)
40 BytesPerOop for this image
41 imageFormatVersion for the VM
42 number of stack pages in use
43 desired number of stack pages (stored in image file header, max 65535)
44 size of eden, in bytes
45 desired size of eden, in bytes (stored in image file header)
46 machine code zone size, in bytes (Cog only; otherwise nil)
47 desired machine code zone size (stored in image file header; Cog only; otherwise nil)
48 various header flags. See getCogVMFlags.
49 max size the image promises to grow the external semaphore table to (0 sets to default, which is 256 as of writing)
50-51 nil; reserved for VM parameters that persist in the image (such as eden above)
52 root/remembered table capacity
53 number of segments (Spur only; otherwise nil)
54 total size of free old space (Spur only, otherwise nil)
55 ratio of growth and image size at or above which a GC will be performed post scavenge
56 number of process switches since startup (read-only)
57 number of ioProcessEvents calls since startup (read-only)
58 number of ForceInterruptCheck calls since startup (read-only)
59 number of check event calls since startup (read-only)
60 number of stack page overflows since startup (read-only)
61 number of stack page divorces since startup (read-only)
62 compiled code compactions since startup (read-only; Cog only; otherwise nil)
63 total milliseconds in compiled code compactions since startup (read-only; Cog only; otherwise nil)
64 the number of methods that currently have jitted machine-code
65 whether the VM supports a certain feature, MULTIPLE_BYTECODE_SETS is bit 0, IMMUTABILITY is bit 1
66 the byte size of a stack page
67 the max allowed size of old space (Spur only; nil otherwise; 0 implies no limit except that of the underlying platform)
68 the average number of live stack pages when scanned by GC (at scavenge/gc/become et al) (read-write)
69 the maximum number of live stack pages when scanned by GC (at scavenge/gc/become et al) (read-write)
70 the vmProxyMajorVersion (the interpreterProxy VM_MAJOR_VERSION)
71 the vmProxyMinorVersion (the interpreterProxy VM_MINOR_VERSION)
72 total milliseconds in full GCs Mark phase since startup (read-only)
73 total milliseconds in full GCs Sweep phase since startup (read-only, can be 0 depending on compactors)
74 maximum pause time due to segment allocation
75 whether the arithmetic primitives perform conversion in case of mixed SmallInteger/Float (true) or fail (false)
Note: Thanks to Ian Piumarta for this primitive."
| paramsArraySize index |
paramsArraySize := 75.
argumentCount = 0 ifTrue: [^self primitiveAllVMParameters: paramsArraySize].
argumentCount > 2 ifTrue: [^self primitiveFailFor: PrimErrBadNumArgs].
"index read & checks"
index := self stackValue: (argumentCount = 1 ifTrue: [0] ifFalse: [1]).
(objectMemory isIntegerObject: index) ifFalse: [^self primitiveFailFor: PrimErrBadArgument].
index := objectMemory integerValueOf: index.
(index < 1 or: [index > paramsArraySize]) ifTrue: [^self primitiveFailFor: PrimErrBadIndex].
argumentCount = 1 ifTrue: "read VM parameter; written this way to avoid branch limits in V3 bytecode set"
[| result |
result := self primitiveGetVMParameter: index.
^self methodReturnValue: (result ifNil: [objectMemory nilObject])].
"write a VM parameter"
self primitiveSetVMParameter: index arg: self stackTop!
Item was changed:
----- Method: VMBasicConstants class>>namesDefinedAtCompileTime (in category 'C translation') -----
namesDefinedAtCompileTime
"Answer the set of names for variables that should be defined at compile time.
Some of these get default values during simulation, and hence get defaulted in
the various initializeMiscConstants methods. But that they have values should
/not/ cause the code generator to do dead code elimination based on their
default values. In particular, methods marked with <option: ANameDefinedAtCompileTime>
will be emitted within #if defined(ANameDefinedAtCompileTime)...#endif.
And of course this is backwards. We'd like to define names that are defined at translation time."
^#(VMBIGENDIAN
IMMUTABILITY
STACKVM COGVM COGMTVM SPURVM
PharoVM "Pharo vs Squeak"
+ TerfVM VM_TICKER "Terf vs Squeak & Qwaq/Teleplace/Terf high-priority thread support"
- TerfVM "Terf vs Squeak"
EnforceAccessControl "Newspeak"
CheckRememberedInTrampoline "IMMUTABILITY"
+ BIT_IDENTICAL_FLOATING_POINT PLATFORM_SPECIFIC_FLOATING_POINT "Alternatives for using fdlibm for floating-point"
- BIT_IDENTICAL_FLOATING_POINT
LLDB "As of lldb-370.0.42 Swift-3.1, passing function parameters to printOopsSuchThat fails with Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call. Turning off link time optimization with -fno-lto has no effect. hence we define some debugging functions as being <option: LLDB>"
"processor related"
__ARM_ARCH__ __arm__ __arm32__ ARM32 __arm64__ ARM64
_M_I386 _X86_ i386 i486 i586 i686 __i386__ __386__ X86 I386
x86_64 __amd64 __x86_64 __amd64__ __x86_64__ _M_AMD64 _M_X64
__mips__ __mips
__powerpc __powerpc__ __powerpc64__ __POWERPC__
__ppc__ __ppc64__ __PPC__ __PPC64__
__sparc__ __sparc __sparc_v8__ __sparc_v9__ __sparcv8 __sparcv9
"Compiler brand related"
__ACK__
__CC_ARM
__clang__
__GNUC__
_MSC_VER
__ICC
__SUNPRO_C
"os related"
ACORN
_AIX
__ANDROID__
__BEOS__
__linux__
__MINGW32__
__FreeBSD__ __NetBSD__ __OpenBSD__
__osf__
EPLAN9
__unix__ __unix UNIX
WIN32 _WIN32 _WIN32_WCE
WIN64 _WIN64 _WIN64_WCE)!
Item was changed:
----- Method: VMMaker class>>generateAllConfigurationsUnderVersionControl (in category 'configurations') -----
generateAllConfigurationsUnderVersionControl
self
executeDisplayingProgress:
(OrderedDictionary
with: 'Generate all newspeak configurations under VCS' -> [ self generateAllNewspeakConfigurationsUnderVersionControl ]
with: 'Generate all squeak configurations under VCS' -> [ self generateAllSqueakConfigurationsUnderVersionControl ]
with: 'Generate all spur lowcode configurations' -> [ self generateAllSpurLowcodeConfigurations ]
with: 'Generate VM plugins' -> [ self generateVMPlugins ]
+ with: 'Generate utilities' -> [ self generateSpur32LeakChecker; generateSpur64LeakChecker; generateUtilityPrograms ])!
- with: 'Generate spur leak checkers' -> [ self generateSpur32LeakChecker; generateSpur64LeakChecker ])!
Item was added:
+ ----- Method: VMMaker class>>generateUtilityPrograms (in category 'configurations') -----
+ generateUtilityPrograms
+ ^(self
+ makerFor: nil
+ and: nil
+ with: #()
+ to: self sourceTree, '/src'
+ platformDir: self sourceTree, '/platforms')
+ generateUtilityPrograms!
Item was added:
+ ----- Method: VMMaker>>generateUtilityPrograms (in category 'generate sources') -----
+ generateUtilityPrograms
+ "Any additional sources not directly part of the VM may be generated here"
+
+ Smalltalk
+ at: #ImageFormat
+ ifPresent:
+ [:cls | "generate ckformat utility program"
+ (self needsToRegenerateCheckFormatFile: cls named: 'ckformat.c') ifTrue:
+ [cls storeCkFormatOnFile: (self sourceDirectory fullNameFor: 'ckformat.c')]]!
Item was added:
+ ----- Method: VMMaker>>needsToRegenerateCheckFormatFile:named: (in category 'generate sources') -----
+ needsToRegenerateCheckFormatFile: cls named: fileName
+ "Check the timestamp for ImageFormat and then the timestamp for ckformat.c if it already exists. Answer if the file needs regenerating."
+
+ | tStamp |
+ tStamp := cls timeStamp.
+
+ "don't translate if the file is newer than my timeStamp"
+ (self sourceDirectory entryAt: fileName ifAbsent: [nil]) ifNotNil:
+ [:fstat| | mTime |
+ mTime := fstat modificationTime.
+ mTime isInteger ifFalse: [mTime := mTime asSeconds].
+ tStamp < mTime ifTrue:
+ [^self confirm: (cls name, ' has not been modified since\', fileName, ' was last generated.\Do you still want to regenerate it?') withCRs]].
+ ^true!
Eliot Miranda uploaded a new version of ImageFormat to project VM Maker:
http://source.squeak.org/VMMaker/ImageFormat-eem.45.mcz
==================== Summary ====================
Name: ImageFormat-eem.45
Author: eem
Time: 28 July 2020, 2:25:22.501872 pm
UUID: 5c29675a-5d64-40de-b535-ae98b04d2f37
Ancestors: ImageFormat-eem.44
And VMMaker.oscog badly needs a class timeStamp. This is harmless to VMMaker.
=============== Diff against ImageFormat-eem.44 ===============
Item was changed:
Object subclass: #ImageFormat
instanceVariableNames: 'wordSize requiresClosureSupport requiresNativeFloatWordOrder requiresSpurSupport requiresNewSpur64TagAssignment requiresMultipleBytecodeSupport'
classVariableNames: 'BaseVersionMask BaseVersionNumbers CapabilitiesBitsMask KnownVersionNumbers MultipleBytecodeBit PlatformByteOrderBit ReservedBitsMask SpurObjectBit'
poolDictionaries: ''
category: 'ImageFormat-Header'!
+ ImageFormat class
+ instanceVariableNames: 'timeStamp'!
!ImageFormat commentStamp: 'dtl 11/7/2010 22:13' prior: 0!
ImageFormat represents the requirements of the image in terms of capabilities that must be supported by the virtual machine. The image format version is saved as an integer value in the header of an image file. When an image is loaded, the virtual machine checks the image format version to determine whether it is capable of supporting the requirements of that image.
The image format version value is treated as a bit map of size 32, derived from the 32-bit integer value saved in the image header. Bits in the bit map represent image format requirements. For example, if the image sets bit 15 to indicate that it requires some capability from the VM, then the VM can check bit 15 and decide whether it is able to satisfy that requirement.
The base image format numbers (6502, 6504, 68000, and 68002) utiliize 10 of the 32 available bits. The high order bit is reserved as an extension bit for future use. The remaining 21 bits are used to represent additional image format requirements. For example, the low order bit is used to indication that the image uses (and requires support for) the platform byte ordering implemented in the StackInterpreter (Cog) VM.
"(ImageFormat fromFile: Smalltalk imageName) description"
!
+ ImageFormat class
+ instanceVariableNames: 'timeStamp'!
Item was added:
+ ----- Method: ImageFormat class>>noteCompilationOf:meta: (in category 'translation') -----
+ noteCompilationOf: aSelector meta: isMeta
+ "note the recompiliation by resetting the timeStamp "
+ timeStamp := Time totalSeconds.
+ ^super noteCompilationOf: aSelector meta: isMeta!
Item was added:
+ ----- Method: ImageFormat class>>timeStamp (in category 'translation') -----
+ timeStamp
+ ^timeStamp ifNil:[0]!
Item was added:
+ ----- Method: ImageFormat class>>touch (in category 'translation') -----
+ touch
+ "Reset the timeStamp"
+ "Smalltalk allClasses select:
+ [:c| (c category includesSubString: 'VMMaker-JIT') ifTrue: [c touch]]"
+ "InterpreterPlugin withAllSubclassesDo:[:pl| pl touch]"
+ timeStamp := Time totalSeconds!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2783.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2783
Author: eem
Time: 27 July 2020, 2:42:27.399676 pm
UUID: dcea91a9-4a6e-4ec1-aefc-a4ee18389e99
Ancestors: VMMaker.oscog-eem.2782
CoInterpreter: Fix a bug in not setting desiredCogCodeSize to the size supplied in the header, hence fixing vm parameter 47's value.
=============== Diff against VMMaker.oscog-eem.2782 ===============
Item was changed:
----- Method: CoInterpreter>>readImageFromFile:HeapSize:StartingAt: (in category 'image save/restore') -----
readImageFromFile: f HeapSize: desiredHeapSize StartingAt: imageOffset
"Read an image from the given file stream, allocating an amount of memory to its object heap.
V3: desiredHeapSize is the total size of the heap. Fail if the image has an unknown format or
requires more than the specified amount of memory.
Spur: desiredHeapSize is ignored; this routine will attempt to provide at least extraVMMemory's
ammount of free space after the image is loaded, taking any free space in the image into account.
extraVMMemory is stored in the image header and is accessible as vmParameterAt: 23. If
extraVMMemory is 0, the value defaults to the default grow headroom. Fail if the image has an
unknown format or if sufficient memory cannot be allocated.
Details: This method detects when the image was stored on a machine with the opposite byte
ordering from this machine and swaps the bytes automatically. Furthermore, it allows the header
information to start 512 bytes into the file, since some file transfer programs for the Macintosh
apparently prepend a Mac-specific header of this size. Note that this same 512 bytes of prefix
area could also be used to store an exec command on Unix systems, allowing one to launch
Smalltalk by invoking the image name as a command."
| swapBytes headerStart headerSize dataSize oldBaseAddr
minimumMemory heapSize bytesRead bytesToShift firstSegSize
hdrNumStackPages hdrEdenBytes hdrCogCodeSize headerFlags hdrMaxExtSemTabSize allocationReserve |
<var: #f type: #sqImageFile>
<var: #heapSize type: #usqInt>
<var: #dataSize type: #'size_t'>
<var: #minimumMemory type: #usqInt>
<var: #desiredHeapSize type: #usqInt>
<var: #allocationReserve type: #usqInt>
<var: #headerStart type: #squeakFileOffsetType>
<var: #imageOffset type: #squeakFileOffsetType>
metaclassNumSlots := 6. "guess Metaclass instSize"
classNameIndex := 6. "guess (Class instVarIndexFor: 'name' ifAbsent: []) - 1"
swapBytes := self checkImageVersionFrom: f startingAt: imageOffset.
headerStart := (self sqImageFilePosition: f) - 4. "record header start position"
headerSize := self getWord32FromFile: f swap: swapBytes.
dataSize := self getLongFromFile: f swap: swapBytes.
oldBaseAddr := self getLongFromFile: f swap: swapBytes.
objectMemory specialObjectsOop: (self getLongFromFile: f swap: swapBytes).
objectMemory lastHash: (self getLongFromFile: f swap: swapBytes). "N.B. not used."
savedWindowSize := self getLongFromFile: f swap: swapBytes.
headerFlags := self getLongFromFile: f swap: swapBytes.
self setImageHeaderFlagsFrom: headerFlags.
extraVMMemory := self getWord32FromFile: f swap: swapBytes. "N.B. ignored in V3."
hdrNumStackPages := self getShortFromFile: f swap: swapBytes.
"4 stack pages is small. Should be able to run with as few as
three. 4 should be comfortable but slow. 8 is a reasonable
default. Can be changed via vmParameterAt: 43 put: n.
Can be set as a preference (Info.plist, VM.ini, command line etc).
If desiredNumStackPages is already non-zero then it has been
set as a preference. Ignore (but preserve) the header's default."
numStackPages := desiredNumStackPages ~= 0
ifTrue: [desiredNumStackPages]
ifFalse: [hdrNumStackPages = 0
ifTrue: [self defaultNumStackPages]
ifFalse: [hdrNumStackPages]].
desiredNumStackPages := hdrNumStackPages.
"This slot holds the size of the native method zone in 1k units. (pad to word boundary)."
hdrCogCodeSize := (self getShortFromFile: f swap: swapBytes) * 1024.
cogCodeSize := desiredCogCodeSize ~= 0
ifTrue: [desiredCogCodeSize]
ifFalse:
[hdrCogCodeSize = 0
ifTrue: [cogit defaultCogCodeSize]
+ ifFalse: [desiredCogCodeSize := hdrCogCodeSize]]. "set for vmParameter 47"
- ifFalse: [hdrCogCodeSize]].
cogCodeSize > cogit maxCogCodeSize ifTrue:
[cogCodeSize := cogit maxCogCodeSize].
hdrEdenBytes := self getWord32FromFile: f swap: swapBytes.
objectMemory edenBytes: (desiredEdenBytes ~= 0
ifTrue: [desiredEdenBytes]
ifFalse:
[hdrEdenBytes = 0
ifTrue: [objectMemory defaultEdenBytes]
ifFalse: [hdrEdenBytes]]).
desiredEdenBytes := hdrEdenBytes.
hdrMaxExtSemTabSize := self getShortFromFile: f swap: swapBytes.
hdrMaxExtSemTabSize ~= 0 ifTrue:
[self setMaxExtSemSizeTo: hdrMaxExtSemTabSize].
"pad to word boundary. This slot can be used for anything else that will fit in 16 bits.
Preserve it to be polite to other VMs."
the2ndUnknownShort := self getShortFromFile: f swap: swapBytes.
firstSegSize := self getLongFromFile: f swap: swapBytes.
objectMemory firstSegmentSize: firstSegSize.
"compare memory requirements with availability"
allocationReserve := self interpreterAllocationReserveBytes.
minimumMemory := cogCodeSize "no need to include the stackZone; this is alloca'ed"
+ dataSize
+ objectMemory newSpaceBytes
+ allocationReserve.
objectMemory hasSpurMemoryManagerAPI
ifTrue:
[| freeOldSpaceInImage headroom |
freeOldSpaceInImage := self getLongFromFile: f swap: swapBytes.
headroom := objectMemory
initialHeadroom: extraVMMemory
givenFreeOldSpaceInImage: freeOldSpaceInImage.
heapSize := objectMemory roundUpHeapSize:
cogCodeSize "no need to include the stackZone; this is alloca'ed"
+ dataSize
+ headroom
+ objectMemory newSpaceBytes
+ (headroom > allocationReserve
ifTrue: [0]
ifFalse: [allocationReserve])]
ifFalse:
[heapSize := cogCodeSize "no need to include the stackZone; this is alloca'ed"
+ desiredHeapSize
+ objectMemory newSpaceBytes
+ (desiredHeapSize - dataSize > allocationReserve
ifTrue: [0]
ifFalse: [allocationReserve]).
heapSize < minimumMemory ifTrue:
[self insufficientMemorySpecifiedError]].
"allocate a contiguous block of memory for the Squeak heap and ancilliary data structures"
objectMemory memory: (self
allocateMemory: heapSize
minimum: minimumMemory
imageFile: f
headerSize: headerSize) asUnsignedInteger.
objectMemory memory ifNil:
[self insufficientMemoryAvailableError].
heapBase := objectMemory
setHeapBase: objectMemory memory + cogCodeSize
memoryLimit: objectMemory memory + heapSize
endOfMemory: objectMemory memory + cogCodeSize + dataSize.
"position file after the header"
self sqImageFile: f Seek: headerStart + headerSize.
"read in the image in bulk, then swap the bytes if necessary"
bytesRead := objectMemory readHeapFromImageFile: f dataBytes: dataSize.
bytesRead ~= dataSize ifTrue: [self unableToReadImageError].
self ensureImageFormatIsUpToDate: swapBytes.
"compute difference between old and new memory base addresses"
bytesToShift := objectMemory memoryBaseForImageRead - oldBaseAddr.
self initializeInterpreter: bytesToShift. "adjusts all oops to new location"
self initializeCodeGenerator.
^dataSize!
David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.417.mcz
==================== Summary ====================
Name: VMMaker-dtl.417
Author: dtl
Time: 26 July 2020, 7:55:15.52 pm
UUID: 14446c08-7d2a-41a6-9370-2f5eba5ac1e8
Ancestors: VMMaker-dtl.416
Update to remove call to deprecated method in ImageFormat.
=============== Diff against VMMaker-dtl.416 ===============
Item was changed:
----- Method: VMMaker>>generateUtilityPrograms (in category 'generate sources') -----
generateUtilityPrograms
"Any additional sources not directly part of the VM may be generated here"
Smalltalk
at: #ImageFormat
ifPresent: [:cls | "generate ckformat utility program"
+ cls storeCkFormatOnFile: (self sourceDirectory fullNameFor: 'ckformat.c')]!
- cls storeCkstatusOnFile: (self sourceDirectory fullNameFor: 'ckformat.c')]!
David T. Lewis uploaded a new version of ImageFormat to project VM Maker:
http://source.squeak.org/VMMaker/ImageFormat-dtl.43.mcz
==================== Summary ====================
Name: ImageFormat-dtl.43
Author: dtl
Time: 26 July 2020, 7:58:32.916 pm
UUID: 3675b184-d74a-495a-8461-28784e447c8b
Ancestors: ImageFormat-dtl.42
Restore deprecated method prematurely removed in the last commit, still refrenced prior to VMMaker-dtl.417. Fix two minor formatting issues.
=============== Diff against ImageFormat-dtl.42 ===============
Item was changed:
----- Method: ImageFileHeader>>readImageVersionFrom:startingAt: (in category 'reading') -----
readImageVersionFrom: aStream startingAt: imageOffset
"Look for image format in the next 4 or 8 bytes and set imageFormat. Answer true
if the header is written in little endian format."
(aStream nextNumber: 4) caseOf:
{
[ 16r00001966 "6502" ] -> [ imageFormat := ImageFormat fromInteger: 6502. ^false ] .
[ 16r66190000 "6502" ] -> [ imageFormat := ImageFormat fromInteger: 6502. ^true ] .
[ 16r00001968 "6504" ] -> [ imageFormat := ImageFormat fromInteger: 6504. ^false ] .
[ 16r68190000 "6504" ] -> [ imageFormat := ImageFormat fromInteger: 6504. ^true ] .
[ 16r00001969 "6505" ] -> [ imageFormat := ImageFormat fromInteger: 6505. ^false ] .
[ 16r69190000 "6505" ] -> [ imageFormat := ImageFormat fromInteger: 6505. ^true ] .
[ 16r00001979 "6521" ] -> [ imageFormat := ImageFormat fromInteger: 6521. ^false ] .
[ 16r79190000 "6521" ] -> [ imageFormat := ImageFormat fromInteger: 6521. ^true ] .
[ 16rA0090100 "68000" ] -> [ imageFormat := ImageFormat fromInteger: 68000. aStream next: 4. ^true ] .
[ 16rA2090100 "68002" ] -> [ imageFormat := ImageFormat fromInteger: 68002. aStream next: 4. ^true ] .
[ 16rA3090100 "68003" ] -> [ imageFormat := ImageFormat fromInteger: 68003. aStream next: 4. ^true ] .
[ 16rB3090100 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. aStream next: 4. ^true ] .
[ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. aStream next: 4. ^false ] .
[ 16rB5090100 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. aStream next: 4. ^true ] .
[ 16r000109B5 "68021" ] -> [ imageFormat := ImageFormat fromInteger: 68021. aStream next: 4. ^false ] .
[ 16r00000000 ] -> [
"Standard interpreter VM puts the format number in the first 64 bits for a 64 bit image, so
the leading 4 bytes are zero in this case. Cog/Spur VMs put the format number in the first
32 bits for both 32 and 64 bit images."
(aStream nextNumber: 4) caseOf: {
[ 16r000109A0 "68000" ] -> [ imageFormat := ImageFormat fromInteger: 68000. ^false ] .
[ 16r000109A2 "68002" ] -> [ imageFormat := ImageFormat fromInteger: 68002. ^false ] .
[ 16r000109A3 "68003" ] -> [ imageFormat := ImageFormat fromInteger: 68003. ^false ] .
+ [ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. ^false ]
- [ 16r000109B3 "68019" ] -> [ imageFormat := ImageFormat fromInteger: 68019. ^false ] .
} otherwise: [self error: self asString , ' unrecognized format number']
]
} otherwise: [self error: self asString , ' unrecognized format number']
"ImageFormat versionNumberByteArrays do: [:e |
Transcript cr; show: e printString , ': ', (ImageFormat fromBytes: e) description]
#[0 0 25 102]: a 32-bit image with no closure support and no native platform float word order requirement (6502)
#[102 25 0 0]: a 32-bit image with no closure support and no native platform float word order requirement (6502)
#[0 0 25 104]: a 32-bit image with closure support and no native platform float word order requirement (6504)
#[104 25 0 0]: a 32-bit image with closure support and no native platform float word order requirement (6504)
#[0 0 0 0 0 1 9 160]: a 64-bit image with no closure support and no native platform float word order requirement (68000)
#[160 9 1 0 0 0 0 0]: a 64-bit image with no closure support and no native platform float word order requirement (68000)
#[0 0 0 0 0 1 9 162]: a 64-bit image with closure support and no native platform float word order requirement (68002)
#[162 9 1 0 0 0 0 0]: a 64-bit image with closure support and no native platform float word order requirement (68002)
#[0 0 25 105]: a 32-bit image with closure support and float words stored in native platform order (6505)
#[105 25 0 0]: a 32-bit image with closure support and float words stored in native platform order (6505)
#[0 0 0 0 0 1 9 163]: a 64-bit image with closure support and float words stored in native platform order (68003)
#[163 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order (68003)
#[0 0 25 121]: a 32-bit image with closure support and float words stored in native platform order using Spur object format (6521)
#[121 25 0 0]: a 32-bit image with closure support and float words stored in native platform order using Spur object format (6521)
#[0 0 0 0 0 1 9 179]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (obsolete) (68019)
#[179 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (obsolete) (68019)
#[0 0 0 0 0 1 9 181]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (68021)
#[181 9 1 0 0 0 0 0]: a 64-bit image with closure support and float words stored in native platform order using Spur object format (68021)
"
!
Item was changed:
----- Method: ImageFormat class>>knownVersionNumbers (in category 'image formats') -----
knownVersionNumbers
"Version numbers currently in use or likely to be used (e.g. 64-bit Cog formats)"
"ImageFormat knownVersionNumbers collect: [:e | (ImageFormat fromInteger: e) description]"
^ ( self baseVersionNumbers, "the original format number variants"
{
6505 . "Cog and StackVM"
68003 . "Cog and StackVM running 64-bit image"
6521 . "Spur 32 bit object memory"
7033 . "Spur 32 bit with Sista bytecodes"
68019 . "Spur 64 bit object memory (early)"
68021 . "Spur 64 bit object memory"
+ 68533 "Spur 64 bit with Sista bytecodes"
- 68533 . "Spur 64 bit with Sista bytecodes"
" ... add others here as bits are allocated to represent requirements of other image formats"
} ) sort.
!
Item was added:
+ ----- Method: ImageFormat class>>storeCkstatusOnFile: (in category 'ckformat') -----
+ storeCkstatusOnFile: fileName
+ "Deprecated 07-Dec-2012, use storeCkFormatOnFile:"
+ ^self storeCkFormatOnFile: fileName
+ !
Eliot Miranda uploaded a new version of VMMakerUI to project VM Maker:
http://source.squeak.org/VMMaker/VMMakerUI-eem.27.mcz
==================== Summary ====================
Name: VMMakerUI-eem.27
Author: eem
Time: 26 July 2020, 12:47:38.901108 pm
UUID: ac8c4a65-9aef-4923-a182-41cee05503b1
Ancestors: VMMakerUI-eem.26
Fix several bugs in SimulatorEventTransformer. The UI is now "usable", i.e. I managed to bring up the About dialog. Now I at least have a chance of debugging the corrupted fixed pitch font output bug observed in the System reporter.
=============== Diff against VMMakerUI-eem.26 ===============
Item was changed:
----- Method: CogVMSimulator>>handleListenEvent: (in category '*VMMakerUI-I/O primitive support') -----
handleListenEvent: aMorphicEvent
"openAsMorph[NoTranscript] registered me for listen events via HandMorph>>addEventListener.
Transform the listen event and add it to my event queue. ALso check if the displayForm should resize."
(displayForm ~~ fakeForm and: [displayForm extent ~= displayView extent]) ifTrue:
[| newForm |
newForm := Form
extent: displayView extent
depth: displayForm depth.
displayForm displayOn: newForm.
displayForm := newForm.
displayView image: displayForm].
((aMorphicEvent isMouse or: [aMorphicEvent isKeyboard])
and: [displayView bounds containsPoint: aMorphicEvent position]) ifTrue:
+ [[eventTransformer degenerateEvent: aMorphicEvent for: self]
+ on: Error
+ do: [:ex|
+ displayView activeHand removeEventListener: self.
+ ex pass]]!
- [eventTransformer degenerateEvent: aMorphicEvent for: self]!
Item was changed:
Object subclass: #SimulatorEventTransformer
+ instanceVariableNames: 'buttons modifiers lastMouseMoveEvent'
- instanceVariableNames: 'buttons modifiers'
classVariableNames: 'Default'
poolDictionaries: 'EventSensorConstants'
category: 'VMMakerUI-InterpreterSimulation-Morphic'!
!SimulatorEventTransformer commentStamp: 'eem 7/14/2015 17:05' prior: 0!
A SimulatorEventTransformer takes events as wrapped by HandMorph and converts them to a form a StackInterpreterSimulator can deal with.
See HandMorph >> handleEvent to see what the wrapping entails.
See HandMorph >> ProcessEvents or EventSensor >> fetchMoreEvents for examples of what an unwrapped event looks like when given to the system for pre-wrapping.
Instance Variables
!
Item was changed:
----- Method: SimulatorEventTransformer>>degenerateKeyboardEvent:for: (in category 'event transformation') -----
degenerateKeyboardEvent: aMorphicEvent for: aClient
"Convert the keyboard event into a low-level event for the VM simulator (aClient).
See HandMorph>>generateKeyboardEvent and EventSensor class comment"
aClient queueForwardedEvent:
+ { EventTypeKeyboard.
+ aClient ioUTCMicroseconds // 1000.
+ aMorphicEvent keyValue. "<--this is wrong. See nextCharFrom:firstEvt: for what needs to be undone. hooo boy"
- { 2.
- aMorphicEvent timeStamp.
- aMorphicEvent keyValue. "<--this is wrong. See Sensor FirstEvt: for what needs to happen. hooo boy"
aMorphicEvent type caseOf: {
[#keyDown] -> [EventKeyDown].
[#keyUp] -> [EventKeyUp].
[#keystroke] -> [EventKeyChar] }.
modifiers.
aMorphicEvent keyValue.
0.
self windowIndex }!
Item was changed:
----- Method: SimulatorEventTransformer>>degenerateMouseEvent:for: (in category 'event transformation') -----
degenerateMouseEvent: aMorphicEvent for: aClient
"Convert the mouse event into low-level events for the VM simulator (aClient). Filter-out mouse moves,
and generate a fake mouse move before each button press.
See HandMorph>>generateMouseEvent"
| translated |
- translated := aMorphicEvent position - aClient displayView bounds origin.
modifiers := aMorphicEvent buttons >> 3. "Sad, but modifiers come in on mouse move events..."
+ "filter-out mouse moves unless buttons are pressed, so simulation doesn't get window leave events when we leave its window"
+ aMorphicEvent type == #mouseMove ifTrue:
+ [(aClient displayView bounds containsPoint: aMorphicEvent position) ifFalse:
+ [^self].
+ "If buttons (which includes modifiers) change, or are pressed, communicate the event, otherwise (at least potentially) filter it out."
+ (aMorphicEvent buttons = 0
+ and: [lastMouseMoveEvent notNil
+ and: [lastMouseMoveEvent buttons = 0]]) ifTrue:
+ [lastMouseMoveEvent := aMorphicEvent copy.
+ lastMouseMoveEvent timeStamp: (aClient ioUTCMicroseconds // 1000).
+ lastMouseMoveEvent position: lastMouseMoveEvent position - aClient displayView bounds origin.
+ ^self]].
+ lastMouseMoveEvent ifNotNil:
+ [aClient queueForwardedEvent:
+ { EventTypeMouse.
+ lastMouseMoveEvent timeStamp.
+ lastMouseMoveEvent position x.
+ lastMouseMoveEvent position y.
+ lastMouseMoveEvent buttons bitAnd: 7.
+ lastMouseMoveEvent buttons >> 3.
+ 0.
+ self windowIndex }.
+ lastMouseMoveEvent := nil].
+ buttons := aMorphicEvent buttons.
+ translated := aMorphicEvent position - aClient displayView bounds origin.
- aMorphicEvent type == #mouseMove
- ifTrue: "filter-out mouse moves unless buttons are pressed, so simulation doesn't get window leave events when we leave its window"
- [buttons = 0 ifTrue: [^nil]]
- ifFalse:"If the buttons are going down, make sure to add a mouse move event to the current position before the buttons are pressed."
- [((buttons bitAnd: 7) = 0 and: [(aMorphicEvent buttons bitAnd: 7) ~= 0]) ifTrue:
- [aClient queueForwardedEvent:
- { 1.
- aMorphicEvent timeStamp.
- translated x.
- translated y.
- 0.
- buttons >> 3. "Thanks dtl"
- 0.
- self windowIndex }].
- buttons := aMorphicEvent buttons].
aClient queueForwardedEvent:
+ { EventTypeMouse.
+ aClient ioUTCMicroseconds // 1000.
- { 1.
- aMorphicEvent timeStamp.
translated x.
translated y.
+ buttons bitAnd: 7. "thanks Ron T."
+ buttons >> 3. "Thanks dtl"
- buttons bitAnd: 7. "thanks Ron T."
- buttons >> 3. "Thanks dtl"
0.
self windowIndex }!
Item was changed:
----- Method: StackInterpreterSimulator>>handleListenEvent: (in category '*VMMakerUI-I/O primitive support') -----
handleListenEvent: aMorphicEvent
"openAsMorph[NoTranscript] registered me for listen events via HandMorph>>addEventListener.
Transform the listen event and add it to my event queue. ALso check if the displayForm should resize."
(displayForm ~~ fakeForm and: [displayForm extent ~= displayView extent]) ifTrue:
[| newForm |
newForm := Form
extent: displayView extent
depth: displayForm depth.
displayForm displayOn: newForm.
displayForm := newForm.
displayView image: displayForm].
((aMorphicEvent isMouse or: [aMorphicEvent isKeyboard])
and: [displayView bounds containsPoint: aMorphicEvent position]) ifTrue:
+ [[eventTransformer degenerateEvent: aMorphicEvent for: self]
+ on: Error
+ do: [:ex|
+ displayView activeHand removeEventListener: self.
+ ex pass]]!
- [eventTransformer degenerateEvent: aMorphicEvent for: self]!
David T. Lewis uploaded a new version of ImageFormat to project VM Maker:
http://source.squeak.org/VMMaker/ImageFormat-dtl.42.mcz
==================== Summary ====================
Name: ImageFormat-dtl.42
Author: dtl
Time: 26 July 2020, 2:09:13.1382 pm
UUID: 58998f37-e8f3-47a5-81c1-5f7e00cc5b5c
Ancestors: ImageFormat-eem.41
Suggestion from David Stes - Let the ckformat program print information about known version numbers. When run with no argument, print usage and help information. Also change the wording in format descriptions from 'Sista' to 'multiple bytecode sets' which is more wordy but techncally more accurate.
=============== Diff against ImageFormat-eem.41 ===============
Item was changed:
----- Method: ImageFormat class>>generateCkFormatProgram:on: (in category 'ckformat') -----
generateCkFormatProgram: programName on: stream
"Generate source code for an image format version reader. The program
is intended for testing image file format from a unix shell script such that
the shell script can decide what VM to run based on image requirements."
| formatNumber |
stream nextPutAll: '/* ', programName, ': Print the image format number on standard output */'; cr;
nextPutAll: '/* for use in a shell script to test image format requirements. */'; cr;
nextPutAll: '/* A non-zero return status code indicates failure. */'; cr; cr;
nextPutAll: '/* Usage: ', programName, ' imageFileName */'; cr; cr;
nextPutAll: '/* --- DO NOT EDIT THIS FILE --- */'; cr;
nextPutAll: '/* --- Automatically generated from class ', self name, ' ', DateAndTime now asString, '--- */'; cr;
nextPutAll: '/* --- Source code is in package ImageFormat in the VMMaker repository --- */'; cr;
nextPutAll: '/* --- DO NOT EDIT THIS FILE --- */'; cr; cr;
nextPutAll: '#include <stdio.h>'; cr;
nextPutAll: '#include <stdlib.h>'; cr;
nextPutAll: '#include <string.h>'; cr; cr;
nextPutAll: 'int main(int argc, char **argv) {'; cr;
tab; nextPutAll: 'FILE *f;'; cr;
tab; nextPutAll: 'unsigned char buf[8];'; cr;
tab; nextPutAll: 'int formatNumber;'; cr;
tab; nextPutAll: 'unsigned char c;'; cr;
tab; nextPutAll: 'int match;'; cr;
tab; nextPutAll: 'if (argc !!= 2) {'; cr;
tab; tab; nextPutAll: 'printf("usage: ', programName, ' imageFileName\n");'; cr;
+ tab; tab; nextPutAll: 'printf("answer the image format number for an image file or 0 if not known\n");'; cr;
+ tab; tab; nextPutAll: 'printf("known image formats:\n");'; cr.
+ KnownVersionNumbers do: [ :e | | s |
+ s := String streamContents: [ :strm |
+ strm nextPutAll: e asString, ': '.
+ (self fromInteger: e) printDescriptionOn: strm withVersionNumber: false ].
+ stream tab; tab; nextPutAll: 'printf("', s, '\n");'; cr ].
+ stream
tab; tab; nextPutAll: 'exit(1);'; cr;
tab; nextPutAll: '}'; cr;
tab; nextPutAll: 'f = fopen(argv[1], "r");'; cr;
tab; nextPutAll: 'if (f == NULL) {'; cr;
tab; tab; nextPutAll: 'perror(argv[1]);'; cr;
tab; tab; nextPutAll: 'exit(2);'; cr;
tab; nextPutAll: '}'; cr.
{ 0. 512 } do: [:offset |
stream
tab; nextPutAll: 'if(fseek(f, '; nextPutAll: offset asString; nextPutAll: 'L, SEEK_SET) !!= 0) {';cr;
tab; tab; nextPutAll: 'fprintf(stderr, "cannot go to pos %d in %s\n", '; nextPutAll: offset asString; nextPutAll: ', argv[1]);'; cr;
tab; tab; nextPutAll: 'exit(3);'; cr;
tab; nextPutAll: '}'; cr;
tab; nextPutAll: 'if (fread(buf, 1, 8, f) < 8) {'; cr;
tab; tab; nextPutAll: 'fprintf(stderr, "cannot read %s\n", argv[1]);'; cr;
tab; tab; nextPutAll: 'exit(3);'; cr;
tab; nextPutAll: '}'; cr.
self versionNumberByteArrays withIndexDo: [ :v :tag | | b |
formatNumber := (self fromBytes: v) asInteger.
b := 'b_', formatNumber asString, '_', tag asString.
stream tab; nextPutAll: '{'; cr; tab; nextPutAll: 'unsigned char ', b, '[', v size asString, ']= { '.
v inject: true into: [:first : elem |
first ifFalse: [stream nextPutAll: ', '].
stream nextPutAll: elem asString.
false].
stream nextPutAll: '};'; cr;
tab; nextPutAll: 'if (memcmp(buf, ', b, ', ', v size asString, ') == 0) {'; cr;
tab; tab; nextPutAll: 'printf("%d\n", ', formatNumber, ');'; cr;
tab; tab; nextPutAll: 'exit(0);'; cr;
tab; nextPutAll: '}'; cr; tab; nextPutAll: '}'; cr]].
stream tab; nextPutAll: 'printf("0\n"); /* print an invalid format number */';cr;
tab; nextPutAll: 'exit (-1); /* not found, exit with error code */'; cr;
nextPutAll: '}'; cr
!
Item was removed:
- ----- Method: ImageFormat class>>storeCkstatusOnFile: (in category 'ckformat') -----
- storeCkstatusOnFile: fileName
- "Deprecated 07-Dec-2012, use storeCkFormatOnFile:"
- ^self storeCkFormatOnFile: fileName
- !
Item was changed:
----- Method: ImageFormat>>printDescriptionOn: (in category 'printing') -----
printDescriptionOn: stream
"
The classic squeak image, aka V3, is 32-bit with magic 6502. The first 64-bit
Squeak image was generated from V3 image made by Dan Ingalls and Ian Piumarta
in 2005. Later, the magic code was changed to 68000.
After full closure support came to Squeak, the magic code changed to 6504 for
32-bit and 68002 for 64-bit images by setting a capability bit.
Cog VM introduced a native order for floats under 6505 magic code. Its
corresponding 64b code would have been 68003 but no such image was produced.
Older Interpreter VMs would simply load 6505 by flipping word order back.
Cog VM also introduced a new object layout for 64-bit images called Spur layout
under a new magic code - 68021. A few images were also generated with 68019,
but this magic is now considered obsolete and deprecated.
"
+ ^ self printDescriptionOn: stream withVersionNumber: true.
- stream nextPutAll: 'a ';
- nextPutAll: (wordSize * 8) asString;
- nextPutAll: '-bit ';
- nextPutAll: (self requiresSpurSupport
- ifTrue: [ 'Spur' ]
- ifFalse: [ 'V3' ]);
- nextPutAll: ' image with '.
- self requiresClosureSupport ifFalse: [stream nextPutAll: 'no '].
- stream nextPutAll: 'closure support and '.
- self requiresNativeFloatWordOrder
- ifTrue: [stream nextPutAll: 'float words stored in native platform order']
- ifFalse: [stream nextPutAll: 'no native platform float word order requirement'].
- self requiresSpurSupport
- ifTrue: [stream nextPutAll: ' using Spur object format'.
- (self is64Bit and: [self requiresNewSpur64TagAssignment not])
- ifTrue: [stream nextPutAll: ' (obsolete)']].
- self requiresMultipleBytecodeSupport
- ifTrue: [ stream nextPutAll: ' and Sista ' ].
- stream nextPutAll: ' (';
- nextPutAll: self asInteger asString;
- nextPut: $).
- ^ stream
!
Item was added:
+ ----- Method: ImageFormat>>printDescriptionOn:withVersionNumber: (in category 'printing') -----
+ printDescriptionOn: stream withVersionNumber: aBoolean
+ "
+ The classic squeak image, aka V3, is 32-bit with magic 6502. The first 64-bit
+ Squeak image was generated from V3 image made by Dan Ingalls and Ian Piumarta
+ in 2005. Later, the magic code was changed to 68000.
+
+ After full closure support came to Squeak, the magic code changed to 6504 for
+ 32-bit and 68002 for 64-bit images by setting a capability bit.
+
+ Cog VM introduced a native order for floats under 6505 magic code. Its
+ corresponding 64b code would have been 68003 but no such image was produced.
+ Older Interpreter VMs would simply load 6505 by flipping word order back.
+
+ Cog VM also introduced a new object layout for 64-bit images called Spur layout
+ under a new magic code - 68021. A few images were also generated with 68019,
+ but this magic is now considered obsolete and deprecated.
+ "
+ stream nextPutAll: 'a ';
+ nextPutAll: (wordSize * 8) asString;
+ nextPutAll: '-bit ';
+ nextPutAll: (self requiresSpurSupport
+ ifTrue: [ 'Spur' ]
+ ifFalse: [ 'V3' ]);
+ nextPutAll: ' image with '.
+ self requiresClosureSupport ifFalse: [stream nextPutAll: 'no '].
+ stream nextPutAll: 'closure support and '.
+ self requiresNativeFloatWordOrder
+ ifTrue: [stream nextPutAll: 'float words stored in native platform order']
+ ifFalse: [stream nextPutAll: 'no native platform float word order requirement'].
+ self requiresSpurSupport
+ ifTrue: [stream nextPutAll: ' using Spur object format'.
+ (self is64Bit and: [self requiresNewSpur64TagAssignment not])
+ ifTrue: [stream nextPutAll: ' (obsolete)']].
+ self requiresMultipleBytecodeSupport
+ ifTrue: [ stream nextPutAll: ' and multiple bytecode sets ' ].
+ aBoolean ifTrue: [
+ stream nextPutAll: ' (';
+ nextPutAll: self asInteger asString;
+ nextPut: $)].
+ ^ stream
+ !
Hi all,
Continuing down the dusty road of bringing the Mac Carbon VM back to
life on PowerPC for research and educational purposes. Here's a
status update and two questions.
First, status update:
I've concluded that the VM will continue to build with very few
changes up to VMMaker 4.4.14, but then a VM that locks up at
interpret() as of 4.4.15. I then fast-forwarded to VMMaker 4.7.8 and
again have a working VM. But, this has required a few changes to
methods and I have had to stop building a few more plugins (to be
expected, I think!), namely B3DEnginePlugin and
SoundGenerationPlugin. The VM built with VMMaker 4.7.8 passes more
tests in Squeak 4.6 than those built with previous versions, but also
happens to be failing one test which may be consequential:
LargeNegativeIntegerTest>>#testMinimumNegativeIntegerArithmetic
I've been working lately within a 4.6 image converted to 6504 format
(thanks for the tip, Dave!). Note that my build product, even at
4.7.8, still can't natively launch & interpret a 6505-format image
like the release version of 4.6 from files.squeak.org. Nor can it
launch & interpret Squeak5.2-V3-18216.image. Squeak5.2-V3-18216.image
is already in 6504 format, so I suspect something else to be at fault
(I just force-quit it now, and found it having trouble at
_primDigitMultiplyNegative and _cDigitMultiplylenwithleninto). May be
worth further research on my part.
By VMMaker 4.7.8, my VM build workspace is as follows:
vmm := (Smalltalk at: #VMMaker) default.
" We can't cascade here. Maybe was fixed in later versions."
vmm deleteEntireGeneratedTree.
vmm makeAllModulesInternal.
vmm internalModules removeAll: #( ADPCMCodecPlugin B3DEnginePlugin
ClipboardExtendedPlugin CroquetPlugin FFIPlugin FloatMathPlugin
FileCopyPlugin ImmX11Plugin LocalePlugin Mpeg3Plugin QuicktimePlugin
SlangTestSupportSSIP SlangTestSupportPlugin SoundGenerationPlugin
TestOSAPlugin).
vmm generateEntire.
((Smalltalk at: #Gnuifier) on: (FileDirectory default fullName), '/src/
vm') gnuify.
The script I used for getting a VMMaker build image going in a "stock"
Squeak 4.5/4.6 image is attached. It was based off of (and, I
believe, clarifies or codifies) the instructions found in platforms/
Mac OS/vm/Documentation/readme.txt re: proper load order.
Question 1:
InterpreterPrimitives>>#signed64BitValueOf:
uses usqLong which wasn't defined in any of my platform support code:
value := 0 - (self cCoerce: value to: 'usqLong').
I changed it to:
value := 0 - (self cCoerce: value to: 'unsigned sqLong').
...does that seem equivalent?
Should I have usqLong defined somewhere in my platform support code?
It is used more heavily in opensmalltalk-vm, but I can't seem to find
where it is defined over there, either.
Question 2:
LargeIntegersPlugin>>#digitMontgomery:times:modulo:mInvModB:
was introduced in VMMaker 4.4.20 (VMMaker-dtl.233) and later bugfixed
in VMMaker 4.5.3 (VMMaker-dtl.239)
However, this method calls "self error:" as follows:
firstLen <= thirdLen ifFalse: [^self error: 'firstLarge must be less
than thirdLarge'].
secondLen <= thirdLen ifFalse: [^self error: 'secondLarge must be
less than thirdLarge'].
(mInv >= 0 and: [mInv <= 255]) ifFalse: [^self error: 'mInvMod256
must be between 0 and 255'].
which results in an undefined symbol _error when building this VM.
What would be the proper way to address this? Find a place to
implement error() in the VM cross/ or platform/ sources (or steal from
newer support code)? Or to change the call to self error: to
something else?
To get the VM building, I've just hand-patched LargeIntegers.c as
follows:
if (!(firstLen <= thirdLen)) {
/* return error("firstLarge must be less than thirdLarge"); */
return interpreterProxy->success(false);
}
if (!(secondLen <= thirdLen)) {
/* return error("secondLarge must be less than thirdLarge"); */
return interpreterProxy->success(false);
}
if (!((mInv >= 0) && (mInv <= 255))) {
/* return error("mInvMod256 must be between 0 and 255"); */
return interpreterProxy->success(false);
}
Lastly: I'm tempted to ask if anybody ever tried controlling the
Xcode project via AppleScript, back when Xcode was still a big part of
building the Mac or iOS VM. Maybe maximum effort with minimum payoff,
but could be interesting or fun to automatically enable/disable plugin
sources based on VMMaker(Tool) selections, and automatically trigger
build/clean from within the Squeak image.
Thanks,
a Tim