Externs and GC

Monkey Forums/Monkey Programming/Externs and GC

Samah(Posted 2012) [#1]
Mark,
I've externed some C++ code that takes an Object pointer and stores it. Monkey proceeds to GC the object, then my pointer is invalid. Is there anything I can do about this short of keeping a reference in Monkey?


AdamRedwoods(Posted 2012) [#2]
try
class Whatever : public Object {
	public:
	Array<short> data;
	
	Whatever() {
	}
	~Whatever() {
	}
	void mark();
};
void Whatever::mark(){
	Object::mark();
	gc_mark(data);

}



Samah(Posted 2012) [#3]
That's a pretty cool way of doing it, but unfortunately this can be ANY object, not just an externed one. If it's the only way, I may need to add a restriction that the code only works with classes extending the externed one, but it really limits what I want to do.

Also, I need to make sure that this is (at least somewhat) target-agnostic. Somehow I feel C/C++ targets are going to be the only ones supported.

Edit:
I think I've worked out a way to do it using reference counting. Basically I'll have a Map<Object,Int> where the key is the Object to be retained and the value is the number of references. I should be able to keep track of this fairly easy.


marksibly(Posted 2012) [#4]
Hi,

> Is there anything I can do about this short of keeping a reference in Monkey?

Currently, all objects must be ultimately reachable from a Monkey global var - if not, they'll be collected.

Mojo handles this by storing singleton driver objects such as graphics/audio drivers in Monkey globals in the appropriate modules.

Then, the mark methods of these driver objects mark any internal 'globals' that need to be kept alive. For example, the mark method of the audio driver marks any sounds currently assigned to channels.

I'll have a look at adding something a bit sexier here, eg: a C++ add_root function that allows you to add non-monkey global vars.


Samah(Posted 2012) [#5]
Perhaps also weak reference functionality like in Java?
Global obj:SomeClass
Global wr:WeakReference<SomeClass>

Function Main:Int()
  ' create an object and a weak reference to it
  obj = New SomeClass
  wr = New WeakReference<SomeClass>(obj)
  ' at this point, wr.ref = obj
  ' clear the global object
  obj = Null
  ' gc occurs somewhere, the reference from wr.ref is ignored
  ' if obj was collected, set wr.ref to Null, but leave the instance of WeakReference
End

Class WeakReference<T>
Private
  Field ref:T
Public
  Method New(ref:T)
    Self.ref = ref
  End
  Method Ref:T() Property
    Return ref
  End
End


Alternatively you could add it as part of the syntax.
Global obj:SomeClass
Global wr:SomeClass Weak
.....
obj = New SomeClass
wr = obj
obj = Null
' obj gets collected, wr is set to Null



Samah(Posted 2012) [#6]
So basically I made a reference counter class that I'm calling from C++. Whenever I store a pointer to an Object, I retain. When the pointer is deleted, I release.