<div dir="ltr">Oh, yes, that's exactly what I wanted, awesome! Thanks!</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 26, 2015 at 3:23 PM, H. Hirzel <span dir="ltr"><<a href="mailto:hannes.hirzel@gmail.com" target="_blank">hannes.hirzel@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">And this seems to cover what you want to do<br>
<br>
How to use an ImageSegment to determine memory usage<br>
<a href="http://wiki.squeak.org/squeak/1260" rel="noreferrer" target="_blank">http://wiki.squeak.org/squeak/1260</a><br>
<span class="im HOEnZb"><br>
<br>
<br>
On 11/26/15, H. Hirzel <<a href="mailto:hannes.hirzel@gmail.com">hannes.hirzel@gmail.com</a>> wrote:<br>
</span><div class="HOEnZb"><div class="h5">> That's interesting,<br>
><br>
> see also <a href="http://wiki.squeak.org/squeak/2316" rel="noreferrer" target="_blank">http://wiki.squeak.org/squeak/2316</a> with a reference to an<br>
> article evaluation ImageSegments at the end.<br>
><br>
><br>
><br>
> On 11/26/15, Luciano Notarfrancesco <<a href="mailto:luchiano@gmail.com">luchiano@gmail.com</a>> wrote:<br>
>> Cool, maybe it's possible to make it into a package, I'll take a look.<br>
>><br>
>> I've never used it to store Projects, tho.. I used before to store<br>
>> things<br>
>> that must be loaded very fast on demand and can be forgotten once there<br>
>> are<br>
>> no more references to them.. like image fragments that compose a map of<br>
>> the<br>
>> world, and small sound fragments that are used to synthesize speech<br>
>> (diphones). Yesterday I just wanted to know how big are my objects, and I<br>
>> wanted to make some experiments to see how the bit-size of my objects<br>
>> grow<br>
>> as the problems I'm modeling grow by some other measure (degree of<br>
>> polynomials, size of matrices are the most basic) and to know how much<br>
>> memory are my algorithms actually using at every step... image segments<br>
>> are<br>
>> ideal for this, you can use them to know exactly how much memory would be<br>
>> freed if a reference to a given object were forgotten.<br>
>><br>
>><br>
>> On Thu, Nov 26, 2015 at 7:36 AM, H. Hirzel <<a href="mailto:hannes.hirzel@gmail.com">hannes.hirzel@gmail.com</a>><br>
>> wrote:<br>
>><br>
>>> Squeak 5.0 still has ImageSegments (class comment below). Saving and<br>
>>> loading of projects currently is blocked in Squeak because of an<br>
>>> unfinished name space (environments implementation).<br>
>>><br>
>>> <a href="http://wiki.squeak.org/squeak/6218" rel="noreferrer" target="_blank">http://wiki.squeak.org/squeak/6218</a><br>
>>><br>
>>> And there is Fuel<br>
>>> <a href="http://rmod.inria.fr/web/software/Fuel" rel="noreferrer" target="_blank">http://rmod.inria.fr/web/software/Fuel</a><br>
>>><br>
>>> ----------<br>
>>><br>
>>> ImageSegment<br>
>>><br>
>>> I represent a segment of Squeak address space. I am created from an<br>
>>> array of root objects. After storing, my segment contains a binary<br>
>>> encoding of every object accessible from my roots but not otherwise<br>
>>> accessible from anywhere else in the system. My segment contains<br>
>>> outward pointers that are indices into my table of outPointers.<br>
>>> On load my segment is converted back into objects and becommed<br>
>>> into an Array of the loaded objects, so they can be enumerated.<br>
>>><br>
>>> The main use of ImageSegments is to store Projects. A dummy<br>
>>> version of SmartRefStream traverses the Project. Everything it finds<br>
>>> is classified as either an object that is owned by the project (only<br>
>>> pointed to inside the project), or an object outside the project that<br>
>>> is pointed to from inside the project. The objects that are<br>
>>> completely owned by the project are compressed into pure binary form<br>
>>> in an ImageSegment. The outside objects are put in the 'outPointers'<br>
>>> array. The entire ImageSegment (binary part plus outPointers) is<br>
>>> encoded in a SmartRefStream, and saved on the disk. (aProject<br>
>>> exportSegmentWithChangeSet:fileName:directory:) calls (anImageSegment<br>
>>> writeForExportWithSources:inDirectory:changeSet:).<br>
>>><br>
>>> Note that every object inside the project is put into the<br>
>>> segment's arrayOfRoots. This is because a dummy SmartRefStream to<br>
>>> scan the project, in order to make intelligent decisions about what<br>
>>> belongs in the project.<br>
>>> See Project's class comment for what messages are sent to<br>
>>> objects as they are unpacked in a new image.<br>
>>><br>
>>> ---- Older Details ------<br>
>>><br>
>>> The primary kind of image segment is an Export Segment. It<br>
>>> can be saved on a server and read into a completely different Squeak<br>
>>> image.<br>
>>> Old way to create one:<br>
>>> (ImageSegment new copyFromRootsForExport: (Array with: Baz with: Baz<br>
>>> class))<br>
>>> writeForExport: 'myFile.extSeg'.<br>
>>> Old way to create one for a project:<br>
>>> (Project named: 'Play With Me - 3') exportSegment.<br>
>>> To read it into another image: Select 'myFile.extSeg' in a FileList,<br>
>>> Menu 'load as project'. It will install its classes automatically.<br>
>>> If you need to see the roots array, it is temporarily stored in<br>
>>> (SmartRefStream scannedObject).<br>
>>><br>
>>> Most of 'states' of an ImageSegment are not used to export a project,<br>
>>> and have been abandoned.<br>
>>><br>
>>> When a segment is written out onto a file, it goes in a<br>
>>> folder called <image name>_segs. If your image is called<br>
>>> "Squeak2.6.image", the folder "Squeak2.6_segs" must accompany the<br>
>>> image whenever your move, copy, or rename it.<br>
>>> Whenever a Class is in arrayOfRoots, its class (aClass class)<br>
>>> must also be in the arrayOfRoots.<br>
>>> There are two kinds of image segments. Normal image segments<br>
>>> are a piece of a specific Squeak image, and can only be read back<br>
>>> into that image. The image holds the array of outPointers that are<br>
>>> necessary to turn the bits in the file into objects.<br>
>>> To put out a normal segment that holds a Project (not the<br>
>>> current project), execute (Project named: 'xxx') storeSegment.<br>
>>><br>
>>><br>
>>> arrayOfRoots The objects that head the tree we will trace.<br>
>>> segment The WordArray of raw bits of all objects in the<br>
>>> tree.<br>
>>> outPointers Oops of all objects outside the segment<br>
>>> pointed to from inside.<br>
>>> state (see below)<br>
>>> segmentName Its basic name. Often the name of a Project.<br>
>>> fileName The local name of the file. 'Foo-23.seg'<br>
>>> userRootCnt number of roots submitted by caller. Extras<br>
>>> are added in preparation for saving.<br>
>>><br>
>>> state that an ImageSegment may exist in...<br>
>>><br>
>>> #activeCopy (has been copied, with the intent to<br>
>>> become active)<br>
>>> arrayOfRoots, segment, and outPointers have been created by<br>
>>> copyFromRoots:. The tree of objects has been encoded in the segment,<br>
>>> but those objects are still present in the Squeak system.<br>
>>><br>
>>> #active (segment is actively holding objects)<br>
>>> The segment is now the only holder of tree of objects. Each of the<br>
>>> original roots has been transmuted into an ImageSegmentRootStub that<br>
>>> refers back to this image segment. The original objects in the<br>
>>> segment will all be garbageCollected.<br>
>>><br>
>>> #onFile<br>
>>> The segment has been written out to a file and replaced by a file<br>
>>> pointer. Only ImageSegmentRootStubs and the array of outPointers<br>
>>> remains in the image. To get this far:<br>
>>> (ImageSegment new copyFromRoots: (Array with: Baz with: Baz class))<br>
>>> writeToFile: 'myFile.seg'.<br>
>>><br>
>>> #inactive<br>
>>> The segment has been brought back into memory and turned back into<br>
>>> objects. rootsArray is set, but the segment is invalid.<br>
>>><br>
>>> #onFileWithSymbols<br>
>>> The segment has been written out to a file, along with the text of<br>
>>> all the symbols in the outPointers array, and replaced by a file<br>
>>> pointer. This reduces the size of the outPointers array, and also<br>
>>> allows the system to reclaim any symbols that are not referred to<br>
>>> from elsewhere in the image. The specific format used is that of a<br>
>>> literal array as follows:<br>
>>> #(symbol1 symbol2 # symbol3 symbol4 'symbolWithSpaces' #<br>
>>> symbol5).<br>
>>> In this case, the original outPointers array was 8 long, but the<br>
>>> compacted table of outPointers retains only two entries. These get<br>
>>> inserted in place of the #'s in the array of symbols after it is read<br>
>>> back in. Symbols with embedded spaces or other strange characters<br>
>>> are written as strings, and converted back to symbols when read back<br>
>>> in. The symbol # is never written out.<br>
>>> NOTE: All IdentitySets or dictionaries must be rehashed when<br>
>>> being read back from this format. The symbols are effectively<br>
>>> internal. (No, not if read back into same image. If a different<br>
>>> image, then use #imported. -tk)<br>
>>><br>
>>> #imported<br>
>>> The segment is on an external file or just read in from one. The<br>
>>> segment and outPointers are meant to be read into a foreign image.<br>
>>> In this form, the image segment can be read from a URL, and<br>
>>> installed. A copy of the original array of root objects is<br>
>>> constructed, with former outPointers bound to existing objects in the<br>
>>> host system.<br>
>>> (Any Class inside the segment MUST be in the arrayOfRoots.<br>
>>> This is so its association can be inserted into Smalltalk. The<br>
>>> class's metaclass must be in roots also. Methods that are in<br>
>>> outPointers because blocks point at them, were found and added to the<br>
>>> roots.<br>
>>> All IdentitySets and dictionaries are rehashed when being<br>
>>> read back from exported segments.)<br>
>>><br>
>>><br>
>>> To discover why only some of the objects in a project are being<br>
>>> written out, try this (***Destructive Test***). This breaks lots of<br>
>>> backpointers in the target project, and puts up an array of<br>
>>> suspicious objects, a list of the classes of the outPointers, and a<br>
>>> debugger.<br>
>>> "Close any transcripts in the target project"<br>
>>> World currentHand objectToPaste ifNotNil: [<br>
>>> self inform: 'Hand is holding a Morph in its paste buffer:\'<br>
>>> withCRs,<br>
>>> World currentHand objectToPaste printString].<br>
>>> PV := Project named: 'xxxx'.<br>
>>> (IS := ImageSegment new) findRogueRootsImSeg:<br>
>>> (Array with: PV world presenter with: PV world).<br>
>>> IS findOwnersOutPtrs. "Optionally: write a file with owner chains"<br>
>>> "Quit and DO NOT save"<br>
>>><br>
>>> When an export image segment is brought into an image, it is like an<br>
>>> image starting up. Certain startUp messages need to be run. These<br>
>>> are byte and word reversals for nonPointer data that comes from a<br>
>>> machine of the opposite endianness. #startUpProc passes over all<br>
>>> objects in the segment, and:<br>
>>> The first time an instance of class X is encountered, (msg _<br>
>>> X startUpFrom: anImageSegment) is sent. If msg is nil, the usual<br>
>>> case, it means that instances of X do not need special work. X is<br>
>>> included in the IdentitySet, noStartUpNeeded. If msg is not nil,<br>
>>> store it in the dictionary, startUps (aClass -> aMessage).<br>
>>> When a later instance of X is encountered, if X is in<br>
>>> noStartUpNeeded, do nothing. If X is in startUps, send the message<br>
>>> to the instance. Typically this is a message like #swapShortObjects.<br>
>>> Every class that implements #startUp, should see if it needs<br>
>>> a parallel implementation of #startUpFrom:.<br>
>>><br>
>>> On 11/26/15, Luciano Notarfrancesco <<a href="mailto:luchiano@gmail.com">luchiano@gmail.com</a>> wrote:<br>
>>> > I don't see image segments in Cuis... I don't even know if they still<br>
>>> exist<br>
>>> > in Squeak... Anyone is still using it?<br>
>>> ><br>
>>> > It would be cool to have it at least as a package. If I remember<br>
>>> correctly<br>
>>> > it was very simple, like two primitives to load and save, but I think<br>
>>> > it<br>
>>> > depended on something like mark and sweep or some particular kind of<br>
>>> > garbage collector and it might not work in new VMs.<br>
>>> ><br>
>>><br>
>>> _______________________________________________<br>
>>> Cuis mailing list<br>
>>> <a href="mailto:Cuis@jvuletich.org">Cuis@jvuletich.org</a><br>
>>> <a href="http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org" rel="noreferrer" target="_blank">http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org</a><br>
>>><br>
>><br>
><br>
<br>
_______________________________________________<br>
Cuis mailing list<br>
<a href="mailto:Cuis@jvuletich.org">Cuis@jvuletich.org</a><br>
<a href="http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org" rel="noreferrer" target="_blank">http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org</a><br>
</div></div></blockquote></div><br></div>