In J2V8, when you first create a runtime, a number of things happen under the hood.
V8Runtime* runtime = new V8Runtime(); runtime->isolate = Isolate::New(); runtime->isolate_scope = new Isolate::Scope(runtime->isolate); HandleScope handle_scope(runtime->isolate);
As you can see, we create an Isolate, IsolateScope and HandleScope. These are stored as fields on a V8Runtime object so they can be accessed later, for example, when a script is executed or a JS variable is accessed.
But how do you access the isolate? Because we may have several isolates (one for each tab in a web browser, for example), we cannot store it as a global variable. One option is to assign each isolate a unique ID and store it in a map. This is what I first did in J2v8, but as soon as you add multiple threads then this map becomes a shared data structure and you need to have a read / write lock around it. A better way is just to store the native reference with the Java object.
Since you cannot actually assign native C++ objects to fields of a Java Object, you just store the pointer. You can use an int, but to ensure things also work on 64 bit architecture I suggest storing the pointer as a long. In C++, you can cast the object reference to a long using reinterpret_cast.
long ptr = reinterpret_cast
This value can now be passed directly to Java and stored as a field within your object. Whenever you need to deference the pointer, you cast it back.
V8Runtime* runtime = reinterpret_cast
I’ve converted the runtime map in J2V8 to use this technique. Without the read/write lock, the performance for the multi-thread support improved 4x. More details to follow.
For more information on J2V8, follow me on twitter.