SmallInetger as methods was not ready yet....now maybe?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: SmallInetger as methods was not ready yet....now maybe?

Mariano Martinez Peck
 


On Fri, Dec 3, 2010 at 11:12 PM, Levente Uzonyi <[hidden email]> wrote:

On Fri, 3 Dec 2010, stephane ducasse wrote:



On Dec 3, 2010, at 7:02 PM, Andreas Raab wrote:

maybe supporting SmallInteger as methods was not a good idea :(

FWIW, Objects as methods weren't intended for SmallInts; they were intended for stuff like method wrappers. Using SmallIntegers for methods is a hack and I'm not surprised it doesn't work.

Me too. They were worked well for normal objects. This is good and valuable hook.

But it is easy to fix - just wrap your ints into something else and you're good to go.

It does not work in mariano special need because the idea was to push as far as possible the idea that we do not have to allocate any new objects and avoid any proxy memory allocation cost. So clearly this is may be a too hackish hack. Else a plain simple (but allocating memory proxy works well but we wanted to know what is the lowest boundary).

I have a working package that can swap out CompiledMethods and replace them with SmallIntegers in the MethodDictionaries. When the method is about to be used by the system, the CompiledMethod is automatically swapped back. It uses the existing ObjectsAsMethods implementation, so I say that SmallIntegers can be used like any other object in this regard.

Thanks Levente. I did more or less the same. In addition, I did some modifications to the VM to mark objects usage, in order to be able to automatically swap out "unused objects".
All these changes, I did it in normal SqueakVM, and this is why I am using such VM. I was just checking Cog and seems it supports much more these problems.
For example, what I said in the first mail of this thread: when Interpreter does the #markAndTraceInterpreterOops:    and tries to do  self markAndTrace: newMethod.
 
That, in SqueakVM crash (as explained in my first email). However, in Cog, it does:


| header lastFieldOffset action |
    self assert: (self addressCouldBeObjWhileForwarding: oop).
    header := self longAt: oop.


notice that assert.  So...I guess Cog is more prepare to supports non-objects for methods.

Eliot, can you confirm that?

I couldn't even compile Cog but now JB gave me some hints....so maybe I will try to give it a shoot and see what happens.


Thanks Levente.

Mariano

I didn't test it with SqueakVM, but it definitely works with CogVM.


Levente



Cheers,
 - Andreas



Reply | Threaded
Open this post in threaded view
|

Re: SmallInetger as methods was not ready yet....now maybe?

Mariano Martinez Peck
In reply to this post by Eliot Miranda-2
 


On Sat, Dec 4, 2010 at 1:18 AM, Eliot Miranda <[hidden email]> wrote:
 


On Fri, Dec 3, 2010 at 10:15 AM, Andreas Raab <[hidden email]> wrote:

On 12/3/2010 10:07 AM, Igor Stasenko wrote:
On 3 December 2010 19:02, Andreas Raab<[hidden email]>  wrote:
maybe supporting SmallInteger as methods was not a good idea :(
FWIW, Objects as methods weren't intended for SmallInts; they were intended
for stuff like method wrappers. Using SmallIntegers for methods is a hack
and I'm not surprised it doesn't work. But it is easy to fix - just wrap
your ints into something else and you're good to go.

clearly, VM should not crash if it finds smallint in method dictionary.
Of course, it may 'not work', but in less destructive way.

Well, there are limits. By the same argument you can come up with any number of things that currently crash the VM where one might say the VM should react in a less destructive way (thisContext swapSender: 0 anyone?). Performance is important in this area and having to throw in a bunch of checks all over the place is something that I'm not to fond of.

Well, if the vm supports "objects as methods" then there needs to be a check for something fetched from a method dictionary being a CompiledMethod somewhere.  It is easy to make this robust in the face of SmallIntegers.  The elegance is in writing the code so that the check occurs in as few places as possible.  In my current Cog I've managed to get this down to two places in the normal lookup machinery, addNewMethodToCache: for the interpreter and lookupAndCog:for: for inline cache misses.  Primitives like primitiveDoNamedPrimitiveWithArgs and primitiveExecuteMethodArgsArray need to check also (5 in all in Cog) but for the normal lookup machinery things feel OK.  


Eliot, I saw these changes, but I wonder if there would be more. I said at the beginning of this thread...for example, the Interpreter has an instVar called "newMethod". If at a certain moment tht instVar has a SmallInteger, do you handle the check in all possible uses of newMethod?  (ok, you did it in markAndTrace hehe)
Because the methodLookUp, methodExecution, etc, are easy to think and detect. But with the markAndTrace it ONLY happened to me when trying to swap out 60000 methods and then, the probability to have a SmallInteger in newMethod was big. Otherwise, I wouldn't notice the bug hahha
 
BTW, Mariano's use of SmallIntegers rather than wrappers is an attempt to get a very compact image and seems a reasonable experiment.  Using wrappers would defeat his use-as-little-memory-as-possible purpose.


Exactly. And since reserch is about future ;) I was thinking that tomorrow, we could have 64 bits, with more than 1 object encoded in the address: small floats, characters, points...whatever. And why not a Proxy class (subclass of ProtoObject) where you can implement your own  dnu/run:with:in ?

I was even going to suggest change all senders of #isIntegerObject:  by a new method  #hasObjectHeader: oop  (or whatever name)
and we let this prepare for when we have not only SmallInteger but other stuff.

Cheers

Mariano



 


If you really want to do something here I'd do it entirely differently: Add a primitive to the VM that can answer the question "can you execute this object?" and use it before adding something to the method dictionary. That way you won't be able to create a method dictionary that contains stuff which is not executable.

Cheers,
 - Andreas

best
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: SmallInetger as methods was not ready yet....now maybe?

Mariano Martinez Peck
In reply to this post by Andreas.Raab
 


On Sat, Dec 4, 2010 at 2:21 AM, Andreas Raab <[hidden email]> wrote:

On 12/3/2010 4:18 PM, Eliot Miranda wrote:
BTW, Mariano's use of SmallIntegers rather than wrappers is an attempt
to get a very compact image and seems a reasonable experiment.  Using
wrappers would defeat his use-as-little-memory-as-possible purpose.

Not at all. The design of objects-as-methods was deliberately done such that one could use a single wrapper for multiple methods. The only thing you need is to map from selector to method being executed. For example:

MethodSwapper>>run: aSelector with: argsArray in: aReceiver
       "Execute the given method"
       method:= methodMap at: aSelector.
       ^aReceiver withArgs: argsArray executeMethod: method

Then you install a single MethodSwapper instance like here:

swapper := MethodSwapper new.
Morph selectorsAndMethodsDo:[:sel :meth| swapper methodMap at: sel put: meth].
Morph selectorsDo:[:sel| Morph addSelector: sel withMethod: swapper].

At this point the only overhead you have is what's in the (single) MethodSwapper instance and even with a most naive implementation (looking up the index by selector) you'd have 8 bytes per method in your image which I suspect is well below 5% of the image size.

But that's exactly what I want to avoid. I can even create the proxy class compact, and I would have 4 bytes if I serach by equality the compiledMethod in all classes.
 

And then of course you can start *really* looking at getting the size down. Did you know that Dan once did a very neat hack where he replaced all symbols with integers? Works great and if you do that you not only reclaim the space for the symbols but also don't need a lookup at all :-)


Yes, I know that. I even saw that the VM was "prepare" to support SmallIntegers as key in the MethodDict. However, I have 2 questions for that approach:

- Is that transparent for the develope?   I mean, are we still able to do things like   MyClass >> #foo  ?  or we are force to do  MyClass methodDict at: 42 ?

- To get those symbols garbageCollected, I guess I need to compact the symbol table all the time.  

Thanks

Mariano
Reply | Threaded
Open this post in threaded view
|

Re: SmallInetger as methods was not ready yet....now maybe?

Mariano Martinez Peck
In reply to this post by Andreas.Raab
 


On Sat, Dec 4, 2010 at 6:39 PM, Andreas Raab <[hidden email]> wrote:

On 12/3/2010 9:12 PM, Igor Stasenko wrote:
don't need a lookup? how?
you still have a method dictionaries, and keys there are not ordered
nor sequential ( yes, you can make selectors in a single class
to be sequential , like 1 , 2 ,3 ,4 , then you don't need to do a
lookup for a single given class, but for the rest of classes which
obviously contain different set of selectors, you won't be able to do
that).

Sorry, "no lookup" referred to the initial comment of wanting somehow to map selectors to some number (which I presumed was an index into some database to load the unloaded compiled method). Of course, method lookup is still required.


Yes, you don't need lookup, but you need the methodMap... I mean, I can also store in the proxy instance its class+selector where it is installed. Or use a global map, or whatever. And yes, I avoid the lookup, but I spend memory on that. Then I can not store anything at all, and search it.
 
Cheers,
 - Andreas

12