chore: update v8 patches for Chromium 70

This commit is contained in:
Samuel Attard 2018-10-25 13:27:11 +11:00 committed by deepak1556
parent f927398b53
commit fd442df851
23 changed files with 1533 additions and 3163 deletions

View file

@ -1,14 +1,5 @@
deps_cherry-pick_0dd3390_from_upstream_v8.patch
deps_cherry-pick_09bca09_from_upstream_v8.patch
deps_cherry-pick_c608122_from_upstream_v8.patch
deps_cherry-pick_e1a7699_from_upstream_v8.patch
deps_cherry-pick_ba752ea_from_upstream_v8.patch
deps_cherry-pick_bf5ea81_from_upstream_v8.patch
deps_cherry-pick_a8f6869_from_upstream_v8.patch
deps_backport_detailed_line_info_for_cpu_profiler.patch
deps_cherry-pick_2363cdf_from_upstream_v8.patch
deps_cherry-pick_dbfcc48_from_upstream_v8.patch
deps_add_missing_handlescope_in_fieldtype_printto.patch
add_realloc.patch
build_gn.patch
array_buffer.patch
@ -19,3 +10,8 @@ disable-warning-win.patch
expose_mksnapshot.patch
build-torque-with-x64-toolchain-on-arm.patch
do_not_run_arm_arm64_mksnapshot_binaries.patch
deps_revert_9136dd8088a9_from_upstream_v8.patch
deps_provide_more_v8_backwards_compatibility.patch
deps_backport_958b761_from_upstream_v8.patch
deps_v8_cherry-pick_64-bit_hash_seed_commits.patch
deps_cherry-pick_b0af309_from_upstream_v8.patch

View file

@ -12,10 +12,10 @@ when we override ReallocateBufferMemory, so we therefore need to implement
Realloc on the v8 side.
diff --git a/include/v8.h b/include/v8.h
index 20a65afcbc61c31360874e45adc03eeda02e9a81..6bba7a177e72b54084b2a52e413c5de6edb26b01 100644
index a83305560c2ea33d4a6247d76655e83c7a14b0ca..fa3a4dd82c0deeaddba0a84e8bf2841e04bc8483 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -4618,6 +4618,13 @@ class V8_EXPORT ArrayBuffer : public Object {
@@ -4604,6 +4604,13 @@ class V8_EXPORT ArrayBuffer : public Object {
*/
virtual void* AllocateUninitialized(size_t length) = 0;
@ -30,10 +30,10 @@ index 20a65afcbc61c31360874e45adc03eeda02e9a81..6bba7a177e72b54084b2a52e413c5de6
* Free the memory block of size |length|, pointed to by |data|.
* That memory is guaranteed to be previously allocated by |Allocate|.
diff --git a/src/api.cc b/src/api.cc
index 6155cbb32579effc500b5c475cd478e77b3ecdf4..9fe5268aa5e615fee058d430b6a137dd40fc9226 100644
index 4eb31a447c3d2dbce8ddaffb777b799ec28c2f8c..809bbe52178a3f8cbcf0b6eb81fba0910c1fb0e6 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -505,6 +505,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
@@ -508,6 +508,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
i::V8::SetSnapshotBlob(snapshot_blob);
}

View file

@ -5,10 +5,10 @@ Subject: array_buffer.patch
diff --git a/include/v8.h b/include/v8.h
index 6bba7a177e72b54084b2a52e413c5de6edb26b01..b1e192dc009b33484148817be0b0b6bb4dc1bf4b 100644
index fa3a4dd82c0deeaddba0a84e8bf2841e04bc8483..3070f4aa50eed8722805feaf8d9b9db0d68fbbbf 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -7766,6 +7766,9 @@ class V8_EXPORT Isolate {
@@ -7737,6 +7737,9 @@ class V8_EXPORT Isolate {
*/
void SetIdle(bool is_idle);
@ -19,10 +19,10 @@ index 6bba7a177e72b54084b2a52e413c5de6edb26b01..b1e192dc009b33484148817be0b0b6bb
bool InContext();
diff --git a/src/api.cc b/src/api.cc
index 9fe5268aa5e615fee058d430b6a137dd40fc9226..5c1f2410bbab4a0d9f4fcd99f19530ba999a66a2 100644
index 809bbe52178a3f8cbcf0b6eb81fba0910c1fb0e6..c1f863d148243d3988a70959fd91a37788137393 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -8290,6 +8290,13 @@ void Isolate::SetIdle(bool is_idle) {
@@ -8107,6 +8107,13 @@ void Isolate::SetIdle(bool is_idle) {
isolate->SetIdle(is_idle);
}

View file

@ -6,10 +6,10 @@ Subject: build-torque-with-x64-toolchain-on-arm.patch
torque binary has to be run during the build.
diff --git a/BUILD.gn b/BUILD.gn
index b5eb09cfcb8add19f4de985cbe7b9777c51c4bd3..dbe4338c3a733cb806e420a9bb0b4bcc65cf333b 100644
index c1b08958b500da1910a8067198cdec7650534f20..78e672e18eff27a3777bd0c0adc94e88a6eb126a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -899,7 +899,8 @@ action("run_torque") {
@@ -914,7 +914,8 @@ action("run_torque") {
# is the target toolchain and, hence, can't be used.
v8_torque_toolchain = v8_snapshot_toolchain
if (host_cpu == "x64" &&
@ -19,7 +19,7 @@ index b5eb09cfcb8add19f4de985cbe7b9777c51c4bd3..dbe4338c3a733cb806e420a9bb0b4bcc
v8_torque_toolchain = "//build/toolchain/linux:clang_x64"
}
@@ -3149,7 +3150,7 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
@@ -3256,7 +3257,7 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
}
}

View file

@ -5,10 +5,10 @@ Subject: build_gn.patch
diff --git a/BUILD.gn b/BUILD.gn
index 443694d88075d59d6e8db7fa4bedc3a812fdafc4..d0ba5ed04e7126deae4a0ab9ee8943cda5ea42e3 100644
index c6a58776cd6a81cf5653b94a8db1a04dd7e54045..ac74cdec115b6cc54d05817f063153628cf5e9fe 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -212,7 +212,7 @@ config("internal_config") {
@@ -221,7 +221,7 @@ config("internal_config") {
defines = []
@ -17,7 +17,7 @@ index 443694d88075d59d6e8db7fa4bedc3a812fdafc4..d0ba5ed04e7126deae4a0ab9ee8943cd
defines += [ "BUILDING_V8_SHARED" ]
}
}
@@ -3138,6 +3138,8 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
@@ -3245,6 +3245,8 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
configs = [ ":internal_config" ]

View file

@ -5,10 +5,10 @@ Subject: dcheck.patch
diff --git a/src/api.cc b/src/api.cc
index 5c1f2410bbab4a0d9f4fcd99f19530ba999a66a2..b464a2187c162bac00620f65e9c94deeaf3d6c95 100644
index c1f863d148243d3988a70959fd91a37788137393..8dca7ec88e59c775da5cf7e30721d064f349c634 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -8851,7 +8851,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
@@ -8649,7 +8649,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
void Isolate::RunMicrotasks() {
@ -18,10 +18,10 @@ index 5c1f2410bbab4a0d9f4fcd99f19530ba999a66a2..b464a2187c162bac00620f65e9c94dee
}
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 6830a90482173174266faa0e9a95618c67fad811..78991a26de6d97e3ee14b66913fc079a795b299d 100644
index 2ec30635be2b75fe1e308068b6e16b9568472ead..7058396f3009fec5635a01961368ab14c287d882 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -5006,9 +5006,9 @@ void Heap::TearDown() {
@@ -5035,9 +5035,9 @@ void Heap::TearDown() {
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
GCType gc_type, void* data) {
DCHECK_NOT_NULL(callback);

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yang Guo <yangguo@chromium.org>
Date: Mon, 17 Sep 2018 07:43:46 +0200
Subject: deps: add missing HandleScope in FieldType::PrintTo
Refs: https://github.com/nodejs/node/issues/22775
PR-URL: https://github.com/nodejs/node/pull/22890
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Refael Ackermann <refack@gmail.com>
diff --git a/src/field-type.cc b/src/field-type.cc
index 3b51095323c06bf8883ce484566fd263249390ac..2eebebe3d616ea786ed60cd0e9bea853ea764c7b 100644
--- a/src/field-type.cc
+++ b/src/field-type.cc
@@ -78,6 +78,7 @@ void FieldType::PrintTo(std::ostream& os) {
os << "None";
} else {
DCHECK(IsClass());
+ HandleScope scope(Map::cast(this)->GetIsolate());
os << "Class(" << static_cast<void*>(*AsClass()) << ")";
}
}

View file

@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matheus Marchini <mat@mmarchini.me>
Date: Mon, 17 Sep 2018 16:22:59 -0300
Subject: deps: backport 958b761 from upstream V8
Original commit message:
[postmortem] add postmortem metadata for symbols
As discussed in https://github.com/nodejs/llnode/issues/156, we need
postmortem metadata for Symbols to properly print Symbol property
names in postmortem debugging tools. Patch suggested by Ben
Noordhuis
(https://github.com/nodejs/llnode/issues/156#issuecomment-350467852).
R=bmeurer@google.com, yangguo@google.com
Change-Id: Ied6d3c079e8b23a9c796bc632c37785ed7dbc118
Reviewed-on: https://chromium-review.googlesource.com/1205052
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55632}
Refs: https://github.com/v8/v8/commit/958b761d3392495c3bf635e97fb9bd0e45
PR-URL: https://github.com/nodejs/node/pull/22914
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/BUILD.gn b/BUILD.gn
index 78e672e18eff27a3777bd0c0adc94e88a6eb126a..ab185573cdfb788b4e6bb0e2f582d7f36d17fadc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -865,6 +865,8 @@ action("postmortem-metadata") {
"src/objects/js-regexp-string-iterator.h",
"src/objects/map.h",
"src/objects/map-inl.h",
+ "src/objects/name.h",
+ "src/objects/name-inl.h",
"src/objects/scope-info.h",
"src/objects/script.h",
"src/objects/script-inl.h",
diff --git a/tools/gen-postmortem-metadata.py b/tools/gen-postmortem-metadata.py
index 8191c8152f5942858cc3a305bdee72d74c4e55e9..9bc1dd66d599f4c5ad8b2c775b145ee0f9cde8f0 100644
--- a/tools/gen-postmortem-metadata.py
+++ b/tools/gen-postmortem-metadata.py
@@ -417,15 +417,10 @@ def load_objects_from_file(objfilename, checktypes):
# way around.
#
for type in types:
- #
- # Symbols and Strings are implemented using the same classes.
- #
- usetype = re.sub('SYMBOL_', 'STRING_', type);
-
#
# REGEXP behaves like REG_EXP, as in JS_REGEXP_TYPE => JSRegExp.
#
- usetype = re.sub('_REGEXP_', '_REG_EXP_', usetype);
+ usetype = re.sub('_REGEXP_', '_REG_EXP_', type);
#
# Remove the "_TYPE" suffix and then convert to camel case,

View file

@ -20,57 +20,15 @@ Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 052869f3081ed662ced727778fefe11231aae6e5..4d5aa6f885465865e0b29c0cd26bcca41571f0bd 100644
index 69ec7472bba0f9a04b32c1ce135083cc82456b0a..4f8b5780c832d2faf27340cffe32b298e3b0b04d 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -1243,6 +1243,9 @@ DEFINE_BOOL(log_function_events, false,
@@ -1267,7 +1267,7 @@ DEFINE_BOOL(log_function_events, false,
DEFINE_BOOL(prof, false,
"Log statistical profiling information (implies --log-code).")
-DEFINE_BOOL(detailed_line_info, false,
+DEFINE_BOOL(detailed_line_info, true,
+ "Always generate detailed line information for CPU profiling.")
+
"Always generate detailed line information for CPU profiling.")
#if defined(ANDROID)
// Phones and tablets have processors that are much slower than desktop
// and laptop computers for which current heuristics are tuned.
diff --git a/src/isolate.cc b/src/isolate.cc
index b0a970305e9d4df8257d1e2a29c79d134896b220..b33b713672a6d471652a1b9c1fc508f15278e1cb 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -3247,6 +3247,10 @@ bool Isolate::use_optimizer() {
!is_precise_count_code_coverage() && !is_block_count_code_coverage();
}
+bool Isolate::NeedsDetailedOptimizedCodeLineInfo() const {
+ return NeedsSourcePositionsForProfiling() || FLAG_detailed_line_info;
+}
+
bool Isolate::NeedsSourcePositionsForProfiling() const {
return FLAG_trace_deopt || FLAG_trace_turbo || FLAG_trace_turbo_graph ||
FLAG_turbo_profiling || FLAG_perf_prof || is_profiling() ||
diff --git a/src/isolate.h b/src/isolate.h
index 09aaf996849017c8626118a2cae8adec1ca18c2d..d94c0fde147f50764171c5a2896921c9811fd0b3 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1044,6 +1044,8 @@ class Isolate : private HiddenFactory {
bool NeedsSourcePositionsForProfiling() const;
+ bool NeedsDetailedOptimizedCodeLineInfo() const;
+
bool is_best_effort_code_coverage() const {
return code_coverage_mode() == debug::Coverage::kBestEffort;
}
diff --git a/src/optimized-compilation-info.cc b/src/optimized-compilation-info.cc
index 09b8a0edeae734d5ad9df8666c2bee4cdcebb3f1..77730919f14dc2545b88d140478d7ac05e6db0b0 100644
--- a/src/optimized-compilation-info.cc
+++ b/src/optimized-compilation-info.cc
@@ -38,7 +38,7 @@ OptimizedCompilationInfo::OptimizedCompilationInfo(
// Collect source positions for optimized code when profiling or if debugger
// is active, to be able to get more precise source positions at the price of
// more memory consumption.
- if (isolate->NeedsSourcePositionsForProfiling()) {
+ if (isolate->NeedsDetailedOptimizedCodeLineInfo()) {
MarkAsSourcePositionsEnabled();
}

View file

@ -1,62 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matheus Marchini <matheus@sthima.com>
Date: Wed, 1 Aug 2018 15:09:51 -0300
Subject: deps: cherry-pick 09bca09 from upstream V8
Original commit message:
[postmortem] add ScopeInfo and Context types
The metadata introduced in this patch will be useful for postmortem
tools to inspect Contexts and ScopeInfos (see
https://github.com/nodejs/llnode/issues/211).
R=bmeurer@google.com, yangguo@google.com
Change-Id: I927fcab4014d128bd782046c1ecb9ee045723e95
Reviewed-on: https://chromium-review.googlesource.com/1153858
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54768}
Refs: https://github.com/v8/v8/commit/09bca095e38d6e4770ae48e174f59d33c
PR-URL: https://github.com/nodejs/node/pull/22068
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
diff --git a/BUILD.gn b/BUILD.gn
index 4c8c8acd593c8151798a5187c44f56fee3f07977..443694d88075d59d6e8db7fa4bedc3a812fdafc4 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -852,6 +852,7 @@ action("postmortem-metadata") {
"src/objects/js-regexp-string-iterator.h",
"src/objects/map.h",
"src/objects/map-inl.h",
+ "src/objects/scope-info.h",
"src/objects/script.h",
"src/objects/script-inl.h",
"src/objects/shared-function-info.h",
diff --git a/tools/gen-postmortem-metadata.py b/tools/gen-postmortem-metadata.py
index d8ef7b4a158a9c6d5d157169defb47bb82683023..8191c8152f5942858cc3a305bdee72d74c4e55e9 100644
--- a/tools/gen-postmortem-metadata.py
+++ b/tools/gen-postmortem-metadata.py
@@ -58,6 +58,9 @@ consts_misc = [
{ 'name': 'APIObjectType', 'value': 'JS_API_OBJECT_TYPE' },
{ 'name': 'SpecialAPIObjectType', 'value': 'JS_SPECIAL_API_OBJECT_TYPE' },
+ { 'name': 'FirstContextType', 'value': 'FIRST_CONTEXT_TYPE' },
+ { 'name': 'LastContextType', 'value': 'LAST_CONTEXT_TYPE' },
+
{ 'name': 'IsNotStringMask', 'value': 'kIsNotStringMask' },
{ 'name': 'StringTag', 'value': 'kStringTag' },
@@ -282,7 +285,7 @@ extras_accessors = [
expected_classes = [
'ConsString', 'FixedArray', 'HeapNumber', 'JSArray', 'JSFunction',
'JSObject', 'JSRegExp', 'JSValue', 'Map', 'Oddball', 'Script',
- 'SeqOneByteString', 'SharedFunctionInfo'
+ 'SeqOneByteString', 'SharedFunctionInfo', 'ScopeInfo'
];

View file

@ -1,495 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Wed, 25 Jul 2018 20:03:35 +0200
Subject: deps: cherry-pick 0dd3390 from upstream V8
Original commit message:
Reland "[builtins] Add %IsTraceCategoryEnabled and %Trace builtins"
This is a reland of 8d4572a22b5d2fa0547195bcc40baa18b7565386
Original change's description:
> [builtins] Add %IsTraceCategoryEnabled and %Trace builtins
>
> Adds the builtin Trace and IsTraceCategoryEnabled functions
> exposed via extra bindings. These are intended to use by
> embedders to allow basic trace event support from JavaScript.
>
> ```js
> isTraceCategoryEnabled('v8.some-category')
>
> trace('e'.charCodeAt(0), 'v8.some-category',
> 'Foo', 0, { abc: 'xyz'})
> ```
>
> Bug: v8:7851
> Change-Id: I7bfb9bb059efdf87d92a56a0aae326650730c250
> Reviewed-on: https://chromium-review.googlesource.com/1103294
> Commit-Queue: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Fadi Meawad <fmeawad@chromium.org>
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#54121}
TBR=cbruni@chromium.org
Bug: v8:7851
Change-Id: Id063754b2834b3b6a2b2654e76e8637bcd6aa5f8
Reviewed-on: https://chromium-review.googlesource.com/1137071
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54532}
Refs: https://github.com/v8/v8/commit/0dd33901a16c7c64290b7e7ddf13945b773c5d79
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/AUTHORS b/AUTHORS
index b9391a0d28499985ae6a5b93394c6d5afc9ea1cd..3873f0ca6816ef28dbbaf63944d66f278c9aff4b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -87,6 +87,7 @@ Jan de Mooij <jandemooij@gmail.com>
Jan Krems <jan.krems@gmail.com>
Jay Freeman <saurik@saurik.com>
James Pike <g00gle@chilon.net>
+James M Snell <jasnell@gmail.com>
Jianghua Yang <jianghua.yjh@alibaba-inc.com>
Joel Stanley <joel@jms.id.au>
Johan Bergström <johan@bergstroem.nu>
diff --git a/BUILD.gn b/BUILD.gn
index 1e31acb2771e6e4137524ff4ae6a9e962092cd90..4c8c8acd593c8151798a5187c44f56fee3f07977 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1588,6 +1588,7 @@ v8_source_set("v8_base") {
"src/builtins/builtins-sharedarraybuffer.cc",
"src/builtins/builtins-string.cc",
"src/builtins/builtins-symbol.cc",
+ "src/builtins/builtins-trace.cc",
"src/builtins/builtins-typed-array.cc",
"src/builtins/builtins-utils.h",
"src/builtins/builtins.cc",
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 6723f3d5d463327cada8477626562a3c27c3e69f..656650cd6498dd82de02e583f5b83ae04a58b0e7 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -5077,6 +5077,15 @@ bool Genesis::InstallExtraNatives() {
Handle<JSObject> extras_binding =
factory()->NewJSObject(isolate()->object_function());
+
+ // binding.isTraceCategoryEnabled(category)
+ SimpleInstallFunction(isolate(), extras_binding, "isTraceCategoryEnabled",
+ Builtins::kIsTraceCategoryEnabled, 1, true);
+
+ // binding.trace(phase, category, name, id, data)
+ SimpleInstallFunction(isolate(), extras_binding, "trace", Builtins::kTrace, 5,
+ true);
+
native_context()->set_extras_binding_object(*extras_binding);
for (int i = ExtraNatives::GetDebuggerCount();
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
index 46b02d88d817199620f02afdac753f12f4829e8f..2d7c780c709c55da93797e45e4352598745d0fd0 100644
--- a/src/builtins/builtins-definitions.h
+++ b/src/builtins/builtins-definitions.h
@@ -1308,7 +1308,11 @@ namespace internal {
ASM(CallApiGetter) \
ASM(DoubleToI) \
TFC(GetProperty, GetProperty, 1) \
- ASM(MathPowInternal)
+ ASM(MathPowInternal) \
+ \
+ /* Trace */ \
+ CPP(IsTraceCategoryEnabled) \
+ CPP(Trace)
#ifdef V8_INTL_SUPPORT
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
diff --git a/src/builtins/builtins-trace.cc b/src/builtins/builtins-trace.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cd0f5a77d0a6177069bfa0bd83515f9ded92b491
--- /dev/null
+++ b/src/builtins/builtins-trace.cc
@@ -0,0 +1,191 @@
+// Copyright 2018 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 "src/api.h"
+#include "src/builtins/builtins-utils.h"
+#include "src/builtins/builtins.h"
+#include "src/counters.h"
+#include "src/json-stringifier.h"
+#include "src/objects-inl.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+using v8::tracing::TracedValue;
+
+#define MAX_STACK_LENGTH 100
+
+class MaybeUtf8 {
+ public:
+ explicit MaybeUtf8(Isolate* isolate, Handle<String> string) : buf_(data_) {
+ string = String::Flatten(isolate, string);
+ int len;
+ if (string->IsOneByteRepresentation()) {
+ // Technically this allows unescaped latin1 characters but the trace
+ // events mechanism currently does the same and the current consuming
+ // tools are tolerant of it. A more correct approach here would be to
+ // escape non-ascii characters but this is easier and faster.
+ len = string->length();
+ AllocateSufficientSpace(len);
+ if (len > 0) {
+ // Why copy? Well, the trace event mechanism requires null-terminated
+ // strings, the bytes we get from SeqOneByteString are not. buf_ is
+ // guaranteed to be null terminated.
+ memcpy(buf_, Handle<SeqOneByteString>::cast(string)->GetChars(), len);
+ }
+ } else {
+ Local<v8::String> local = Utils::ToLocal(string);
+ len = local->Utf8Length();
+ AllocateSufficientSpace(len);
+ if (len > 0) {
+ local->WriteUtf8(reinterpret_cast<char*>(buf_));
+ }
+ }
+ buf_[len] = 0;
+ }
+ const char* operator*() const { return reinterpret_cast<const char*>(buf_); }
+
+ private:
+ void AllocateSufficientSpace(int len) {
+ if (len + 1 > MAX_STACK_LENGTH) {
+ allocated_.reset(new uint8_t[len + 1]);
+ buf_ = allocated_.get();
+ }
+ }
+
+ // In the most common cases, the buffer here will be stack allocated.
+ // A heap allocation will only occur if the data is more than MAX_STACK_LENGTH
+ // Given that this is used primarily for trace event categories and names,
+ // the MAX_STACK_LENGTH should be more than enough.
+ uint8_t* buf_;
+ uint8_t data_[MAX_STACK_LENGTH];
+ std::unique_ptr<uint8_t> allocated_;
+};
+
+class JsonTraceValue : public ConvertableToTraceFormat {
+ public:
+ explicit JsonTraceValue(Isolate* isolate, Handle<String> object) {
+ // object is a JSON string serialized using JSON.stringify() from within
+ // the BUILTIN(Trace) method. This may (likely) contain UTF8 values so
+ // to grab the appropriate buffer data we have to serialize it out. We
+ // hold on to the bits until the AppendAsTraceFormat method is called.
+ MaybeUtf8 data(isolate, object);
+ data_ = *data;
+ }
+
+ void AppendAsTraceFormat(std::string* out) const override { *out += data_; }
+
+ private:
+ std::string data_;
+};
+
+const uint8_t* GetCategoryGroupEnabled(Isolate* isolate,
+ Handle<String> string) {
+ MaybeUtf8 category(isolate, string);
+ return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(*category);
+}
+
+#undef MAX_STACK_LENGTH
+
+} // namespace
+
+// Builins::kIsTraceCategoryEnabled(category) : bool
+BUILTIN(IsTraceCategoryEnabled) {
+ HandleScope scope(isolate);
+ Handle<Object> category = args.atOrUndefined(isolate, 1);
+ if (!category->IsString()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
+ }
+ return isolate->heap()->ToBoolean(
+ *GetCategoryGroupEnabled(isolate, Handle<String>::cast(category)));
+}
+
+// Builtins::kTrace(phase, category, name, id, data) : bool
+BUILTIN(Trace) {
+ HandleScope handle_scope(isolate);
+
+ Handle<Object> phase_arg = args.atOrUndefined(isolate, 1);
+ Handle<Object> category = args.atOrUndefined(isolate, 2);
+ Handle<Object> name_arg = args.atOrUndefined(isolate, 3);
+ Handle<Object> id_arg = args.atOrUndefined(isolate, 4);
+ Handle<Object> data_arg = args.atOrUndefined(isolate, 5);
+
+ const uint8_t* category_group_enabled =
+ GetCategoryGroupEnabled(isolate, Handle<String>::cast(category));
+
+ // Exit early if the category group is not enabled.
+ if (!*category_group_enabled) {
+ return ReadOnlyRoots(isolate).false_value();
+ }
+
+ if (!phase_arg->IsNumber()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventPhaseError));
+ }
+ if (!category->IsString()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
+ }
+ if (!name_arg->IsString()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventNameError));
+ }
+
+ uint32_t flags = TRACE_EVENT_FLAG_COPY;
+ int32_t id = 0;
+ if (!id_arg->IsNullOrUndefined(isolate)) {
+ if (!id_arg->IsNumber()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventIDError));
+ }
+ flags |= TRACE_EVENT_FLAG_HAS_ID;
+ id = DoubleToInt32(id_arg->Number());
+ }
+
+ Handle<String> name_str = Handle<String>::cast(name_arg);
+ if (name_str->length() == 0) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kTraceEventNameLengthError));
+ }
+ MaybeUtf8 name(isolate, name_str);
+
+ // We support passing one additional trace event argument with the
+ // name "data". Any JSON serializable value may be passed.
+ static const char* arg_name = "data";
+ int32_t num_args = 0;
+ uint8_t arg_type;
+ uint64_t arg_value;
+
+ if (!data_arg->IsUndefined(isolate)) {
+ // Serializes the data argument as a JSON string, which is then
+ // copied into an object. This eliminates duplicated code but
+ // could have perf costs. It is also subject to all the same
+ // limitations as JSON.stringify() as it relates to circular
+ // references and value limitations (e.g. BigInt is not supported).
+ JsonStringifier stringifier(isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ stringifier.Stringify(data_arg, isolate->factory()->undefined_value(),
+ isolate->factory()->undefined_value()));
+ std::unique_ptr<JsonTraceValue> traced_value;
+ traced_value.reset(
+ new JsonTraceValue(isolate, Handle<String>::cast(result)));
+ tracing::SetTraceValue(std::move(traced_value), &arg_type, &arg_value);
+ num_args++;
+ }
+
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ static_cast<char>(DoubleToInt32(phase_arg->Number())),
+ category_group_enabled, *name, tracing::kGlobalScope, id, tracing::kNoId,
+ num_args, &arg_name, &arg_type, &arg_value, flags);
+
+ return ReadOnlyRoots(isolate).true_value();
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/src/debug/debug-evaluate.cc b/src/debug/debug-evaluate.cc
index 0dd23037723ff4ebf1158f7ecd4f813ed53e18e0..d263fa45a9a4ea3f2604f8c47085a39963c12a91 100644
--- a/src/debug/debug-evaluate.cc
+++ b/src/debug/debug-evaluate.cc
@@ -567,6 +567,9 @@ DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
case Builtins::kArrayMap:
case Builtins::kArrayReduce:
case Builtins::kArrayReduceRight:
+ // Trace builtins.
+ case Builtins::kIsTraceCategoryEnabled:
+ case Builtins::kTrace:
// TypedArray builtins.
case Builtins::kTypedArrayConstructor:
case Builtins::kTypedArrayPrototypeBuffer:
diff --git a/src/messages.h b/src/messages.h
index 1d1a07d7b696f32e7c7d56fceda4739bdf30b8ea..68078bb3736023e688a764709566bbc334e77791 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -757,7 +757,14 @@ class ErrorUtils : public AllStatic {
T(DataCloneDeserializationError, "Unable to deserialize cloned data.") \
T(DataCloneDeserializationVersionError, \
"Unable to deserialize cloned data due to invalid or unsupported " \
- "version.")
+ "version.") \
+ /* Builtins-Trace Errors */ \
+ T(TraceEventCategoryError, "Trace event category must be a string.") \
+ T(TraceEventNameError, "Trace event name must be a string.") \
+ T(TraceEventNameLengthError, \
+ "Trace event name must not be an empty string.") \
+ T(TraceEventPhaseError, "Trace event phase must be a number.") \
+ T(TraceEventIDError, "Trace event id must be a number.")
class MessageTemplate {
public:
diff --git a/test/cctest/test-trace-event.cc b/test/cctest/test-trace-event.cc
index 7b736b907dd9aebc8c0c505ce5a6542b79050c69..47545af37f89c0fcd648293a5bb1c70a5e6360b0 100644
--- a/test/cctest/test-trace-event.cc
+++ b/test/cctest/test-trace-event.cc
@@ -75,7 +75,7 @@ class MockTracingController : public v8::TracingController {
const char* name, uint64_t handle) override {}
const uint8_t* GetCategoryGroupEnabled(const char* name) override {
- if (strcmp(name, "v8-cat")) {
+ if (strncmp(name, "v8-cat", 6)) {
static uint8_t no = 0;
return &no;
} else {
@@ -282,3 +282,135 @@ TEST(TestEventWithTimestamp) {
CHECK_EQ(20683, GET_TRACE_OBJECT(3)->timestamp);
CHECK_EQ(32832, GET_TRACE_OBJECT(4)->timestamp);
}
+
+TEST(BuiltinsIsTraceCategoryEnabled) {
+ CcTest::InitializeVM();
+ MockTracingPlatform platform;
+
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
+ CHECK(!binding.IsEmpty());
+
+ auto undefined = v8::Undefined(isolate);
+ auto isTraceCategoryEnabled =
+ binding->Get(env.local(), v8_str("isTraceCategoryEnabled"))
+ .ToLocalChecked()
+ .As<v8::Function>();
+
+ {
+ // Test with an enabled category
+ v8::Local<v8::Value> argv[] = {v8_str("v8-cat")};
+ auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(result->BooleanValue());
+ }
+
+ {
+ // Test with a disabled category
+ v8::Local<v8::Value> argv[] = {v8_str("cat")};
+ auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(!result->BooleanValue());
+ }
+
+ {
+ // Test with an enabled utf8 category
+ v8::Local<v8::Value> argv[] = {v8_str("v8-cat\u20ac")};
+ auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(result->BooleanValue());
+ }
+}
+
+TEST(BuiltinsTrace) {
+ CcTest::InitializeVM();
+ MockTracingPlatform platform;
+
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
+ CHECK(!binding.IsEmpty());
+
+ auto undefined = v8::Undefined(isolate);
+ auto trace = binding->Get(env.local(), v8_str("trace"))
+ .ToLocalChecked()
+ .As<v8::Function>();
+
+ // Test with disabled category
+ {
+ v8::Local<v8::String> category = v8_str("cat");
+ v8::Local<v8::String> name = v8_str("name");
+ v8::Local<v8::Value> argv[] = {
+ v8::Integer::New(isolate, 'b'), // phase
+ category, name, v8::Integer::New(isolate, 0), // id
+ undefined // data
+ };
+ auto result = trace->Call(env.local(), undefined, 5, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(!result->BooleanValue());
+ CHECK_EQ(0, GET_TRACE_OBJECTS_LIST->size());
+ }
+
+ // Test with enabled category
+ {
+ v8::Local<v8::String> category = v8_str("v8-cat");
+ v8::Local<v8::String> name = v8_str("name");
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Object> data = v8::Object::New(isolate);
+ data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
+ v8::Local<v8::Value> argv[] = {
+ v8::Integer::New(isolate, 'b'), // phase
+ category, name, v8::Integer::New(isolate, 123), // id
+ data // data arg
+ };
+ auto result = trace->Call(env.local(), undefined, 5, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(result->BooleanValue());
+ CHECK_EQ(1, GET_TRACE_OBJECTS_LIST->size());
+
+ CHECK_EQ(123, GET_TRACE_OBJECT(0)->id);
+ CHECK_EQ('b', GET_TRACE_OBJECT(0)->phase);
+ CHECK_EQ("name", GET_TRACE_OBJECT(0)->name);
+ CHECK_EQ(1, GET_TRACE_OBJECT(0)->num_args);
+ }
+
+ // Test with enabled utf8 category
+ {
+ v8::Local<v8::String> category = v8_str("v8-cat\u20ac");
+ v8::Local<v8::String> name = v8_str("name\u20ac");
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::Object> data = v8::Object::New(isolate);
+ data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
+ v8::Local<v8::Value> argv[] = {
+ v8::Integer::New(isolate, 'b'), // phase
+ category, name, v8::Integer::New(isolate, 123), // id
+ data // data arg
+ };
+ auto result = trace->Call(env.local(), undefined, 5, argv)
+ .ToLocalChecked()
+ .As<v8::Boolean>();
+
+ CHECK(result->BooleanValue());
+ CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->size());
+
+ CHECK_EQ(123, GET_TRACE_OBJECT(1)->id);
+ CHECK_EQ('b', GET_TRACE_OBJECT(1)->phase);
+ CHECK_EQ("name\u20ac", GET_TRACE_OBJECT(1)->name);
+ CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
+ }
+}

View file

@ -23,10 +23,10 @@ Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
diff --git a/src/libplatform/tracing/tracing-controller.cc b/src/libplatform/tracing/tracing-controller.cc
index b4aa7baf724d4f29b4df08f3b57fdc018f6a32a7..e0a6a1234c597071b327d051c7da1d2b784529e5 100644
index daaebc291a5a3f566fcd65cfcced0f5c3725fe08..aa8789fa07c167ecce97dd787782ce684d3a7c38 100644
--- a/src/libplatform/tracing/tracing-controller.cc
+++ b/src/libplatform/tracing/tracing-controller.cc
@@ -63,13 +63,15 @@ uint64_t TracingController::AddTraceEvent(
@@ -77,13 +77,15 @@ uint64_t TracingController::AddTraceEvent(
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
@ -49,7 +49,7 @@ index b4aa7baf724d4f29b4df08f3b57fdc018f6a32a7..e0a6a1234c597071b327d051c7da1d2b
}
return handle;
}
@@ -81,13 +83,15 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
@@ -95,13 +97,15 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int64_t timestamp) {

View file

@ -1,303 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Tue, 4 Sep 2018 21:24:34 +0200
Subject: deps: cherry-pick a8f6869 from upstream V8
Original commit message:
[debug] Fully implement Debug::ArchiveDebug and Debug::RestoreDebug.
I have a project that embeds V8 and uses a single `Isolate` from multiple
threads. The program runs just fine, but sometimes the inspector doesn't
stop on the correct line after stepping over a statement that switches
threads behind the scenes, even though the original thread is restored by
the time the next statement is executed.
After some digging, I discovered that the `Debug::ArchiveDebug` and
`Debug::RestoreDebug` methods, which should be responsible for
saving/restoring this `ThreadLocal` information when switching threads,
currently don't do anything.
This commit implements those methods using MemCopy, in the style of other
Archive/Restore methods in the V8 codebase.
Related: https://groups.google.com/forum/#!topic/v8-users/_Qf2rwljRk8
Note: I believe my employer, Meteor Development Group, has previously
signed the CLA using the group email address google-contrib@meteor.com.
R=yangguo@chromium.org,jgruber@chromium.org
CC=info@bnoordhuis.nl
Bug: v8:7230
Change-Id: Id517c873eb81cd53f7216c7efd441b956cf7f943
Reviewed-on: https://chromium-review.googlesource.com/833260
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54902}
Refs: https://github.com/v8/v8/commit/a8f6869177685cfb9c199c454a86f4698c260515
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/AUTHORS b/AUTHORS
index 3873f0ca6816ef28dbbaf63944d66f278c9aff4b..6179e2230d8011025fa3202327071c5b05fee86f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,6 +32,7 @@ Facebook, Inc. <*@fb.com>
Facebook, Inc. <*@oculus.com>
Vewd Software AS <*@vewd.com>
Groupon <*@groupon.com>
+Meteor Development Group <*@meteor.com>
Cloudflare, Inc. <*@cloudflare.com>
Aaron Bieber <deftly@gmail.com>
@@ -49,6 +50,7 @@ Andrei Kashcha <anvaka@gmail.com>
Anna Henningsen <anna@addaleax.net>
Bangfu Tao <bangfu.tao@samsung.com>
Ben Coe <ben@npmjs.com>
+Ben Newman <ben@meteor.com>
Ben Noordhuis <info@bnoordhuis.nl>
Benjamin Tan <demoneaux@gmail.com>
Bert Belder <bertbelder@gmail.com>
diff --git a/src/debug/debug.cc b/src/debug/debug.cc
index 47de9523a50f84bdcf88d35bed7a3602a160b6cd..3877f156efac34279a9f55c0d335468330867380 100644
--- a/src/debug/debug.cc
+++ b/src/debug/debug.cc
@@ -355,19 +355,31 @@ void Debug::ThreadInit() {
char* Debug::ArchiveDebug(char* storage) {
- // Simply reset state. Don't archive anything.
- ThreadInit();
+ MemCopy(storage, reinterpret_cast<char*>(&thread_local_),
+ ArchiveSpacePerThread());
return storage + ArchiveSpacePerThread();
}
-
char* Debug::RestoreDebug(char* storage) {
- // Simply reset state. Don't restore anything.
- ThreadInit();
+ MemCopy(reinterpret_cast<char*>(&thread_local_), storage,
+ ArchiveSpacePerThread());
+
+ // Enter the debugger.
+ DebugScope debug_scope(this);
+
+ // Clear any one-shot breakpoints that may have been set by the other
+ // thread, and reapply breakpoints for this thread.
+ ClearOneShot();
+
+ if (thread_local_.last_step_action_ != StepNone) {
+ // Reset the previous step action for this thread.
+ PrepareStep(thread_local_.last_step_action_);
+ }
+
return storage + ArchiveSpacePerThread();
}
-int Debug::ArchiveSpacePerThread() { return 0; }
+int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
void Debug::Iterate(RootVisitor* v) {
v->VisitRootPointer(Root::kDebug, nullptr, &thread_local_.return_value_);
diff --git a/src/debug/debug.h b/src/debug/debug.h
index 31881fe10696abdfc01b4503f78e3778e6297392..13844769c1434955b8c65b762cce771a360cc7f5 100644
--- a/src/debug/debug.h
+++ b/src/debug/debug.h
@@ -314,6 +314,7 @@ class Debug {
static int ArchiveSpacePerThread();
void FreeThreadResources() { }
void Iterate(RootVisitor* v);
+ void InitThread(const ExecutionAccess& lock) { ThreadInit(); }
bool CheckExecutionState() { return is_active() && break_id() != 0; }
diff --git a/src/v8threads.cc b/src/v8threads.cc
index db927010ef174916921d5ee03b1f2d1df3269e8a..0fb333c1f37572e688560aa7de7f6e478364b6b6 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -45,7 +45,7 @@ void Locker::Initialize(v8::Isolate* isolate) {
} else {
internal::ExecutionAccess access(isolate_);
isolate_->stack_guard()->ClearThread(access);
- isolate_->stack_guard()->InitThread(access);
+ isolate_->thread_manager()->InitThread(access);
}
}
DCHECK(isolate_->thread_manager()->IsLockedByCurrentThread());
@@ -95,6 +95,10 @@ Unlocker::~Unlocker() {
namespace internal {
+void ThreadManager::InitThread(const ExecutionAccess& lock) {
+ isolate_->stack_guard()->InitThread(lock);
+ isolate_->debug()->InitThread(lock);
+}
bool ThreadManager::RestoreThread() {
DCHECK(IsLockedByCurrentThread());
@@ -127,7 +131,7 @@ bool ThreadManager::RestoreThread() {
isolate_->FindPerThreadDataForThisThread();
if (per_thread == nullptr || per_thread->thread_state() == nullptr) {
// This is a new thread.
- isolate_->stack_guard()->InitThread(access);
+ InitThread(access);
return false;
}
ThreadState* state = per_thread->thread_state();
diff --git a/src/v8threads.h b/src/v8threads.h
index bb87afea7d849766e913fbd137142d0d0144ad55..7fde0c9ec494e77dbbcf8bdbeb3817ab1a9d4c00 100644
--- a/src/v8threads.h
+++ b/src/v8threads.h
@@ -67,6 +67,7 @@ class ThreadManager {
void Lock();
void Unlock();
+ void InitThread(const ExecutionAccess&);
void ArchiveThread();
bool RestoreThread();
void FreeThreadResources();
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d3c10822ffe49f46ab829aa0ab1e035c4393fa1e..7430fbf06b802e54233edfb94196a806e2b68d6b 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -3717,6 +3717,133 @@ TEST(DebugBreakOffThreadTerminate) {
CHECK(try_catch.HasTerminated());
}
+class ArchiveRestoreThread : public v8::base::Thread,
+ public v8::debug::DebugDelegate {
+ public:
+ ArchiveRestoreThread(v8::Isolate* isolate, int spawn_count)
+ : Thread(Options("ArchiveRestoreThread")),
+ isolate_(isolate),
+ debug_(reinterpret_cast<i::Isolate*>(isolate_)->debug()),
+ spawn_count_(spawn_count),
+ break_count_(0) {}
+
+ virtual void Run() {
+ v8::Locker locker(isolate_);
+ isolate_->Enter();
+
+ v8::HandleScope scope(isolate_);
+ v8::Local<v8::Context> context = v8::Context::New(isolate_);
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::Function> test = CompileFunction(isolate_,
+ "function test(n) {\n"
+ " debugger;\n"
+ " return n + 1;\n"
+ "}\n",
+ "test");
+
+ debug_->SetDebugDelegate(this);
+ v8::internal::DisableBreak enable_break(debug_, false);
+
+ v8::Local<v8::Value> args[1] = {v8::Integer::New(isolate_, spawn_count_)};
+
+ int result = test->Call(context, context->Global(), 1, args)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust();
+
+ // Verify that test(spawn_count_) returned spawn_count_ + 1.
+ CHECK_EQ(spawn_count_ + 1, result);
+
+ isolate_->Exit();
+ }
+
+ void BreakProgramRequested(v8::Local<v8::Context> context,
+ const std::vector<v8::debug::BreakpointId>&) {
+ auto stack_traces = v8::debug::StackTraceIterator::Create(isolate_);
+ if (!stack_traces->Done()) {
+ v8::debug::Location location = stack_traces->GetSourceLocation();
+
+ i::PrintF("ArchiveRestoreThread #%d hit breakpoint at line %d\n",
+ spawn_count_, location.GetLineNumber());
+
+ switch (location.GetLineNumber()) {
+ case 1: // debugger;
+ CHECK_EQ(break_count_, 0);
+
+ // Attempt to stop on the next line after the first debugger
+ // statement. If debug->{Archive,Restore}Debug() improperly reset
+ // thread-local debug information, the debugger will fail to stop
+ // before the test function returns.
+ debug_->PrepareStep(StepNext);
+
+ // Spawning threads while handling the current breakpoint verifies
+ // that the parent thread correctly archived and restored the
+ // state necessary to stop on the next line. If not, then control
+ // will simply continue past the `return n + 1` statement.
+ MaybeSpawnChildThread();
+
+ break;
+
+ case 2: // return n + 1;
+ CHECK_EQ(break_count_, 1);
+ break;
+
+ default:
+ CHECK(false);
+ }
+ }
+
+ ++break_count_;
+ }
+
+ void MaybeSpawnChildThread() {
+ if (spawn_count_ > 1) {
+ v8::Unlocker unlocker(isolate_);
+
+ // Spawn a thread that spawns a thread that spawns a thread (and so
+ // on) so that the ThreadManager is forced to archive and restore
+ // the current thread.
+ ArchiveRestoreThread child(isolate_, spawn_count_ - 1);
+ child.Start();
+ child.Join();
+
+ // The child thread sets itself as the debug delegate, so we need to
+ // usurp it after the child finishes, or else future breakpoints
+ // will be delegated to a destroyed ArchiveRestoreThread object.
+ debug_->SetDebugDelegate(this);
+
+ // This is the most important check in this test, since
+ // child.GetBreakCount() will return 1 if the debugger fails to stop
+ // on the `return n + 1` line after the grandchild thread returns.
+ CHECK_EQ(child.GetBreakCount(), 2);
+ }
+ }
+
+ int GetBreakCount() { return break_count_; }
+
+ private:
+ v8::Isolate* isolate_;
+ v8::internal::Debug* debug_;
+ const int spawn_count_;
+ int break_count_;
+};
+
+TEST(DebugArchiveRestore) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+
+ ArchiveRestoreThread thread(isolate, 5);
+ // Instead of calling thread.Start() and thread.Join() here, we call
+ // thread.Run() directly, to make sure we exercise archive/restore
+ // logic on the *current* thread as well as other threads.
+ thread.Run();
+ CHECK_EQ(thread.GetBreakCount(), 2);
+
+ isolate->Dispose();
+}
+
class DebugEventExpectNoException : public v8::debug::DebugDelegate {
public:
void ExceptionThrown(v8::Local<v8::Context> paused_context,

View file

@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anna Henningsen <anna@addaleax.net>
Date: Wed, 10 Oct 2018 15:24:08 -0700
Subject: deps: cherry-pick b0af309 from upstream V8
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Original commit message:
[api] Remove deprecated wasm methods
These methods were deprecated in 7.0, now we can remove them.
R=adamk@chromium.org
Bug: v8:7868
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I60badb378a055152bdd27aed67d11ddf74fce174
Reviewed-on: https://chromium-review.googlesource.com/1209283
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55695}
Refs: https://github.com/v8/v8/commit/b0af30948505b68c843b538e109ab378d3750e37
PR-URL: https://github.com/nodejs/node/pull/23415
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
diff --git a/include/v8.h b/include/v8.h
index cc2fefc56a4eeaeab48f2042d6c8dbbadb1e3210..3902c6330ab9cc9e16fda69dc83ca88424216454 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -4362,13 +4362,6 @@ class V8_EXPORT WasmCompiledModule : public Object {
public:
typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> SerializedModule;
-// The COMMA macro allows us to use ',' inside of the V8_DEPRECATED macro.
-#define COMMA ,
- V8_DEPRECATED(
- "Use BufferReference.",
- typedef std::pair<const uint8_t * COMMA size_t> CallerOwnedBuffer);
-#undef COMMA
-
/**
* A unowned reference to a byte buffer.
*/
@@ -4377,12 +4370,6 @@ class V8_EXPORT WasmCompiledModule : public Object {
size_t size;
BufferReference(const uint8_t* start, size_t size)
: start(start), size(size) {}
- // Temporarily allow conversion to and from CallerOwnedBuffer.
- V8_DEPRECATED(
- "Use BufferReference directly.",
- inline BufferReference(CallerOwnedBuffer)); // NOLINT(runtime/explicit)
- V8_DEPRECATED("Use BufferReference directly.",
- inline operator CallerOwnedBuffer());
};
/**
@@ -4429,8 +4416,6 @@ class V8_EXPORT WasmCompiledModule : public Object {
* Get the wasm-encoded bytes that were used to compile this module.
*/
BufferReference GetWasmWireBytesRef();
- V8_DEPRECATED("Use GetWasmWireBytesRef version.",
- Local<String> GetWasmWireBytes());
/**
* Serialize the compiled module. The serialized data does not include the
@@ -4463,15 +4448,6 @@ class V8_EXPORT WasmCompiledModule : public Object {
static void CheckCast(Value* obj);
};
-// TODO(clemensh): Remove after M70 branch.
-WasmCompiledModule::BufferReference::BufferReference(
- WasmCompiledModule::CallerOwnedBuffer buf)
- : BufferReference(buf.first, buf.second) {}
-WasmCompiledModule::BufferReference::
-operator WasmCompiledModule::CallerOwnedBuffer() {
- return {start, size};
-}
-
/**
* The V8 interface for WebAssembly streaming compilation. When streaming
* compilation is initiated, V8 passes a {WasmStreaming} object to the embedder
diff --git a/src/api.cc b/src/api.cc
index bc544f1c7c7f9f8e3bac9804697848ededb6a30a..3575cc89dda68d34ffde1574cca9e7b56017fd09 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -7386,14 +7386,6 @@ WasmCompiledModule::BufferReference WasmCompiledModule::GetWasmWireBytesRef() {
return {bytes_vec.start(), bytes_vec.size()};
}
-Local<String> WasmCompiledModule::GetWasmWireBytes() {
- BufferReference ref = GetWasmWireBytesRef();
- CHECK_LE(ref.size, String::kMaxLength);
- return String::NewFromOneByte(GetIsolate(), ref.start, NewStringType::kNormal,
- static_cast<int>(ref.size))
- .ToLocalChecked();
-}
-
WasmCompiledModule::TransferrableModule
WasmCompiledModule::GetTransferrableModule() {
if (i::FLAG_wasm_shared_code) {

View file

@ -1,708 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Tue, 4 Sep 2018 21:22:51 +0200
Subject: deps: cherry-pick ba752ea from upstream V8
Original commit message:
[cpu-profiler] Use instruction start as the key for the CodeMap
Previously we used the start address of the AbstractCode object. This
doesn't make sense for off-heap builtins, where the code isn't contained
in the object itself. It also hides other potential problems - sometimes
the sample.pc is inside the AbstractCode object header - this is
never valid.
There were a few changes necessary to make this happen:
- Change the interface of CodeMoveEvent. Now 'to' and 'from' are both
AbstractCode objects, which is nice because many users were taking
'to' and adding the header offset to it to try and find the
instruction start address. This isn't valid for off-heap builtins.
- Fix a bug in CodeMap::MoveCode where we didn't update the CodeEntry
object to reflect the new instruction_start.
- Rename the 'start' field in all of the CodeEventRecord sub-classes
to make it clear that this is the address of the first instruction.
- Fix the confusion in RecordTickSample between 'tos' and 'pc' which
caused pc_offset to be calculated incorrectly.
Bug: v8:7983
Change-Id: I3e9dddf74e4b2e96a5f031d216ef7008d6f184d1
Reviewed-on: https://chromium-review.googlesource.com/1148457
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54749}
Refs: https://github.com/v8/v8/commit/ba752ea4c50713dff1e94f45a79db3ba968a8d66
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/src/code-events.h b/src/code-events.h
index 09cd5a62e00beb4320e3e9cb05e07f019f26ab37..ec07a2e107917bce4a3ea3d1f9973ef54f28a2f0 100644
--- a/src/code-events.h
+++ b/src/code-events.h
@@ -83,7 +83,7 @@ class CodeEventListener {
virtual void GetterCallbackEvent(Name* name, Address entry_point) = 0;
virtual void SetterCallbackEvent(Name* name, Address entry_point) = 0;
virtual void RegExpCodeCreateEvent(AbstractCode* code, String* source) = 0;
- virtual void CodeMoveEvent(AbstractCode* from, Address to) = 0;
+ virtual void CodeMoveEvent(AbstractCode* from, AbstractCode* to) = 0;
virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
virtual void CodeMovingGCEvent() = 0;
virtual void CodeDisableOptEvent(AbstractCode* code,
@@ -154,7 +154,7 @@ class CodeEventDispatcher {
void RegExpCodeCreateEvent(AbstractCode* code, String* source) {
CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
}
- void CodeMoveEvent(AbstractCode* from, Address to) {
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
}
void SharedFunctionInfoMoveEvent(Address from, Address to) {
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 48ae74bc5d472a7136ee660af6f100f1f6858bad..2170568e261cbc927bbf217fb67c65dd9e9f191c 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -1149,7 +1149,7 @@ class ProfilingMigrationObserver final : public MigrationObserver {
int size) final {
if (dest == CODE_SPACE || (dest == OLD_SPACE && dst->IsBytecodeArray())) {
PROFILE(heap_->isolate(),
- CodeMoveEvent(AbstractCode::cast(src), dst->address()));
+ CodeMoveEvent(AbstractCode::cast(src), AbstractCode::cast(dst)));
}
heap_->OnMoveEvent(dst, src, size);
}
diff --git a/src/log.cc b/src/log.cc
index 77d68ef94eb6d5f41e881d434e815a28c121410c..f19897b27b14e3cd96e4b8e91d729981cd09113d 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -270,7 +270,7 @@ class PerfBasicLogger : public CodeEventLogger {
explicit PerfBasicLogger(Isolate* isolate);
~PerfBasicLogger() override;
- void CodeMoveEvent(AbstractCode* from, Address to) override {}
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {}
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override {}
@@ -496,7 +496,7 @@ class LowLevelLogger : public CodeEventLogger {
LowLevelLogger(Isolate* isolate, const char* file_name);
~LowLevelLogger() override;
- void CodeMoveEvent(AbstractCode* from, Address to) override;
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override {}
void SnapshotPositionEvent(HeapObject* obj, int pos);
@@ -615,11 +615,10 @@ void LowLevelLogger::LogRecordedBuffer(const wasm::WasmCode* code,
code->instructions().length());
}
-void LowLevelLogger::CodeMoveEvent(AbstractCode* from, Address to) {
+void LowLevelLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
CodeMoveStruct event;
event.from_address = from->InstructionStart();
- size_t header_size = from->InstructionStart() - from->address();
- event.to_address = to + header_size;
+ event.to_address = to->InstructionStart();
LogWriteStruct(event);
}
@@ -641,7 +640,7 @@ class JitLogger : public CodeEventLogger {
public:
JitLogger(Isolate* isolate, JitCodeEventHandler code_event_handler);
- void CodeMoveEvent(AbstractCode* from, Address to) override;
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override {}
void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset,
@@ -700,7 +699,7 @@ void JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
code_event_handler_(&event);
}
-void JitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
+void JitLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
base::LockGuard<base::Mutex> guard(&logger_mutex_);
JitCodeEvent event;
@@ -709,12 +708,7 @@ void JitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
from->IsCode() ? JitCodeEvent::JIT_CODE : JitCodeEvent::BYTE_CODE;
event.code_start = reinterpret_cast<void*>(from->InstructionStart());
event.code_len = from->InstructionSize();
-
- // Calculate the header size.
- const size_t header_size = from->InstructionStart() - from->address();
-
- // Calculate the new start address of the instructions.
- event.new_code_start = reinterpret_cast<void*>(to + header_size);
+ event.new_code_start = reinterpret_cast<void*>(to->InstructionStart());
event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
code_event_handler_(&event);
@@ -1431,9 +1425,10 @@ void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
msg.WriteToLogFile();
}
-void Logger::CodeMoveEvent(AbstractCode* from, Address to) {
+void Logger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
if (!is_listening_to_code_events()) return;
- MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(), to);
+ MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(),
+ to->address());
}
namespace {
diff --git a/src/log.h b/src/log.h
index 485de0f4d17db71cbbe4170dff0155c4eac0105a..3bc54a5926d35cca6b1544c4f7fce52ae96bca95 100644
--- a/src/log.h
+++ b/src/log.h
@@ -222,7 +222,7 @@ class Logger : public CodeEventListener {
// Emits a code create event for a RegExp.
void RegExpCodeCreateEvent(AbstractCode* code, String* source);
// Emits a code move event.
- void CodeMoveEvent(AbstractCode* from, Address to);
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to);
// Emits a code line info record event.
void CodeLinePosInfoRecordEvent(Address code_start,
ByteArray* source_position_table);
@@ -486,7 +486,7 @@ class ExternalCodeEventListener : public CodeEventListener {
void GetterCallbackEvent(Name* name, Address entry_point) override {}
void SetterCallbackEvent(Name* name, Address entry_point) override {}
void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
- void CodeMoveEvent(AbstractCode* from, Address to) override {}
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {}
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override {}
void CodeMovingGCEvent() override {}
diff --git a/src/perf-jit.cc b/src/perf-jit.cc
index 3aaa36bc12f4ecdbeeab97f4f73adb482ef14211..f6b2cf401a719fd1696f1ac327bcf04b0800092a 100644
--- a/src/perf-jit.cc
+++ b/src/perf-jit.cc
@@ -420,7 +420,7 @@ void PerfJitLogger::LogWriteUnwindingInfo(Code* code) {
LogWriteBytes(padding_bytes, static_cast<int>(padding_size));
}
-void PerfJitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
+void PerfJitLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
// We may receive a CodeMove event if a BytecodeArray object moves. Otherwise
// code relocation is not supported.
CHECK(from->IsBytecodeArray());
diff --git a/src/perf-jit.h b/src/perf-jit.h
index d08f4b91ab26ef10a55043c84f4694bd1466496a..3b11cf30c23a7027f356c4ab299f88a5efb8dcc9 100644
--- a/src/perf-jit.h
+++ b/src/perf-jit.h
@@ -41,7 +41,7 @@ class PerfJitLogger : public CodeEventLogger {
explicit PerfJitLogger(Isolate* isolate);
virtual ~PerfJitLogger();
- void CodeMoveEvent(AbstractCode* from, Address to) override;
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override {}
@@ -120,7 +120,7 @@ class PerfJitLogger : public CodeEventLogger {
public:
explicit PerfJitLogger(Isolate* isolate) : CodeEventLogger(isolate) {}
- void CodeMoveEvent(AbstractCode* from, Address to) override {
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {
UNIMPLEMENTED();
}
diff --git a/src/profiler/cpu-profiler-inl.h b/src/profiler/cpu-profiler-inl.h
index f6eaa8f8a33e72ca28bf7431747607e0c3764b92..9274bc03c66d860bb0754bf46f4692622861ed0c 100644
--- a/src/profiler/cpu-profiler-inl.h
+++ b/src/profiler/cpu-profiler-inl.h
@@ -16,17 +16,17 @@ namespace v8 {
namespace internal {
void CodeCreateEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->AddCode(start, entry, size);
+ code_map->AddCode(instruction_start, entry, instruction_size);
}
void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->MoveCode(from, to);
+ code_map->MoveCode(from_instruction_start, to_instruction_start);
}
void CodeDisableOptEventRecord::UpdateCodeMap(CodeMap* code_map) {
- CodeEntry* entry = code_map->FindEntry(start);
+ CodeEntry* entry = code_map->FindEntry(instruction_start);
if (entry != nullptr) {
entry->set_bailout_reason(bailout_reason);
}
@@ -34,7 +34,7 @@ void CodeDisableOptEventRecord::UpdateCodeMap(CodeMap* code_map) {
void CodeDeoptEventRecord::UpdateCodeMap(CodeMap* code_map) {
- CodeEntry* entry = code_map->FindEntry(start);
+ CodeEntry* entry = code_map->FindEntry(instruction_start);
if (entry == nullptr) return;
std::vector<CpuProfileDeoptFrame> frames_vector(
deopt_frames, deopt_frames + deopt_frame_count);
@@ -44,7 +44,7 @@ void CodeDeoptEventRecord::UpdateCodeMap(CodeMap* code_map) {
void ReportBuiltinEventRecord::UpdateCodeMap(CodeMap* code_map) {
- CodeEntry* entry = code_map->FindEntry(start);
+ CodeEntry* entry = code_map->FindEntry(instruction_start);
if (!entry) {
// Code objects for builtins should already have been added to the map but
// some of them have been filtered out by CpuProfiler.
diff --git a/src/profiler/cpu-profiler.cc b/src/profiler/cpu-profiler.cc
index 463a30f1842c24a1545b198cb230d99199a33374..555c47f2f4e418b2511c6352b2ef639bee1305f6 100644
--- a/src/profiler/cpu-profiler.cc
+++ b/src/profiler/cpu-profiler.cc
@@ -426,7 +426,7 @@ void CpuProfiler::LogBuiltins() {
CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
Builtins::Name id = static_cast<Builtins::Name>(i);
- rec->start = builtins->builtin(id)->address();
+ rec->instruction_start = builtins->builtin(id)->InstructionStart();
rec->builtin_id = id;
processor_->Enqueue(evt_rec);
}
diff --git a/src/profiler/cpu-profiler.h b/src/profiler/cpu-profiler.h
index febc15480215b7406a4453b74e0106d9885ee537..78bb3b4a25f4807dbefe22c7a226969b476a21ba 100644
--- a/src/profiler/cpu-profiler.h
+++ b/src/profiler/cpu-profiler.h
@@ -53,9 +53,9 @@ class CodeEventRecord {
class CodeCreateEventRecord : public CodeEventRecord {
public:
- Address start;
+ Address instruction_start;
CodeEntry* entry;
- unsigned size;
+ unsigned instruction_size;
V8_INLINE void UpdateCodeMap(CodeMap* code_map);
};
@@ -63,8 +63,8 @@ class CodeCreateEventRecord : public CodeEventRecord {
class CodeMoveEventRecord : public CodeEventRecord {
public:
- Address from;
- Address to;
+ Address from_instruction_start;
+ Address to_instruction_start;
V8_INLINE void UpdateCodeMap(CodeMap* code_map);
};
@@ -72,7 +72,7 @@ class CodeMoveEventRecord : public CodeEventRecord {
class CodeDisableOptEventRecord : public CodeEventRecord {
public:
- Address start;
+ Address instruction_start;
const char* bailout_reason;
V8_INLINE void UpdateCodeMap(CodeMap* code_map);
@@ -81,7 +81,7 @@ class CodeDisableOptEventRecord : public CodeEventRecord {
class CodeDeoptEventRecord : public CodeEventRecord {
public:
- Address start;
+ Address instruction_start;
const char* deopt_reason;
int deopt_id;
Address pc;
@@ -95,7 +95,7 @@ class CodeDeoptEventRecord : public CodeEventRecord {
class ReportBuiltinEventRecord : public CodeEventRecord {
public:
- Address start;
+ Address instruction_start;
Builtins::Name builtin_id;
V8_INLINE void UpdateCodeMap(CodeMap* code_map);
diff --git a/src/profiler/profile-generator.cc b/src/profiler/profile-generator.cc
index 92619f2fbf3cf52c75b812cb97d4ed4e270fd983..845fe97b6473f2b7d3009964e01f81ff042780e0 100644
--- a/src/profiler/profile-generator.cc
+++ b/src/profiler/profile-generator.cc
@@ -529,6 +529,8 @@ void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
ClearCodesInRange(addr, addr + size);
unsigned index = AddCodeEntry(addr, entry);
code_map_.emplace(addr, CodeEntryMapInfo{index, size});
+ DCHECK(entry->instruction_start() == kNullAddress ||
+ addr == entry->instruction_start());
}
void CodeMap::ClearCodesInRange(Address start, Address end) {
@@ -550,8 +552,14 @@ CodeEntry* CodeMap::FindEntry(Address addr) {
auto it = code_map_.upper_bound(addr);
if (it == code_map_.begin()) return nullptr;
--it;
- Address end_address = it->first + it->second.size;
- return addr < end_address ? entry(it->second.index) : nullptr;
+ Address start_address = it->first;
+ Address end_address = start_address + it->second.size;
+ CodeEntry* ret = addr < end_address ? entry(it->second.index) : nullptr;
+ if (ret && ret->instruction_start() != kNullAddress) {
+ DCHECK_EQ(start_address, ret->instruction_start());
+ DCHECK(addr >= start_address && addr < end_address);
+ }
+ return ret;
}
void CodeMap::MoveCode(Address from, Address to) {
@@ -563,6 +571,9 @@ void CodeMap::MoveCode(Address from, Address to) {
DCHECK(from + info.size <= to || to + info.size <= from);
ClearCodesInRange(to, to + info.size);
code_map_.emplace(to, info);
+
+ CodeEntry* entry = code_entries_[info.index].entry;
+ entry->set_instruction_start(to);
}
unsigned CodeMap::AddCodeEntry(Address start, CodeEntry* entry) {
@@ -693,26 +704,29 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
if (sample.pc != nullptr) {
if (sample.has_external_callback && sample.state == EXTERNAL) {
// Don't use PC when in external callback code, as it can point
- // inside callback's code, and we will erroneously report
+ // inside a callback's code, and we will erroneously report
// that a callback calls itself.
stack_trace.push_back(
{FindEntry(reinterpret_cast<Address>(sample.external_callback_entry)),
no_line_info});
} else {
- CodeEntry* pc_entry = FindEntry(reinterpret_cast<Address>(sample.pc));
- // If there is no pc_entry we're likely in native code.
- // Find out, if top of stack was pointing inside a JS function
- // meaning that we have encountered a frameless invocation.
+ Address attributed_pc = reinterpret_cast<Address>(sample.pc);
+ CodeEntry* pc_entry = FindEntry(attributed_pc);
+ // If there is no pc_entry, we're likely in native code. Find out if the
+ // top of the stack (the return address) was pointing inside a JS
+ // function, meaning that we have encountered a frameless invocation.
if (!pc_entry && !sample.has_external_callback) {
- pc_entry = FindEntry(reinterpret_cast<Address>(sample.tos));
+ attributed_pc = reinterpret_cast<Address>(sample.tos);
+ pc_entry = FindEntry(attributed_pc);
}
// If pc is in the function code before it set up stack frame or after the
- // frame was destroyed SafeStackFrameIterator incorrectly thinks that
- // ebp contains return address of the current function and skips caller's
- // frame. Check for this case and just skip such samples.
+ // frame was destroyed, SafeStackFrameIterator incorrectly thinks that
+ // ebp contains the return address of the current function and skips the
+ // caller's frame. Check for this case and just skip such samples.
if (pc_entry) {
- int pc_offset = static_cast<int>(reinterpret_cast<Address>(sample.pc) -
- pc_entry->instruction_start());
+ int pc_offset =
+ static_cast<int>(attributed_pc - pc_entry->instruction_start());
+ DCHECK_GE(pc_offset, 0);
src_line = pc_entry->GetSourceLine(pc_offset);
if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
src_line = pc_entry->line_number();
@@ -744,6 +758,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
// Find out if the entry has an inlining stack associated.
int pc_offset =
static_cast<int>(stack_pos - entry->instruction_start());
+ DCHECK_GE(pc_offset, 0);
const std::vector<std::unique_ptr<CodeEntry>>* inline_stack =
entry->GetInlineStack(pc_offset);
if (inline_stack) {
diff --git a/src/profiler/profile-generator.h b/src/profiler/profile-generator.h
index 3e301a40829ea1acbbd8283bed0d3e43dee679e9..8eef05bcdb382600e987608bdcb9270e3307e998 100644
--- a/src/profiler/profile-generator.h
+++ b/src/profiler/profile-generator.h
@@ -108,7 +108,9 @@ class CodeEntry {
const std::vector<std::unique_ptr<CodeEntry>>* GetInlineStack(
int pc_offset) const;
+ void set_instruction_start(Address start) { instruction_start_ = start; }
Address instruction_start() const { return instruction_start_; }
+
CodeEventListener::LogEventsAndTags tag() const {
return TagField::decode(bit_field_);
}
diff --git a/src/profiler/profiler-listener.cc b/src/profiler/profiler-listener.cc
index 9c29da9ec7972ac9a5fb2a6be8065fe30d7dddd1..f90a2e11d3f3a247fdec39abbb1a04e4d86204e5 100644
--- a/src/profiler/profiler-listener.cc
+++ b/src/profiler/profiler-listener.cc
@@ -24,9 +24,9 @@ ProfilerListener::~ProfilerListener() = default;
void ProfilerListener::CallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = entry_point;
+ rec->instruction_start = entry_point;
rec->entry = NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name));
- rec->size = 1;
+ rec->instruction_size = 1;
DispatchCodeEvent(evt_rec);
}
@@ -34,13 +34,13 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, const char* name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->entry = NewCodeEntry(tag, GetName(name), CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, nullptr,
code->InstructionStart());
RecordInliningInfo(rec->entry, code);
- rec->size = code->ExecutableSize();
+ rec->instruction_size = code->InstructionSize();
DispatchCodeEvent(evt_rec);
}
@@ -48,13 +48,13 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, Name* name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->entry = NewCodeEntry(tag, GetName(name), CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, nullptr,
code->InstructionStart());
RecordInliningInfo(rec->entry, code);
- rec->size = code->ExecutableSize();
+ rec->instruction_size = code->InstructionSize();
DispatchCodeEvent(evt_rec);
}
@@ -64,7 +64,7 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
Name* script_name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->entry = NewCodeEntry(tag, GetName(shared->DebugName()),
GetName(InferScriptName(script_name, shared)),
CpuProfileNode::kNoLineNumberInfo,
@@ -72,7 +72,7 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
code->InstructionStart());
RecordInliningInfo(rec->entry, code);
rec->entry->FillFunctionInfo(shared);
- rec->size = code->ExecutableSize();
+ rec->instruction_size = code->InstructionSize();
DispatchCodeEvent(evt_rec);
}
@@ -83,7 +83,7 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
int column) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = abstract_code->address();
+ rec->instruction_start = abstract_code->InstructionStart();
std::unique_ptr<SourcePositionTable> line_table;
if (shared->script()->IsScript()) {
Script* script = Script::cast(shared->script());
@@ -105,7 +105,7 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
std::move(line_table), abstract_code->InstructionStart());
RecordInliningInfo(rec->entry, abstract_code);
rec->entry->FillFunctionInfo(shared);
- rec->size = abstract_code->ExecutableSize();
+ rec->instruction_size = abstract_code->InstructionSize();
DispatchCodeEvent(evt_rec);
}
@@ -114,20 +114,20 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
wasm::WasmName name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = code->instruction_start();
+ rec->instruction_start = code->instruction_start();
rec->entry = NewCodeEntry(
tag, GetName(name.start()), CodeEntry::kWasmResourceNamePrefix,
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
nullptr, code->instruction_start());
- rec->size = code->instructions().length();
+ rec->instruction_size = code->instructions().length();
DispatchCodeEvent(evt_rec);
}
-void ProfilerListener::CodeMoveEvent(AbstractCode* from, Address to) {
+void ProfilerListener::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
- rec->from = from->address();
- rec->to = to;
+ rec->from_instruction_start = from->InstructionStart();
+ rec->to_instruction_start = to->InstructionStart();
DispatchCodeEvent(evt_rec);
}
@@ -135,7 +135,7 @@ void ProfilerListener::CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
DispatchCodeEvent(evt_rec);
}
@@ -145,7 +145,7 @@ void ProfilerListener::CodeDeoptEvent(Code* code, DeoptimizeKind kind,
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DEOPT);
CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc);
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->deopt_reason = DeoptimizeReasonToString(info.deopt_reason);
rec->deopt_id = info.deopt_id;
rec->pc = pc;
@@ -160,10 +160,10 @@ void ProfilerListener::CodeDeoptEvent(Code* code, DeoptimizeKind kind,
void ProfilerListener::GetterCallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = entry_point;
+ rec->instruction_start = entry_point;
rec->entry =
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("get ", name));
- rec->size = 1;
+ rec->instruction_size = 1;
DispatchCodeEvent(evt_rec);
}
@@ -171,23 +171,22 @@ void ProfilerListener::RegExpCodeCreateEvent(AbstractCode* code,
String* source) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = code->address();
+ rec->instruction_start = code->InstructionStart();
rec->entry = NewCodeEntry(
CodeEventListener::REG_EXP_TAG, GetConsName("RegExp: ", source),
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
- CpuProfileNode::kNoColumnNumberInfo, nullptr,
- code->raw_instruction_start());
- rec->size = code->ExecutableSize();
+ CpuProfileNode::kNoColumnNumberInfo, nullptr, code->InstructionStart());
+ rec->instruction_size = code->InstructionSize();
DispatchCodeEvent(evt_rec);
}
void ProfilerListener::SetterCallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
- rec->start = entry_point;
+ rec->instruction_start = entry_point;
rec->entry =
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("set ", name));
- rec->size = 1;
+ rec->instruction_size = 1;
DispatchCodeEvent(evt_rec);
}
diff --git a/src/profiler/profiler-listener.h b/src/profiler/profiler-listener.h
index 5cff7cc11d1e91ed773f8e1633b4f4363ba1246b..51fba18a60960f8a65115516401952b46ebb5d71 100644
--- a/src/profiler/profiler-listener.h
+++ b/src/profiler/profiler-listener.h
@@ -44,7 +44,7 @@ class ProfilerListener : public CodeEventListener {
wasm::WasmName name) override;
void CodeMovingGCEvent() override {}
- void CodeMoveEvent(AbstractCode* from, Address to) override;
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override;
void CodeDeoptEvent(Code* code, DeoptimizeKind kind, Address pc,
diff --git a/src/snapshot/serializer.h b/src/snapshot/serializer.h
index 6a5d1a4aacae64930066405855e079c4d98dacb0..658d37f286c5a103738ebfe22c84d68ea6c7b222 100644
--- a/src/snapshot/serializer.h
+++ b/src/snapshot/serializer.h
@@ -28,8 +28,8 @@ class CodeAddressMap : public CodeEventLogger {
isolate_->logger()->RemoveCodeEventListener(this);
}
- void CodeMoveEvent(AbstractCode* from, Address to) override {
- address_to_name_map_.Move(from->address(), to);
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {
+ address_to_name_map_.Move(from->address(), to->address());
}
void CodeDisableOptEvent(AbstractCode* code,
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 4e7a70c76f28b1404f03ffb5ad771227425ac43e..f74bdf1ede87f53b4f396bb85f0a792895f8a40a 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -176,27 +176,29 @@ TEST(CodeEvents) {
"comment");
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code,
"comment2");
- profiler_listener.CodeMoveEvent(comment2_code, moved_code->address());
+ profiler_listener.CodeMoveEvent(comment2_code, moved_code);
// Enqueue a tick event to enable code events processing.
- EnqueueTickSampleEvent(processor, aaa_code->address());
+ EnqueueTickSampleEvent(processor, aaa_code->InstructionStart());
isolate->logger()->RemoveCodeEventListener(&profiler_listener);
processor->StopSynchronously();
// Check the state of profile generator.
- CodeEntry* aaa = generator->code_map()->FindEntry(aaa_code->address());
+ CodeEntry* aaa =
+ generator->code_map()->FindEntry(aaa_code->InstructionStart());
CHECK(aaa);
CHECK_EQ(0, strcmp(aaa_str, aaa->name()));
CodeEntry* comment =
- generator->code_map()->FindEntry(comment_code->address());
+ generator->code_map()->FindEntry(comment_code->InstructionStart());
CHECK(comment);
CHECK_EQ(0, strcmp("comment", comment->name()));
- CHECK(!generator->code_map()->FindEntry(comment2_code->address()));
+ CHECK(!generator->code_map()->FindEntry(comment2_code->InstructionStart()));
- CodeEntry* comment2 = generator->code_map()->FindEntry(moved_code->address());
+ CodeEntry* comment2 =
+ generator->code_map()->FindEntry(moved_code->InstructionStart());
CHECK(comment2);
CHECK_EQ(0, strcmp("comment2", comment2->name()));
}
@@ -298,11 +300,11 @@ TEST(Issue1398) {
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb");
v8::TickSample* sample = processor->StartTickSample();
- sample->pc = reinterpret_cast<void*>(code->address());
+ sample->pc = reinterpret_cast<void*>(code->InstructionStart());
sample->tos = nullptr;
sample->frames_count = v8::TickSample::kMaxFramesCount;
for (unsigned i = 0; i < sample->frames_count; ++i) {
- sample->stack[i] = reinterpret_cast<void*>(code->address());
+ sample->stack[i] = reinterpret_cast<void*>(code->InstructionStart());
}
processor->FinishTickSample();
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 0b13a7e6607cc45ab824725cff38a963b10feca8..1dfa22b4cc6f53972b18f14346a9703fe48bf8a0 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -751,7 +751,7 @@ TEST(Issue539892) {
explicit FakeCodeEventLogger(i::Isolate* isolate)
: CodeEventLogger(isolate) {}
- void CodeMoveEvent(i::AbstractCode* from, Address to) override {}
+ void CodeMoveEvent(i::AbstractCode* from, i::AbstractCode* to) override {}
void CodeDisableOptEvent(i::AbstractCode* code,
i::SharedFunctionInfo* shared) override {}
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index 9b2d7e3ab2fe9dcc273c0946589a4714768bb86d..b53bf148e615e45581a653438af77d9d3af93909 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -676,7 +676,8 @@ int GetFunctionLineNumber(CpuProfiler& profiler, LocalContext& env,
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
env->Global()->Get(env.local(), v8_str(name)).ToLocalChecked())));
- CodeEntry* func_entry = code_map->FindEntry(func->abstract_code()->address());
+ CodeEntry* func_entry =
+ code_map->FindEntry(func->abstract_code()->InstructionStart());
if (!func_entry) FATAL("%s", name);
return func_entry->line_number();
}

View file

@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Tue, 4 Sep 2018 21:24:03 +0200
Subject: deps: cherry-pick bf5ea81 from upstream V8
Original commit message:
[tracing] allow dynamic control of tracing
If the trace_buffer_ was null, we were returning a pointer to a static
flag back that permanently disabled that particular trace point.
This implied an assumption that tracing will be statically enabled at
process startup, and once it is disabled, it will never be enabled
again. On Node.js side we want to dynamically enable/disable tracing as per
programmer intent.
Change-Id: Ic7a7839b8450ab5c356d85e8e0826f42824907f4
Reviewed-on: https://chromium-review.googlesource.com/1161518
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Ali Ijaz Sheikh <ofrobots@google.com>
Cr-Commit-Position: refs/heads/master@{#54903}
Refs: https://github.com/v8/v8/commit/bf5ea8138c0726613c9d722a3ccb552a8f477992
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/src/libplatform/tracing/tracing-controller.cc b/src/libplatform/tracing/tracing-controller.cc
index 647306d62790af5f977c3a74ec272f446f3acabf..b4aa7baf724d4f29b4df08f3b57fdc018f6a32a7 100644
--- a/src/libplatform/tracing/tracing-controller.cc
+++ b/src/libplatform/tracing/tracing-controller.cc
@@ -24,18 +24,17 @@ namespace tracing {
// convert internally to determine the category name from the char enabled
// pointer.
const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
- "toplevel", "tracing already shutdown",
+ "toplevel",
"tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
"__metadata"};
// The enabled flag is char instead of bool so that the API can be used from C.
unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0};
// Indexes here have to match the g_category_groups array indexes above.
-const int g_category_already_shutdown = 1;
-const int g_category_categories_exhausted = 2;
+const int g_category_categories_exhausted = 1;
// Metadata category not used in V8.
-// const int g_category_metadata = 3;
-const int g_num_builtin_categories = 4;
+// const int g_category_metadata = 2;
+const int g_num_builtin_categories = 3;
// Skip default categories.
v8::base::AtomicWord g_category_index = g_num_builtin_categories;
@@ -103,10 +102,6 @@ void TracingController::UpdateTraceEventDuration(
const uint8_t* TracingController::GetCategoryGroupEnabled(
const char* category_group) {
- if (!trace_buffer_) {
- DCHECK(!g_category_group_enabled[g_category_already_shutdown]);
- return &g_category_group_enabled[g_category_already_shutdown];
- }
return GetCategoryGroupEnabledInternal(category_group);
}

View file

@ -1,305 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Sun, 19 Aug 2018 21:53:40 +0200
Subject: deps: cherry-pick c608122 from upstream V8
Original commit message:
[api][keys] Allow skipping indices for Proxies with GetPropertyNames
Bug: v8:7942
Change-Id: I7b3740b04cbcaa56dc809150900ab8d821b054ce
Reviewed-on: https://chromium-review.googlesource.com/1156544
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54821}
Refs: https://github.com/v8/v8/commit/c608122b85238397a43910246f5ff218eb43fb24
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/src/keys.cc b/src/keys.cc
index 8ecbe0a1d7b2ad09a12b5c826db4f24efa222bcb..689f4ac3dfeb8d3980946884c57237778724e132 100644
--- a/src/keys.cc
+++ b/src/keys.cc
@@ -38,10 +38,10 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
// static
MaybeHandle<FixedArray> KeyAccumulator::GetKeys(
Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter,
- GetKeysConversion keys_conversion, bool is_for_in) {
+ GetKeysConversion keys_conversion, bool is_for_in, bool skip_indices) {
Isolate* isolate = object->GetIsolate();
- FastKeyAccumulator accumulator(isolate, object, mode, filter);
- accumulator.set_is_for_in(is_for_in);
+ FastKeyAccumulator accumulator(isolate, object, mode, filter, is_for_in,
+ skip_indices);
return accumulator.GetKeys(keys_conversion);
}
@@ -355,7 +355,8 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
template <bool fast_properties>
MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
Handle<JSObject> object,
- GetKeysConversion convert) {
+ GetKeysConversion convert,
+ bool skip_indices) {
Handle<FixedArray> keys;
ElementsAccessor* accessor = object->GetElementsAccessor();
if (fast_properties) {
@@ -364,8 +365,14 @@ MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
// TODO(cbruni): preallocate big enough array to also hold elements.
keys = KeyAccumulator::GetOwnEnumPropertyKeys(isolate, object);
}
- MaybeHandle<FixedArray> result =
- accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
+
+ MaybeHandle<FixedArray> result;
+ if (skip_indices) {
+ result = keys;
+ } else {
+ result =
+ accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
+ }
if (FLAG_trace_for_in_enumerate) {
PrintF("| strings=%d symbols=0 elements=%u || prototypes>=1 ||\n",
@@ -403,7 +410,8 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
// Do not try to use the enum-cache for dict-mode objects.
if (map->is_dictionary_map()) {
- return GetOwnKeysWithElements<false>(isolate_, object, keys_conversion);
+ return GetOwnKeysWithElements<false>(isolate_, object, keys_conversion,
+ skip_indices_);
}
int enum_length = receiver_->map()->EnumLength();
if (enum_length == kInvalidEnumCacheSentinel) {
@@ -421,7 +429,8 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
}
// The properties-only case failed because there were probably elements on the
// receiver.
- return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion);
+ return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion,
+ skip_indices_);
}
MaybeHandle<FixedArray>
@@ -450,6 +459,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
GetKeysConversion keys_conversion) {
KeyAccumulator accumulator(isolate_, mode_, filter_);
accumulator.set_is_for_in(is_for_in_);
+ accumulator.set_skip_indices(skip_indices_);
accumulator.set_last_non_empty_prototype(last_non_empty_prototype_);
MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_),
@@ -699,13 +709,15 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
Maybe<bool> KeyAccumulator::CollectAccessCheckInterceptorKeys(
Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
Handle<JSObject> object) {
- MAYBE_RETURN((CollectInterceptorKeysInternal(
- receiver, object,
- handle(InterceptorInfo::cast(
- access_check_info->indexed_interceptor()),
- isolate_),
- this, kIndexed)),
- Nothing<bool>());
+ if (!skip_indices_) {
+ MAYBE_RETURN((CollectInterceptorKeysInternal(
+ receiver, object,
+ handle(InterceptorInfo::cast(
+ access_check_info->indexed_interceptor()),
+ isolate_),
+ this, kIndexed)),
+ Nothing<bool>());
+ }
MAYBE_RETURN(
(CollectInterceptorKeysInternal(
receiver, object,
@@ -942,9 +954,9 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys(
Handle<FixedArray> keys;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate_, keys,
- KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly,
- ALL_PROPERTIES,
- GetKeysConversion::kConvertToString, is_for_in_),
+ KeyAccumulator::GetKeys(
+ target, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
+ GetKeysConversion::kConvertToString, is_for_in_, skip_indices_),
Nothing<bool>());
Maybe<bool> result = AddKeysFromJSProxy(proxy, keys);
return result;
diff --git a/src/keys.h b/src/keys.h
index 649d6a95999fc70358f48bb18ec71687f3de8e75..5abbaac5cd0e5af2d9dca0d41d927b4b72c626ec 100644
--- a/src/keys.h
+++ b/src/keys.h
@@ -40,7 +40,7 @@ class KeyAccumulator final BASE_EMBEDDED {
static MaybeHandle<FixedArray> GetKeys(
Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter,
GetKeysConversion keys_conversion = GetKeysConversion::kKeepNumbers,
- bool is_for_in = false);
+ bool is_for_in = false, bool skip_indices = false);
Handle<FixedArray> GetKeys(
GetKeysConversion convert = GetKeysConversion::kKeepNumbers);
@@ -128,14 +128,19 @@ class KeyAccumulator final BASE_EMBEDDED {
class FastKeyAccumulator {
public:
FastKeyAccumulator(Isolate* isolate, Handle<JSReceiver> receiver,
- KeyCollectionMode mode, PropertyFilter filter)
- : isolate_(isolate), receiver_(receiver), mode_(mode), filter_(filter) {
+ KeyCollectionMode mode, PropertyFilter filter,
+ bool is_for_in = false, bool skip_indices = false)
+ : isolate_(isolate),
+ receiver_(receiver),
+ mode_(mode),
+ filter_(filter),
+ is_for_in_(is_for_in),
+ skip_indices_(skip_indices) {
Prepare();
}
bool is_receiver_simple_enum() { return is_receiver_simple_enum_; }
bool has_empty_prototype() { return has_empty_prototype_; }
- void set_is_for_in(bool value) { is_for_in_ = value; }
MaybeHandle<FixedArray> GetKeys(
GetKeysConversion convert = GetKeysConversion::kKeepNumbers);
@@ -153,6 +158,7 @@ class FastKeyAccumulator {
KeyCollectionMode mode_;
PropertyFilter filter_;
bool is_for_in_ = false;
+ bool skip_indices_ = false;
bool is_receiver_simple_enum_ = false;
bool has_empty_prototype_ = false;
diff --git a/src/runtime/runtime-forin.cc b/src/runtime/runtime-forin.cc
index 5df16faf46faca09d446a700633917fb76fc02b2..ed1e2260602f42d1dba93d0f26357a30a19bc29f 100644
--- a/src/runtime/runtime-forin.cc
+++ b/src/runtime/runtime-forin.cc
@@ -26,8 +26,7 @@ MaybeHandle<HeapObject> Enumerate(Isolate* isolate,
JSObject::MakePrototypesFast(receiver, kStartAtReceiver, isolate);
FastKeyAccumulator accumulator(isolate, receiver,
KeyCollectionMode::kIncludePrototypes,
- ENUMERABLE_STRINGS);
- accumulator.set_is_for_in(true);
+ ENUMERABLE_STRINGS, true);
// Test if we have an enum cache for {receiver}.
if (!accumulator.is_receiver_simple_enum()) {
Handle<FixedArray> keys;
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index d5d1ae101b38c22036fb92d4af09f53f9a556649..a018e12853199aaff9d4aa914429baa03501a830 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -15360,14 +15360,107 @@ THREADED_TEST(PropertyEnumeration2) {
}
}
-THREADED_TEST(PropertyNames) {
+THREADED_TEST(GetPropertyNames) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Value> result = CompileRun(
"var result = {0: 0, 1: 1, a: 2, b: 3};"
"result[Symbol('symbol')] = true;"
- "result.__proto__ = {2: 4, 3: 5, c: 6, d: 7};"
+ "result.__proto__ = {__proto__:null, 2: 4, 3: 5, c: 6, d: 7};"
+ "result;");
+ v8::Local<v8::Object> object = result.As<v8::Object>();
+ v8::PropertyFilter default_filter =
+ static_cast<v8::PropertyFilter>(v8::ONLY_ENUMERABLE | v8::SKIP_SYMBOLS);
+ v8::PropertyFilter include_symbols_filter = v8::ONLY_ENUMERABLE;
+
+ v8::Local<v8::Array> properties =
+ object->GetPropertyNames(context.local()).ToLocalChecked();
+ const char* expected_properties1[] = {"0", "1", "a", "b", "2", "3", "c", "d"};
+ CheckStringArray(isolate, properties, 8, expected_properties1);
+
+ properties =
+ object
+ ->GetPropertyNames(context.local(),
+ v8::KeyCollectionMode::kIncludePrototypes,
+ default_filter, v8::IndexFilter::kIncludeIndices)
+ .ToLocalChecked();
+ CheckStringArray(isolate, properties, 8, expected_properties1);
+
+ properties = object
+ ->GetPropertyNames(context.local(),
+ v8::KeyCollectionMode::kIncludePrototypes,
+ include_symbols_filter,
+ v8::IndexFilter::kIncludeIndices)
+ .ToLocalChecked();
+ const char* expected_properties1_1[] = {"0", "1", "a", "b", nullptr,
+ "2", "3", "c", "d"};
+ CheckStringArray(isolate, properties, 9, expected_properties1_1);
+ CheckIsSymbolAt(isolate, properties, 4, "symbol");
+
+ properties =
+ object
+ ->GetPropertyNames(context.local(),
+ v8::KeyCollectionMode::kIncludePrototypes,
+ default_filter, v8::IndexFilter::kSkipIndices)
+ .ToLocalChecked();
+ const char* expected_properties2[] = {"a", "b", "c", "d"};
+ CheckStringArray(isolate, properties, 4, expected_properties2);
+
+ properties = object
+ ->GetPropertyNames(context.local(),
+ v8::KeyCollectionMode::kIncludePrototypes,
+ include_symbols_filter,
+ v8::IndexFilter::kSkipIndices)
+ .ToLocalChecked();
+ const char* expected_properties2_1[] = {"a", "b", nullptr, "c", "d"};
+ CheckStringArray(isolate, properties, 5, expected_properties2_1);
+ CheckIsSymbolAt(isolate, properties, 2, "symbol");
+
+ properties =
+ object
+ ->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
+ default_filter, v8::IndexFilter::kIncludeIndices)
+ .ToLocalChecked();
+ const char* expected_properties3[] = {"0", "1", "a", "b"};
+ CheckStringArray(isolate, properties, 4, expected_properties3);
+
+ properties = object
+ ->GetPropertyNames(
+ context.local(), v8::KeyCollectionMode::kOwnOnly,
+ include_symbols_filter, v8::IndexFilter::kIncludeIndices)
+ .ToLocalChecked();
+ const char* expected_properties3_1[] = {"0", "1", "a", "b", nullptr};
+ CheckStringArray(isolate, properties, 5, expected_properties3_1);
+ CheckIsSymbolAt(isolate, properties, 4, "symbol");
+
+ properties =
+ object
+ ->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
+ default_filter, v8::IndexFilter::kSkipIndices)
+ .ToLocalChecked();
+ const char* expected_properties4[] = {"a", "b"};
+ CheckStringArray(isolate, properties, 2, expected_properties4);
+
+ properties = object
+ ->GetPropertyNames(
+ context.local(), v8::KeyCollectionMode::kOwnOnly,
+ include_symbols_filter, v8::IndexFilter::kSkipIndices)
+ .ToLocalChecked();
+ const char* expected_properties4_1[] = {"a", "b", nullptr};
+ CheckStringArray(isolate, properties, 3, expected_properties4_1);
+ CheckIsSymbolAt(isolate, properties, 2, "symbol");
+}
+
+THREADED_TEST(ProxyGetPropertyNames) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Value> result = CompileRun(
+ "var target = {0: 0, 1: 1, a: 2, b: 3};"
+ "target[Symbol('symbol')] = true;"
+ "target.__proto__ = {__proto__:null, 2: 4, 3: 5, c: 6, d: 7};"
+ "var result = new Proxy(target, {});"
"result;");
v8::Local<v8::Object> object = result.As<v8::Object>();
v8::PropertyFilter default_filter =

View file

@ -1,754 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Kozyatinskiy <kozyatinskiy@chromium.org>
Date: Fri, 10 Aug 2018 13:09:49 -0700
Subject: deps: cherry-pick dbfcc48 from upstream V8
Original commit message:
```
[inspector] added V8InspectorClient::resourceNameToUrl
Some clients (see Node.js) use platform path as ScriptOrigin.
Reporting platform path in protocol makes using protocol much harder.
This CL introduced V8InspectorClient::resourceNameToUrl method that
is called for any reported using protocol url.
V8Inspector uses url internally as well so protocol client may generate
pattern for blackboxing with file urls only and does not need to build
complicated regexp that covers files urls and platform paths on
different platforms.
R=lushnikov@chromium.org
TBR=yangguo@chromium.org
Bug: none
Change-Id: Iff302e7441df922fa5d689fe510f5a9bfd470b9b
Reviewed-on: https://chromium-review.googlesource.com/1164624
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Reviewed-by: Alexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55029}
```
Refs: https://github.com/v8/v8/commit/dbfcc48
PR-URL: https://github.com/nodejs/node/pull/22251
Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
diff --git a/include/v8-inspector.h b/include/v8-inspector.h
index d879a94373e427892bb6921eafff5139e05509b0..ad04d01bd212583c3ae9c3911c5dcfd0ef07cd79 100644
--- a/include/v8-inspector.h
+++ b/include/v8-inspector.h
@@ -215,6 +215,11 @@ class V8_EXPORT V8InspectorClient {
virtual bool canExecuteScripts(int contextGroupId) { return true; }
virtual void maxAsyncCallStackDepthChanged(int depth) {}
+
+ virtual std::unique_ptr<StringBuffer> resourceNameToUrl(
+ const StringView& resourceName) {
+ return nullptr;
+ }
};
// These stack trace ids are intended to be passed between debuggers and be
diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc
index e4e6492b67a0c5a2200875340dca4f3e8f3ab1b7..d9cb49b1d4d2ef354fd2478623a4046cd7c25354 100644
--- a/src/inspector/v8-debugger-agent-impl.cc
+++ b/src/inspector/v8-debugger-agent-impl.cc
@@ -1396,7 +1396,7 @@ void V8DebuggerAgentImpl::didParseSource(
protocol::StringUtil::parseJSON(inspected->auxData()));
}
bool isLiveEdit = script->isLiveEdit();
- bool hasSourceURL = script->hasSourceURL();
+ bool hasSourceURLComment = script->hasSourceURLComment();
bool isModule = script->isModule();
String16 scriptId = script->scriptId();
String16 scriptURL = script->sourceURL();
@@ -1416,7 +1416,8 @@ void V8DebuggerAgentImpl::didParseSource(
Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
std::move(executionContextAuxData));
const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
- const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
+ const bool* hasSourceURLParam =
+ hasSourceURLComment ? &hasSourceURLComment : nullptr;
const bool* isModuleParam = isModule ? &isModule : nullptr;
std::unique_ptr<V8StackTraceImpl> stack =
V8StackTraceImpl::capture(m_inspector->debugger(), contextGroupId, 1);
diff --git a/src/inspector/v8-debugger-script.cc b/src/inspector/v8-debugger-script.cc
index c40477ae2af74dfea6a950bc7be6e5b4efa42fe8..d861265e148559a16e27b20b371c4d7bba364add 100644
--- a/src/inspector/v8-debugger-script.cc
+++ b/src/inspector/v8-debugger-script.cc
@@ -6,6 +6,7 @@
#include "src/inspector/inspected-context.h"
#include "src/inspector/string-util.h"
+#include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/wasm-translation.h"
#include "src/utils.h"
@@ -110,9 +111,9 @@ class ActualScript : public V8DebuggerScript {
public:
ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
- bool isLiveEdit)
+ bool isLiveEdit, V8InspectorClient* client)
: V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
- GetNameOrSourceUrl(script)),
+ GetScriptURL(script, client)),
m_isLiveEdit(isLiveEdit) {
Initialize(script);
}
@@ -218,10 +219,18 @@ class ActualScript : public V8DebuggerScript {
}
private:
- String16 GetNameOrSourceUrl(v8::Local<v8::debug::Script> script) {
- v8::Local<v8::String> name;
- if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name))
- return toProtocolString(name);
+ String16 GetScriptURL(v8::Local<v8::debug::Script> script,
+ V8InspectorClient* client) {
+ v8::Local<v8::String> sourceURL;
+ if (script->SourceURL().ToLocal(&sourceURL) && sourceURL->Length() > 0)
+ return toProtocolString(sourceURL);
+ v8::Local<v8::String> v8Name;
+ if (script->Name().ToLocal(&v8Name) && v8Name->Length() > 0) {
+ String16 name = toProtocolString(v8Name);
+ std::unique_ptr<StringBuffer> url =
+ client->resourceNameToUrl(toStringView(name));
+ return url ? toString16(url->string()) : name;
+ }
return String16();
}
@@ -231,7 +240,8 @@ class ActualScript : public V8DebuggerScript {
void Initialize(v8::Local<v8::debug::Script> script) {
v8::Local<v8::String> tmp;
- if (script->SourceURL().ToLocal(&tmp)) m_sourceURL = toProtocolString(tmp);
+ m_hasSourceURLComment =
+ script->SourceURL().ToLocal(&tmp) && tmp->Length() > 0;
if (script->SourceMappingURL().ToLocal(&tmp))
m_sourceMappingURL = toProtocolString(tmp);
m_startLine = script->LineOffset();
@@ -398,9 +408,9 @@ class WasmVirtualScript : public V8DebuggerScript {
std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
- bool isLiveEdit) {
+ bool isLiveEdit, V8InspectorClient* client) {
return std::unique_ptr<ActualScript>(
- new ActualScript(isolate, scriptObj, isLiveEdit));
+ new ActualScript(isolate, scriptObj, isLiveEdit, client));
}
std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm(
@@ -418,12 +428,11 @@ V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
V8DebuggerScript::~V8DebuggerScript() {}
-const String16& V8DebuggerScript::sourceURL() const {
- return m_sourceURL.isEmpty() ? m_url : m_sourceURL;
-}
-
void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
- m_sourceURL = sourceURL;
+ if (sourceURL.length() > 0) {
+ m_hasSourceURLComment = true;
+ m_url = sourceURL;
+ }
}
bool V8DebuggerScript::setBreakpoint(const String16& condition,
@@ -431,5 +440,4 @@ bool V8DebuggerScript::setBreakpoint(const String16& condition,
v8::HandleScope scope(m_isolate);
return script()->SetBreakpoint(toV8String(m_isolate, condition), loc, id);
}
-
} // namespace v8_inspector
diff --git a/src/inspector/v8-debugger-script.h b/src/inspector/v8-debugger-script.h
index e0e7d93b20275221e873f026a9d44e663fad2e30..38e6448f48d8e8dcdde0935c516b45ddc7cf4db5 100644
--- a/src/inspector/v8-debugger-script.h
+++ b/src/inspector/v8-debugger-script.h
@@ -40,13 +40,14 @@
namespace v8_inspector {
// Forward declaration.
+class V8InspectorClient;
class WasmTranslation;
class V8DebuggerScript {
public:
static std::unique_ptr<V8DebuggerScript> Create(
v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
- bool isLiveEdit);
+ bool isLiveEdit, V8InspectorClient* client);
static std::unique_ptr<V8DebuggerScript> CreateWasm(
v8::Isolate* isolate, WasmTranslation* wasmTranslation,
v8::Local<v8::debug::WasmScript> underlyingScript, String16 id,
@@ -55,9 +56,9 @@ class V8DebuggerScript {
virtual ~V8DebuggerScript();
const String16& scriptId() const { return m_id; }
- const String16& url() const { return m_url; }
- bool hasSourceURL() const { return !m_sourceURL.isEmpty(); }
- const String16& sourceURL() const;
+ bool hasSourceURLComment() const { return m_hasSourceURLComment; }
+ const String16& sourceURL() const { return m_url; }
+
virtual const String16& sourceMappingURL() const = 0;
virtual const String16& source() const = 0;
virtual const String16& hash() const = 0;
@@ -95,7 +96,7 @@ class V8DebuggerScript {
String16 m_id;
String16 m_url;
- String16 m_sourceURL;
+ bool m_hasSourceURLComment = false;
int m_executionContextId = 0;
v8::Isolate* m_isolate;
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc
index 1ceb4210f7f476ddbc1fc795239d6b2153788a55..7d1f7cefd15db3f5482e27fa47880bb6227bb322 100644
--- a/src/inspector/v8-debugger.cc
+++ b/src/inspector/v8-debugger.cc
@@ -226,13 +226,15 @@ void V8Debugger::getCompiledScripts(
v8::Local<v8::debug::Script> script = scripts.Get(i);
if (!script->WasCompiled()) continue;
if (script->IsEmbedded()) {
- result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
+ result.push_back(V8DebuggerScript::Create(m_isolate, script, false,
+ m_inspector->client()));
continue;
}
int contextId;
if (!script->ContextId().To(&contextId)) continue;
if (m_inspector->contextGroupId(contextId) != contextGroupId) continue;
- result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
+ result.push_back(V8DebuggerScript::Create(m_isolate, script, false,
+ m_inspector->client()));
}
}
@@ -585,13 +587,14 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
});
} else if (m_ignoreScriptParsedEventsCounter == 0) {
v8::Isolate* isolate = m_isolate;
+ V8InspectorClient* client = m_inspector->client();
m_inspector->forEachSession(
m_inspector->contextGroupId(contextId),
- [&isolate, &script, &has_compile_error,
- &is_live_edited](V8InspectorSessionImpl* session) {
+ [&isolate, &script, &has_compile_error, &is_live_edited,
+ &client](V8InspectorSessionImpl* session) {
if (!session->debuggerAgent()->enabled()) return;
session->debuggerAgent()->didParseSource(
- V8DebuggerScript::Create(isolate, script, is_live_edited),
+ V8DebuggerScript::Create(isolate, script, is_live_edited, client),
!has_compile_error);
});
}
diff --git a/src/inspector/v8-profiler-agent-impl.cc b/src/inspector/v8-profiler-agent-impl.cc
index 59a99d79d54c2fb8dee1ff3e950a1c995889a8ac..f14815fdc4b031c640795ce10fb4b963310656be 100644
--- a/src/inspector/v8-profiler-agent-impl.cc
+++ b/src/inspector/v8-profiler-agent-impl.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "src/base/atomicops.h"
+#include "src/debug/debug-interface.h"
#include "src/flags.h" // TODO(jgruber): Remove include and DEPS entry.
#include "src/inspector/protocol/Protocol.h"
#include "src/inspector/string-util.h"
@@ -31,6 +32,15 @@ static const char typeProfileStarted[] = "typeProfileStarted";
namespace {
+String16 resourceNameToUrl(V8InspectorImpl* inspector,
+ v8::Local<v8::String> v8Name) {
+ String16 name = toProtocolString(v8Name);
+ if (!inspector) return name;
+ std::unique_ptr<StringBuffer> url =
+ inspector->client()->resourceNameToUrl(toStringView(name));
+ return url ? toString16(url->string()) : name;
+}
+
std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>>
buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) {
unsigned lineCount = node->GetHitLineCount();
@@ -51,13 +61,14 @@ buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) {
}
std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor(
- v8::Isolate* isolate, const v8::CpuProfileNode* node) {
+ V8InspectorImpl* inspector, const v8::CpuProfileNode* node) {
+ v8::Isolate* isolate = inspector->isolate();
v8::HandleScope handleScope(isolate);
auto callFrame =
protocol::Runtime::CallFrame::create()
.setFunctionName(toProtocolString(node->GetFunctionName()))
.setScriptId(String16::fromInteger(node->GetScriptId()))
- .setUrl(toProtocolString(node->GetScriptResourceName()))
+ .setUrl(resourceNameToUrl(inspector, node->GetScriptResourceName()))
.setLineNumber(node->GetLineNumber() - 1)
.setColumnNumber(node->GetColumnNumber() - 1)
.build();
@@ -107,18 +118,19 @@ std::unique_ptr<protocol::Array<int>> buildInspectorObjectForTimestamps(
return array;
}
-void flattenNodesTree(v8::Isolate* isolate, const v8::CpuProfileNode* node,
+void flattenNodesTree(V8InspectorImpl* inspector,
+ const v8::CpuProfileNode* node,
protocol::Array<protocol::Profiler::ProfileNode>* list) {
- list->addItem(buildInspectorObjectFor(isolate, node));
+ list->addItem(buildInspectorObjectFor(inspector, node));
const int childrenCount = node->GetChildrenCount();
for (int i = 0; i < childrenCount; i++)
- flattenNodesTree(isolate, node->GetChild(i), list);
+ flattenNodesTree(inspector, node->GetChild(i), list);
}
std::unique_ptr<protocol::Profiler::Profile> createCPUProfile(
- v8::Isolate* isolate, v8::CpuProfile* v8profile) {
+ V8InspectorImpl* inspector, v8::CpuProfile* v8profile) {
auto nodes = protocol::Array<protocol::Profiler::ProfileNode>::create();
- flattenNodesTree(isolate, v8profile->GetTopDownRoot(), nodes.get());
+ flattenNodesTree(inspector, v8profile->GetTopDownRoot(), nodes.get());
return protocol::Profiler::Profile::create()
.setNodes(std::move(nodes))
.setStartTime(static_cast<double>(v8profile->GetStartTime()))
@@ -320,7 +332,7 @@ std::unique_ptr<protocol::Profiler::CoverageRange> createCoverageRange(
}
Response coverageToProtocol(
- v8::Isolate* isolate, const v8::debug::Coverage& coverage,
+ V8InspectorImpl* inspector, const v8::debug::Coverage& coverage,
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
out_result) {
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result =
@@ -361,8 +373,10 @@ Response coverageToProtocol(
}
String16 url;
v8::Local<v8::String> name;
- if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
+ if (script->SourceURL().ToLocal(&name) && name->Length()) {
url = toProtocolString(name);
+ } else if (script->Name().ToLocal(&name) && name->Length()) {
+ url = resourceNameToUrl(inspector, name);
}
result->addItem(protocol::Profiler::ScriptCoverage::create()
.setScriptId(String16::fromInteger(script->Id()))
@@ -384,7 +398,7 @@ Response V8ProfilerAgentImpl::takePreciseCoverage(
}
v8::HandleScope handle_scope(m_isolate);
v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate);
- return coverageToProtocol(m_isolate, coverage, out_result);
+ return coverageToProtocol(m_session->inspector(), coverage, out_result);
}
Response V8ProfilerAgentImpl::getBestEffortCoverage(
@@ -393,12 +407,12 @@ Response V8ProfilerAgentImpl::getBestEffortCoverage(
v8::HandleScope handle_scope(m_isolate);
v8::debug::Coverage coverage =
v8::debug::Coverage::CollectBestEffort(m_isolate);
- return coverageToProtocol(m_isolate, coverage, out_result);
+ return coverageToProtocol(m_session->inspector(), coverage, out_result);
}
namespace {
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>
-typeProfileToProtocol(v8::Isolate* isolate,
+typeProfileToProtocol(V8InspectorImpl* inspector,
const v8::debug::TypeProfile& type_profile) {
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>
result = protocol::Array<protocol::Profiler::ScriptTypeProfile>::create();
@@ -426,8 +440,10 @@ typeProfileToProtocol(v8::Isolate* isolate,
}
String16 url;
v8::Local<v8::String> name;
- if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
+ if (script->SourceURL().ToLocal(&name) && name->Length()) {
url = toProtocolString(name);
+ } else if (script->Name().ToLocal(&name) && name->Length()) {
+ url = resourceNameToUrl(inspector, name);
}
result->addItem(protocol::Profiler::ScriptTypeProfile::create()
.setScriptId(String16::fromInteger(script->Id()))
@@ -462,7 +478,7 @@ Response V8ProfilerAgentImpl::takeTypeProfile(
v8::HandleScope handle_scope(m_isolate);
v8::debug::TypeProfile type_profile =
v8::debug::TypeProfile::Collect(m_isolate);
- *out_result = typeProfileToProtocol(m_isolate, type_profile);
+ *out_result = typeProfileToProtocol(m_session->inspector(), type_profile);
return Response::OK();
}
@@ -491,7 +507,7 @@ std::unique_ptr<protocol::Profiler::Profile> V8ProfilerAgentImpl::stopProfiling(
m_profiler->StopProfiling(toV8String(m_isolate, title));
std::unique_ptr<protocol::Profiler::Profile> result;
if (profile) {
- if (serialize) result = createCPUProfile(m_isolate, profile);
+ if (serialize) result = createCPUProfile(m_session->inspector(), profile);
profile->Delete();
}
--m_startedProfilesCount;
diff --git a/src/inspector/v8-stack-trace-impl.cc b/src/inspector/v8-stack-trace-impl.cc
index 75293c59afee8e09f05a33d8aa806ee79bd01e99..9be0d4fa385f2a02da6ba9865f7d658ac1912a5e 100644
--- a/src/inspector/v8-stack-trace-impl.cc
+++ b/src/inspector/v8-stack-trace-impl.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "src/inspector/v8-debugger.h"
+#include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/wasm-translation.h"
namespace v8_inspector {
@@ -73,7 +74,10 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon(
std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>>
inspectorFrames = protocol::Array<protocol::Runtime::CallFrame>::create();
for (size_t i = 0; i < frames.size(); i++) {
- inspectorFrames->addItem(frames[i]->buildInspectorObject());
+ V8InspectorClient* client = nullptr;
+ if (debugger && debugger->inspector())
+ client = debugger->inspector()->client();
+ inspectorFrames->addItem(frames[i]->buildInspectorObject(client));
}
std::unique_ptr<protocol::Runtime::StackTrace> stackTrace =
protocol::Runtime::StackTrace::create()
@@ -117,7 +121,9 @@ StackFrame::StackFrame(v8::Local<v8::StackFrame> v8Frame)
m_scriptId(String16::fromInteger(v8Frame->GetScriptId())),
m_sourceURL(toProtocolString(v8Frame->GetScriptNameOrSourceURL())),
m_lineNumber(v8Frame->GetLineNumber() - 1),
- m_columnNumber(v8Frame->GetColumn() - 1) {
+ m_columnNumber(v8Frame->GetColumn() - 1),
+ m_hasSourceURLComment(v8Frame->GetScriptName() !=
+ v8Frame->GetScriptNameOrSourceURL()) {
DCHECK_NE(v8::Message::kNoLineNumberInfo, m_lineNumber + 1);
DCHECK_NE(v8::Message::kNoColumnInfo, m_columnNumber + 1);
}
@@ -137,12 +143,20 @@ int StackFrame::lineNumber() const { return m_lineNumber; }
int StackFrame::columnNumber() const { return m_columnNumber; }
-std::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject()
- const {
+std::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject(
+ V8InspectorClient* client) const {
+ String16 frameUrl = m_sourceURL;
+ if (client && !m_hasSourceURLComment && frameUrl.length() > 0) {
+ std::unique_ptr<StringBuffer> url =
+ client->resourceNameToUrl(toStringView(m_sourceURL));
+ if (url) {
+ frameUrl = toString16(url->string());
+ }
+ }
return protocol::Runtime::CallFrame::create()
.setFunctionName(m_functionName)
.setScriptId(m_scriptId)
- .setUrl(m_sourceURL)
+ .setUrl(frameUrl)
.setLineNumber(m_lineNumber)
.setColumnNumber(m_columnNumber)
.build();
diff --git a/src/inspector/v8-stack-trace-impl.h b/src/inspector/v8-stack-trace-impl.h
index a8f23c48b67231f6015d1004ec14995c65967239..019fd469cdd72e1fd03ed7a0ab8554e054fb8498 100644
--- a/src/inspector/v8-stack-trace-impl.h
+++ b/src/inspector/v8-stack-trace-impl.h
@@ -33,7 +33,8 @@ class StackFrame {
const String16& sourceURL() const;
int lineNumber() const; // 0-based.
int columnNumber() const; // 0-based.
- std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject() const;
+ std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject(
+ V8InspectorClient* client) const;
bool isEqual(StackFrame* frame) const;
private:
@@ -42,6 +43,7 @@ class StackFrame {
String16 m_sourceURL;
int m_lineNumber; // 0-based.
int m_columnNumber; // 0-based.
+ bool m_hasSourceURLComment;
};
class V8StackTraceImpl : public V8StackTrace {
diff --git a/test/inspector/debugger/resource-name-to-url-expected.txt b/test/inspector/debugger/resource-name-to-url-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0ecd0b82ef239072ab20a4d8844fa48b4b477586
--- /dev/null
+++ b/test/inspector/debugger/resource-name-to-url-expected.txt
@@ -0,0 +1,122 @@
+Tests V8InspectorClient::resourceNameToUrl.
+Check script with url:
+{
+ method : Debugger.scriptParsed
+ params : {
+ endColumn : 16
+ endLine : 0
+ executionContextId : <executionContextId>
+ hasSourceURL : false
+ hash : 033b33d191ed51ed823355d865eb871d811403e2
+ isLiveEdit : false
+ isModule : false
+ length : 16
+ scriptId : <scriptId>
+ sourceMapURL :
+ startColumn : 0
+ startLine : 0
+ url : prefix://url
+ }
+}
+Check script with sourceURL comment:
+{
+ method : Debugger.scriptParsed
+ params : {
+ endColumn : 37
+ endLine : 0
+ executionContextId : <executionContextId>
+ hasSourceURL : true
+ hash : 06c136ce206c5f505f32af524e6ec71b5baa0bbb
+ isLiveEdit : false
+ isModule : false
+ length : 37
+ scriptId : <scriptId>
+ sourceMapURL :
+ startColumn : 0
+ startLine : 0
+ url : foo.js
+ }
+}
+Check script failed to parse:
+{
+ method : Debugger.scriptFailedToParse
+ params : {
+ endColumn : 15
+ endLine : 0
+ executionContextId : <executionContextId>
+ hasSourceURL : false
+ hash : 033b33d191ed51ed1f44cd0465eb871d811403e2
+ isModule : false
+ length : 15
+ scriptId : <scriptId>
+ sourceMapURL :
+ startColumn : 0
+ startLine : 0
+ url : prefix://url
+ }
+}
+Check script failed to parse with sourceURL comment:
+{
+ method : Debugger.scriptFailedToParse
+ params : {
+ endColumn : 36
+ endLine : 0
+ executionContextId : <executionContextId>
+ hasSourceURL : true
+ hash : 23a2885951475580023e2a742563d78876d8f05e
+ isModule : false
+ length : 36
+ scriptId : <scriptId>
+ sourceMapURL :
+ startColumn : 0
+ startLine : 0
+ url : foo.js
+ }
+}
+Test runtime stack trace:
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ description : 42
+ type : number
+ value : 42
+ }
+ ]
+ executionContextId : <executionContextId>
+ stackTrace : {
+ callFrames : [
+ [0] : {
+ columnNumber : 14
+ functionName : foo
+ lineNumber : 2
+ scriptId : <scriptId>
+ url : prefix://url
+ }
+ [1] : {
+ columnNumber : 0
+ functionName :
+ lineNumber : 0
+ scriptId : <scriptId>
+ url : boo.js
+ }
+ [2] : {
+ columnNumber : 4
+ functionName :
+ lineNumber : 4
+ scriptId : <scriptId>
+ url : prefix://url
+ }
+ ]
+ }
+ timestamp : <timestamp>
+ type : log
+ }
+}
+Test debugger stack trace:
+[
+ [0] : prefix://url
+ [1] : boo.js
+ [2] : prefix://url
+]
diff --git a/test/inspector/debugger/resource-name-to-url.js b/test/inspector/debugger/resource-name-to-url.js
new file mode 100644
index 0000000000000000000000000000000000000000..620c7a2864b406539fc7fc0e4b5a89b06a0847f3
--- /dev/null
+++ b/test/inspector/debugger/resource-name-to-url.js
@@ -0,0 +1,49 @@
+// Copyright 2018 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Tests V8InspectorClient::resourceNameToUrl.');
+
+(async function test(){
+ Protocol.Runtime.enable();
+ await Protocol.Debugger.enable();
+ contextGroup.addScript(`inspector.setResourceNamePrefix('prefix://')`);
+ await Protocol.Debugger.onceScriptParsed();
+
+ InspectorTest.log('Check script with url:');
+ contextGroup.addScript('function foo(){}', 0, 0, 'url');
+ InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed());
+
+ InspectorTest.log('Check script with sourceURL comment:');
+ contextGroup.addScript('function foo(){} //# sourceURL=foo.js', 0, 0, 'url');
+ InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed());
+
+ InspectorTest.log('Check script failed to parse:');
+ contextGroup.addScript('function foo(){', 0, 0, 'url');
+ InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse());
+
+ InspectorTest.log('Check script failed to parse with sourceURL comment:');
+ contextGroup.addScript('function foo(){ //# sourceURL=foo.js', 0, 0, 'url');
+ InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse());
+
+ InspectorTest.log('Test runtime stack trace:');
+ contextGroup.addScript(`
+ function foo() {
+ console.log(42);
+ }
+ eval('foo(); //# sourceURL=boo.js');
+ `, 0, 0, 'url');
+ InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+ InspectorTest.log('Test debugger stack trace:');
+ contextGroup.addScript(`
+ function foo() {
+ debugger;
+ }
+ eval('foo(); //# sourceURL=boo.js');
+ `, 0, 0, 'url');
+ const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+ InspectorTest.logMessage(callFrames.map(frame => frame.url));
+ InspectorTest.completeTest();
+})();
diff --git a/test/inspector/inspector-test.cc b/test/inspector/inspector-test.cc
index 668a9463d5b9cf7db0981b6907e303425df6c25c..93a8b1d3f2188015aa153cdc15b3b369d1f353d9 100644
--- a/test/inspector/inspector-test.cc
+++ b/test/inspector/inspector-test.cc
@@ -712,6 +712,9 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
ToV8String(isolate, "setAllowCodeGenerationFromStrings"),
v8::FunctionTemplate::New(
isolate, &InspectorExtension::SetAllowCodeGenerationFromStrings));
+ inspector->Set(ToV8String(isolate, "setResourceNamePrefix"),
+ v8::FunctionTemplate::New(
+ isolate, &InspectorExtension::SetResourceNamePrefix));
global->Set(ToV8String(isolate, "inspector"), inspector);
}
@@ -973,6 +976,18 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
args.GetIsolate()->GetCurrentContext()->AllowCodeGenerationFromStrings(
args[0].As<v8::Boolean>()->Value());
}
+
+ static void SetResourceNamePrefix(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ if (args.Length() != 1 || !args[0]->IsString()) {
+ fprintf(stderr, "Internal error: setResourceNamePrefix('prefix').");
+ Exit();
+ }
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ IsolateData* data = IsolateData::FromContext(context);
+ data->SetResourceNamePrefix(v8::Local<v8::String>::Cast(args[0]));
+ }
};
bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
diff --git a/test/inspector/isolate-data.cc b/test/inspector/isolate-data.cc
index 15eee89a61faa25d6f635b6983d81bdea943c8e1..a669cc41a1f26a2c6a76c59eb081c8ca0a83bfdd 100644
--- a/test/inspector/isolate-data.cc
+++ b/test/inspector/isolate-data.cc
@@ -423,3 +423,32 @@ void IsolateData::maxAsyncCallStackDepthChanged(int depth) {
if (!log_max_async_call_stack_depth_changed_) return;
fprintf(stdout, "maxAsyncCallStackDepthChanged: %d\n", depth);
}
+
+void IsolateData::SetResourceNamePrefix(v8::Local<v8::String> prefix) {
+ resource_name_prefix_.Reset(v8::Isolate::GetCurrent(), prefix);
+}
+
+namespace {
+class StringBufferImpl : public v8_inspector::StringBuffer {
+ public:
+ StringBufferImpl(v8::Isolate* isolate, v8::Local<v8::String> string)
+ : data_(ToVector(string)),
+ view_(data_.start(), data_.length()) {}
+ const v8_inspector::StringView& string() override { return view_; }
+
+ private:
+ v8::internal::Vector<uint16_t> data_;
+ v8_inspector::StringView view_;
+};
+} // anonymous namespace
+
+std::unique_ptr<v8_inspector::StringBuffer> IsolateData::resourceNameToUrl(
+ const v8_inspector::StringView& resourceName) {
+ if (resource_name_prefix_.IsEmpty()) return nullptr;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::String> name = ToString(isolate, resourceName);
+ v8::Local<v8::String> prefix = resource_name_prefix_.Get(isolate);
+ v8::Local<v8::String> url = v8::String::Concat(prefix, name);
+ return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(isolate, url));
+}
diff --git a/test/inspector/isolate-data.h b/test/inspector/isolate-data.h
index 5eb9803a7416fb67937283960c90269681403c1f..d0a263e573827c3b22810d70b0cf4f0c6f9243f3 100644
--- a/test/inspector/isolate-data.h
+++ b/test/inspector/isolate-data.h
@@ -76,6 +76,7 @@ class IsolateData : public v8_inspector::V8InspectorClient {
void FireContextCreated(v8::Local<v8::Context> context, int context_group_id);
void FireContextDestroyed(v8::Local<v8::Context> context);
void FreeContext(v8::Local<v8::Context> context);
+ void SetResourceNamePrefix(v8::Local<v8::String> prefix);
private:
struct VectorCompare {
@@ -114,6 +115,8 @@ class IsolateData : public v8_inspector::V8InspectorClient {
v8_inspector::V8StackTrace*) override;
bool isInspectableHeapObject(v8::Local<v8::Object>) override;
void maxAsyncCallStackDepthChanged(int depth) override;
+ std::unique_ptr<v8_inspector::StringBuffer> resourceNameToUrl(
+ const v8_inspector::StringView& resourceName) override;
// The isolate gets deleted by its {Dispose} method, not by the default
// deleter. Therefore we have to define a custom deleter for the unique_ptr to
@@ -141,6 +144,7 @@ class IsolateData : public v8_inspector::V8InspectorClient {
bool log_console_api_message_calls_ = false;
bool log_max_async_call_stack_depth_changed_ = false;
v8::Global<v8::Private> not_inspectable_private_;
+ v8::Global<v8::String> resource_name_prefix_;
DISALLOW_COPY_AND_ASSIGN(IsolateData);
};

View file

@ -1,364 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Camillo Bruni <cbruni@chromium.org>
Date: Sat, 18 Aug 2018 13:41:51 -0400
Subject: deps: cherry-pick e1a7699 from upstream V8
Original commit message:
[api][runtime] Support all-in ctors of {Named,Indexed}PropertyHandlerConfiguration
- Explicitly allows construction of
{Named,Indexed}PropertyHandlerConfiguration with all the members filled.
Bug: v8:7612
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I426ea33846b5dbf2b3482c722c963a6e4b0abded
Reviewed-on: https://chromium-review.googlesource.com/1163882
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55142}
PR-URL: https://github.com/nodejs/node/pull/22390
Fixes: https://github.com/nodejs/node/issues/17480
Fixes: https://github.com/nodejs/node/issues/17481
Refs: https://github.com/v8/v8/commit/e1a76995ef311eb3ca66e12ef1941ed596034d59
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/include/v8.h b/include/v8.h
index 23d5ba36db97dab2bb706ab90930ee1403a68104..20a65afcbc61c31360874e45adc03eeda02e9a81 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -5994,6 +5994,26 @@ enum class PropertyHandlerFlags {
};
struct NamedPropertyHandlerConfiguration {
+ NamedPropertyHandlerConfiguration(
+ GenericNamedPropertyGetterCallback getter,
+ GenericNamedPropertySetterCallback setter,
+ GenericNamedPropertyQueryCallback query,
+ GenericNamedPropertyDeleterCallback deleter,
+ GenericNamedPropertyEnumeratorCallback enumerator,
+ GenericNamedPropertyDefinerCallback definer,
+ GenericNamedPropertyDescriptorCallback descriptor,
+ Local<Value> data = Local<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+ : getter(getter),
+ setter(setter),
+ query(query),
+ deleter(deleter),
+ enumerator(enumerator),
+ definer(definer),
+ descriptor(descriptor),
+ data(data),
+ flags(flags) {}
+
NamedPropertyHandlerConfiguration(
/** Note: getter is required */
GenericNamedPropertyGetterCallback getter = 0,
@@ -6045,6 +6065,25 @@ struct NamedPropertyHandlerConfiguration {
struct IndexedPropertyHandlerConfiguration {
+ IndexedPropertyHandlerConfiguration(
+ IndexedPropertyGetterCallback getter,
+ IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query,
+ IndexedPropertyDeleterCallback deleter,
+ IndexedPropertyEnumeratorCallback enumerator,
+ IndexedPropertyDefinerCallback definer,
+ IndexedPropertyDescriptorCallback descriptor,
+ Local<Value> data = Local<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+ : getter(getter),
+ setter(setter),
+ query(query),
+ deleter(deleter),
+ enumerator(enumerator),
+ definer(definer),
+ descriptor(descriptor),
+ data(data),
+ flags(flags) {}
+
IndexedPropertyHandlerConfiguration(
/** Note: getter is required */
IndexedPropertyGetterCallback getter = 0,
diff --git a/src/api.cc b/src/api.cc
index 7c569e3a9f0824e1c61b665236589e3b7c1cc464..6155cbb32579effc500b5c475cd478e77b3ecdf4 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1879,10 +1879,6 @@ static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
i::Isolate* isolate, Getter getter, Setter setter, Query query,
Descriptor descriptor, Deleter remover, Enumerator enumerator,
Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
- // Either intercept attributes or descriptor.
- DCHECK(query == nullptr || descriptor == nullptr);
- // Only use descriptor callback with definer callback.
- DCHECK(query == nullptr || definer == nullptr);
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE, i::TENURED));
obj->set_flags(0);
diff --git a/src/objects.cc b/src/objects.cc
index 01421bacc4495150fe9dc05469e216c66d513c64..0aac39d30427e0a02b8c99b0b08ea40712ab1dad 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -7817,41 +7817,42 @@ Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
}
}
- if (it->state() == LookupIterator::INTERCEPTOR) {
- Isolate* isolate = it->isolate();
- Handle<InterceptorInfo> interceptor = it->GetInterceptor();
- if (!interceptor->descriptor()->IsUndefined(isolate)) {
- Handle<Object> result;
- Handle<JSObject> holder = it->GetHolder<JSObject>();
+ if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
- Handle<Object> receiver = it->GetReceiver();
- if (!receiver->IsJSReceiver()) {
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, receiver, Object::ConvertReceiver(isolate, receiver),
- Nothing<bool>());
- }
+ Isolate* isolate = it->isolate();
+ Handle<InterceptorInfo> interceptor = it->GetInterceptor();
+ if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
- PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
- *holder, kDontThrow);
- if (it->IsElement()) {
- result = args.CallIndexedDescriptor(interceptor, it->index());
- } else {
- result = args.CallNamedDescriptor(interceptor, it->name());
- }
- if (!result.is_null()) {
- // Request successfully intercepted, try to set the property
- // descriptor.
- Utils::ApiCheck(
- PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
- it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
- : "v8::NamedPropertyDescriptorCallback",
- "Invalid property descriptor.");
+ Handle<Object> result;
+ Handle<JSObject> holder = it->GetHolder<JSObject>();
- return Just(true);
- }
- it->Next();
- }
+ Handle<Object> receiver = it->GetReceiver();
+ if (!receiver->IsJSReceiver()) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
+ Object::ConvertReceiver(isolate, receiver),
+ Nothing<bool>());
+ }
+
+ PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
+ *holder, kDontThrow);
+ if (it->IsElement()) {
+ result = args.CallIndexedDescriptor(interceptor, it->index());
+ } else {
+ result = args.CallNamedDescriptor(interceptor, it->name());
}
+ if (!result.is_null()) {
+ // Request successfully intercepted, try to set the property
+ // descriptor.
+ Utils::ApiCheck(
+ PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
+ it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
+ : "v8::NamedPropertyDescriptorCallback",
+ "Invalid property descriptor.");
+
+ return Just(true);
+ }
+
+ it->Next();
return Just(false);
}
} // namespace
diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc
index 2f9f0e459e6fed4c688fc0ee7389593cf86e07c8..b13384f18adfefe69dc5be232a5f620a7efd8ba7 100644
--- a/test/unittests/api/interceptor-unittest.cc
+++ b/test/unittests/api/interceptor-unittest.cc
@@ -29,4 +29,180 @@ TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) {
}
} // namespace
+
+namespace internal {
+namespace {
+
+class InterceptorLoggingTest : public TestWithNativeContext {
+ public:
+ InterceptorLoggingTest() {}
+
+ static const int kTestIndex = 0;
+
+ static void NamedPropertyGetter(Local<v8::Name> name,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named getter");
+ }
+
+ static void NamedPropertySetter(Local<v8::Name> name, Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named setter");
+ }
+
+ static void NamedPropertyQuery(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ LogCallback(info, "named query");
+ }
+
+ static void NamedPropertyDeleter(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ LogCallback(info, "named deleter");
+ }
+
+ static void NamedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<Array>& info) {
+ LogCallback(info, "named enumerator");
+ }
+
+ static void NamedPropertyDefiner(
+ Local<v8::Name> name, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named definer");
+ }
+
+ static void NamedPropertyDescriptor(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named descriptor");
+ }
+
+ static void IndexedPropertyGetter(
+ uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed getter");
+ }
+
+ static void IndexedPropertySetter(
+ uint32_t index, Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed setter");
+ }
+
+ static void IndexedPropertyQuery(
+ uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ LogCallback(info, "indexed query");
+ }
+
+ static void IndexedPropertyDeleter(
+ uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ LogCallback(info, "indexed deleter");
+ }
+
+ static void IndexedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<Array>& info) {
+ LogCallback(info, "indexed enumerator");
+ }
+
+ static void IndexedPropertyDefiner(
+ uint32_t index, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed definer");
+ }
+
+ static void IndexedPropertyDescriptor(
+ uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed descriptor");
+ }
+
+ template <class T>
+ static void LogCallback(const v8::PropertyCallbackInfo<T>& info,
+ const char* callback_name) {
+ InterceptorLoggingTest* test = reinterpret_cast<InterceptorLoggingTest*>(
+ info.This()->GetAlignedPointerFromInternalField(kTestIndex));
+ test->Log(callback_name);
+ }
+
+ void Log(const char* callback_name) {
+ if (log_is_empty_) {
+ log_is_empty_ = false;
+ } else {
+ log_ << ", ";
+ }
+ log_ << callback_name;
+ }
+
+ protected:
+ void SetUp() override {
+ // Set up the object that supports full interceptors.
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(v8_isolate());
+ templ->SetInternalFieldCount(1);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NamedPropertyGetter, NamedPropertySetter, NamedPropertyQuery,
+ NamedPropertyDeleter, NamedPropertyEnumerator, NamedPropertyDefiner,
+ NamedPropertyDescriptor));
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ IndexedPropertyGetter, IndexedPropertySetter, IndexedPropertyQuery,
+ IndexedPropertyDeleter, IndexedPropertyEnumerator,
+ IndexedPropertyDefiner, IndexedPropertyDescriptor));
+ v8::Local<v8::Object> instance =
+ templ->NewInstance(context()).ToLocalChecked();
+ instance->SetAlignedPointerInInternalField(kTestIndex, this);
+ SetGlobalProperty("obj", instance);
+ }
+
+ std::string Run(const char* script) {
+ log_is_empty_ = true;
+ log_.str(std::string());
+ log_.clear();
+
+ RunJS(script);
+ return log_.str();
+ }
+
+ private:
+ bool log_is_empty_ = false;
+ std::stringstream log_;
+};
+
+TEST_F(InterceptorLoggingTest, DispatchTest) {
+ EXPECT_EQ(Run("for (var p in obj) {}"),
+ "indexed enumerator, named enumerator");
+ EXPECT_EQ(Run("Object.keys(obj)"), "indexed enumerator, named enumerator");
+
+ EXPECT_EQ(Run("obj.foo"), "named getter");
+ EXPECT_EQ(Run("obj[42]"), "indexed getter");
+
+ EXPECT_EQ(Run("obj.foo = null"), "named setter");
+ EXPECT_EQ(Run("obj[42] = null"), "indexed setter");
+
+ EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
+ "named descriptor");
+
+ EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 42)"),
+ "indexed descriptor");
+
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {value: 42})"),
+ "named descriptor, named definer, named setter");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){} })"),
+ "named descriptor, named definer");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {set(value){}})"),
+ "named descriptor, named definer");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){}, set(value){}})"),
+ "named descriptor, named definer");
+
+ EXPECT_EQ(Run("Object.defineProperty(obj, 42, {value: 'foo'})"),
+ "indexed descriptor, "
+ // then attempt definer first and fallback to setter.
+ "indexed definer, indexed setter");
+
+ EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 'a')"),
+ "named query");
+ EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 42)"),
+ "indexed query");
+
+ EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, 'a')"),
+ "named query");
+ // TODO(cbruni): Fix once hasOnwProperty is fixed (https://crbug.com/872628)
+ EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, '42')"), "");
+}
+} // namespace
+} // namespace internal
} // namespace v8

View file

@ -0,0 +1,352 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anna Henningsen <anna@addaleax.net>
Date: Fri, 28 Sep 2018 22:43:38 -0400
Subject: deps: provide more V8 backwards compatibility
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add back a number deprecated APIs, using shims that
should work well enough at least for the duration of Node 11
and do not come with significant maintenance overhead.
Refs: https://github.com/nodejs/node/issues/23122
PR-URL: https://github.com/nodejs/node/pull/23158
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
diff --git a/include/v8.h b/include/v8.h
index 784e1830edeebaf2b15eaad4230f318f91acad5f..cc2fefc56a4eeaeab48f2042d6c8dbbadb1e3210 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1123,6 +1123,10 @@ class V8_EXPORT PrimitiveArray {
public:
static Local<PrimitiveArray> New(Isolate* isolate, int length);
int Length() const;
+ V8_DEPRECATED("Use Isolate* version",
+ void Set(int index, Local<Primitive> item));
+ V8_DEPRECATED("Use Isolate* version",
+ Local<Primitive> Get(int index));
void Set(Isolate* isolate, int index, Local<Primitive> item);
Local<Primitive> Get(Isolate* isolate, int index);
};
@@ -1829,6 +1833,8 @@ class V8_EXPORT StackTrace {
/**
* Returns a StackFrame at a particular index.
*/
+ V8_DEPRECATED("Use Isolate version",
+ Local<StackFrame> GetFrame(uint32_t index) const);
Local<StackFrame> GetFrame(Isolate* isolate, uint32_t index) const;
/**
@@ -2537,6 +2543,13 @@ class V8_EXPORT Value : public Data {
V8_DEPRECATE_SOON("Use maybe version",
Local<Int32> ToInt32(Isolate* isolate) const);
+ inline V8_DEPRECATED("Use maybe version",
+ Local<Boolean> ToBoolean() const);
+ inline V8_DEPRECATED("Use maybe version", Local<String> ToString() const);
+ inline V8_DEPRECATED("Use maybe version", Local<Object> ToObject() const);
+ inline V8_DEPRECATED("Use maybe version",
+ Local<Integer> ToInteger() const);
+
/**
* Attempts to convert a string to an array index.
* Returns an empty handle if the conversion fails.
@@ -2552,7 +2565,14 @@ class V8_EXPORT Value : public Data {
Local<Context> context) const;
V8_WARN_UNUSED_RESULT Maybe<int32_t> Int32Value(Local<Context> context) const;
+ V8_DEPRECATED("Use maybe version", bool BooleanValue() const);
+ V8_DEPRECATED("Use maybe version", double NumberValue() const);
+ V8_DEPRECATED("Use maybe version", int64_t IntegerValue() const);
+ V8_DEPRECATED("Use maybe version", uint32_t Uint32Value() const);
+ V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
+
/** JS == */
+ V8_DEPRECATED("Use maybe version", bool Equals(Local<Value> that) const);
V8_WARN_UNUSED_RESULT Maybe<bool> Equals(Local<Context> context,
Local<Value> that) const;
bool StrictEquals(Local<Value> that) const;
@@ -2659,6 +2679,8 @@ class V8_EXPORT String : public Name {
* Returns the number of bytes in the UTF-8 encoded
* representation of this string.
*/
+ V8_DEPRECATED("Use Isolate version instead", int Utf8Length() const);
+
int Utf8Length(Isolate* isolate) const;
/**
@@ -2715,12 +2737,23 @@ class V8_EXPORT String : public Name {
// 16-bit character codes.
int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
int options = NO_OPTIONS) const;
+ V8_DEPRECATED("Use Isolate* version",
+ int Write(uint16_t* buffer, int start = 0, int length = -1,
+ int options = NO_OPTIONS) const);
// One byte characters.
int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
int length = -1, int options = NO_OPTIONS) const;
+ V8_DEPRECATED("Use Isolate* version",
+ int WriteOneByte(uint8_t* buffer, int start = 0,
+ int length = -1, int options = NO_OPTIONS)
+ const);
// UTF-8 encoded characters.
int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
int* nchars_ref = NULL, int options = NO_OPTIONS) const;
+ V8_DEPRECATED("Use Isolate* version",
+ int WriteUtf8(char* buffer, int length = -1,
+ int* nchars_ref = NULL,
+ int options = NO_OPTIONS) const);
/**
* A zero length string.
@@ -2884,6 +2917,9 @@ class V8_EXPORT String : public Name {
*/
static Local<String> Concat(Isolate* isolate, Local<String> left,
Local<String> right);
+ static V8_DEPRECATED("Use Isolate* version",
+ Local<String> Concat(Local<String> left,
+ Local<String> right));
/**
* Creates a new external string using the data defined in the given
@@ -2952,6 +2988,8 @@ class V8_EXPORT String : public Name {
*/
class V8_EXPORT Utf8Value {
public:
+ V8_DEPRECATED("Use Isolate version",
+ explicit Utf8Value(Local<v8::Value> obj));
Utf8Value(Isolate* isolate, Local<v8::Value> obj);
~Utf8Value();
char* operator*() { return str_; }
@@ -2975,6 +3013,7 @@ class V8_EXPORT String : public Name {
*/
class V8_EXPORT Value {
public:
+ V8_DEPRECATED("Use Isolate version", explicit Value(Local<v8::Value> obj));
Value(Isolate* isolate, Local<v8::Value> obj);
~Value();
uint16_t* operator*() { return str_; }
@@ -5224,6 +5263,8 @@ class V8_EXPORT BooleanObject : public Object {
class V8_EXPORT StringObject : public Object {
public:
static Local<Value> New(Isolate* isolate, Local<String> value);
+ V8_DEPRECATED("Use Isolate* version",
+ static Local<Value> New(Local<String> value));
Local<String> ValueOf() const;
@@ -10226,6 +10267,30 @@ template <class T> Value* Value::Cast(T* value) {
}
+Local<Boolean> Value::ToBoolean() const {
+ return ToBoolean(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(Local<Boolean>());
+}
+
+
+Local<String> Value::ToString() const {
+ return ToString(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(Local<String>());
+}
+
+
+Local<Object> Value::ToObject() const {
+ return ToObject(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(Local<Object>());
+}
+
+
+Local<Integer> Value::ToInteger() const {
+ return ToInteger(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(Local<Integer>());
+}
+
+
Boolean* Boolean::Cast(v8::Value* value) {
#ifdef V8_ENABLE_CHECKS
CheckCast(value);
diff --git a/src/api.cc b/src/api.cc
index 7a53cc1370cf30c858fd87156e2eb75d4b57a60b..bc544f1c7c7f9f8e3bac9804697848ededb6a30a 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2161,6 +2161,10 @@ int PrimitiveArray::Length() const {
return array->length();
}
+void PrimitiveArray::Set(int index, Local<Primitive> item) {
+ return Set(Isolate::GetCurrent(), index, item);
+}
+
void PrimitiveArray::Set(Isolate* v8_isolate, int index,
Local<Primitive> item) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
@@ -2174,6 +2178,10 @@ void PrimitiveArray::Set(Isolate* v8_isolate, int index,
array->set(index, *i_item);
}
+Local<Primitive> PrimitiveArray::Get(int index) {
+ return Get(Isolate::GetCurrent(), index);
+}
+
Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
@@ -2904,6 +2912,10 @@ void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
// --- S t a c k T r a c e ---
+Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
+ return GetFrame(Isolate::GetCurrent(), index);
+}
+
Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
uint32_t index) const {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
@@ -3880,6 +3892,36 @@ void v8::RegExp::CheckCast(v8::Value* that) {
}
+bool Value::BooleanValue() const {
+ return BooleanValue(Isolate::GetCurrent()->GetCurrentContext())
+ .FromJust();
+}
+
+
+double Value::NumberValue() const {
+ return NumberValue(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(std::numeric_limits<double>::quiet_NaN());
+}
+
+
+int64_t Value::IntegerValue() const {
+ return NumberValue(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(0);
+}
+
+
+uint32_t Value::Uint32Value() const {
+ return Uint32Value(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(0);
+}
+
+
+int32_t Value::Int32Value() const {
+ return Int32Value(Isolate::GetCurrent()->GetCurrentContext())
+ .FromMaybe(0);
+}
+
+
Maybe<bool> Value::BooleanValue(Local<Context> context) const {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
return Just(Utils::OpenHandle(this)->BooleanValue(isolate));
@@ -3968,6 +4010,12 @@ MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
}
+bool Value::Equals(Local<Value> that) const {
+ return Equals(Isolate::GetCurrent()->GetCurrentContext(), that)
+ .FromMaybe(false);
+}
+
+
Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
auto self = Utils::OpenHandle(this);
@@ -5299,6 +5347,10 @@ bool String::ContainsOnlyOneByte() const {
return helper.Check(*str);
}
+int String::Utf8Length() const {
+ return Utf8Length(Isolate::GetCurrent());
+}
+
int String::Utf8Length(Isolate* isolate) const {
i::Handle<i::String> str = Utils::OpenHandle(this);
str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
@@ -5522,6 +5574,14 @@ static bool RecursivelySerializeToUtf8(i::String* current,
return true;
}
+
+int String::WriteUtf8(char* buffer, int capacity,
+ int* nchars_ref, int options) const {
+ return WriteUtf8(Isolate::GetCurrent(),
+ buffer, capacity, nchars_ref, options);
+}
+
+
int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
int* nchars_ref, int options) const {
i::Handle<i::String> str = Utils::OpenHandle(this);
@@ -5589,6 +5649,18 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string,
}
+int String::WriteOneByte(uint8_t* buffer, int start,
+ int length, int options) const {
+ return WriteOneByte(Isolate::GetCurrent(), buffer, start, length, options);
+}
+
+
+int String::Write(uint16_t* buffer, int start, int length,
+ int options) const {
+ return Write(Isolate::GetCurrent(), buffer, start, length, options);
+}
+
+
int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
int length, int options) const {
return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
@@ -6536,6 +6608,11 @@ MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
return result;
}
+Local<String> v8::String::Concat(Local<String> left,
+ Local<String> right) {
+ return Concat(Isolate::GetCurrent(), left, right);
+}
+
Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
Local<String> right) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
@@ -6762,6 +6839,11 @@ bool v8::BooleanObject::ValueOf() const {
}
+Local<v8::Value> v8::StringObject::New(Local<String> value) {
+ return New(Isolate::GetCurrent(), value);
+}
+
+
Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
Local<String> value) {
i::Handle<i::String> string = Utils::OpenHandle(*value);
@@ -8904,6 +8986,9 @@ bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8Isolate) {
return isolate->IsRunningMicrotasks();
}
+String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
+ : Utf8Value(Isolate::GetCurrent(), obj) {}
+
String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
: str_(nullptr), length_(0) {
if (obj.IsEmpty()) return;
@@ -8923,6 +9008,9 @@ String::Utf8Value::~Utf8Value() {
i::DeleteArray(str_);
}
+String::Value::Value(v8::Local<v8::Value> obj)
+ : Value(Isolate::GetCurrent(), obj) {}
+
String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
: str_(nullptr), length_(0) {
if (obj.IsEmpty()) return;

View file

@ -0,0 +1,409 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anna Henningsen <anna@addaleax.net>
Date: Thu, 4 Oct 2018 14:38:59 -0700
Subject: deps: revert 9136dd8088a9 from upstream V8
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reverting this enables us to provide slower, but longer-lasting
replacements for the deprecated APIs.
Original commit message:
Put back deleted V8_DEPRECATE_SOON methods
This partially reverts
https://chromium-review.googlesource.com/c/v8/v8/+/1177861,
which deleted many V8_DEPRECATE_SOON methods rather than moving them to
V8_DEPRECATED first. This puts them back and marks them V8_DEPRECATED.
Note V8_DEPRECATED that were deleted in the same CL stay deleted.
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
Bug: v8:7786, v8:8240
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I00330036d957f98dab403465b25e30d8382aac22
Reviewed-on: https://chromium-review.googlesource.com/1251422
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Michael Hablich <hablich@chromium.org>
Cr-Commit-Position: refs/branch-heads/7.0@{#49}
Cr-Branched-From: 6e2adae6f7f8e891cfd01f3280482b20590427a6-refs/heads/7.0.276@{#1}
Cr-Branched-From: bc08a8624cbbea7a2d30071472bc73ad9544eadf-refs/heads/master@{#55424}
Refs: https://github.com/v8/v8/commit/9136dd8088a95484b059a0301b25235510fc2882
Refs: https://github.com/nodejs/node/issues/23122
PR-URL: https://github.com/nodejs/node/pull/23158
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
diff --git a/include/v8.h b/include/v8.h
index 3070f4aa50eed8722805feaf8d9b9db0d68fbbbf..784e1830edeebaf2b15eaad4230f318f91acad5f 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1125,10 +1125,6 @@ class V8_EXPORT PrimitiveArray {
int Length() const;
void Set(Isolate* isolate, int index, Local<Primitive> item);
Local<Primitive> Get(Isolate* isolate, int index);
-
- V8_DEPRECATED("Use Isolate version",
- void Set(int index, Local<Primitive> item));
- V8_DEPRECATED("Use Isolate version", Local<Primitive> Get(int index));
};
/**
@@ -1833,8 +1829,6 @@ class V8_EXPORT StackTrace {
/**
* Returns a StackFrame at a particular index.
*/
- V8_DEPRECATED("Use Isolate version",
- Local<StackFrame> GetFrame(uint32_t index) const);
Local<StackFrame> GetFrame(Isolate* isolate, uint32_t index) const;
/**
@@ -2543,11 +2537,6 @@ class V8_EXPORT Value : public Data {
V8_DEPRECATE_SOON("Use maybe version",
Local<Int32> ToInt32(Isolate* isolate) const);
- inline V8_DEPRECATED("Use maybe version", Local<Boolean> ToBoolean() const);
- inline V8_DEPRECATED("Use maybe version", Local<String> ToString() const);
- inline V8_DEPRECATED("Use maybe version", Local<Object> ToObject() const);
- inline V8_DEPRECATED("Use maybe version", Local<Integer> ToInteger() const);
-
/**
* Attempts to convert a string to an array index.
* Returns an empty handle if the conversion fails.
@@ -2563,14 +2552,7 @@ class V8_EXPORT Value : public Data {
Local<Context> context) const;
V8_WARN_UNUSED_RESULT Maybe<int32_t> Int32Value(Local<Context> context) const;
- V8_DEPRECATED("Use maybe version", bool BooleanValue() const);
- V8_DEPRECATED("Use maybe version", double NumberValue() const);
- V8_DEPRECATED("Use maybe version", int64_t IntegerValue() const);
- V8_DEPRECATED("Use maybe version", uint32_t Uint32Value() const);
- V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
-
/** JS == */
- V8_DEPRECATED("Use maybe version", bool Equals(Local<Value> that) const);
V8_WARN_UNUSED_RESULT Maybe<bool> Equals(Local<Context> context,
Local<Value> that) const;
bool StrictEquals(Local<Value> that) const;
@@ -2677,8 +2659,6 @@ class V8_EXPORT String : public Name {
* Returns the number of bytes in the UTF-8 encoded
* representation of this string.
*/
- V8_DEPRECATED("Use Isolate version instead", int Utf8Length() const);
-
int Utf8Length(Isolate* isolate) const;
/**
@@ -2735,23 +2715,12 @@ class V8_EXPORT String : public Name {
// 16-bit character codes.
int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
int options = NO_OPTIONS) const;
- V8_DEPRECATED("Use Isolate* version",
- int Write(uint16_t* buffer, int start = 0, int length = -1,
- int options = NO_OPTIONS) const);
// One byte characters.
int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
int length = -1, int options = NO_OPTIONS) const;
- V8_DEPRECATED("Use Isolate* version",
- int WriteOneByte(uint8_t* buffer, int start = 0,
- int length = -1, int options = NO_OPTIONS)
- const);
// UTF-8 encoded characters.
int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
int* nchars_ref = NULL, int options = NO_OPTIONS) const;
- V8_DEPRECATED("Use Isolate* version",
- int WriteUtf8(char* buffer, int length = -1,
- int* nchars_ref = NULL, int options = NO_OPTIONS)
- const);
/**
* A zero length string.
@@ -2915,9 +2884,6 @@ class V8_EXPORT String : public Name {
*/
static Local<String> Concat(Isolate* isolate, Local<String> left,
Local<String> right);
- static V8_DEPRECATED("Use Isolate* version",
- Local<String> Concat(Local<String> left,
- Local<String> right));
/**
* Creates a new external string using the data defined in the given
@@ -5258,8 +5224,6 @@ class V8_EXPORT BooleanObject : public Object {
class V8_EXPORT StringObject : public Object {
public:
static Local<Value> New(Isolate* isolate, Local<String> value);
- static V8_DEPRECATED("Use Isolate* version",
- Local<Value> New(Local<String> value));
Local<String> ValueOf() const;
@@ -10261,25 +10225,6 @@ template <class T> Value* Value::Cast(T* value) {
return static_cast<Value*>(value);
}
-Local<Boolean> Value::ToBoolean() const {
- return ToBoolean(Isolate::GetCurrent()->GetCurrentContext())
- .FromMaybe(Local<Boolean>());
-}
-
-Local<String> Value::ToString() const {
- return ToString(Isolate::GetCurrent()->GetCurrentContext())
- .FromMaybe(Local<String>());
-}
-
-Local<Object> Value::ToObject() const {
- return ToObject(Isolate::GetCurrent()->GetCurrentContext())
- .FromMaybe(Local<Object>());
-}
-
-Local<Integer> Value::ToInteger() const {
- return ToInteger(Isolate::GetCurrent()->GetCurrentContext())
- .FromMaybe(Local<Integer>());
-}
Boolean* Boolean::Cast(v8::Value* value) {
#ifdef V8_ENABLE_CHECKS
diff --git a/src/api.cc b/src/api.cc
index 8dca7ec88e59c775da5cf7e30721d064f349c634..7a53cc1370cf30c858fd87156e2eb75d4b57a60b 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -219,28 +219,6 @@ Local<Context> ContextFromNeverReadOnlySpaceObject(
return reinterpret_cast<v8::Isolate*>(obj->GetIsolate())->GetCurrentContext();
}
-// TODO(delphick): Remove this completely when the deprecated functions that use
-// it are removed.
-// DO NOT USE THIS IN NEW CODE!
-i::Isolate* UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject> obj) {
- // Use MemoryChunk directly instead of Isolate::FromWritableHeapObject to
- // temporarily allow isolate access from read-only space objects.
- i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj);
- return chunk->heap()->isolate();
-}
-
-// TODO(delphick): Remove this completely when the deprecated functions that use
-// it are removed.
-// DO NOT USE THIS IN NEW CODE!
-Local<Context> UnsafeContextFromHeapObject(i::Handle<i::Object> obj) {
- // Use MemoryChunk directly instead of Isolate::FromWritableHeapObject to
- // temporarily allow isolate access from read-only space objects.
- i::MemoryChunk* chunk =
- i::MemoryChunk::FromHeapObject(i::HeapObject::cast(*obj));
- return reinterpret_cast<Isolate*>(chunk->heap()->isolate())
- ->GetCurrentContext();
-}
-
class InternalEscapableScope : public v8::EscapableHandleScope {
public:
explicit inline InternalEscapableScope(i::Isolate* isolate)
@@ -2196,12 +2174,6 @@ void PrimitiveArray::Set(Isolate* v8_isolate, int index,
array->set(index, *i_item);
}
-void PrimitiveArray::Set(int index, Local<Primitive> item) {
- i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(array);
- Set(reinterpret_cast<Isolate*>(isolate), index, item);
-}
-
Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
@@ -2214,12 +2186,6 @@ Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
return ToApiHandle<Primitive>(i_item);
}
-Local<Primitive> PrimitiveArray::Get(int index) {
- i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(array);
- return Get(reinterpret_cast<Isolate*>(isolate), index);
-}
-
Module::Status Module::GetStatus() const {
i::Handle<i::Module> self = Utils::OpenHandle(this);
switch (self->status()) {
@@ -2948,11 +2914,6 @@ Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
return scope.Escape(Utils::StackFrameToLocal(info));
}
-Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(Utils::OpenHandle(this));
- return GetFrame(reinterpret_cast<Isolate*>(isolate), index);
-}
-
int StackTrace::GetFrameCount() const {
return Utils::OpenHandle(this)->length();
}
@@ -3924,14 +3885,6 @@ Maybe<bool> Value::BooleanValue(Local<Context> context) const {
return Just(Utils::OpenHandle(this)->BooleanValue(isolate));
}
-bool Value::BooleanValue() const {
- auto obj = Utils::OpenHandle(this);
- if (obj->IsSmi()) return *obj != i::Smi::kZero;
- DCHECK(obj->IsHeapObject());
- i::Isolate* isolate =
- UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject>::cast(obj));
- return obj->BooleanValue(isolate);
-}
Maybe<double> Value::NumberValue(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
@@ -3945,12 +3898,6 @@ Maybe<double> Value::NumberValue(Local<Context> context) const {
return Just(num->Number());
}
-double Value::NumberValue() const {
- auto obj = Utils::OpenHandle(this);
- if (obj->IsNumber()) return obj->Number();
- return NumberValue(UnsafeContextFromHeapObject(obj))
- .FromMaybe(std::numeric_limits<double>::quiet_NaN());
-}
Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
@@ -3966,17 +3913,6 @@ Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
return Just(NumberToInt64(*num));
}
-int64_t Value::IntegerValue() const {
- auto obj = Utils::OpenHandle(this);
- if (obj->IsNumber()) {
- if (obj->IsSmi()) {
- return i::Smi::ToInt(*obj);
- } else {
- return static_cast<int64_t>(obj->Number());
- }
- }
- return IntegerValue(UnsafeContextFromHeapObject(obj)).FromMaybe(0);
-}
Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
@@ -3991,11 +3927,6 @@ Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
: static_cast<int32_t>(num->Number()));
}
-int32_t Value::Int32Value() const {
- auto obj = Utils::OpenHandle(this);
- if (obj->IsNumber()) return NumberToInt32(*obj);
- return Int32Value(UnsafeContextFromHeapObject(obj)).FromMaybe(0);
-}
Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
@@ -4010,11 +3941,6 @@ Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
: static_cast<uint32_t>(num->Number()));
}
-uint32_t Value::Uint32Value() const {
- auto obj = Utils::OpenHandle(this);
- if (obj->IsNumber()) return NumberToUint32(*obj);
- return Uint32Value(UnsafeContextFromHeapObject(obj)).FromMaybe(0);
-}
MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
auto self = Utils::OpenHandle(this);
@@ -4049,19 +3975,6 @@ Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
return i::Object::Equals(isolate, self, other);
}
-bool Value::Equals(Local<Value> that) const {
- auto self = Utils::OpenHandle(this);
- auto other = Utils::OpenHandle(*that);
- if (self->IsSmi() && other->IsSmi()) {
- return self->Number() == other->Number();
- }
- if (self->IsJSObject() && other->IsJSObject()) {
- return *self == *other;
- }
- auto heap_object = self->IsSmi() ? other : self;
- auto context = UnsafeContextFromHeapObject(heap_object);
- return Equals(context, that).FromMaybe(false);
-}
bool Value::StrictEquals(Local<Value> that) const {
auto self = Utils::OpenHandle(this);
@@ -5386,11 +5299,6 @@ bool String::ContainsOnlyOneByte() const {
return helper.Check(*str);
}
-int String::Utf8Length() const {
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(Utils::OpenHandle(this));
- return Utf8Length(reinterpret_cast<Isolate*>(isolate));
-}
-
int String::Utf8Length(Isolate* isolate) const {
i::Handle<i::String> str = Utils::OpenHandle(this);
str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
@@ -5659,14 +5567,6 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
return writer.CompleteWrite(write_null, nchars_ref);
}
-int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref,
- int options) const {
- i::Handle<i::String> str = Utils::OpenHandle(this);
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(str);
- return WriteUtf8(reinterpret_cast<Isolate*>(isolate), buffer, capacity,
- nchars_ref, options);
-}
-
template <typename CharType>
static inline int WriteHelper(i::Isolate* isolate, const String* string,
CharType* buffer, int start, int length,
@@ -5688,11 +5588,6 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string,
return end - start;
}
-int String::WriteOneByte(uint8_t* buffer, int start, int length,
- int options) const {
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(Utils::OpenHandle(this));
- return WriteHelper(isolate, this, buffer, start, length, options);
-}
int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
int length, int options) const {
@@ -5700,10 +5595,6 @@ int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
start, length, options);
}
-int String::Write(uint16_t* buffer, int start, int length, int options) const {
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(Utils::OpenHandle(this));
- return WriteHelper(isolate, this, buffer, start, length, options);
-}
int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
int options) const {
@@ -6662,12 +6553,6 @@ Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
return Utils::ToLocal(result);
}
-Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
- i::Handle<i::String> left_string = Utils::OpenHandle(*left);
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(left_string);
- return Concat(reinterpret_cast<Isolate*>(isolate), left, right);
-}
-
MaybeLocal<String> v8::String::NewExternalTwoByte(
Isolate* isolate, v8::String::ExternalStringResource* resource) {
CHECK(resource && resource->data());
@@ -6876,11 +6761,6 @@ bool v8::BooleanObject::ValueOf() const {
return jsvalue->value()->IsTrue(isolate);
}
-Local<v8::Value> v8::StringObject::New(Local<String> value) {
- i::Handle<i::String> string = Utils::OpenHandle(*value);
- i::Isolate* isolate = UnsafeIsolateFromHeapObject(string);
- return New(reinterpret_cast<Isolate*>(isolate), value);
-}
Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
Local<String> value) {

View file

@ -0,0 +1,562 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yang Guo <yangguo@chromium.org>
Date: Thu, 4 Oct 2018 14:25:50 +0200
Subject: deps: V8: cherry-pick 64-bit hash seed commits
This serves as mitigation for the so-called HashWick vulnerability.
Original commit messages:
commit 3833fef57368c53c6170559ffa524c8c69f16ee5
Author: Yang Guo <yangguo@chromium.org>
Date: Thu Sep 20 11:43:13 2018
Refactor integer hashing function names
We now clearly differentiate between:
- unseeded hash for 32-bit integers
- unseeded hash for 64-bit integers
- seeded hash for 32-bit integers
- seeded hash for strings
R=bmeurer@chromium.org
Bug: chromium:680662
Change-Id: I7459958c4158ee3501c962943dff8f33258bb5ce
Reviewed-on: https://chromium-review.googlesource.com/1235973
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56068}
commit 95a979e02d7154e45b293261a6998c99d71fc238
Author: Yang Guo <yangguo@chromium.org>
Date: Thu Sep 20 14:34:48 2018
Call into C++ to compute seeded integer hash
R=bmeurer@chromium.org
Bug: chromium:680662
Change-Id: I8dace89d576dfcc5833fd539ce698a9ade1cb5a0
Reviewed-on: https://chromium-review.googlesource.com/1235928
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56091}
commit 2c2af0022d5feb9e525a00a76cb15db9f3e38dba
Author: Yang Guo <yangguo@chromium.org>
Date: Thu Sep 27 16:37:57 2018
Use 64-bit for seeded integer hashes
R=petermarshall@chromium.org
Bug: chromium:680662
Change-Id: If48d1043dbe1e1bb695ec890c23e103a6cacf2d4
Reviewed-on: https://chromium-review.googlesource.com/1244220
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56271}
Refs: https://github.com/nodejs/node/issues/23259
PR-URL: https://github.com/nodejs/node/pull/23264
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
diff --git a/src/builtins/builtins-collections-gen.cc b/src/builtins/builtins-collections-gen.cc
index 5808d2a98caacd404960b0ae5e146c96c7b520e4..aab0475e21bd8a9c9d9db0ef51653edff002189b 100644
--- a/src/builtins/builtins-collections-gen.cc
+++ b/src/builtins/builtins-collections-gen.cc
@@ -689,7 +689,7 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler {
Node* key_tagged, Variable* result,
Label* entry_found,
Label* not_found);
- Node* ComputeIntegerHashForString(Node* context, Node* string_key);
+ Node* ComputeStringHash(Node* context, Node* string_key);
void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key,
Label* if_same, Label* if_not_same);
@@ -846,8 +846,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey(
Node* table, Node* smi_key, Variable* result, Label* entry_found,
Label* not_found) {
Node* const key_untagged = SmiUntag(smi_key);
- Node* const hash =
- ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0)));
+ Node* const hash = ChangeInt32ToIntPtr(ComputeUnseededHash(key_untagged));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
result->Bind(hash);
FindOrderedHashTableEntry<CollectionType>(
@@ -862,7 +861,7 @@ template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey(
Node* context, Node* table, Node* key_tagged, Variable* result,
Label* entry_found, Label* not_found) {
- Node* const hash = ComputeIntegerHashForString(context, key_tagged);
+ Node* const hash = ComputeStringHash(context, key_tagged);
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
result->Bind(hash);
FindOrderedHashTableEntry<CollectionType>(
@@ -920,8 +919,8 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey(
result, entry_found, not_found);
}
-Node* CollectionsBuiltinsAssembler::ComputeIntegerHashForString(
- Node* context, Node* string_key) {
+Node* CollectionsBuiltinsAssembler::ComputeStringHash(Node* context,
+ Node* string_key) {
VARIABLE(var_result, MachineType::PointerRepresentation());
Label hash_not_computed(this), done(this, &var_result);
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 2527e89a25061e913d5b7a3d80134bb2d3bcf7d4..5bd780b520b307df7d3c9390e938e722c4024eaa 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -253,40 +253,6 @@ HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR);
HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST);
#undef HEAP_CONSTANT_TEST
-TNode<Int64T> CodeStubAssembler::HashSeed() {
- DCHECK(Is64());
- TNode<HeapObject> hash_seed_root =
- TNode<HeapObject>::UncheckedCast(LoadRoot(Heap::kHashSeedRootIndex));
- return TNode<Int64T>::UncheckedCast(LoadObjectField(
- hash_seed_root, ByteArray::kHeaderSize, MachineType::Int64()));
-}
-
-TNode<Int32T> CodeStubAssembler::HashSeedHigh() {
- DCHECK(!Is64());
-#ifdef V8_TARGET_BIG_ENDIAN
- static int kOffset = 0;
-#else
- static int kOffset = kInt32Size;
-#endif
- TNode<HeapObject> hash_seed_root =
- TNode<HeapObject>::UncheckedCast(LoadRoot(Heap::kHashSeedRootIndex));
- return TNode<Int32T>::UncheckedCast(LoadObjectField(
- hash_seed_root, ByteArray::kHeaderSize + kOffset, MachineType::Int32()));
-}
-
-TNode<Int32T> CodeStubAssembler::HashSeedLow() {
- DCHECK(!Is64());
-#ifdef V8_TARGET_BIG_ENDIAN
- static int kOffset = kInt32Size;
-#else
- static int kOffset = 0;
-#endif
- TNode<HeapObject> hash_seed_root =
- TNode<HeapObject>::UncheckedCast(LoadRoot(Heap::kHashSeedRootIndex));
- return TNode<Int32T>::UncheckedCast(LoadObjectField(
- hash_seed_root, ByteArray::kHeaderSize + kOffset, MachineType::Int32()));
-}
-
Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) {
if (mode == SMI_PARAMETERS) {
return SmiConstant(value);
@@ -7709,14 +7675,9 @@ template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
TNode<GlobalDictionary>, TNode<Name>, Label*, TVariable<IntPtrT>*, Label*,
int, LookupMode);
-Node* CodeStubAssembler::ComputeIntegerHash(Node* key) {
- return ComputeIntegerHash(key, IntPtrConstant(kZeroHashSeed));
-}
-
-Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
- // See v8::internal::ComputeIntegerHash()
+Node* CodeStubAssembler::ComputeUnseededHash(Node* key) {
+ // See v8::internal::ComputeUnseededHash()
Node* hash = TruncateIntPtrToInt32(key);
- hash = Word32Xor(hash, seed);
hash = Int32Add(Word32Xor(hash, Int32Constant(0xFFFFFFFF)),
Word32Shl(hash, Int32Constant(15)));
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
@@ -7727,6 +7688,21 @@ Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
return Word32And(hash, Int32Constant(0x3FFFFFFF));
}
+Node* CodeStubAssembler::ComputeSeededHash(Node* key) {
+ Node* const function_addr =
+ ExternalConstant(ExternalReference::compute_integer_hash());
+ Node* const isolate_ptr =
+ ExternalConstant(ExternalReference::isolate_address(isolate()));
+
+ MachineType type_ptr = MachineType::Pointer();
+ MachineType type_uint32 = MachineType::Uint32();
+
+ Node* const result =
+ CallCFunction2(type_uint32, type_ptr, type_uint32, function_addr,
+ isolate_ptr, TruncateIntPtrToInt32(key));
+ return result;
+}
+
void CodeStubAssembler::NumberDictionaryLookup(
TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
Label* if_found, TVariable<IntPtrT>* var_entry, Label* if_not_found) {
@@ -7737,16 +7713,7 @@ void CodeStubAssembler::NumberDictionaryLookup(
TNode<IntPtrT> capacity = SmiUntag(GetCapacity<NumberDictionary>(dictionary));
TNode<WordT> mask = IntPtrSub(capacity, IntPtrConstant(1));
- TNode<Int32T> int32_seed;
-
- if (Is64()) {
- int32_seed = TruncateInt64ToInt32(HashSeed());
- } else {
- int32_seed = HashSeedLow();
- }
-
- TNode<WordT> hash =
- ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
+ TNode<WordT> hash = ChangeUint32ToWord(ComputeSeededHash(intptr_index));
Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
// See Dictionary::FirstProbe().
diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h
index 51ed647412b97f42e09cb6bc717a05d0a4c14cb6..38fc9717de0542b9b94f4143c5a5e4e3e60f1dc0 100644
--- a/src/code-stub-assembler.h
+++ b/src/code-stub-assembler.h
@@ -450,10 +450,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST)
#undef HEAP_CONSTANT_TEST
- TNode<Int64T> HashSeed();
- TNode<Int32T> HashSeedHigh();
- TNode<Int32T> HashSeedLow();
-
Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
TNode<Smi> LanguageModeConstant(LanguageMode mode) {
return SmiConstant(static_cast<int>(mode));
@@ -2288,8 +2284,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
int inlined_probes = kInlinedDictionaryProbes,
LookupMode mode = kFindExisting);
- Node* ComputeIntegerHash(Node* key);
- Node* ComputeIntegerHash(Node* key, Node* seed);
+ Node* ComputeUnseededHash(Node* key);
+ Node* ComputeSeededHash(Node* key);
void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
TNode<IntPtrT> intptr_index, Label* if_found,
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
index 9b12c022c49e3bfbfa0c58b0ee95b4db4b410623..4bb4f8df776ffde88c5b76cea6d58d6c482a767f 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -4768,8 +4768,8 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
}
}
-Node* EffectControlLinearizer::ComputeIntegerHash(Node* value) {
- // See v8::internal::ComputeIntegerHash()
+Node* EffectControlLinearizer::ComputeUnseededHash(Node* value) {
+ // See v8::internal::ComputeUnseededHash()
value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xFFFFFFFF)),
__ Word32Shl(value, __ Int32Constant(15)));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
@@ -4787,7 +4787,7 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
Node* key = NodeProperties::GetValueInput(node, 1);
// Compute the integer hash code.
- Node* hash = ChangeUint32ToUintPtr(ComputeIntegerHash(key));
+ Node* hash = ChangeUint32ToUintPtr(ComputeUnseededHash(key));
Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField(
AccessBuilder::ForOrderedHashTableBaseNumberOfBuckets(), table));
diff --git a/src/compiler/effect-control-linearizer.h b/src/compiler/effect-control-linearizer.h
index aa174ed45e80e2987ab658a715962ce2dce90aa2..272bc44599692c27abc2d86b566b3eb8a1c2fdfc 100644
--- a/src/compiler/effect-control-linearizer.h
+++ b/src/compiler/effect-control-linearizer.h
@@ -182,7 +182,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* BuildFloat64RoundDown(Node* value);
Node* BuildFloat64RoundTruncate(Node* input);
Node* BuildUint32Mod(Node* lhs, Node* rhs);
- Node* ComputeIntegerHash(Node* value);
+ Node* ComputeUnseededHash(Node* value);
Node* LowerStringComparison(Callable const& callable, Node* node);
Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind);
diff --git a/src/external-reference.cc b/src/external-reference.cc
index 8f6bf22d385d53af70972f387283b89537dfece2..0fbde95a1cbd1fb6a02119f82330ad5ce1fa58f9 100644
--- a/src/external-reference.cc
+++ b/src/external-reference.cc
@@ -764,6 +764,15 @@ ExternalReference ExternalReference::jsreceiver_create_identity_hash(
return ExternalReference(Redirect(FUNCTION_ADDR(f)));
}
+static uint32_t ComputeSeededIntegerHash(Isolate* isolate, uint32_t key) {
+ DisallowHeapAllocation no_gc;
+ return ComputeSeededHash(key, isolate->heap()->HashSeed());
+}
+
+ExternalReference ExternalReference::compute_integer_hash() {
+ return ExternalReference(Redirect(FUNCTION_ADDR(ComputeSeededIntegerHash)));
+}
+
ExternalReference
ExternalReference::copy_fast_number_jsarray_elements_to_typed_array() {
return ExternalReference(
diff --git a/src/external-reference.h b/src/external-reference.h
index 2f7794698269372c6bf3d311a85c5c81279e356c..fb3ec07c8bf713abb51d09898d39c3f3ef6176dc 100644
--- a/src/external-reference.h
+++ b/src/external-reference.h
@@ -83,6 +83,7 @@ class StatsCounter;
V(address_of_uint32_bias, "uint32_bias") \
V(bytecode_size_table_address, "Bytecodes::bytecode_size_table_address") \
V(check_object_type, "check_object_type") \
+ V(compute_integer_hash, "ComputeSeededHash") \
V(compute_output_frames_function, "Deoptimizer::ComputeOutputFrames()") \
V(copy_fast_number_jsarray_elements_to_typed_array, \
"copy_fast_number_jsarray_elements_to_typed_array") \
diff --git a/src/frames.cc b/src/frames.cc
index e5751e2bb705601b5d97d82b36c76d0290959462..9dee01698e3ae1ee1a32b859cec336888db35186 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -2133,7 +2133,7 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
isolate_->counters()->pc_to_code()->Increment();
DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
- uint32_t hash = ComputeIntegerHash(
+ uint32_t hash = ComputeUnseededHash(
ObjectAddressForHashing(reinterpret_cast<void*>(inner_pointer)));
uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
InnerPointerToCodeCacheEntry* entry = cache(index);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 05b2b9653fdef5b5d673d2f2e176d08aea5c5adb..ed3e15ed9e9856fb6b5217a46910b92c21dc536b 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2980,14 +2980,14 @@ bool NumberDictionaryBaseShape::IsMatch(uint32_t key, Object* other) {
}
uint32_t NumberDictionaryBaseShape::Hash(Isolate* isolate, uint32_t key) {
- return ComputeIntegerHash(key, isolate->heap()->HashSeed());
+ return ComputeSeededHash(key, isolate->heap()->HashSeed());
}
uint32_t NumberDictionaryBaseShape::HashForObject(Isolate* isolate,
Object* other) {
DCHECK(other->IsNumber());
- return ComputeIntegerHash(static_cast<uint32_t>(other->Number()),
- isolate->heap()->HashSeed());
+ return ComputeSeededHash(static_cast<uint32_t>(other->Number()),
+ isolate->heap()->HashSeed());
}
Handle<Object> NumberDictionaryBaseShape::AsHandle(Isolate* isolate,
@@ -3067,18 +3067,18 @@ uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object* other) {
Object* Object::GetSimpleHash(Object* object) {
DisallowHeapAllocation no_gc;
if (object->IsSmi()) {
- uint32_t hash = ComputeIntegerHash(Smi::ToInt(object));
+ uint32_t hash = ComputeUnseededHash(Smi::ToInt(object));
return Smi::FromInt(hash & Smi::kMaxValue);
}
if (object->IsHeapNumber()) {
double num = HeapNumber::cast(object)->value();
if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
- // Use ComputeIntegerHash for all values in Signed32 range, including -0,
+ // Use ComputeUnseededHash for all values in Signed32 range, including -0,
// which is considered equal to 0 because collections use SameValueZero.
uint32_t hash;
// Check range before conversion to avoid undefined behavior.
if (num >= kMinInt && num <= kMaxInt && FastI2D(FastD2I(num)) == num) {
- hash = ComputeIntegerHash(FastD2I(num));
+ hash = ComputeUnseededHash(FastD2I(num));
} else {
hash = ComputeLongHash(double_to_uint64(num));
}
diff --git a/src/objects/bigint.h b/src/objects/bigint.h
index f8c5c3dbf697981d6c4e36b94a7d1f1c7a7046b2..a30a4779deef8ca72bead4b31815860d51075422 100644
--- a/src/objects/bigint.h
+++ b/src/objects/bigint.h
@@ -137,7 +137,7 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
bool ToBoolean() { return !is_zero(); }
uint32_t Hash() {
// TODO(jkummerow): Improve this. At least use length and sign.
- return is_zero() ? 0 : ComputeIntegerHash(static_cast<uint32_t>(digit(0)));
+ return is_zero() ? 0 : ComputeLongHash(static_cast<uint64_t>(digit(0)));
}
static bool EqualToString(Isolate* isolate, Handle<BigInt> x,
diff --git a/src/objects/ordered-hash-table.h b/src/objects/ordered-hash-table.h
index 20f3fe2eda6216f957a802d53d859ff3cd1236a0..0ee0f71c5c8ac284490a9abdbd9fba285fcc9233 100644
--- a/src/objects/ordered-hash-table.h
+++ b/src/objects/ordered-hash-table.h
@@ -144,7 +144,7 @@ class OrderedHashTable : public OrderedHashTableBase {
// This special cases for Smi, so that we avoid the HandleScope
// creation below.
if (key->IsSmi()) {
- uint32_t hash = ComputeIntegerHash(Smi::ToInt(key));
+ uint32_t hash = ComputeUnseededHash(Smi::ToInt(key));
return HashToEntry(hash & Smi::kMaxValue);
}
HandleScope scope(isolate);
diff --git a/src/profiler/allocation-tracker.cc b/src/profiler/allocation-tracker.cc
index 21843325f93e83a7afe3d96ebc09c0137b41fa18..e5b31397855171c08be8f6c0e6a02b01661ee9b3 100644
--- a/src/profiler/allocation-tracker.cc
+++ b/src/profiler/allocation-tracker.cc
@@ -239,7 +239,7 @@ void AllocationTracker::AllocationEvent(Address addr, int size) {
static uint32_t SnapshotObjectIdHash(SnapshotObjectId id) {
- return ComputeIntegerHash(static_cast<uint32_t>(id));
+ return ComputeUnseededHash(static_cast<uint32_t>(id));
}
diff --git a/src/profiler/heap-snapshot-generator.cc b/src/profiler/heap-snapshot-generator.cc
index 96ac785273c30aa6acb9f6697edb386a6fd232b1..5d98a98b8ea0e9d9cf62e5cfe2aef51d8648fa04 100644
--- a/src/profiler/heap-snapshot-generator.cc
+++ b/src/profiler/heap-snapshot-generator.cc
@@ -535,7 +535,7 @@ SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
heap_->HashSeed());
intptr_t element_count = info->GetElementCount();
if (element_count != -1) {
- id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count));
+ id ^= ComputeUnseededHash(static_cast<uint32_t>(element_count));
}
return id << 1;
}
diff --git a/src/profiler/heap-snapshot-generator.h b/src/profiler/heap-snapshot-generator.h
index f28852fdc213f0607bc64992c3178e86543251b2..f25bee9f46435bf181583eb2e2bb4d2073ea26bc 100644
--- a/src/profiler/heap-snapshot-generator.h
+++ b/src/profiler/heap-snapshot-generator.h
@@ -309,7 +309,7 @@ class HeapEntriesMap {
private:
static uint32_t Hash(HeapThing thing) {
- return ComputeIntegerHash(
+ return ComputeUnseededHash(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)));
}
@@ -520,7 +520,7 @@ class NativeObjectsExplorer {
struct RetainedInfoHasher {
std::size_t operator()(v8::RetainedObjectInfo* info) const {
- return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()));
+ return ComputeUnseededHash(static_cast<uint32_t>(info->GetHash()));
}
};
struct RetainedInfoEquals {
diff --git a/src/profiler/profile-generator.cc b/src/profiler/profile-generator.cc
index c0c5242219c8e9360696f5c6d9ecf78c57b01fd1..d60da5a44dfa2ff913916e801be1b1d3b33feda2 100644
--- a/src/profiler/profile-generator.cc
+++ b/src/profiler/profile-generator.cc
@@ -84,16 +84,16 @@ CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() {
}
uint32_t CodeEntry::GetHash() const {
- uint32_t hash = ComputeIntegerHash(tag());
+ uint32_t hash = ComputeUnseededHash(tag());
if (script_id_ != v8::UnboundScript::kNoScriptId) {
- hash ^= ComputeIntegerHash(static_cast<uint32_t>(script_id_));
- hash ^= ComputeIntegerHash(static_cast<uint32_t>(position_));
+ hash ^= ComputeUnseededHash(static_cast<uint32_t>(script_id_));
+ hash ^= ComputeUnseededHash(static_cast<uint32_t>(position_));
} else {
- hash ^= ComputeIntegerHash(
+ hash ^= ComputeUnseededHash(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
- hash ^= ComputeIntegerHash(
+ hash ^= ComputeUnseededHash(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)));
- hash ^= ComputeIntegerHash(line_number_);
+ hash ^= ComputeUnseededHash(line_number_);
}
return hash;
}
diff --git a/src/profiler/profile-generator.h b/src/profiler/profile-generator.h
index 8eef05bcdb382600e987608bdcb9270e3307e998..ac9506ab219c91d1196af15ae246b89711e574e8 100644
--- a/src/profiler/profile-generator.h
+++ b/src/profiler/profile-generator.h
@@ -243,7 +243,7 @@ class ProfileNode {
};
struct Hasher {
std::size_t operator()(CodeEntryAndLineNumber pair) const {
- return pair.code_entry->GetHash() ^ ComputeIntegerHash(pair.line_number);
+ return pair.code_entry->GetHash() ^ ComputeUnseededHash(pair.line_number);
}
};
diff --git a/src/utils.h b/src/utils.h
index 9f4bb08614a580cbd74bea1ee3a8e14a2104226d..f4669524a72e8f11b49054a155c726447a65ef90 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -476,10 +476,9 @@ class BitSetComputer {
static const uint64_t kZeroHashSeed = 0;
// Thomas Wang, Integer Hash Functions.
-// http://www.concentric.net/~Ttwang/tech/inthash.htm
-inline uint32_t ComputeIntegerHash(uint32_t key, uint64_t seed) {
+// http://www.concentric.net/~Ttwang/tech/inthash.htm`
+inline uint32_t ComputeUnseededHash(uint32_t key) {
uint32_t hash = key;
- hash = hash ^ static_cast<uint32_t>(seed);
hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
hash = hash ^ (hash >> 12);
hash = hash + (hash << 2);
@@ -489,10 +488,6 @@ inline uint32_t ComputeIntegerHash(uint32_t key, uint64_t seed) {
return hash & 0x3fffffff;
}
-inline uint32_t ComputeIntegerHash(uint32_t key) {
- return ComputeIntegerHash(key, kZeroHashSeed);
-}
-
inline uint32_t ComputeLongHash(uint64_t key) {
uint64_t hash = key;
hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
@@ -501,17 +496,20 @@ inline uint32_t ComputeLongHash(uint64_t key) {
hash = hash ^ (hash >> 11);
hash = hash + (hash << 6);
hash = hash ^ (hash >> 22);
- return static_cast<uint32_t>(hash);
+ return static_cast<uint32_t>(hash & 0x3fffffff);
}
+inline uint32_t ComputeSeededHash(uint32_t key, uint64_t seed) {
+ return ComputeLongHash(static_cast<uint64_t>(key) ^ seed);
+}
inline uint32_t ComputePointerHash(void* ptr) {
- return ComputeIntegerHash(
+ return ComputeUnseededHash(
static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)));
}
inline uint32_t ComputeAddressHash(Address address) {
- return ComputeIntegerHash(static_cast<uint32_t>(address & 0xFFFFFFFFul));
+ return ComputeUnseededHash(static_cast<uint32_t>(address & 0xFFFFFFFFul));
}
// ----------------------------------------------------------------------------
diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
index d7cdb39933fd2bf462777d53cef7ae868d2b78dd..2036e13450548e8de6639127f5070e359eb7a119 100644
--- a/test/cctest/test-code-stub-assembler.cc
+++ b/test/cctest/test-code-stub-assembler.cc
@@ -332,15 +332,7 @@ TEST(ComputeIntegerHash) {
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
- TNode<Int32T> int32_seed;
- if (m.Is64()) {
- int32_seed = m.TruncateInt64ToInt32(m.HashSeed());
- } else {
- int32_seed = m.HashSeedLow();
- }
-
- m.Return(m.SmiFromInt32(
- m.ComputeIntegerHash(m.SmiUntag(m.Parameter(0)), int32_seed)));
+ m.Return(m.SmiFromInt32(m.ComputeSeededHash(m.SmiUntag(m.Parameter(0)))));
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
@@ -352,7 +344,7 @@ TEST(ComputeIntegerHash) {
Handle<Smi> key(Smi::FromInt(k), isolate);
Handle<Object> result = ft.Call(key).ToHandleChecked();
- uint32_t hash = ComputeIntegerHash(k, isolate->heap()->HashSeed());
+ uint32_t hash = ComputeSeededHash(k, isolate->heap()->HashSeed());
Smi* expected = Smi::FromInt(hash & Smi::kMaxValue);
CHECK_EQ(expected, Smi::cast(*result));
}

View file

@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch
Needed in order to build mksnapshot on arm.
diff --git a/BUILD.gn b/BUILD.gn
index d0ba5ed04e7126deae4a0ab9ee8943cda5ea42e3..b5eb09cfcb8add19f4de985cbe7b9777c51c4bd3 100644
index ac74cdec115b6cc54d05817f063153628cf5e9fe..c1b08958b500da1910a8067198cdec7650534f20 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -3130,8 +3130,6 @@ if (v8_monolithic) {
@@ -3237,8 +3237,6 @@ if (v8_monolithic) {
if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
v8_executable("mksnapshot") {