While utilizing V8 for running custom JavaScript code and exposing the OnUpdate
function to the JS world, everything seems to be functioning smoothly. However, I have a concern regarding the performance of the following code - is it necessary to acquire the v8::Locker
for executing any user-defined function? Upon inspecting with Instruments.app
, it appears that a significant amount of time is being spent within the v8::Locker
constructor and destructor -
https://i.sstatic.net/sFVc6.png
Comparing 90 ms (actual code execution time) to ~4000ms (time spent on Locker
& ~Locker
) seems unreasonable, and I suspect that there might be something amiss in my approach.
Therefore, my main inquiry is whether it is truly essential to acquire the v8::Locker
in order to execute a v8::Function::Call
? If I were to remove the v8::Locker
in the current configuration, I receive the following error message:
# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place
Snippet of the code:
int Bucket::send_doc_update_bucket(const char *msg) {
Locker locker(GetIsolate());
Isolate::Scope isolate_scope(GetIsolate());
HandleScope handle_scope(GetIsolate());
Local<Context> context = Local<Context>::New(GetIsolate(), context_);
Context::Scope context_scope(context);
TryCatch try_catch;
Local<Value> args[1];
args[0] = String::NewFromUtf8(GetIsolate(), msg);
assert(!try_catch.HasCaught());
Handle<Value> val;
if(!context->Global()->Get(context,
createUtf8String(GetIsolate(),
"OnUpdate")).ToLocal(&val) ||
!val->IsFunction()) {
return 3;
}
Handle<Function> on_doc_update = Handle<Function>::Cast(val);
on_doc_update->Call(context, context->Global(), 1, args);
if (try_catch.HasCaught()) {
//w->last_exception = ExceptionString(GetIsolate(), &try_catch);
return 2;
}
return 0;
}