Michaël Zasso 918fe04351
deps: update V8 to 13.6.233.8
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:06:53 +02:00

227 lines
8.0 KiB
C++

// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/v8-context.h"
#include "include/v8-fast-api-calls.h"
#include "include/v8-internal.h"
#include "include/v8-local-handle.h"
#include "include/v8-persistent-handle.h"
#include "include/v8-template.h"
#include "src/base/macros.h"
#include "test/benchmarks/cpp/benchmark-utils.h"
#include "third_party/google_benchmark_chrome/src/include/benchmark/benchmark.h"
namespace {
v8::Local<v8::String> v8_str(const char* x) {
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x).ToLocalChecked();
}
class FastApiBenchmark : public v8::benchmarking::BenchmarkWithIsolate {
public:
static void RegularCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
}
static void FastCallback(v8::Local<v8::Value> receiver,
v8::FastApiCallbackOptions& options) {}
static uint32_t FastStringValueView(v8::Local<v8::Value> receiver,
v8::Local<v8::Value> value,
v8::FastApiCallbackOptions& options) {
v8::Local<v8::String> str = value.As<v8::String>();
v8::String::ValueView view(options.isolate, str);
return view.length();
}
static uint32_t FastOneByteString(v8::Local<v8::Value> receiver,
const v8::FastOneByteString& str,
v8::FastApiCallbackOptions& options) {
return str.length;
}
static void RegularString(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Local<v8::String> str = info[0].As<v8::String>();
v8::String::ValueView view(info.GetIsolate(), str);
info.GetReturnValue().Set(view.length());
}
void SetUp(::benchmark::State& state) override {
auto* isolate = v8_isolate();
v8::HandleScope handle_scope(isolate);
auto proxy_template_function = v8::FunctionTemplate::New(isolate);
auto object_template = proxy_template_function->InstanceTemplate();
{
v8::CFunction fast_callback =
v8::CFunction::Make(FastApiBenchmark::FastCallback);
object_template->Set(
isolate, "fastApiCall",
v8::FunctionTemplate::New(
isolate, FastApiBenchmark::RegularCallback,
v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 1,
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect, &fast_callback));
}
{
object_template->Set(isolate, "regularApiCall",
v8::FunctionTemplate::New(
isolate, FastApiBenchmark::RegularCallback));
}
{
v8::CFunction fast_callback =
v8::CFunction::Make(FastApiBenchmark::FastOneByteString);
object_template->Set(
isolate, "fastOneByteString",
v8::FunctionTemplate::New(
isolate, FastApiBenchmark::RegularString, v8::Local<v8::Value>(),
v8::Local<v8::Signature>(), 1, v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect, &fast_callback));
}
{
v8::CFunction fast_callback =
v8::CFunction::Make(FastApiBenchmark::FastStringValueView);
object_template->Set(
isolate, "fastStringValueView",
v8::FunctionTemplate::New(
isolate, FastApiBenchmark::RegularString, v8::Local<v8::Value>(),
v8::Local<v8::Signature>(), 1, v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect, &fast_callback));
}
{
object_template->Set(
isolate, "regularString",
v8::FunctionTemplate::New(isolate, FastApiBenchmark::RegularString));
}
v8::Local<v8::Context> context =
v8::Context::New(isolate, nullptr, object_template);
context_.Reset(isolate, context);
context->Enter();
}
void TearDown(::benchmark::State& state) override {
auto* isolate = v8_isolate();
v8::HandleScope handle_scope(isolate);
auto context = context_.Get(isolate);
context->Exit();
context_.Reset();
}
v8::Local<v8::Script> CompileBenchmarkScript(const char* source) {
v8::EscapableHandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::String> v8_source = v8_str(source);
v8::Local<v8::Script> script =
v8::Script::Compile(context, v8_source).ToLocalChecked();
return handle_scope.Escape(script);
}
protected:
v8::Local<v8::Context> v8_context() { return context_.Get(v8_isolate()); }
v8::Global<v8::Context> context_;
};
} // namespace
BENCHMARK_F(FastApiBenchmark, FastCallToEmptyCallback)(benchmark::State& st) {
const char* kScript =
"function invoke() { globalThis.fastApiCall(); }"
"\%PrepareFunctionForOptimization(invoke);"
"invoke();"
"\%OptimizeFunctionOnNextCall(invoke);"
"for (var i =0; i < 1_000_000; i++) invoke();";
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::Script> script = CompileBenchmarkScript(kScript);
v8::HandleScope benchmark_handle_scope(v8_isolate());
for (auto _ : st) {
USE(_);
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_F(FastApiBenchmark, RegularCallToEmptyCallback)
(benchmark::State& st) {
const char* kScript =
"function invoke() { globalThis.regularApiCall(); }"
"\%PrepareFunctionForOptimization(invoke);"
"invoke();"
"\%OptimizeFunctionOnNextCall(invoke);"
"for (var i =0; i < 1_000_000; i++) invoke();";
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::Script> script = CompileBenchmarkScript(kScript);
v8::HandleScope benchmark_handle_scope(v8_isolate());
for (auto _ : st) {
USE(_);
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_F(FastApiBenchmark, FastOneByteString)(benchmark::State& st) {
const char* kScript =
"function invoke() { globalThis.fastOneByteString('Hello World'); }"
"\%PrepareFunctionForOptimization(invoke);"
"invoke();"
"\%OptimizeFunctionOnNextCall(invoke);"
"for (var i =0; i < 1_000_000; i++) invoke();";
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::Script> script = CompileBenchmarkScript(kScript);
v8::HandleScope benchmark_handle_scope(v8_isolate());
for (auto _ : st) {
USE(_);
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_F(FastApiBenchmark, FastStringValueView)(benchmark::State& st) {
const char* kScript =
"function invoke() { globalThis.fastStringValueView('Hello World'); }"
"\%PrepareFunctionForOptimization(invoke);"
"invoke();"
"\%OptimizeFunctionOnNextCall(invoke);"
"for (var i =0; i < 1_000_000; i++) invoke();";
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::Script> script = CompileBenchmarkScript(kScript);
v8::HandleScope benchmark_handle_scope(v8_isolate());
for (auto _ : st) {
USE(_);
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_F(FastApiBenchmark, RegularString)(benchmark::State& st) {
const char* kScript =
"function invoke() { globalThis.regularString('Hello World'); }"
"\%PrepareFunctionForOptimization(invoke);"
"invoke();"
"\%OptimizeFunctionOnNextCall(invoke);"
"for (var i =0; i < 1_000_000; i++) invoke();";
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8_context();
v8::Local<v8::Script> script = CompileBenchmarkScript(kScript);
v8::HandleScope benchmark_handle_scope(v8_isolate());
for (auto _ : st) {
USE(_);
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
benchmark::DoNotOptimize(result);
}
}