【问题标题】:Can V8 perform build-time precompilation of JS code?V8 可以执行 JS 代码的构建时预编译吗?
【发布时间】:2021-04-22 16:13:28
【问题描述】:

我们正在尝试优化 JS 代码在移动设备上的启动时间并寻找机会。我发现 Facebook Hermes JS engine 是为类似目的而创建的,但我们目前严重依赖 V8。

是否可以使用 V8 完成构建时预编译,这意味着解析和代码优化将在编译时完成并在运行时节省一些时间?从源代码生成 LLVM 位码并在运行时执行位码似乎非常接近我的想象。 WASM 似乎不是一种选择(至少对于移动设备而言)。

如果可以的话,能否提供一个简单的用 V8 优化的 JS 代码的简单示例?

附言。可能它也有助于减少内存消耗,这可能是次要目标。

【问题讨论】:

    标签: javascript android v8 escape-analysis ahead-of-time-compile


    【解决方案1】:

    V8 为此目的支持heap snapshots。例如,used by the Atom editor 用于缩短启动时间。与其说是预编译,不如说是关于预构建全局环境和实例化函数(可能还没有编译,只是转换为Ignition 的字节码,这就足够了)。如果您使用的是 Electron,mksnapshot npm package 可能会很有用。 (如果没有,看看它是如何工作的可能仍然有用。)

    我没有做过任何 V8 黑客攻击,但他们从 blog post above 链接的 example 如下:

    TEST(PerIsolateSnapshotBlobs) {
      DisableTurbofan();
      const char* source1 = "function f() { return 42; }";
      const char* source2 =
          "function f() { return g() * 2; }"
          "function g() { return 43; }"
          "/./.test('a')";
      v8::StartupData data1 = v8::V8::CreateSnapshotDataBlob(source1);
      v8::StartupData data2 = v8::V8::CreateSnapshotDataBlob(source2);
      v8::Isolate::CreateParams params1;
      params1.snapshot_blob = &data1;
      params1.array_buffer_allocator = CcTest::array_buffer_allocator();
      v8::Isolate* isolate1 = v8::Isolate::New(params1);
      {
        v8::Isolate::Scope i_scope(isolate1);
        v8::HandleScope h_scope(isolate1);
        v8::Local<v8::Context> context = v8::Context::New(isolate1);
        delete[] data1.data;  // We can dispose of the snapshot blob now.
        v8::Context::Scope c_scope(context);
        CHECK_EQ(42, CompileRun("f()")->ToInt32(isolate1)->Int32Value());
        CHECK(CompileRun("this.g")->IsUndefined());
      }
      isolate1->Dispose();
      v8::Isolate::CreateParams params2;
      params2.snapshot_blob = &data2;
      params2.array_buffer_allocator = CcTest::array_buffer_allocator();
      v8::Isolate* isolate2 = v8::Isolate::New(params2);
      {
        v8::Isolate::Scope i_scope(isolate2);
        v8::HandleScope h_scope(isolate2);
        v8::Local<v8::Context> context = v8::Context::New(isolate2);
        delete[] data2.data;  // We can dispose of the snapshot blob now.
        v8::Context::Scope c_scope(context);
        CHECK_EQ(86, CompileRun("f()")->ToInt32(isolate2)->Int32Value());
        CHECK_EQ(43, CompileRun("g()")->ToInt32(isolate2)->Int32Value());
      }
      isolate2->Dispose();
    }
    

    那篇博文(以及相关的例子?)是 2015 年的,所以从那以后事情可能已经发生了变化。

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 2013-04-25
      • 1970-01-01
      • 2014-01-16
      • 2014-05-10
      • 1970-01-01
      • 2014-11-28
      • 1970-01-01
      • 2013-06-08
      相关资源
      最近更新 更多