Skip to content

Commit 2ad665e

Browse files
joyeecheungtargos
authored andcommitted
deps: V8: cherry-pick efb1133eb894
Original commit message: [api] Add v8::ScriptCompiler::CachedData::CompatibilityCheck() This patch adds a new API v8::ScriptCompiler::CachedData::CompatibilityCheck() in order to allow embedders to check if the code cache can be used in the current isolate without looking up for the source code. It also returns more detailed reasons about why the code cache cannot be used when it's bound to be rejected. This makes it possible to enforce portability checks in case code code becomes CPU-dependent in the future. Refs: #42566 (comment) Change-Id: Ia1d677b949050add961af6fbf62c44342c061312 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4905290 Reviewed-by: Marja Hölttä <[email protected]> Reviewed-by: Toon Verwaest <[email protected]> Commit-Queue: Joyee Cheung <[email protected]> Cr-Commit-Position: refs/heads/main@{#90833} Refs: v8/v8@efb1133 PR-URL: #51551 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 6603d32 commit 2ad665e

File tree

5 files changed

+109
-17
lines changed

5 files changed

+109
-17
lines changed

Diff for: common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.19',
39+
'v8_embedder_string': '-node.20',
4040

4141
##### V8 defaults for Node.js #####
4242

Diff for: deps/v8/include/v8-script.h

+21
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,27 @@ class V8_EXPORT ScriptCompiler {
388388
CachedData(const uint8_t* data, int length,
389389
BufferPolicy buffer_policy = BufferNotOwned);
390390
~CachedData();
391+
392+
enum CompatibilityCheckResult {
393+
// Don't change order/existing values of this enum since it keys into the
394+
// `code_cache_reject_reason` histogram. Append-only!
395+
kSuccess = 0,
396+
kMagicNumberMismatch = 1,
397+
kVersionMismatch = 2,
398+
kSourceMismatch = 3,
399+
kFlagsMismatch = 5,
400+
kChecksumMismatch = 6,
401+
kInvalidHeader = 7,
402+
kLengthMismatch = 8,
403+
kReadOnlySnapshotChecksumMismatch = 9,
404+
405+
// This should always point at the last real enum value.
406+
kLast = kReadOnlySnapshotChecksumMismatch
407+
};
408+
409+
// Check if the CachedData can be loaded in the given isolate.
410+
CompatibilityCheckResult CompatibilityCheck(Isolate* isolate);
411+
391412
// TODO(marja): Async compilation; add constructors which take a callback
392413
// which will be called when V8 no longer needs the data.
393414
const uint8_t* data;

Diff for: deps/v8/src/api/api.cc

+12
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,18 @@ ScriptCompiler::CachedData::~CachedData() {
19501950
}
19511951
}
19521952

1953+
ScriptCompiler::CachedData::CompatibilityCheckResult
1954+
ScriptCompiler::CachedData::CompatibilityCheck(Isolate* isolate) {
1955+
i::AlignedCachedData aligned(data, length);
1956+
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1957+
i::SerializedCodeSanityCheckResult result;
1958+
i::SerializedCodeData scd =
1959+
i::SerializedCodeData::FromCachedDataWithoutSource(
1960+
i_isolate->AsLocalIsolate(), &aligned, &result);
1961+
return static_cast<ScriptCompiler::CachedData::CompatibilityCheckResult>(
1962+
result);
1963+
}
1964+
19531965
ScriptCompiler::StreamedSource::StreamedSource(
19541966
std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
19551967
: impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}

Diff for: deps/v8/src/snapshot/code-serializer.h

+3-16
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,9 @@ class V8_EXPORT_PRIVATE AlignedCachedData {
4949
int length_;
5050
};
5151

52-
enum class SerializedCodeSanityCheckResult {
53-
// Don't change order/existing values of this enum since it keys into the
54-
// `code_cache_reject_reason` histogram. Append-only!
55-
kSuccess = 0,
56-
kMagicNumberMismatch = 1,
57-
kVersionMismatch = 2,
58-
kSourceMismatch = 3,
59-
kFlagsMismatch = 5,
60-
kChecksumMismatch = 6,
61-
kInvalidHeader = 7,
62-
kLengthMismatch = 8,
63-
kReadOnlySnapshotChecksumMismatch = 9,
64-
65-
// This should always point at the last real enum value.
66-
kLast = kReadOnlySnapshotChecksumMismatch
67-
};
52+
typedef v8::ScriptCompiler::CachedData::CompatibilityCheckResult
53+
SerializedCodeSanityCheckResult;
54+
6855
// If this fails, update the static_assert AND the code_cache_reject_reason
6956
// histogram definition.
7057
static_assert(static_cast<int>(SerializedCodeSanityCheckResult::kLast) == 9);

