chore: deprecate apply-patches in favour of git-{import,export}-patches (#15300)
This commit is contained in:
parent
4185efa08f
commit
335e9f68b7
123 changed files with 4368 additions and 4780 deletions
20
patches/common/v8/.patches
Normal file
20
patches/common/v8/.patches
Normal file
|
@ -0,0 +1,20 @@
|
|||
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
|
||||
ostreams.patch
|
||||
export_platform.patch
|
||||
dcheck.patch
|
||||
disable-warning-win.patch
|
||||
expose_mksnapshot.patch
|
||||
build-torque-with-x64-toolchain-on-arm.patch
|
|
@ -1,72 +0,0 @@
|
|||
repo: src/v8
|
||||
patches:
|
||||
-
|
||||
author: null
|
||||
file: node_v8_patches.patch
|
||||
description: |
|
||||
Patches that node applies to v8.
|
||||
Generated with
|
||||
|
||||
$ cd third_party/electron_node
|
||||
$ CURRENT_NODE_VERSION=vX.Y.Z
|
||||
# Find the last commit with the message "deps: update V8 to <some version>"
|
||||
# This commit corresponds to node resetting V8 to its pristine upstream
|
||||
# state at the stated version.
|
||||
$ LAST_V8_UPDATE="$(git log --grep='^deps: update V8' --format='%H' -1 deps/v8)"
|
||||
# This creates a patch file containing all changes in deps/v8 from
|
||||
# $LAST_V8_UPDATE up to the current node version, formatted in a way that
|
||||
# it will apply cleanly to the V8 repository (i.e. with `deps/v8`
|
||||
# stripped off the path and excluding the v8/gypfiles directory, which
|
||||
# isn't present in V8.
|
||||
$ git format-patch \
|
||||
--relative=deps/v8 \
|
||||
$LAST_V8_UPDATE..$CURRENT_NODE_VERSION \
|
||||
deps/v8 \
|
||||
':(exclude)deps/v8/gypfiles' \
|
||||
--stdout
|
||||
-
|
||||
author: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
file: add_realloc.patch
|
||||
description: |
|
||||
Blink overrides ArrayBuffer's allocator with its own one, while Node simply
|
||||
uses malloc and free, so we need to use v8's allocator in Node. As part of the
|
||||
10.6.0 upgrade, we needed to make SerializerDelegate accept an allocator
|
||||
argument in its constructor, and override ReallocateBufferMemory and
|
||||
FreeBufferMemory to use the allocator. We cannot simply allocate and then memcpy
|
||||
when we override ReallocateBufferMemory, so we therefore need to implement
|
||||
Realloc on the v8 side.
|
||||
-
|
||||
author: Ales Pergl <alpergl@microsoft.com>
|
||||
file: build_gn.patch
|
||||
description: null
|
||||
-
|
||||
author: Cheng Zhao <zcbenz@gmail.com>
|
||||
file: array_buffer.patch
|
||||
description: null
|
||||
-
|
||||
author: Cheng Zhao <zcbenz@gmail.com>
|
||||
file: ostreams.patch
|
||||
description: null
|
||||
-
|
||||
author: Aleksei Kuzmin <alkuzmin@microsoft.com>
|
||||
file: export_platform.patch
|
||||
description: |
|
||||
v8::Platform::SystemClockTimeMillis must be exported so that node::NodePlatform can call it
|
||||
-
|
||||
author: Ales Pergl <alpergl@microsoft.com>
|
||||
file: dcheck.patch
|
||||
description: null
|
||||
-
|
||||
author: Nitish Sakhawalkar <nitsakh@icloud.com>
|
||||
file: disable-warning-win.patch
|
||||
description:
|
||||
Disable unit test windows build warning
|
||||
-
|
||||
author: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
file: expose_mksnapshot.patch
|
||||
description: Needed in order to build mksnapshot on arm.
|
||||
-
|
||||
author: Aleksei Kuzmin <alkuzmin@microsoft.com>
|
||||
file: build-torque-with-x64-toolchain-on-arm.patch
|
||||
description: |
|
||||
torque binary has to be run during the build.
|
27
patches/common/v8/README.md
Normal file
27
patches/common/v8/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
### Exporting node's patches to v8
|
||||
|
||||
```
|
||||
$ cd third_party/electron_node
|
||||
$ CURRENT_NODE_VERSION=vX.Y.Z # e.g. v10.11.0
|
||||
|
||||
# Find the last commit with the message "deps: update V8 to <some version>"
|
||||
# This commit corresponds to node resetting V8 to its pristine upstream
|
||||
# state at the stated version.
|
||||
$ LAST_V8_UPDATE="$(git log --grep='^deps: update V8' --format='%H' -1 deps/v8)"
|
||||
|
||||
# This creates a patch file containing all changes in deps/v8 from
|
||||
# $LAST_V8_UPDATE up to the current node version, formatted in a way that
|
||||
# it will apply cleanly to the V8 repository (i.e. with `deps/v8`
|
||||
# stripped off the path and excluding the v8/gypfiles directory, which
|
||||
# isn't present in V8.
|
||||
$ git format-patch \
|
||||
--relative=deps/v8 \
|
||||
$LAST_V8_UPDATE..$CURRENT_NODE_VERSION \
|
||||
deps/v8 \
|
||||
':(exclude)deps/v8/gypfiles' \
|
||||
--stdout
|
||||
```
|
||||
|
||||
When upgrading to a new version of node, make sure to match node's patches to
|
||||
v8 by removing all the `deps_*` patches and re-exporting node's v8 patches
|
||||
using the process above.
|
|
@ -1,8 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:11 -0700
|
||||
Subject: add_realloc.patch
|
||||
|
||||
Blink overrides ArrayBuffer's allocator with its own one, while Node simply
|
||||
uses malloc and free, so we need to use v8's allocator in Node. As part of the
|
||||
10.6.0 upgrade, we needed to make SerializerDelegate accept an allocator
|
||||
argument in its constructor, and override ReallocateBufferMemory and
|
||||
FreeBufferMemory to use the allocator. We cannot simply allocate and then memcpy
|
||||
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 573e80176d..5eefe26fe9 100644
|
||||
index 20a65afcbc61c31360874e45adc03eeda02e9a81..6bba7a177e72b54084b2a52e413c5de6edb26b01 100644
|
||||
--- a/include/v8.h
|
||||
+++ b/include/v8.h
|
||||
@@ -4318,6 +4318,13 @@ class V8_EXPORT ArrayBuffer : public Object {
|
||||
@@ -4618,6 +4618,13 @@ class V8_EXPORT ArrayBuffer : public Object {
|
||||
*/
|
||||
virtual void* AllocateUninitialized(size_t length) = 0;
|
||||
|
||||
|
@ -17,10 +30,10 @@ index 573e80176d..5eefe26fe9 100644
|
|||
* 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 8b177d041d..e06ca2a207 100644
|
||||
index 6155cbb32579effc500b5c475cd478e77b3ecdf4..9fe5268aa5e615fee058d430b6a137dd40fc9226 100644
|
||||
--- a/src/api.cc
|
||||
+++ b/src/api.cc
|
||||
@@ -460,6 +460,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
|
||||
@@ -505,6 +505,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
|
||||
i::V8::SetSnapshotBlob(snapshot_blob);
|
||||
}
|
||||
|
||||
|
@ -31,3 +44,6 @@ index 8b177d041d..e06ca2a207 100644
|
|||
namespace {
|
||||
|
||||
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: array_buffer.patch
|
||||
|
||||
|
||||
diff --git a/include/v8.h b/include/v8.h
|
||||
index 573e80176d..80bfd1d22a 100644
|
||||
index 6bba7a177e72b54084b2a52e413c5de6edb26b01..b1e192dc009b33484148817be0b0b6bb4dc1bf4b 100644
|
||||
--- a/include/v8.h
|
||||
+++ b/include/v8.h
|
||||
@@ -7337,6 +7337,9 @@ class V8_EXPORT Isolate {
|
||||
@@ -7766,6 +7766,9 @@ class V8_EXPORT Isolate {
|
||||
*/
|
||||
void SetIdle(bool is_idle);
|
||||
|
||||
|
@ -13,10 +19,10 @@ index 573e80176d..80bfd1d22a 100644
|
|||
bool InContext();
|
||||
|
||||
diff --git a/src/api.cc b/src/api.cc
|
||||
index 8b177d041d..f58a350f0f 100644
|
||||
index 9fe5268aa5e615fee058d430b6a137dd40fc9226..5c1f2410bbab4a0d9f4fcd99f19530ba999a66a2 100644
|
||||
--- a/src/api.cc
|
||||
+++ b/src/api.cc
|
||||
@@ -8139,6 +8139,13 @@ void Isolate::SetIdle(bool is_idle) {
|
||||
@@ -8290,6 +8290,13 @@ void Isolate::SetIdle(bool is_idle) {
|
||||
isolate->SetIdle(is_idle);
|
||||
}
|
||||
|
||||
|
@ -30,3 +36,6 @@ index 8b177d041d..f58a350f0f 100644
|
|||
bool Isolate::InContext() {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
return isolate->context() != nullptr;
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksei Kuzmin <alkuzmin@microsoft.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:13 -0700
|
||||
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 456a318..af803ff 100644
|
||||
index b5eb09cfcb8add19f4de985cbe7b9777c51c4bd3..dbe4338c3a733cb806e420a9bb0b4bcc65cf333b 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -870,7 +870,8 @@ action("run_torque") {
|
||||
@@ -899,7 +899,8 @@ action("run_torque") {
|
||||
# is the target toolchain and, hence, can't be used.
|
||||
v8_torque_toolchain = v8_snapshot_toolchain
|
||||
if (host_cpu == "x64" &&
|
||||
|
@ -12,7 +19,7 @@ index 456a318..af803ff 100644
|
|||
v8_torque_toolchain = "//build/toolchain/linux:clang_x64"
|
||||
}
|
||||
|
||||
@@ -3079,7 +3080,7 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
|
||||
@@ -3149,7 +3150,7 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,3 +28,5 @@ index 456a318..af803ff 100644
|
|||
v8_executable("torque") {
|
||||
visibility = [ ":*" ] # Only targets in this file can depend on this.
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ales Pergl <alpergl@microsoft.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: build_gn.patch
|
||||
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index 443694d880..d0ba5ed04e 100644
|
||||
index 443694d88075d59d6e8db7fa4bedc3a812fdafc4..d0ba5ed04e7126deae4a0ab9ee8943cda5ea42e3 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -212,7 +212,7 @@ config("internal_config") {
|
||||
|
@ -20,3 +26,6 @@ index 443694d880..d0ba5ed04e 100644
|
|||
deps = [
|
||||
":v8_base",
|
||||
":v8_init",
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ales Pergl <alpergl@microsoft.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: dcheck.patch
|
||||
|
||||
|
||||
diff --git a/src/api.cc b/src/api.cc
|
||||
index 8531cd5c05..47254c9f5c 100644
|
||||
index 5c1f2410bbab4a0d9f4fcd99f19530ba999a66a2..b464a2187c162bac00620f65e9c94deeaf3d6c95 100644
|
||||
--- a/src/api.cc
|
||||
+++ b/src/api.cc
|
||||
@@ -8598,7 +8604,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
|
||||
@@ -8851,7 +8851,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
|
||||
|
||||
|
||||
void Isolate::RunMicrotasks() {
|
||||
|
@ -12,10 +18,10 @@ index 8531cd5c05..47254c9f5c 100644
|
|||
}
|
||||
|
||||
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
||||
index 62a5856f34..c59dfad2c8 100644
|
||||
index 6830a90482173174266faa0e9a95618c67fad811..78991a26de6d97e3ee14b66913fc079a795b299d 100644
|
||||
--- a/src/heap/heap.cc
|
||||
+++ b/src/heap/heap.cc
|
||||
@@ -5963,9 +5963,9 @@ void Heap::TearDown() {
|
||||
@@ -5006,9 +5006,9 @@ void Heap::TearDown() {
|
||||
void Heap::AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
|
||||
GCType gc_type, void* data) {
|
||||
DCHECK_NOT_NULL(callback);
|
||||
|
@ -28,3 +34,6 @@ index 62a5856f34..c59dfad2c8 100644
|
|||
gc_prologue_callbacks_.emplace_back(callback, gc_type, data);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
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()) << ")";
|
||||
}
|
||||
}
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Marshall <p.s.marshall0@gmail.com>
|
||||
Date: Tue, 4 Sep 2018 15:48:15 +0200
|
||||
Subject: deps: backport detailed line info for CPU profiler
|
||||
|
||||
[cpu-profiler] Add flag to always generate accurate line info.
|
||||
https://chromium.googlesource.com/v8/v8/+/
|
||||
56baf56790de439b3f69e887e94beb3b301ed77c
|
||||
|
||||
[cpu-profiler] Turn on detailed line info for optimized code
|
||||
https://chromium.googlesource.com/v8/v8/+/
|
||||
84894ce6d2af7feb9e1f5574409355120887326c
|
||||
|
||||
[cpu-profiler] Separate the flags for generating extra line information
|
||||
https://chromium.googlesource.com/v8/v8/+/
|
||||
30ff6719db441cc7ef220d449970cc169067e256
|
||||
|
||||
PR-URL: https://github.com/nodejs/node/pull/22688
|
||||
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
|
||||
--- a/src/flag-definitions.h
|
||||
+++ b/src/flag-definitions.h
|
||||
@@ -1243,6 +1243,9 @@ DEFINE_BOOL(log_function_events, false,
|
||||
DEFINE_BOOL(prof, false,
|
||||
"Log statistical profiling information (implies --log-code).")
|
||||
|
||||
+DEFINE_BOOL(detailed_line_info, true,
|
||||
+ "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();
|
||||
}
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
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'
|
||||
];
|
||||
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,498 @@
|
|||
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);
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ali Ijaz Sheikh <ofrobots@google.com>
|
||||
Date: Tue, 11 Sep 2018 15:40:28 -0700
|
||||
Subject: deps: cherry-pick 2363cdf from upstream V8
|
||||
|
||||
Original commit message:
|
||||
|
||||
[tracing] do not add traces when disabled
|
||||
|
||||
https://github.com/nodejs/node/issues/21038
|
||||
|
||||
Change-Id: Ic4c9f403b5e54a97d3170b2311dd5aab8c8357c8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/1217726
|
||||
Commit-Queue: Ali Ijaz Sheikh <ofrobots@google.com>
|
||||
Reviewed-by: Yang Guo <yangguo@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#55809}
|
||||
|
||||
Refs: https://github.com/v8/v8/commit/2363cdfefeb643285cbe8593b7c17d80e5d06cd9
|
||||
PR-URL: https://github.com/nodejs/node/pull/22812
|
||||
Reviewed-By: Refael Ackermann <refack@gmail.com>
|
||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||
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
|
||||
--- a/src/libplatform/tracing/tracing-controller.cc
|
||||
+++ b/src/libplatform/tracing/tracing-controller.cc
|
||||
@@ -63,13 +63,15 @@ uint64_t TracingController::AddTraceEvent(
|
||||
const uint64_t* arg_values,
|
||||
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
|
||||
unsigned int flags) {
|
||||
- uint64_t handle;
|
||||
- TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
|
||||
- if (trace_object) {
|
||||
- trace_object->Initialize(
|
||||
- phase, category_enabled_flag, name, scope, id, bind_id, num_args,
|
||||
- arg_names, arg_types, arg_values, arg_convertables, flags,
|
||||
- CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds());
|
||||
+ uint64_t handle = 0;
|
||||
+ if (mode_ != DISABLED) {
|
||||
+ TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
|
||||
+ if (trace_object) {
|
||||
+ trace_object->Initialize(
|
||||
+ phase, category_enabled_flag, name, scope, id, bind_id, num_args,
|
||||
+ arg_names, arg_types, arg_values, arg_convertables, flags,
|
||||
+ CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds());
|
||||
+ }
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
@@ -81,13 +83,15 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
|
||||
const uint64_t* arg_values,
|
||||
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
|
||||
unsigned int flags, int64_t timestamp) {
|
||||
- uint64_t handle;
|
||||
- TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
|
||||
- if (trace_object) {
|
||||
- trace_object->Initialize(phase, category_enabled_flag, name, scope, id,
|
||||
- bind_id, num_args, arg_names, arg_types,
|
||||
- arg_values, arg_convertables, flags, timestamp,
|
||||
- CurrentCpuTimestampMicroseconds());
|
||||
+ uint64_t handle = 0;
|
||||
+ if (mode_ != DISABLED) {
|
||||
+ TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
|
||||
+ if (trace_object) {
|
||||
+ trace_object->Initialize(phase, category_enabled_flag, name, scope, id,
|
||||
+ bind_id, num_args, arg_names, arg_types,
|
||||
+ arg_values, arg_convertables, flags, timestamp,
|
||||
+ CurrentCpuTimestampMicroseconds());
|
||||
+ }
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
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,
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,711 @@
|
|||
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();
|
||||
}
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
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);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
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 =
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,757 @@
|
|||
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);
|
||||
};
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
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
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -1,5 +1,12 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nitish Sakhawalkar <nitsakh@icloud.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: disable-warning-win.patch
|
||||
|
||||
Disable unit test windows build warning
|
||||
|
||||
diff --git a/test/unittests/base/bits-unittest.cc b/test/unittests/base/bits-unittest.cc
|
||||
index 45fb921797..8c9f249609 100644
|
||||
index 6f787eb72783570812f7cbda57b836df56b5f2cb..c36dfcc836d6351d11d2178a8e6c3556b3ff3422 100644
|
||||
--- a/test/unittests/base/bits-unittest.cc
|
||||
+++ b/test/unittests/base/bits-unittest.cc
|
||||
@@ -13,7 +13,9 @@
|
||||
|
@ -13,3 +20,6 @@ index 45fb921797..8c9f249609 100644
|
|||
namespace v8 {
|
||||
namespace base {
|
||||
namespace bits {
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksei Kuzmin <alkuzmin@microsoft.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: export_platform.patch
|
||||
|
||||
v8::Platform::SystemClockTimeMillis must be exported so that node::NodePlatform can call it
|
||||
|
||||
diff --git a/include/v8-platform.h b/include/v8-platform.h
|
||||
index ddc200abab..046de4e257 100644
|
||||
index cfeb13b65829f9e0bad2518b8c4b03a645b6223c..2b38e24e233b5ba7061fd4a3d5e49063b0165f11 100644
|
||||
--- a/include/v8-platform.h
|
||||
+++ b/include/v8-platform.h
|
||||
@@ -11,6 +11,7 @@
|
||||
|
@ -10,7 +17,7 @@ index ddc200abab..046de4e257 100644
|
|||
#include "v8config.h" // NOLINT(build/include)
|
||||
|
||||
namespace v8 {
|
||||
@@ -465,7 +466,7 @@ class Platform {
|
||||
@@ -387,7 +388,7 @@ class Platform {
|
||||
* since epoch. Useful for implementing |CurrentClockTimeMillis| if
|
||||
* nothing special needed.
|
||||
*/
|
||||
|
@ -19,3 +26,6 @@ index ddc200abab..046de4e257 100644
|
|||
};
|
||||
|
||||
} // namespace v8
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:13 -0700
|
||||
Subject: expose_mksnapshot.patch
|
||||
|
||||
Needed in order to build mksnapshot on arm.
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index 30e9ec34cf..fea543df9c 100644
|
||||
index d0ba5ed04e7126deae4a0ab9ee8943cda5ea42e3..b5eb09cfcb8add19f4de985cbe7b9777c51c4bd3 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -2904,8 +2904,6 @@ if (v8_monolithic) {
|
||||
@@ -3130,8 +3130,6 @@ if (v8_monolithic) {
|
||||
|
||||
if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
|
||||
v8_executable("mksnapshot") {
|
||||
|
@ -11,3 +18,6 @@ index 30e9ec34cf..fea543df9c 100644
|
|||
sources = [
|
||||
"src/snapshot/mksnapshot.cc",
|
||||
]
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,11 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon, 22 Oct 2018 10:47:12 -0700
|
||||
Subject: ostreams.patch
|
||||
|
||||
|
||||
diff --git a/src/ostreams.h b/src/ostreams.h
|
||||
index c6b64a1cd9..236a73d018 100644
|
||||
index c6b64a1cd95b92ed37abe56d71dd6132c4ff9db4..236a73d01800f58a4f37c8abdd8df346d8fcf2c5 100644
|
||||
--- a/src/ostreams.h
|
||||
+++ b/src/ostreams.h
|
||||
@@ -32,7 +32,7 @@ class OFStreamBase : public std::streambuf {
|
||||
|
@ -11,3 +17,6 @@ index c6b64a1cd9..236a73d018 100644
|
|||
public:
|
||||
explicit OFStream(FILE* f);
|
||||
virtual ~OFStream();
|
||||
--
|
||||
2.17.0
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue