Skip to content

Commit 5bb985d

Browse files
committed
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: v8/v8@0dd3390 PR-URL: #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>
1 parent f04ab3c commit 5bb985d

9 files changed

+352
-4
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
# Reset this number to 0 on major V8 upgrades.
3131
# Increment by one for each non-official patch applied to deps/v8.
32-
'v8_embedder_string': '-node.1',
32+
'v8_embedder_string': '-node.2',
3333

3434
# Enable disassembler for `--print-code` v8 options
3535
'v8_enable_disassembler': 1,

deps/v8/AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Jan de Mooij <jandemooij@gmail.com>
8787
Jan Krems <jan.krems@gmail.com>
8888
Jay Freeman <saurik@saurik.com>
8989
James Pike <g00gle@chilon.net>
90+
James M Snell <jasnell@gmail.com>
9091
Jianghua Yang <jianghua.yjh@alibaba-inc.com>
9192
Joel Stanley <joel@jms.id.au>
9293
Johan Bergström <johan@bergstroem.nu>

deps/v8/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,7 @@ v8_source_set("v8_base") {
15881588
"src/builtins/builtins-sharedarraybuffer.cc",
15891589
"src/builtins/builtins-string.cc",
15901590
"src/builtins/builtins-symbol.cc",
1591+
"src/builtins/builtins-trace.cc",
15911592
"src/builtins/builtins-typed-array.cc",
15921593
"src/builtins/builtins-utils.h",
15931594
"src/builtins/builtins.cc",

deps/v8/src/bootstrapper.cc

+9
Original file line numberDiff line numberDiff line change
@@ -5077,6 +5077,15 @@ bool Genesis::InstallExtraNatives() {
50775077

50785078
Handle<JSObject> extras_binding =
50795079
factory()->NewJSObject(isolate()->object_function());
5080+
5081+
// binding.isTraceCategoryEnabled(category)
5082+
SimpleInstallFunction(isolate(), extras_binding, "isTraceCategoryEnabled",
5083+
Builtins::kIsTraceCategoryEnabled, 1, true);
5084+
5085+
// binding.trace(phase, category, name, id, data)
5086+
SimpleInstallFunction(isolate(), extras_binding, "trace", Builtins::kTrace, 5,
5087+
true);
5088+
50805089
native_context()->set_extras_binding_object(*extras_binding);
50815090

50825091
for (int i = ExtraNatives::GetDebuggerCount();

deps/v8/src/builtins/builtins-definitions.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,11 @@ namespace internal {
13081308
ASM(CallApiGetter) \
13091309
ASM(DoubleToI) \
13101310
TFC(GetProperty, GetProperty, 1) \
1311-
ASM(MathPowInternal)
1311+
ASM(MathPowInternal) \
1312+
\
1313+
/* Trace */ \
1314+
CPP(IsTraceCategoryEnabled) \
1315+
CPP(Trace)
13121316

13131317
#ifdef V8_INTL_SUPPORT
13141318
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Copyright 2018 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "src/api.h"
6+
#include "src/builtins/builtins-utils.h"
7+
#include "src/builtins/builtins.h"
8+
#include "src/counters.h"
9+
#include "src/json-stringifier.h"
10+
#include "src/objects-inl.h"
11+
12+
namespace v8 {
13+
namespace internal {
14+
15+
namespace {
16+
17+
using v8::tracing::TracedValue;
18+
19+
#define MAX_STACK_LENGTH 100
20+
21+
class MaybeUtf8 {
22+
public:
23+
explicit MaybeUtf8(Isolate* isolate, Handle<String> string) : buf_(data_) {
24+
string = String::Flatten(isolate, string);
25+
int len;
26+
if (string->IsOneByteRepresentation()) {
27+
// Technically this allows unescaped latin1 characters but the trace
28+
// events mechanism currently does the same and the current consuming
29+
// tools are tolerant of it. A more correct approach here would be to
30+
// escape non-ascii characters but this is easier and faster.
31+
len = string->length();
32+
AllocateSufficientSpace(len);
33+
if (len > 0) {
34+
// Why copy? Well, the trace event mechanism requires null-terminated
35+
// strings, the bytes we get from SeqOneByteString are not. buf_ is
36+
// guaranteed to be null terminated.
37+
memcpy(buf_, Handle<SeqOneByteString>::cast(string)->GetChars(), len);
38+
}
39+
} else {
40+
Local<v8::String> local = Utils::ToLocal(string);
41+
len = local->Utf8Length();
42+
AllocateSufficientSpace(len);
43+
if (len > 0) {
44+
local->WriteUtf8(reinterpret_cast<char*>(buf_));
45+
}
46+
}
47+
buf_[len] = 0;
48+
}
49+
const char* operator*() const { return reinterpret_cast<const char*>(buf_); }
50+
51+
private:
52+
void AllocateSufficientSpace(int len) {
53+
if (len + 1 > MAX_STACK_LENGTH) {
54+
allocated_.reset(new uint8_t[len + 1]);
55+
buf_ = allocated_.get();
56+
}
57+
}
58+
59+
// In the most common cases, the buffer here will be stack allocated.
60+
// A heap allocation will only occur if the data is more than MAX_STACK_LENGTH
61+
// Given that this is used primarily for trace event categories and names,
62+
// the MAX_STACK_LENGTH should be more than enough.
63+
uint8_t* buf_;
64+
uint8_t data_[MAX_STACK_LENGTH];
65+
std::unique_ptr<uint8_t> allocated_;
66+
};
67+
68+
class JsonTraceValue : public ConvertableToTraceFormat {
69+
public:
70+
explicit JsonTraceValue(Isolate* isolate, Handle<String> object) {
71+
// object is a JSON string serialized using JSON.stringify() from within
72+
// the BUILTIN(Trace) method. This may (likely) contain UTF8 values so
73+
// to grab the appropriate buffer data we have to serialize it out. We
74+
// hold on to the bits until the AppendAsTraceFormat method is called.
75+
MaybeUtf8 data(isolate, object);
76+
data_ = *data;
77+
}
78+
79+
void AppendAsTraceFormat(std::string* out) const override { *out += data_; }
80+
81+
private:
82+
std::string data_;
83+
};
84+
85+
const uint8_t* GetCategoryGroupEnabled(Isolate* isolate,
86+
Handle<String> string) {
87+
MaybeUtf8 category(isolate, string);
88+
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(*category);
89+
}
90+
91+
#undef MAX_STACK_LENGTH
92+
93+
} // namespace
94+
95+
// Builins::kIsTraceCategoryEnabled(category) : bool
96+
BUILTIN(IsTraceCategoryEnabled) {
97+
HandleScope scope(isolate);
98+
Handle<Object> category = args.atOrUndefined(isolate, 1);
99+
if (!category->IsString()) {
100+
THROW_NEW_ERROR_RETURN_FAILURE(
101+
isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
102+
}
103+
return isolate->heap()->ToBoolean(
104+
*GetCategoryGroupEnabled(isolate, Handle<String>::cast(category)));
105+
}
106+
107+
// Builtins::kTrace(phase, category, name, id, data) : bool
108+
BUILTIN(Trace) {
109+
HandleScope handle_scope(isolate);
110+
111+
Handle<Object> phase_arg = args.atOrUndefined(isolate, 1);
112+
Handle<Object> category = args.atOrUndefined(isolate, 2);
113+
Handle<Object> name_arg = args.atOrUndefined(isolate, 3);
114+
Handle<Object> id_arg = args.atOrUndefined(isolate, 4);
115+
Handle<Object> data_arg = args.atOrUndefined(isolate, 5);
116+
117+
const uint8_t* category_group_enabled =
118+
GetCategoryGroupEnabled(isolate, Handle<String>::cast(category));
119+
120+
// Exit early if the category group is not enabled.
121+
if (!*category_group_enabled) {
122+
return ReadOnlyRoots(isolate).false_value();
123+
}
124+
125+
if (!phase_arg->IsNumber()) {
126+
THROW_NEW_ERROR_RETURN_FAILURE(
127+
isolate, NewTypeError(MessageTemplate::kTraceEventPhaseError));
128+
}
129+
if (!category->IsString()) {
130+
THROW_NEW_ERROR_RETURN_FAILURE(
131+
isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
132+
}
133+
if (!name_arg->IsString()) {
134+
THROW_NEW_ERROR_RETURN_FAILURE(
135+
isolate, NewTypeError(MessageTemplate::kTraceEventNameError));
136+
}
137+
138+
uint32_t flags = TRACE_EVENT_FLAG_COPY;
139+
int32_t id = 0;
140+
if (!id_arg->IsNullOrUndefined(isolate)) {
141+
if (!id_arg->IsNumber()) {
142+
THROW_NEW_ERROR_RETURN_FAILURE(
143+
isolate, NewTypeError(MessageTemplate::kTraceEventIDError));
144+
}
145+
flags |= TRACE_EVENT_FLAG_HAS_ID;
146+
id = DoubleToInt32(id_arg->Number());
147+
}
148+
149+
Handle<String> name_str = Handle<String>::cast(name_arg);
150+
if (name_str->length() == 0) {
151+
THROW_NEW_ERROR_RETURN_FAILURE(
152+
isolate, NewTypeError(MessageTemplate::kTraceEventNameLengthError));
153+
}
154+
MaybeUtf8 name(isolate, name_str);
155+
156+
// We support passing one additional trace event argument with the
157+
// name "data". Any JSON serializable value may be passed.
158+
static const char* arg_name = "data";
159+
int32_t num_args = 0;
160+
uint8_t arg_type;
161+
uint64_t arg_value;
162+
163+
if (!data_arg->IsUndefined(isolate)) {
164+
// Serializes the data argument as a JSON string, which is then
165+
// copied into an object. This eliminates duplicated code but
166+
// could have perf costs. It is also subject to all the same
167+
// limitations as JSON.stringify() as it relates to circular
168+
// references and value limitations (e.g. BigInt is not supported).
169+
JsonStringifier stringifier(isolate);
170+
Handle<Object> result;
171+
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
172+
isolate, result,
173+
stringifier.Stringify(data_arg, isolate->factory()->undefined_value(),
174+
isolate->factory()->undefined_value()));
175+
std::unique_ptr<JsonTraceValue> traced_value;
176+
traced_value.reset(
177+
new JsonTraceValue(isolate, Handle<String>::cast(result)));
178+
tracing::SetTraceValue(std::move(traced_value), &arg_type, &arg_value);
179+
num_args++;
180+
}
181+
182+
TRACE_EVENT_API_ADD_TRACE_EVENT(
183+
static_cast<char>(DoubleToInt32(phase_arg->Number())),
184+
category_group_enabled, *name, tracing::kGlobalScope, id, tracing::kNoId,
185+
num_args, &arg_name, &arg_type, &arg_value, flags);
186+
187+
return ReadOnlyRoots(isolate).true_value();
188+
}
189+
190+
} // namespace internal
191+
} // namespace v8

deps/v8/src/debug/debug-evaluate.cc

+3
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,9 @@ DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
567567
case Builtins::kArrayMap:
568568
case Builtins::kArrayReduce:
569569
case Builtins::kArrayReduceRight:
570+
// Trace builtins.
571+
case Builtins::kIsTraceCategoryEnabled:
572+
case Builtins::kTrace:
570573
// TypedArray builtins.
571574
case Builtins::kTypedArrayConstructor:
572575
case Builtins::kTypedArrayPrototypeBuffer:

deps/v8/src/messages.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,14 @@ class ErrorUtils : public AllStatic {
757757
T(DataCloneDeserializationError, "Unable to deserialize cloned data.") \
758758
T(DataCloneDeserializationVersionError, \
759759
"Unable to deserialize cloned data due to invalid or unsupported " \
760-
"version.")
760+
"version.") \
761+
/* Builtins-Trace Errors */ \
762+
T(TraceEventCategoryError, "Trace event category must be a string.") \
763+
T(TraceEventNameError, "Trace event name must be a string.") \
764+
T(TraceEventNameLengthError, \
765+
"Trace event name must not be an empty string.") \
766+
T(TraceEventPhaseError, "Trace event phase must be a number.") \
767+
T(TraceEventIDError, "Trace event id must be a number.")
761768

762769
class MessageTemplate {
763770
public:

0 commit comments

Comments
 (0)