Diff for: deps/v8/test/cctest/test-serialize.cc

+72
Original file line numberDiff line numberDiff line change
@@ -2790,6 +2790,78 @@ TEST(CodeSerializerFlagChange) {
27902790
isolate2->Dispose();
27912791
}
27922792

2793+
TEST(CachedDataCompatibilityCheck) {
2794+
{
2795+
v8::Isolate::CreateParams create_params;
2796+
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
2797+
v8::Isolate* isolate = v8::Isolate::New(create_params);
2798+
// Hand-craft a zero-filled cached data which cannot be valid.
2799+
int length = 64;
2800+
uint8_t* payload = new uint8_t[length];
2801+
memset(payload, 0, length);
2802+
v8::ScriptCompiler::CachedData cache(
2803+
payload, length, v8::ScriptCompiler::CachedData::BufferOwned);
2804+
{
2805+
v8::Isolate::Scope iscope(isolate);
2806+
v8::ScriptCompiler::CachedData::CompatibilityCheckResult result =
2807+
cache.CompatibilityCheck(isolate);
2808+
CHECK_NE(result, v8::ScriptCompiler::CachedData::kSuccess);
2809+
}
2810+
isolate->Dispose();
2811+
}
2812+
2813+
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
2814+
std::unique_ptr<v8::ScriptCompiler::CachedData> cache;
2815+
{
2816+
v8::Isolate::CreateParams create_params;
2817+
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
2818+
v8::Isolate* isolate = v8::Isolate::New(create_params);
2819+
{
2820+
v8::Isolate::Scope iscope(isolate);
2821+
v8::HandleScope scope(isolate);
2822+
v8::Local<v8::Context> context = v8::Context::New(isolate);
2823+
v8::Context::Scope context_scope(context);
2824+
v8::ScriptCompiler::Source source(v8_str(js_source),
2825+
{isolate, v8_str("test")});
2826+
v8::Local<v8::UnboundScript> script =
2827+
v8::ScriptCompiler::CompileUnboundScript(
2828+
isolate, &source, v8::ScriptCompiler::kEagerCompile)
2829+
.ToLocalChecked();
2830+
cache.reset(ScriptCompiler::CreateCodeCache(script));
2831+
}
2832+
isolate->Dispose();
2833+
}
2834+
2835+
{
2836+
v8::Isolate::CreateParams create_params;
2837+
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
2838+
v8::Isolate* isolate = v8::Isolate::New(create_params);
2839+
{
2840+
v8::Isolate::Scope iscope(isolate);
2841+
v8::ScriptCompiler::CachedData::CompatibilityCheckResult result =
2842+
cache->CompatibilityCheck(isolate);
2843+
CHECK_EQ(result, v8::ScriptCompiler::CachedData::kSuccess);
2844+
}
2845+
isolate->Dispose();
2846+
}
2847+
2848+
{
2849+
v8_flags.allow_natives_syntax =
2850+
true; // Flag change should trigger cache reject.
2851+
FlagList::EnforceFlagImplications();
2852+
v8::Isolate::CreateParams create_params;
2853+
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
2854+
v8::Isolate* isolate = v8::Isolate::New(create_params);
2855+
{
2856+
v8::Isolate::Scope iscope(isolate);
2857+
v8::ScriptCompiler::CachedData::CompatibilityCheckResult result =
2858+
cache->CompatibilityCheck(isolate);
2859+
CHECK_EQ(result, v8::ScriptCompiler::CachedData::kFlagsMismatch);
2860+
}
2861+
isolate->Dispose();
2862+
}
2863+
}
2864+
27932865
TEST(CodeSerializerBitFlip) {
27942866
i::v8_flags.verify_snapshot_checksum = true;
27952867
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";

0 commit comments

Comments
 (0)