Thank you Tim, Bob, John, Stephen and everyone else for your great responses. I feel a bit more informed about it, but still wondering a bit about:
- In VisualAge, I'm able to store and retrieve CompiledMethods just fine because the literals and pointer variables are actually *instance variables* of the class CompiledMethod. If the CompiledMethod in Squeak only holds "references" to the literals (since it inherits from ByteArray, I presume this to be a memory-location-integer-reference to the String literal, and not the String itself), then how do the String literals themselves avoid being garbage collected?
- How do the ReferenceStreams manage to rematerialize CompiledMethods? Do they instantiate and then go back through the literals and change them to point to the "real" literal? I'll have to check this out.
- The next thing on my list is to get the BlockContexts going. They have a methodContext, so am I going to have similar challenges w/ blocks?
- And finally, what is VI4? If it is going to make this easier then I may just wait for it..
You know, I think the Squeak community provides better "support" (in my experience) than a lot of high-priced corporate service contracts!
Best regards, Chris
PS - Bob, to answer your question about going the source route, it is still an option, but this is for a GemStone-like ODBMS and I want to be able to store objects as close to their "native" form as possible. Recompiling the source introduces some added complexity and probably lower performance but, as I said, it is a worthy option. Thank you..
The "semi-compiled" format that Stephen suggested is also being considered. I used to have "storage objects" for a couple of classes (which were simply a different representation of the object that made rematerailization feasible. For example, storing LargeIntegers > 64-bits into a wrapper of its printString). However, I have moved away from them in favor of custom buffer formats for various implementation complexity reasons..
__________________________________________________ Do You Yahoo!? Yahoo! Sports - Coverage of the 2002 Olympic Games http://sports.yahoo.com
Chris Muller afunkyobject@yahoo.com is claimed by the authorities to have written:
- In VisualAge, I'm able to store and retrieve CompiledMethods just fine
because the literals and pointer variables are actually *instance variables* of the class CompiledMethod.
And this is how it will be when the VI4 project release is available. I did the 'New CompiledMethod' stuff years ago and Anthony H. has included it in his BlockClosures work. Search the swiki for some details.
If the CompiledMethod in Squeak only holds "references" to the literals (since it inherits from ByteArray, I presume this to be a memory-location-integer-reference to the String literal, and not the String itself), then how do the String literals themselves avoid being garbage collected?
It's all a big cheat. you really don't want to know the details since they could make green slime drip from your ears. For a week, at least.
You know, I think the Squeak community provides better "support" (in my experience) than a lot of high-priced corporate service contracts!
You're most welcome to send us the money instead of those non-supporting vendors :-)
As for handling this stufff right now, I pointed out a couple of weeks ago:-
If one really needs to do this before the VI4 is available, try the following approach:-
Literals can be obtained from the method with #literals (duh!), stick them in an array. #initialPC gives you the index of the first actual bytecode, #endPC that of the last - copy bytes from one to the other into a ByteArray. #sourcePointer gets you the source pointer integer. #header gets you the method header value
Now you have all the components available to save a clean set of everything needed to recreate the method later. Take a look at MethodNode>generate: to see how methods are normally put together and copy as much as possible.
Really, given your CM to pillage, grab the list of literals (what you do about globals etc is your problem!), the source pointer, the header and then use copyFrom: cm initialPC to: endPC to get the bytes.
Inspect an instance of CompiledMethod (try TestTMethod compiledMethodAt: #fixUpReturns) and then try this snippet in the inspector:-
|lits hdr srcP begin end bcs ncm | "extract the stuff from the original" lits _ self literals. hdr _ self header. srcP _ self sourcePointer. begin _ self initialPC. end _ self endPC. bcs _ ByteArray new: (end - begin +1). bcs replaceFrom: 1 to: bcs size with: self startingAt: begin. "You could now save all the above wherever" "create the copy" ncm _ CompiledMethod newMethod: end - begin + 1 + 4 header: hdr. lits withIndexDo: [:lit :index | ncm literalAt: index put: lit]. ncm setSourcePointer: srcP. ncm replaceFrom: ncm initialPC to: ncm endPC with: bcs startingAt:1. ncm = self
It should return true. Hopefully this will give you enough info to work the rest out.
tim
squeak-dev@lists.squeakfoundation.org