SMOP REFERENCE and RELEASE Policy
All files were reviewed, SMOP is valgrind-clean at the moment.
Even if not all object systems use reference counting garbage collection, the possible existance of some object system that does, requires us to implement the mechanisms that make it possible. That is why, besides MESSAGE, two other functions are defined in the responder interface lowlevel type. The REFERENCE and RELEASE functions. This functions are supposed to be the hooks for implementing a refcount garbage collector.
Who owns the object?
This is the most important question in the matter of when to call REFERENCE and when to call RELEASE. And a simple policy shall describe this decision:
- When an object is created, it's owned by the code who called the method that creates it.
- Passing an object to a capture implies transfering the ownership of the object.
- A call to REFERENCE defines an additional owner to the object.
- A call to RELEASE implies that this owner no longer wants the object.
- Using an object as Intepreter, Responder Interface or Identifier of a SLIME call doesn't transfer the ownership.
What does it mean?
Simple as: every time you pass an object as an argument to a call, the object will belong to the called method and you will no longer be allowed to use the object. Unless, of course, you pass it while defining a new REFERENCE. A little code to illustrate:
SMOP__Object* foo = smop_lowlevel_alloc(sizeof(SMOP__Object));
// the object is owned by the current code.
// if you want to be able to use the object after passing it to
// a capture, you must reference it.
SMOP__Object* cap = SMOP__NATIVE__capture_create(intr, SMOP_REFERENCE(intr,foo), NULL, NULL);
// but if you won't need the object in this code anymore, you can
// save a little effort and just do.
SMOP__Object* cap2 = SMOP__NATIVE__capture_create(intr, foo, NULL, NULL);
// but Objects that you own must be released when you don't need them
The same concept is valid for the capture itself, when you pass a capture in a DISPATCH, you're implying transfer of ownership. Some code to illustrate it:
// The capture object is owned by the current code.
SMOP__Object* cap = SMOP__NATIVE__capture_create(intr, NULL, NULL, NULL);
// if you want to use it later, you must reference it.
// but when you won't use it later, you can simply
// pass it along, and the called method should release
// it when its not needed anymore