On Thu, Apr 21, 2016 at 1:24 PM, stepharo <[email protected]> wrote: > Hi eliot > > do you imply that the logic at the level of the image changed in squeak. > Because Pharo50 is also running Spur on a CogSpur Vm? >
The only logic that chanes at the image level is - no more compact classes, so indexIfCompact is missing - a primitive to answer allInstances instead of someInstance/nextInstance loop - a primitive to answer allObjects instead of a firstObject/nextObject loop - a special primitive version of identityHash in Behavior Above this layer everything looks the same. But some things work much better (many more identityHash values, faster allocation, etc). > Stef > > Le 21/4/16 16:48, Eliot Miranda a écrit : > > Hi Bernhard, >> >> On Apr 20, 2016, at 9:56 PM, Bernhard Pieber <[email protected]> wrote: >>> >>> Hi Eliot, >>> >>> Right, but in the latest Squeak5.1-trunk with the latest >>> CogSpur.r3663.app it takes only 3 milliseconds. I guess it’s just an >>> optimized implementation, there. (Can’t look right now.) >>> >> Indeed ;-). In most Smalltalk implementations an object's header >> contains a direct reference (a pointer) to its class, but in Spur, an >> object's header contains a "class index" (as does the Dart VM). IIRC this >> is an approach first tried in a system at Xerox PARC, but what follows, I >> invented for 64-bit VW, to avoid having 64-bits of class reference in every >> object. >> >> The object header contains both a 22-bit classIndex, for up to 4 million >> classes, and a 22-bit identityHash field for 4 million hash values. The >> classIndex is used in all method caches, which has advantages for the GC, >> and means that when sending a message via an inline cache, the object's >> index is fetched, not its class. >> >> Classes are stored in a hidden two-level sparse array (array of arrays), >> the class table. If the object's class object is required (for the #class >> message or to do a full message lookup searching the inheritance hierarchy) >> the classIndex is used to index the class table. >> >> The classes known to the VM, Array, Message, Context, >> LargeNegativeInteger, LargePositiveInteger have known indices and occupy >> the first page of the class table. So the VM can allocate instances of >> these by simply writing a header containing the relevant classIndex. A >> conventional implementation would have to fetch the class from the >> specialObjectsArray and write it into the header (and in pre-Spur, there >> are 31 "compact class indices" of which a handful are used for a subset of >> the classes). >> >> But how does the VM find the classIndex of an arbitrary class? Searching >> the table would be very slow. So Spur arranges that a class's identityHash >> is also its index in the classTable. Classes have their own special >> identityHash primitive, see Behavior>>#identityHash. Whenever the VM tries >> to Instantiate a class, or whenever the class's identityHash primitive is >> run, if the class's identityHash is zero, the VM assigns an unused index in >> the class table as the identityHash and stores the class in the table. So >> a class's identityHash is its index in the class table. >> >> To Instantiate a class its identityHash is copied into the classIndex >> field of the new instance's header. To search for all instances of a >> class, the VM searches for objects whose classIndex is that class's >> identityHash. A consequence is that if a class doesn't yet have an >> identityHash (identityHash = 0) it can't have instances, and so there is no >> need to scan the heap. >> >> >> Note that you can't (easily) tell from the image. If you send >> identityHash to a class that will enter it into the table. There's a >> hidden hasIdentityHash primitive that can be used, and if you're curious I >> can post code to get at it. Note that this implies all the metaclasses are >> in the table because they have as their single instance a normal named >> class, but Metaclasses holds onto its instance via thisClass and so can >> also avoid traversing the heap. >> >> Some things to try: >> >> {Array. ByteString. Character. Context. LargeNegativeInteger. >> LargePositiveInteger. Message. SmallFloat64. BoxedFloat64. SmallInteger} >> collect: #identityHash >> >> and in a pre-Spur system >> >> Smalltalk compactClassesArray select: [:c| Smalltalk specialObjectsArray >> includes: c] thenCollect: [:c| {c. c indexIfCompact] >> >> Hope this explains what's going on under the covers. >> >> Cheers, >>> Bernhard >>> >>> Am 20.04.2016 um 17:43 schrieb Eliot Miranda <[email protected]>: >>>> >>>> Hi Bernhard, >>>> >>>> >>>> On Apr 20, 2016, at 5:26 AM, Bernhard Pieber <[email protected]> >>>>> wrote: >>>>> >>>>> Dear Pharoers, >>>>> >>>>> I found something strange: >>>>> Time millisecondsToRun: [ Class allSubInstances size ]. „23617" >>>>> >>>> Because it does an allInstances for Class and all its subclasses, and >>>> allInstances visits every object in the heap, so this does thousands of >>>> scans of the heap. >>>> >>>> >>>> I did this on a new Pharo 5 image >>>>> curl get.pharo.org/alpha+vmLatest | bash >>>>> >>>>> Can somebody confirm this on their machine? What might be the reason? >>>>> >>>>> Cheers, >>>>> Bernhard >>>>> >>>> >>> >> > > -- _,,,^..^,,,_ best, Eliot
