在制作v8 :: Function :: Call之前是否需要抓取v8 :: Locker?

时间:2016-06-25 18:31:38

标签: javascript c++ v8 embedded-v8 libv8

我使用V8执行一些自定义javascript代码,将OnUpdate函数暴露给JS世界。整体代码工作正常,但目前我关注下面代码的性能 - 是否需要抓取v8::Locker来执行任何用户定义的函数? Instruments.app显示代码在v8::Locker构造函数和析构函数中花费了太多时间 -

v8 profile

90 ms(实际代码执行中)vs~4000ms(Locker& ~Locker) - 这很荒谬,我觉得我可能做错了。

所以我的基本问题是抓住v8::Locker执行v8::Function::Call真的有必要吗?在当前状态下如果我注释掉v8::Locker,我会收到以下错误消息:

# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place

代码段:

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;
 }

1 个答案:

答案 0 :(得分:0)

如果您没有进行任何多线程处理,则永远不需要触摸v8 :: Locker。但是,只要你这么做,那么你必须在任何地方都拥有它。

一个v8 :: Locker是为了阻止来自同一个v8 :: Isolate的多个v8 :: Context同时运行。

如果您想要多个同时执行的线程,则必须在不同的隔离中创建每个上下文。