Dear Andrew,
"Andrew C. Greenberg" wrote:
Looking at your code gave me some thoughts:
I think you pointed out a great issue that I might address in the next version. What happens when loading and coercing a variable in the prolog may cause a garbagecollection? It seems to me that if you generate:
foo: a with: b: with: c with: d with: e
self primitive: 'primFoo' parameters: #(Oop LargeOrSmallInteger Oop LargeOrSmallInteger Oop) receiver: #Oop. ^self internalFoo: a with: b with: c with: d with: e
then the generated code ought to be something like:
/* code to load a from stack: 4 after coercing */ interpreterProxy->pushRemappableOop(a); /* code to load b from stack: 3 after coercing, can cause GC */ /* code to load c from stack: 2 after coercing */ interpreterProxy->pushRemappableOop(b); interpreterProxy->pushRemappableOop(c); /* code to load d from stack: 1 afer coercing, can cause GC */ /* code to load e from stack: 0 after coercing */ c = interpreterProxy->popRemappableOop; b = interpreterProxy->popRemappableOop; a = interpreterProxy->popRemappableOop; interpreterProxy->popthenPush(6, internalFoowithwithwith(a,b,c,d))
If I add a coercion function to let the codegenerator know whether a prolog is "dangerous," this can all be automatic. Thus, you could define a coercion, say, LargeOrSmallInteger, that does all the work of loading values, checking if they are SmallIntegers and coercing to large integers if they are. The GC pointer saves can be efficiently handled, and you need never worry about it again.
What do you think?
I want to argument from a newby (what I was a few weeks or days before) in plugin programming view.
First I think it is important to know, which coercion functions are available and with which semantics at all. In case of a LargeOrSmallInteger conversion a user could think: 'If it is an SmallInteger it becomes a C integer, if a LargeInteger a LargeInteger oop', what isn't intended. It takes some time for a newby in plugin programming to grasp the semantics, that some objects like e.g. SmallIntegers are converted in C ints automatically, but normally oops remain oops. I think you cannot protect the plugin programmer from the effort to get a full understanding of the possible problems originating from GC of oops. As more implicit conversion there are as later these problems occur, but they occur though!
The GC pointer saves can be efficiently handled, and you need never worry about it again.
This is true for the calling process of primitives for some kind of object. But normally you aren't able to avoid GC issues at all, e.g. for generating ST objects as results.
As a result I think it is a good idea to give some more conversion functions - with implicit GC safe behavior. But only with precise documentation regarding their behavior: 'What do they convert, which preconditions have been met, what are the results?'.
Some documentation concerning the GC originating problems, in which a plugin programmer runs into, would also be nice (I know that this is work, what isn't so funny as improving code... So this shouldn't be read as a request to me or you for something what has to be made. But it would be nice...).
Greetings,
Stephan
squeak-dev@lists.squeakfoundation.org