Reputation: 33
I'm using V8 to execute some custom javascript code, exposing OnUpdate
function to JS world. Overall code works fine but currently I'm concerned about performance of below code - is it required to grab v8::Locker
for executing any user defined function? Instruments.app
shows code here spends way too much time in v8::Locker
constructor and destructor -
90 ms (in actual code execution) vs ~4000ms (by Locker
& ~Locker
) - this is absurd and I feel I might be doing something wrong.
So my basic question is it really necessary to grab v8::Locker
to execute a v8::Function::Call
? In current state if I comment out v8::Locker
I get below error message:
# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place
Code snippet:
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;
}
Upvotes: 0
Views: 1991
Reputation: 19781
If you're not doing any multithreading, you never need to touch v8::Locker. As soon as you do, though, then you have to have it pretty much everywhere.
A v8::Locker is to stop multiple v8::Context's from the same v8::Isolate from running at the same time.
If you want multiple simultaneous threads of execution, each context must be created in a different isolate.
Upvotes: 0