Branch: refs/heads/Cog
Home: https://github.com/OpenSmalltalk/opensmalltalk-vm
Commit: 154cf29d5d0872356e9e07341ad05d56e5b31baa
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/154cf29d5d0872356e…
Author: Tobias Pape <tobias(a)netshed.de>
Date: 2023-04-11 (Tue, 11 Apr 2023)
Changed paths:
M platforms/unix/config/config.guess
M platforms/unix/config/config.sub
Log Message:
-----------
Update autocinf infra
Commit: 4383082ee11672c55057b9bdd9b4cd43a27a9b97
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/4383082ee11672c550…
Author: Tobias Pape <tobias(a)netshed.de>
Date: 2023-04-11 (Tue, 11 Apr 2023)
Changed paths:
M platforms/unix/config/config.h.in
M platforms/unix/config/configure
A platforms/unix/plugins/JoystickTabletPlugin/acinclude.m4
Log Message:
-----------
Add joystick config-time check
Commit: ee216e0de306f613d501e85ac01131d779ab72cb
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/ee216e0de306f613d5…
Author: Tobias Pape <tobias(a)netshed.de>
Date: 2023-04-11 (Tue, 11 Apr 2023)
Changed paths:
M platforms/unix/plugins/JoystickTabletPlugin/sqUnixJoystickTablet.c
Log Message:
-----------
Sligthly cleanup joystick plugin on unix
note that the event code header itself is unneccessary, it has always
been included by input.h itself. So, if it is there, it has been
included regardless, and if it it not there (old linux), it will
complain. So remove that.
Also, include sq.h as customary for plugins and thus lose a few
common headers
Compare: https://github.com/OpenSmalltalk/opensmalltalk-vm/compare/ed1f7431a09f...ee…
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-eem.3323.mcz
==================== Summary ====================
Name: VMMaker.oscog.seperateMarking-eem.3323
Author: eem
Time: 6 April 2023, 4:41:32.682144 pm
UUID: 56aae874-f3bd-4c0c-b9df-b554ab1ac468
Ancestors: VMMaker.oscog.seperateMarking-eem.3322
Merge
VMMaker.oscog-eem.3314
VMMaker.oscog-eem.3315
VMMaker.oscog-eem.3316
VMMaker.oscog-eem.3317
=============== Diff against VMMaker.oscog.seperateMarking-eem.3322 ===============
Item was added:
+ ----- Method: ClipboardExtendedPlugin class>>hasHeaderFile (in category 'translation') -----
+ hasHeaderFile
+
+ ^true!
Item was removed:
- ----- Method: ClipboardExtendedPlugin class>>preambleCCode (in category 'translation') -----
- preambleCCode
- ^'// declarations for the support API. eem, 10/10/2022\\void sqPasteboardClear(void *inPasteboard);\sqInt sqPasteboardGetItemCount(void *inPasteboard);\sqInt sqPasteboardCopyItemFlavorsitemNumber(void *inPasteboard, sqInt formatNumber);\void *sqCreateClipboard(void);\void sqPasteboardPutItemFlavordatalengthformatTypeformatLength(void *inPasteboard, char *inData, sqInt dataLength, char *format, sqInt formatLength);\void sqPasteboardPutItemFlavordatalengthformatType(void *inPasteboard, char *inData, sqInt dataLength, sqInt format);\sqInt sqPasteboardCopyItemFlavorDataformatformatLength(void *inPasteboard, char *format, sqInt formatLength);\sqInt sqPasteboardCopyItemFlavorDataformat(void *inPasteboard, sqInt format);\sqInt sqPasteboardhasDataInFormatformatLength(void *inPasteboard, char *format, sqInt formatLength);\sqInt sqPasteboardhasDataInFormat(void *inPasteboard, sqInt format);' withCRs
-
- "quick test:"
- "ExtendedClipboardInterface current addClipboardDataConvertFormToPNG: Display"!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveStoreImageSegment (in category 'image segment in/out') -----
primitiveStoreImageSegment
"This primitive is called from Squeak as...
<imageSegment> storeSegmentFor: arrayOfRoots into: aWordArray outPointers: anArray."
"This primitive will store a binary image segment (in the same format as the Squeak image file) of the receiver and every object in its proper tree of subParts (ie, that is not refered to from anywhere else outside the tree). All pointers from within the tree to objects outside the tree will be copied into the array of outpointers. In their place in the image segment will be an oop equal to the offset in the outPointer array (the first would be 4). but with the high bit set."
"The primitive expects the array and wordArray to be more than adequately long. In this case it returns normally, and truncates the two arrays to exactly the right size. To simplify truncation, both incoming arrays are required to be 256 bytes or more long (ie with 3-word headers). If either array is too small, the primitive will fail, but in no other case.
During operation of the primitive, it is necessary to convert from both internal and external oops to their mapped values. To make this fast, the headers of the original objects in question are replaced by the mapped values (and this is noted by adding the forbidden XX header type). Tables are kept of both kinds of oops, as well as of the original headers for restoration.
To be specific, there are two similar two-part tables, the outpointer array, and one in the upper fifth of the segmentWordArray. Each grows oops from the bottom up, and preserved headers from halfway up.
In case of either success or failure, the headers must be restored. In the event of primitive failure, the table of outpointers must also be nilled out (since the garbage in the high half will not have been discarded."
+
- <staticallyResolveReceiver: 'objectMemory' to: #SpurStopTheWorldGarbageCollector>
| outPointerArray segmentWordArray arrayOfRoots ecode |
outPointerArray := self stackTop.
segmentWordArray := self stackValue: 1.
arrayOfRoots := self stackValue: 2.
"Essential type checks"
((objectMemory isArray: arrayOfRoots) "Must be indexable pointers"
and: [(objectMemory isArray: outPointerArray) "Must be indexable pointers"
and: [objectMemory isWords: segmentWordArray]]) "Must be indexable words"
+ ifFalse: [^self primitiveFailFor: PrimErrBadArgument].
- ifFalse: [^self primitiveFail].
ecode := objectMemory storeImageSegmentInto: segmentWordArray outPointers: outPointerArray roots: arrayOfRoots.
(objectMemory hasSpurMemoryManagerAPI
and: [ecode = PrimErrNeedCompaction]) ifTrue:
[objectMemory fullGC.
outPointerArray := self stackTop.
segmentWordArray := self stackValue: 1.
arrayOfRoots := self stackValue: 2.
ecode := objectMemory storeImageSegmentInto: segmentWordArray outPointers: outPointerArray roots: arrayOfRoots].
ecode = PrimNoErr
ifTrue: [self pop: 3] "...leaving the receiver on the stack as return value"
ifFalse: [self primitiveFailFor: ecode]!
Item was added:
+ ----- Method: NewObjectMemorySimulator>>memoryOffset (in category 'simulation only') -----
+ memoryOffset
+ ^0!
Item was added:
+ ----- Method: Spur32BitMMLESimulator>>memoryOffset (in category 'Cog JIT support') -----
+ memoryOffset
+ "The first word of memory is unused in order to implement a null pointer trap."
+ ^4!
Item was added:
+ ----- Method: Spur64BitMMLESimulator>>memoryOffset (in category 'Cog JIT support') -----
+ memoryOffset
+ "The first word of memory is unused in order to implement a null pointer trap."
+ ^4!
Item was added:
+ ----- Method: Spur64BitMMLESimulatorFor64Bits>>memoryOffset (in category 'Cog JIT support') -----
+ memoryOffset
+ "The first word of memory is unused in order to implement a null pointer trap."
+ ^8!
Item was changed:
----- Method: SpurGenerationScavenger>>initializeRememberedSet (in category 'initialization') -----
initializeRememberedSet
| obj |
obj := manager rememberedSetObj.
obj = manager nilObject
ifTrue:
[obj := manager allocatePinnedSlots: 1024.
manager rememberedSetObj: obj]
ifFalse: "The Spur32to64BitBootstrap failed to set the type of rememberedSetObj to 64-bit indexability.
+ This is unimportant except for simulation; rememberedSet is declared as sqInt *, but to have
- This is unimportant except for simulation; rememberedSet is declared as sqInt *, but in to have
firstIndexableField: below answer a suitable type the format must be wordIndexableFormat."
[manager setFormatOf: obj to: manager wordIndexableFormat].
self assert: (manager formatOf: obj) = manager wordIndexableFormat.
self assert: (manager isPinned: obj).
rememberedSet := manager firstIndexableField: obj.
rememberedSetSize := 0.
rememberedSetLimit := manager numSlotsOf: obj.
self setRememberedSetRedZone!
Item was changed:
----- Method: SpurMemoryManager>>allocatePinnedSlots: (in category 'sista support') -----
allocatePinnedSlots: nSlots
<api>
| obj |
obj := self allocateSlotsForPinningInOldSpace: nSlots
bytes: (self objectBytesForSlots: nSlots)
format: self wordIndexableFormat
+ classIndex: self wordSizeClassIndexPun.
- classIndex: self wordSizeClassIndexPun.
obj ifNotNil:
+ [self assert: (self isPinned: obj).
+ self fillObj: obj numSlots: nSlots with: 0].
- [self fillObj: obj numSlots: nSlots with: 0].
^obj!
Item was added:
+ ----- Method: SpurMemoryManager>>objStackPageSlots (in category 'obj stacks') -----
+ objStackPageSlots
+ ^ObjStackPageSlots!
Item was changed:
----- Method: SpurMemoryManager>>storeImageSegmentInto:outPointers:roots: (in category 'image segment in/out') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: SpurSegmentManager>>writeSegment:nextSegment:toFile: (in category 'snapshot') -----
writeSegment: segment nextSegment: nextSegment toFile: aBinaryStream
"Write the segment contents, the size of and the distance to the next segment to aBinaryStream."
<var: 'segment' type: #'SpurSegmentInfo *'>
<var: 'nextSegment' type: #'SpurSegmentInfo *'>
<var: 'aBinaryStream' type: #sqImageFile>
| pier1 pier2 firstSavedBridgeWord secondSavedBridgeWord nWritten |
<var: 'firstSavedBridgeWord' type: #usqLong>
<var: 'secondSavedBridgeWord' type: #usqLong>
pier1 := segment segLimit - manager bridgeSize.
pier2 := pier1 + manager baseHeaderSize.
self assert: (self isValidSegmentBridge: (self bridgeFor: segment)).
self assert: (manager startOfObject: (self bridgeFor: segment)) = pier1.
"Temporarily change the bridge to bridge to the next non-empty segment.
The first double word of the bridge includes the bridge size in slots, and
hence specifies the distance to the next segment. The following double
word is replaced by the size of the next segment, or 0 if there isn't one."
firstSavedBridgeWord := manager long64At: pier1.
secondSavedBridgeWord := manager long64At: pier2.
self bridgeFrom: segment to: nextSegment.
manager
long64At: pier2
put: (nextSegment ifNil: [0] ifNotNil: [nextSegment segSize]).
nWritten := self cCode:
[self
sq: segment segStart asVoidPointer
Image: 1
File: segment segSize
Write: aBinaryStream]
inSmalltalk:
[| bytesPerElement |
bytesPerElement := manager memory bytesPerElement.
aBinaryStream
next: segment segSize / bytesPerElement
putAll: manager memory
+ startingAt: segment segStart - manager memoryOffset / bytesPerElement + 1.
- startingAt: segment segStart / bytesPerElement + 1.
segment segSize].
manager
long64At: pier1 put: firstSavedBridgeWord;
long64At: pier2 put: secondSavedBridgeWord.
^nWritten!
Item was changed:
----- Method: StackInterpreter>>writeImageFileIOSimulation (in category 'image save/restore') -----
writeImageFileIOSimulation
"Write the image header and heap contents to imageFile for snapshot.
c.f. writeImageFileIO. The game below is to maintain 64-bit alignment
for all putLong:toFile: occurrences."
<doNotGenerate>
| headerSize file |
headerSize := objectMemory wordSize * 16.
(file := FileStream fileNamed: self imageName) ifNil:
[self primitiveFail.
^nil].
[file binary.
self putWord32: self imageFormatVersion toFile: file.
self putWord32: headerSize toFile: file.
{
objectMemory imageSizeToWrite.
objectMemory baseAddressOfImage.
objectMemory specialObjectsOop.
objectMemory lastHash.
self ioScreenSize.
self getImageHeaderFlags
}
do: [:long | self putLong: long toFile: file].
self putWord32: (extraVMMemory ifNil: [0]) toFile: file.
{ desiredNumStackPages. self unknownShortOrCodeSizeInKs } do:
[:short| self putShort: short toFile: file].
self putWord32: desiredEdenBytes toFile: file.
{ maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]. 0 } do:
[:short| self putShort: short toFile: file].
objectMemory hasSpurMemoryManagerAPI
ifTrue:
[| bytesWritten |
self putLong: objectMemory firstSegmentBytes toFile: file.
self putLong: objectMemory bytesLeftInOldSpace toFile: file.
2 timesRepeat: [self putLong: 0 toFile: file] "Pad the rest of the header.".
objectMemory wordSize = 8 ifTrue:
[3 timesRepeat: [self putLong: 0 toFile: file]].
self assert: file position = headerSize.
bytesWritten := objectMemory writeImageSegmentsToFile: file.
self assert: bytesWritten = objectMemory imageSizeToWrite]
ifFalse:
["Pad the rest of the header."
4 timesRepeat: [self putLong: 0 toFile: file].
objectMemory wordSize = 8 ifTrue:
[3 timesRepeat: [self putLong: 0 toFile: file]].
self assert: file position = headerSize.
"Write the object memory."
file
next: objectMemory imageSizeToWrite // objectMemory memory bytesPerElement
putAll: objectMemory memory
+ startingAt: objectMemory baseAddressOfImage - objectMemory memoryOffset // objectMemory memory bytesPerElement].
- startingAt: objectMemory baseAddressOfImage // objectMemory memory bytesPerElement].
file truncate: file position.
self success: true]
ensure: [file ifNotNil: [file close]]!
Item was removed:
- ----- Method: ThreadedARM64AppleFFIPlugin>>alignCurrentArgOf:to: (in category 'marshalling') -----
- alignCurrentArgOf: calloutState to: boundary
- <var: #calloutState type: #'CalloutState *'>
- <inline: #always>
- | misAlignedBytes |
- misAlignedBytes := calloutState currentArg asInteger bitAnd: boundary - 1.
- misAlignedBytes ~= 0 ifTrue:
- [calloutState currentArg: calloutState currentArg + (boundary - misAlignedBytes)]!
Item was added:
+ ----- Method: ThreadedARM64FFIPlugin>>alignCurrentArgOf:to: (in category 'marshalling') -----
+ alignCurrentArgOf: calloutState to: boundary
+ <var: #calloutState type: #'CalloutState *'>
+ <inline: #always>
+ | misAlignedBytes |
+ misAlignedBytes := calloutState currentArg asInteger bitAnd: boundary - 1.
+ misAlignedBytes ~= 0 ifTrue:
+ [calloutState currentArg: calloutState currentArg + (boundary - misAlignedBytes)]!
Item was changed:
----- Method: ThreadedARM64FFIPlugin>>ffiPushStructure:ofSize:typeSpec:ofLength:in: (in category 'marshalling') -----
ffiPushStructure: pointer ofSize: structSize typeSpec: argSpec ofLength: argSpecSize in: calloutState
<var: #pointer type: #'void *'>
<var: #argSpec type: #'unsigned int *'>
<var: #calloutState type: #'CalloutState *'>
<inline: #always>
| availableRegisterSpace roundedSize |
"Stage B
B.1 If the argument type is a Composite Type whose size cannot be statically determined by both the caller
and the callee, the argument is copied to memory and the argument is replaced by a pointer to the copy.
(There are no such types in C/C++ but they exist in other languages or in language extensions).
B.2 If the argument type is an HFA or an HVA, then the argument is used unmodified.
B.3 If the argument type is a Composite Type that is larger than 16 bytes, then the argument is copied to
memory allocated by the caller and the argument is replaced by a pointer to the copy.
B.4 If the argument type is a Composite Type then the size of the argument is rounded up to the nearest
multiple of 8 bytes."
"See IHI0055B_aapcs64.pdf sections 4.3.5 & 5.4.2 Stage C"
(self structIsHomogenousFloatArrayOfSize: structSize typeSpec: argSpec ofLength: argSpecSize)
ifTrue:
[availableRegisterSpace := (NumFloatRegArgs - calloutState floatRegisterIndex) * self wordSize.
structSize <= availableRegisterSpace ifTrue: "Stage C, step C.2, all in floating-point registers (!!!!)"
[self
memcpy: (self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: calloutState floatRegisterIndex)) to: #'void *')
_: pointer
_: structSize.
"Round structSize up and divide by 8 ( NB: _not_ 4 !!)"
calloutState floatRegisterIndex: calloutState floatRegisterIndex + (structSize + 7 bitShift: -3).
^0].
"Stage C, step C.3"
availableRegisterSpace := 0.
calloutState floatRegisterIndex: 8]
ifFalse:
[availableRegisterSpace := (NumIntRegArgs - calloutState integerRegisterIndex) * self wordSize].
"If it's small (16 bytes or less) and will fit in registers it is passed in registers, otherwise it is copied to memory.
If it is a Homogenous Short Vector (HVA) (up to 32 bytes long) and will fit it is passed in registers."
(structSize <= availableRegisterSpace "all in integer registers; we have no way of getting to SIMD registers"
and: [structSize <= 16
or: [self structIsHomogenousIntegerArrayOfSize: structSize typeSpec: argSpec ofLength: argSpecSize]]) ifTrue:
[structSize <= availableRegisterSpace ifTrue:"all in integer registers"
[self
memcpy: (self cCoerceSimple: (self addressOf: (calloutState integerRegisters at: calloutState integerRegisterIndex)) to: #'void *')
_: pointer
_: structSize.
"Round structSize up and divide by 8 ( NB: _not_ 4 !!)"
calloutState integerRegisterIndex: calloutState integerRegisterIndex + (structSize + 7 bitShift: -3).
^0]].
"If small and won't fit in registers, copy to the stack.
N.B. my (eem) reading of IHI0055B_aapcs64.pdf is that unlike the 32-bit PCS, aggregates are never split between memory and registers."
structSize <= 16 ifTrue:
[roundedSize := structSize + 7 bitClear: 7.
calloutState currentArg + roundedSize > calloutState limit ifTrue:
[^FFIErrorCallFrameTooBig].
+ self alignCurrentArgOf: calloutState to: self wordSize.
- self alignCurrentArgOf: calloutState to: 8.
self memcpy: calloutState currentArg _: pointer _: structSize.
calloutState currentArg: calloutState currentArg + roundedSize].
"If it is not small it is passed as a pointer. N.B. Spur guarantees only 8-byte alignment. IHI0055B_aapcs64.pdf is vague on the memory's alignment.
Arguably the memory should be pinned in case of a callback. Don't bother for now. eem 3/11/2023"
^self ffiPushPointer: pointer in: calloutState!