Hi,
my vacation is over, I have to continue working on
something else. Therfore I have less time now to
continue with the Self port. I think that there is
not missing too much to finally get a running system
(with all the applications :-)). It all comes down to
the stack walking code.
In order to give others the chance to participate, too,
I have put the stuff on the web server. Everybody who
likes to see Self on Linux as soon as possible, and
knows how to use a debugger is invited to help fixing
the remaining problems. I will continue, too, of course.
Maybe, I also made some mistakes...
http://www.cichon.de/self/
-gordon
--
----------------------------------------------------
Gordon Cichon email: Gordon(a)Cichon.de
------------------------------------------------------------------------
eGroup home: http://www.eGroups.com/list/self-interest
Free Web-based e-mail groups by eGroups.com
Hello all,
I have carried an experiment which I would like to report to all, so
that someone can help me explain it. I have started a standard Self
world, full of objects. I opened the spy with _Spy: true. Then, slowly,
I have removed slots from the lobby with lobby _RemoveSlot: '<slot
name>' until the lobby became an empty object. Then I typed
_GarbageCollect to try to force all objects that aren't the lobby to be
garbage collected, what didn't actually happen. What happened and why
does it happen?
My thesis was that all objects that aren't referenced by the lobby would
be reclaimed by the garbage collector. Even though this is contradictory
if we take into account the fact that many objects that are named
anObject aren't referenced by the lobby and don't get garbage collected
after some time. Where are Self objects hung? Does anyone know? How
could I garbage collect them?
No, I never opened frogs at school...
Regards,
Douglas
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
A couple of questions about primitives and the role of my interpreter in
sending them to objects...
1. How can I lookup a primitive send? (This one I have found out, just
now).
2. What is special about internal primitives?
3. What is the protocol primitives understand for calling them (like
arguments that should be passed, meaning of return values, etc.)? Is
there a standard?
4. Upon elimination of code related to the compilers, assembler, part of
runtime, zone and lookup: can some primitives be discarded together? are
there primitives that rely on this code?
That's it for now. If anyone wants to help answer or give any other
questions, I appreciate.
Regards,
Douglas
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
You mean EnterSelf? I have come to the conclusion that CallSelf handles some
threading issues before and after it forwards the "do it request" to EnterSelf
(written in assembly in runtime/sun4.runtime.s), which carries out the task of
executing the nmethod.
Anyway, EnterSelf also takes only the receiver and one argument. So if a method
that has more than one argument slot (not including :self) is compiled into an
nmethod, how can its argument slots be properly initialized? In other words, how
are the real arguments bound to the "formals" of the nmethod? The Programmer's
Reference states that when a method is executed it is cloned to create a method
activation and the argument slots are initialized to the arguments given in the
message send. How is this implemented?
Douglas
David.Ungar(a)Eng.Sun.COM wrote:
> I seem to recall that CallSelf just invokes a "doIt" method that
> calls the real method.
>
> - Dave
>
> At 8:27 AM -0300 6/16/99, Douglas Atique wrote:
> >Hello, all. (BTW, I have noticed the list is rather quiet lately.)
> >Here is a little question about the VM.
> >We know there are three kinds of sends: unary, binary and keyword. I
> >have been looking at the runtime part of the VM code and found out about
> >an assembly routine named
> >oop CallSelf(nmethod method, oop receiver, oop arg)
> >which seems to me the part of code that really evaluates a send with
> >compiled native methods, returning an oop. As you might have noticed,
> >this function takes only one argument. In my opinion, to the send. My
> >question is: how can the VM evaluate binary and keyword sends if it can
> >give CallSelf only 1 argument?
> >I hope not to be too simplistic, but I am not very fluent in SPARC
> >assembly and didn't understand much of the code. It also seems that all
> >this is mixed in intricate ways with the Self threading system.
> >Regards,
> >Douglas
> >
> >
> >
> >------------------------------------------------------------------------
> >eGroups Spotlight:
> >"Lightning Strike Survivor List" - on-line support group for lightning strike
> >survivors and their families. http://clickhere.egroups.com/click/111
> >
> >
> >eGroups.com home: http://www.egroups.com/group/self-interest
> >http://www.egroups.com - Simplifying group communications
>
>
>
> David Ungar
> Sun Microsystems Laboratories
> (650) 336-2618
>
> ------------------------------------------------------------------------
> FreeShop is the #1 place for free and trial offers and great deals!
> Try something new and find out how you could win two round-trip tickets
> anywhere in the U.S.! http://clickhere.egroups.com/click/368
>
> eGroups.com home: http://www.egroups.com/group/self-interest
> http://www.egroups.com - Simplifying group communications
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
Hello, all. (BTW, I have noticed the list is rather quiet lately.)
Here is a little question about the VM.
We know there are three kinds of sends: unary, binary and keyword. I
have been looking at the runtime part of the VM code and found out about
an assembly routine named
oop CallSelf(nmethod method, oop receiver, oop arg)
which seems to me the part of code that really evaluates a send with
compiled native methods, returning an oop. As you might have noticed,
this function takes only one argument. In my opinion, to the send. My
question is: how can the VM evaluate binary and keyword sends if it can
give CallSelf only 1 argument?
I hope not to be too simplistic, but I am not very fluent in SPARC
assembly and didn't understand much of the code. It also seems that all
this is mixed in intricate ways with the Self threading system.
Regards,
Douglas
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
> Ain't this a bit strange? I mean, if I (a Self programmer) remove all references to
> an object (and I guess for us Self programmers the lobby is THE root) by removing
> it from the lobby, shouldn't the VM garbage collect the object?
What I'm saying is that the lobby is not the only root, nor can it
be. All those other objects have to exist too. For example, there
has to be a true object because you can write 1 _Equals: 1 and the VM
has to return _something_. Similarly for all the other objects whose
existence is implied by the language (nil, true, the assignment
object, prototypical activations, etc.), their parents, and their
mirrors. The object ID array is there because otherwise you wouldn't
be able to refer to the results of expressions entered at the VM
prompt.
Anything not reachable from the set of roots (as enumerated in my
earlier email) _will_ be GCed.
Mario
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
> But for the user objects, those that don't play a special role in
> implementing the language definition, the root is still the lobby. Am I right?
All those objects are roots, but most -- the lobby being the obvious
exception -- don't have references to user objects.
> If one performs the destructive process I did, of removing all slots from the lobby,
> theoretically, one should end with a useless world because nothing could be typed in the
> prompt, besides self, that would match any slot in any accessible object. But with
> primitives one can reconstruct everything (at least from the initial empty world) by
> recovering objects from the objectIDArray.
The array is there purely for convenience. Try setting it to zero
size (using 0 _NumObjectIDs) and then try to your experiment again.
You can also reconstruct slots and valuse using primitives
(_AddSlots:, etc), so the empty world is not totally useless (indeed,
this is how we bootstrap the world). Try starting the VM without a
snapshot!
> I have noticed that between sessions the IDs assigned to an object are not fixed and
> unique, for example, when I open Self with the empty world and type self at the prompt,
> the lobby is assigned ID <0>. However, if I type some expression that evaluates to an
> error, the <0> ID is assigned to the process object and lobby gets ID <1>.
It's modelled on the history list of csh.
-Mario
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
The lobby is not the only root for GC. This is the full list (from
memory/universe.h in the VM sources). These are all the objects that
are required for correct VM operation and therefore cannot be
reclaimed. You probably had some stuff lying around reference from
one or more of these (the object ID array is a likely culprit -- see
the code in the environment for a full GC for how to clear it).
-Mario
# define APPLY_TO_VM_OOPS(template) \
template(&Memory->lobbyObj) \
template(&Memory->nilObj) \
template(&Memory->trueObj) \
template(&Memory->falseObj) \
template(&Memory->stringObj) \
template(&Memory->assignmentObj) \
template(&Memory->objVectorObj) \
template(&Memory->byteVectorObj) \
template(&Memory->blockTraitsObj) \
template(&Memory->deadBlockObj) \
template(&Memory->processObj) \
template(&Memory->profilerObj) \
template(&Memory->outerActivationObj) \
template(&Memory->blockActivationObj) \
template(&Memory->proxyObj) \
template(&Memory->fctProxyObj) \
template(&Memory->literalsObj) \
template(&Memory->slotAnnotationObj) \
template(&Memory->objectAnnotationObj) \
template(&Memory->errorObj) \
\
template(&Memory->assignmentMirrorObj) \
template(&Memory->blockMirrorObj) \
template(&Memory->byteVectorMirrorObj) \
template(&Memory->outerMethodMirrorObj) \
template(&Memory->blockMethodMirrorObj) \
template(&Memory->floatMirrorObj) \
template(&Memory->objVectorMirrorObj) \
template(&Memory->slotsMirrorObj) \
template(&Memory->smiMirrorObj) \
template(&Memory->stringMirrorObj) \
template(&Memory->processMirrorObj) \
template(&Memory->outerActivationMirrorObj) \
template(&Memory->blockActivationMirrorObj) \
template(&Memory->proxyMirrorObj) \
template(&Memory->fctProxyMirrorObj) \
template(&Memory->profilerMirrorObj) \
template(&Memory->mirrorMirrorObj) \
\
template(&Memory->objectIDArray) \
template(&BugHuntNames) \
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
Hello, folks.
Remember my message about the bytecode interpreter for Self? It goes on,
this time I think I have refined the algorithm, which I would like to
discuss with you again.
My strategy is to replace the processor-dependent code to be able to run
the VM on Solaris x86, and in a later phase, to remove the
Solaris-dependent glue to be able to run the VM on other systems. Well,
let's see the first part.
I don't exactly know what happens in assembly inside the VM, but I have
the rough idea of the read-eval-print loop:
- user types expression on prompt
- parser generates a Self object (call it OBJ) from the text
- compiler generates a native method from the object OBJ above
- CallSelf executes the nmethod and returns an oop
- prompt waits for another expression.
My plan is to switch off the compiler and underlying support code so
that instead of compiling OBJ we feed it to an interpreter that will,
well, evaluate it.
>From the principles of the Self language, we know that an object can
have code or not. If the object has code, evaluating that object means
executing the code and returning whatever the code returns. If the
object doesn't have code, evaluating it returns itself.
So, to determine whether an object has code, I intend to use
oopClass::is_method_like(). That means my interpreter takes as argument
an oop. But if the object has code, it can also have argument slots,
which are used by the code to access its arguments. How does the VM make
the binding among the arguments that are passed from the message sent*
and the argument slots in the method object that matches the selector?
This is a question that I couldn't yet answer but is essential for my
interpreter to come true. I have read in the Self 4.0 Programmer's
Reference (ยง2.1.6) that the method is cloned to produce a method
activation, which I understand as isolating the definition of the method
from the execution scope of it (I'm not sure I was clear enough, but I
can't right now express it better). In this method activation, there is
at least one argument slot(:self), which is initialized to the receiver
of the message. So are any other argument slots that the method may
contain. Well, I'm still investigating.
Another issue that concerns me is the fact that inside a method there
may be a primitive call. How should that be handled? How can one perform
primitive lookup? Is there some special VM object that holds all
primitives, and can execute (or return a pointer to) a primitive upon
request?
Well, folks, this could be called a position paper, if it weren't so
informal. :-)
Comments are welcome.
Regards to all,
Douglas
______
*or expression typed by the user, which is nothing more than a message
sent by a special "object", at least IMHO as seen by the system the doIt
slot of the lobby is only a proxy for the user to act as an object.
Suppose the user were an object and had a slot with a method that did
exactly what (s)he has typed on the prompt. Suppose that the user could
send messages to other objects just by evaluating one of its slots. This
is a strange view, but it can make sense if 1) I elaborate a little more
on it, 2) one spends a lot of time simulating the VM code
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications
Fedi(a)siscor.bibnal.edu.ar wrote:
>
> object _MirrorContentsAt: 'x'
>
> I would like to know if this works the way I think, that is, that the
> primitive does a slot lookup through the parent slot (to find the slot
> 'x') and then returns the mirror on 'x', or if it fails.
No, this will only return a mirror on the contents of the slot
names 'x' in the receiver object itself. There are methods to
invoke a lookup, but you will probably get what you want with:
object _Perform: 'x'
If 'x' in either the object itself or one of its ancestors is a
data slot, you will get the its content directly (not a mirror).
If it is a method slot, then the code will be executed which may
not be what you want.
The argument for the '_Perform:' primitive must be a cannonical
string (the equivalent of Smalltalk's Symbol). Literal strings
are always cannonical, but if you got the string as an argument
for a method or something you might want to ensure that it is
cannonical with something like this:
object _Perform: str canonicalize
Of course, it is best to avoid using primitives directly like
this.
-- Jecel
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interesthttp://www.egroups.com - Simplifying group communications