Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.865.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.865
Author: eem
Time: 26 August 2014, 9:33:50.954 am
UUID: 4efffc12-280e-4060-b741-9066fb3fc970
Ancestors: VMMaker.oscog-eem.864
Fix a simulation only method by marking it <doNotGenerate>.
=============== Diff against VMMaker.oscog-eem.864 ===============
Item was changed:
----- Method: SpurSegmentManager>>initSegmentForInImageCompilationFrom:to: (in category 'simulation') -----
initSegmentForInImageCompilationFrom: base to: limit
+ <doNotGenerate>
| bridge |
self allocateOrExtendSegmentInfos.
numSegments := 1.
bridge := manager initSegmentBridgeWithBytes: manager memory byteSize - limit at: limit - manager bridgeSize.
segments := {SpurSegmentInfo new
segStart: base;
segSize: limit - base;
yourself}.
segments := CArrayAccessor on: segments!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.862.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.862
Author: eem
Time: 21 August 2014, 8:14:01.395 am
UUID: 34b8f089-7da3-4c40-9996-2d2611fe5111
Ancestors: VMMaker.oscog-eem.861
Make nameOfClass: more robust, in both the real and
simulated VMs.
Add a documentation method for the structure of a
CogMethod.
=============== Diff against VMMaker.oscog-eem.861 ===============
Item was changed:
VMStructType subclass: #CogBlockMethod
instanceVariableNames: 'objectHeader homeOffset startpc padToWord cmNumArgs cmType cmRefersToYoung cpicHasMNUCase cmUsageCount cmUsesPenultimateLit cmUnusedFlags stackCheckOffset'
classVariableNames: ''
poolDictionaries: 'CogMethodConstants VMBasicConstants'
category: 'VMMaker-JIT'!
+ !CogBlockMethod commentStamp: 'eem 8/19/2014 17:07' prior: 0!
+ I am the rump method header for a block method embedded in a full CogMethod. I am the superclass of CogMethod, which is a Cog method header proper. Instances of both classes have the same second word. The homeOffset and startpc fields are overlaid on the objectHeader in a CogMethod. See Cogit class>>structureOfACogMethod for more information. In C I look like
- !CogBlockMethod commentStamp: 'eem 1/9/2011 08:41' prior: 0!
- I am the rump method header for a block method embedded in a full CogMethod. I am the superclass of CogMethod, which is a Cog method header proper. Instances of both classes have the same second word. The homeOffset abd startpc fields are overlaid on the objectHeader in a CogMethod. In C I look like
typedef struct {
unsigned short homeOffset;
unsigned short startpc;
unsigned cmNumArgs : 8;
unsigned cmType : 3;
unsigned cmRefersToYoung : 1;
unsigned cmIsUnlinked : 1;
unsigned cmUsageCount : 3;
unsigned stackCheckOffset : 16;
} CogBlockMethod;
My instances are not actually used. The methods exist only as input to Slang. The simulator uses my surrogates (CogBlockMethodSurrogate32 and CogBlockMethodSurrogate64.!
Item was changed:
CogBlockMethod subclass: #CogMethod
instanceVariableNames: 'blockSize blockEntryOffset methodObject methodHeader selector'
classVariableNames: ''
poolDictionaries: ''
category: 'VMMaker-JIT'!
+ !CogMethod commentStamp: 'eem 8/19/2014 17:07' prior: 0!
+ I am a native Cog method or polymorphic inline cache. If the former I have been produced by compiling a bytecoded CompiledMethod into machine code by the JIT, and I have a circular reference to that CompiledMethod. The CompiledMethod's header field is a pointer to me, the CogMethod, and my methodHeader field holds the compiled method's actual header. My objectHeader field looks like a single word object with a compact header with the mark bit set so as to placate the GC, i.e. make a CogMethod look like an object so that the reference to a CogMethod from a compiled method doesn't break the GC. The cmType, stackCheckOffset, cmNumArgs & cmNumTemps fields are early in the structure because we place dummy two-word CogMethod headers within a method for each block within it to record this information for each block method (see my superclass CogBlockMethod). In this case the objectHeader field is overlaid by the homeOffset and startpc fields. The objectHeader field is also used to hold the relocation distance when compacting methods since when functioning as an obhject header it is a constant value and so can easily be reinitialized. See Cogit class>>structureOfACogMethod for more information.
- !CogMethod commentStamp: 'eem 1/9/2011 08:49' prior: 0!
- I am a native Cog method or polymorphic inline cache. If the former I have been produced by compiling a bytecoded CompiledMethod into machine code by the JIT, and I have a circular reference to that CompiledMethod. The CompiledMethod's header field is a pointer to me, the CogMethod, and my methodHeader field holds the compiled method's actual header. My objectHeader field looks like a single word object with a compact header with the mark bit set so as to placate the GC, i.e. make a CogMethod look like an object so that the reference to a CogMethod from a compiled method doesn't break the GC. The cmType, stackCheckOffset, cmNumArgs & cmNumTemps fields are early in the structure because we place dummy two-word CogMethod headers within a method for each block within it to record this information for each block method (see my superclass CogBlockMethod). In this case the objectHeader field is overlaid by the homeOffset and startpc fields. The objectHeader field is also used to hold the relocation distance when compacting methods since when functioning as an obhject header it is a constant value and so can easily be reinitialized.
In C I look like
typedef struct {
sqInt objectHeader;
unsigned cmNumArgs : 8;
unsigned cmType : 3;
unsigned cmRefersToYoung : 1;
unsigned cmIsUnlinked : 1;
unsigned cmUsageCount : 3;
unsigned stackCheckOffset : 16;
unsigned short blockSize;
unsigned short blockEntryOffset;
sqInt methodObject;
sqInt methodHeader;
sqInt selector;
} CogMethod;
Note that in a 64-bit system all fields from cmNumArgs through blockEntry fit in a single 64-bit word.
My instances are not actually used. The methods exist only as input to Slang. The simulator uses my surrogates (CogMethodSurrogate32 and CogMethodSurrogate64.!
Item was changed:
----- Method: CogVMSimulator>>nameOfClass: (in category 'debug support') -----
nameOfClass: classOop
+ | numSlots maybeThisClassOop maybeNameOop name |
- | numSlots |
classNameIndex ifNil: [^'??nil cnidx??'].
numSlots := objectMemory numSlotsOf: classOop.
numSlots = metaclassNumSlots ifTrue:
+ [maybeThisClassOop := objectMemory fetchPointer: thisClassIndex ofObject: classOop.
+ (self addressCouldBeClassObj: maybeThisClassOop) ifTrue:
+ [name := self nameOfClass: maybeThisClassOop.
+ (name beginsWith: 'bad ') ifFalse:
+ [^name, ' class']].
+ ^'bad class'].
+ (numSlots > classNameIndex
+ and: [maybeNameOop := objectMemory fetchPointer: classNameIndex ofObject: classOop.
+ objectMemory isBytes: maybeNameOop]) ifFalse:
- [^(self nameOfClass:
- (objectMemory fetchPointer: thisClassIndex ofObject: classOop)) , ' class'].
- numSlots <= classNameIndex ifTrue:
[^'bad class'].
+ ^self stringOf: maybeNameOop!
- ^self stringOf: (objectMemory fetchPointer: classNameIndex ofObject: classOop)!
Item was added:
+ ----- Method: Cogit class>>structureOfACogMethod (in category 'tests') -----
+ structureOfACogMethod
+ "A CogMethod is the machine code for executable code in the Cog VM, and in the simulator these are
+ instances of CogMethod. In actuality they are structures in memory in the CogMethodZone.. There
+ are four real kinds, defined by the cmType field, free space: CMFree, methods: CMMethod, closed
+ PICs: CMClosedPIC (finite polymorphic inline caches with up to 6 entries), and open PICs: CMOpenPIC
+ (infinite megamorphicinline caches that probe the first-level method lookup cache). There is a sixth
+ kind of method, which is merely a header, for blocks: CMBlock, one which exists only within CMMethods,
+ and exist only to allow block activations to refer to something that looks like a CogMethod.
+
+ The blockSize field in a CogMethod is the size in bytes of the entire method, including the header.
+ Methods are aligned to an 8 byte boundary in the CogMethodZone. The size is used to iterate over
+ the methods in the zone.
+
+ Follwing the header is the abort and entry code. Starting immediately after the header is the call to
+ the abort routine called when either a send fails or a stack limit check fails. Following that is the
+ checked entry point that checks the receiver is of the right class, and this code ends in the unchecked
+ entry point. Following this is either primitive code, followed by frame building code, or frame-building
+ code, or, for frameless methods, the code for the frameless method. Following that is the code for the
+ method. If the mehtrod contains blocks then followng the method code will be a CMBlock header,
+ followed by code for the block, for each block, and following this will be the block dispatch code,
+ which is pointed to by the blockEntryOffset field in the CogMethod.
+
+ Following either the return in the method, or the block dispatch, is the meta data which identifies
+ intersting points in the machine code. This meta data starts at the end of teh structure and is read
+ backwards towards the start of the method, and is terminated by a null byte. So the blockSize is
+ used to find the start of the metadata. The metadata reveals where object references, sends and
+ pc-mapping points exist in the machine code. Hence the metadata is parsed when garbage collect-
+ ing to find and update object references."
+ !
Item was changed:
----- Method: StackInterpreter>>nameOfClass: (in category 'debug printing') -----
nameOfClass: classOop
"Brain-damaged nameOfClass: for C VM. Does *not* answer Foo class for metaclasses.
Use e.g. classIsMeta: to avoid being fooled."
<inline: false>
+ <returnTypeC: #'char *'>
+ | numSlots maybeNameOop maybeThisClassOop |
- <returnTypeC: 'char *'>
- | numSlots |
numSlots := objectMemory numSlotsOf: classOop.
numSlots = metaclassNumSlots ifTrue:
+ [maybeThisClassOop := objectMemory fetchPointer: thisClassIndex ofObject: classOop.
+ (self addressCouldBeClassObj: maybeThisClassOop) ifTrue:
+ [^self nameOfClass: (objectMemory fetchPointer: thisClassIndex ofObject: classOop)].
+ ^'bad class'].
+ (numSlots > classNameIndex
+ and: [maybeNameOop := objectMemory fetchPointer: classNameIndex ofObject: classOop.
+ objectMemory isBytes: maybeNameOop]) ifFalse:
- [^self nameOfClass: (objectMemory fetchPointer: thisClassIndex ofObject: classOop)].
- numSlots <= classNameIndex ifTrue:
[^'bad class'].
+ ^objectMemory firstIndexableField: maybeNameOop!
- ^objectMemory firstIndexableField: (objectMemory fetchPointer: classNameIndex ofObject: classOop)!
Item was changed:
----- Method: StackInterpreterSimulator>>nameOfClass: (in category 'debug support') -----
nameOfClass: classOop
+ | numSlots maybeThisClassOop maybeNameOop name |
- | numSlots |
classNameIndex ifNil: [^'??nil cnidx??'].
numSlots := objectMemory numSlotsOf: classOop.
numSlots = metaclassNumSlots ifTrue:
+ [maybeThisClassOop := objectMemory fetchPointer: thisClassIndex ofObject: classOop.
+ (self addressCouldBeClassObj: maybeThisClassOop) ifTrue:
+ [name := self nameOfClass: maybeThisClassOop.
+ (name beginsWith: 'bad ') ifFalse:
+ [^name, ' class']].
+ ^'bad class'].
+ (numSlots > classNameIndex
+ and: [maybeNameOop := objectMemory fetchPointer: classNameIndex ofObject: classOop.
+ objectMemory isBytes: maybeNameOop]) ifFalse:
- [^(self nameOfClass:
- (objectMemory fetchPointer: thisClassIndex ofObject: classOop)) , ' class'].
- numSlots <= classNameIndex ifTrue:
[^'bad class'].
+ ^self stringOf: maybeNameOop!
- ^self stringOf: (objectMemory fetchPointer: classNameIndex ofObject: classOop)!
Hi Ronie, This is really exciting (and I've cross-posted to vm-dev). I
guess this will help multi-monitor displays to have a window on each
monitor?
Ronie Salgado wrote:
> Hello There,
>
> I have been working in OSWindow, which is a cross platform API for
> dealing with native operating system windows. This API requires using
> a custom VM and the library SDL2.
>
> With this API, even the main Pharo window is handled almost completely
> in image side using NativeBoost.
>
> The only support required from the VM is a small periodical check in
> the heartbeat about the presence of events. This no more than 10 lines
> of code.
Is there much you needed to change/delete from the existing VM window
initialization. Since the VM is shared with other Smalltalk platforms,
how compatible would this be to maintain in parallel with the existing
VM windows initialization?
cheers -ben
>
> This is currently working very well in my Linux machine, so I need to
> start testing this stuff.
>
> For Windows, soon I will be building the custom VM. My last built was
> very dirty and I want to do something more clean.
>
> For Mac OS X, I don't have one for testing. But Alex is going allow me
> to borrow one for some time. So be patience.
>
> As for Woden, it is a new 3D graphics engine that I started making.
> This one requires currently support of OSWindow and also shows some
> cool stuffs.
>
> As for prebuilt versions of the VM with OSWindow support along with
> preloaded images for both, OSWindow and Woden. And screenshots.
>
> Well, I am putting them here: http://ronie.cl/OSWindow/
>
> Greetings,
> Ronie