Skip to content

Commit a3e0834

Browse files
authored
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: nodejs#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: nodejs#51551 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent ad0bcb9 commit a3e0834

File tree

5 files changed

+109
-17
lines changed

5 files changed

+109
-17
lines changed

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.12',
39+
'v8_embedder_string': '-node.13',
4040

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

deps/v8/include/v8-script.h

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

deps/v8/src/api/api.cc

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

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

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

deps/v8/test/cctest/test-serialize.cc

+72
Original file line numberDiff line numberDiff line change
@@ -2799,6 +2799,78 @@ TEST(CodeSerializerFlagChange) {
27992799
isolate2->Dispose();
28002800
}
28012801

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

0 commit comments

Comments
 (0)