Skip to content

Commit 8f85acd

Browse files
marjakhaduh95
andcommitted
deps: V8: backport ebd15783b7ba
Original commit message: [objects]: Defer CallSiteInfo creation Store the raw data in a FixedArray and create the CallSiteInfo objects only on demand. This can be further optimized to omit CallSiteInfo creation altogether in some code paths, but currently those code paths are not critically important. Change-Id: I6480862caf6b64020737527c571e3e3eac704ed3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7673818 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#106127} Refs: v8/v8@ebd1578 Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #65764 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent bc73dea commit 8f85acd

12 files changed

Lines changed: 222 additions & 69 deletions

File tree

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
# Reset this number to 0 on major V8 upgrades.
4545
# Increment by one for each non-official patch applied to deps/v8.
46-
'v8_embedder_string': '-node.29',
46+
'v8_embedder_string': '-node.30',
4747

4848
##### V8 defaults for Node.js #####
4949

deps/v8/src/execution/isolate.cc

Lines changed: 85 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -878,18 +878,21 @@ class CallSiteBuilder {
878878
// framework and library code, and stack depth tends to be more than
879879
// a dozen frames, so we over-allocate a bit here to avoid growing
880880
// the elements array in the common case.
881-
elements_ = isolate->factory()->NewFixedArray(std::min(64, limit));
881+
elements_ = isolate->factory()->NewFixedArray(CallSiteInfo::Fields::kCount *
882+
std::min(64, limit));
882883
}
883884

884885
void SetPrevFrameAsConstructCall() {
885886
if (skipped_prev_frame_) return;
886887
DCHECK_GT(index_, 0);
887-
Tagged<CallSiteInfo> info =
888-
Tagged<CallSiteInfo>::cast(elements_->get(index_ - 1));
888+
int base_index = (index_ - 1) * CallSiteInfo::Fields::kCount;
889+
int flags =
890+
Smi::ToInt(elements_->get(base_index + CallSiteInfo::Fields::kFlags));
889891
#if V8_ENABLE_WEBASSEMBLY
890-
if (info->IsWasm()) return;
892+
if (flags & CallSiteInfo::kIsWasm) return;
891893
#endif
892-
info->set_flags(info->flags() | CallSiteInfo::kIsConstructor);
894+
elements_->set(base_index + CallSiteInfo::Fields::kFlags,
895+
Smi::FromInt(flags | CallSiteInfo::kIsConstructor));
893896
}
894897

895898
bool Visit(FrameSummary const& summary) {
@@ -1051,7 +1054,8 @@ class CallSiteBuilder {
10511054
bool Full() { return index_ >= limit_; }
10521055

10531056
Handle<FixedArray> Build() {
1054-
return FixedArray::RightTrimOrEmpty(isolate_, elements_, index_);
1057+
return FixedArray::RightTrimOrEmpty(isolate_, elements_,
1058+
CallSiteInfo::Fields::kCount * index_);
10551059
}
10561060

10571061
private:
@@ -1116,17 +1120,42 @@ class CallSiteBuilder {
11161120

11171121
void AppendFrame(DirectHandle<UnionOf<JSAny, Hole>> receiver_or_instance,
11181122
DirectHandle<UnionOf<Smi, JSFunction>> function,
1119-
DirectHandle<HeapObject> code, int offset, int flags,
1123+
DirectHandle<HeapObject> code_obj, int offset, int flags,
11201124
DirectHandle<FixedArray> parameters) {
11211125
if (IsTheHole(*receiver_or_instance, isolate_)) {
11221126
// TODO(jgruber): Fix all cases in which frames give us a hole value
11231127
// (e.g. the receiver in RegExp constructor frames).
11241128
receiver_or_instance = isolate_->factory()->undefined_value();
11251129
}
1126-
auto info = isolate_->factory()->NewCallSiteInfo(
1127-
Cast<JSAny>(receiver_or_instance), function, code, offset, flags,
1128-
parameters);
1129-
elements_ = FixedArray::SetAndGrow(isolate_, elements_, index_++, info);
1130+
1131+
int base_index = index_ * CallSiteInfo::Fields::kCount;
1132+
1133+
// Set the last field first and grow the array if needed.
1134+
static_assert(CallSiteInfo::Fields::kFlags ==
1135+
CallSiteInfo::Fields::kCount - 1);
1136+
elements_ = FixedArray::SetAndGrow(
1137+
isolate_, elements_, base_index + CallSiteInfo::Fields::kFlags,
1138+
Smi::FromInt(flags));
1139+
1140+
elements_->set(base_index + CallSiteInfo::Fields::kReceiver,
1141+
*receiver_or_instance);
1142+
elements_->set(base_index + CallSiteInfo::Fields::kFunction, *function);
1143+
1144+
if (DirectHandle<Code> code; TryCast(code_obj, &code)) {
1145+
elements_->set(base_index + CallSiteInfo::Fields::kCode, code->wrapper());
1146+
} else if (DirectHandle<BytecodeArray> bytecode;
1147+
TryCast(code_obj, &bytecode)) {
1148+
elements_->set(base_index + CallSiteInfo::Fields::kCode,
1149+
bytecode->wrapper());
1150+
} else {
1151+
elements_->set(base_index + CallSiteInfo::Fields::kCode,
1152+
*isolate_->factory()->undefined_value());
1153+
}
1154+
1155+
elements_->set(base_index + CallSiteInfo::Fields::kOffset,
1156+
Smi::FromInt(offset));
1157+
1158+
index_++;
11301159
skipped_prev_frame_ = false;
11311160
}
11321161

@@ -1442,13 +1471,18 @@ Handle<FixedArray> CaptureSimpleStackTrace(Isolate* isolate, int limit,
14421471
}
14431472

14441473
DirectHandle<StackTraceInfo> GetDetailedStackTraceFromCallSiteInfos(
1445-
Isolate* isolate, DirectHandle<FixedArray> call_site_infos, int limit) {
1446-
auto frames = isolate->factory()->NewFixedArray(
1447-
std::min(limit, call_site_infos->length()));
1448-
int index = 0;
1449-
for (int i = 0; i < call_site_infos->length() && index < limit; ++i) {
1450-
DirectHandle<CallSiteInfo> call_site_info(
1451-
Cast<CallSiteInfo>(call_site_infos->get(i)), isolate);
1474+
Isolate* isolate, DirectHandle<FixedArray> raw_data_for_call_site_infos,
1475+
uint32_t limit) {
1476+
uint32_t call_site_infos_len =
1477+
raw_data_for_call_site_infos->length() /
1478+
CallSiteInfo::Fields::kCount;
1479+
auto frames =
1480+
isolate->factory()->NewFixedArray(std::min(limit, call_site_infos_len));
1481+
uint32_t index = 0;
1482+
for (uint32_t i = 0; i < call_site_infos_len && index < limit; ++i) {
1483+
DirectHandle<CallSiteInfo> call_site_info =
1484+
CallSiteInfo::ConstructFromRawData(isolate,
1485+
raw_data_for_call_site_infos, i);
14521486
if (call_site_info->IsAsync()) {
14531487
break;
14541488
}
@@ -1519,14 +1553,19 @@ MaybeDirectHandle<JSObject> Isolate::CaptureAndSetErrorStack(
15191553
stack_trace_for_uncaught_exceptions_frame_limit_,
15201554
stack_trace_for_uncaught_exceptions_options_);
15211555
} else {
1522-
auto call_site_infos =
1556+
auto raw_data_for_call_site_infos =
15231557
Cast<FixedArray>(call_site_infos_or_formatted_stack);
15241558
stack_trace = GetDetailedStackTraceFromCallSiteInfos(
1525-
this, call_site_infos,
1526-
stack_trace_for_uncaught_exceptions_frame_limit_);
1527-
if (stack_trace_limit < call_site_infos->length()) {
1559+
this, raw_data_for_call_site_infos,
1560+
static_cast<uint32_t>(
1561+
stack_trace_for_uncaught_exceptions_frame_limit_));
1562+
DCHECK_GE(stack_trace_limit, 0);
1563+
if (static_cast<int>(stack_trace_limit) *
1564+
CallSiteInfo::Fields::kCount <
1565+
raw_data_for_call_site_infos->length()) {
15281566
call_site_infos_or_formatted_stack = FixedArray::RightTrimOrEmpty(
1529-
this, call_site_infos, stack_trace_limit);
1567+
this, raw_data_for_call_site_infos,
1568+
stack_trace_limit * CallSiteInfo::Fields::kCount);
15301569
}
15311570
// Notify the debugger.
15321571
OnStackTraceCaptured(stack_trace);
@@ -1556,17 +1595,27 @@ Handle<FixedArray> Isolate::GetSimpleStackTrace(
15561595
ErrorUtils::StackPropertyLookupResult lookup =
15571596
ErrorUtils::GetErrorStackProperty(this, maybe_error_object);
15581597

1598+
Handle<FixedArray> raw_data;
15591599
if (IsFixedArray(*lookup.error_stack)) {
1560-
return Cast<FixedArray>(lookup.error_stack);
1561-
}
1562-
if (!IsErrorStackData(*lookup.error_stack)) {
1600+
raw_data = Cast<FixedArray>(lookup.error_stack);
1601+
} else if (IsErrorStackData(*lookup.error_stack)) {
1602+
auto error_stack_data = Cast<ErrorStackData>(lookup.error_stack);
1603+
if (!error_stack_data->HasRawDataForCallSiteInfos()) {
1604+
return factory()->empty_fixed_array();
1605+
}
1606+
raw_data = handle(error_stack_data->raw_data_for_call_site_infos(), this);
1607+
} else {
15631608
return factory()->empty_fixed_array();
15641609
}
1565-
auto error_stack_data = Cast<ErrorStackData>(lookup.error_stack);
1566-
if (!error_stack_data->HasCallSiteInfos()) {
1567-
return factory()->empty_fixed_array();
1610+
1611+
int frame_count = raw_data->length() / CallSiteInfo::Fields::kCount;
1612+
Handle<FixedArray> call_site_infos = factory()->NewFixedArray(frame_count);
1613+
for (int i = 0; i < frame_count; ++i) {
1614+
DirectHandle<CallSiteInfo> call_site_info =
1615+
CallSiteInfo::ConstructFromRawData(this, raw_data, i);
1616+
call_site_infos->set(i, *call_site_info);
15681617
}
1569-
return handle(error_stack_data->call_site_infos(), this);
1618+
return call_site_infos;
15701619
}
15711620

15721621
Address Isolate::GetAbstractPC(int* line, int* column) {
@@ -3168,8 +3217,11 @@ void Isolate::PrintCurrentStackTrace(
31683217
this, FixedArray::kMaxLength, SKIP_NONE, factory()->undefined_value());
31693218

31703219
IncrementalStringBuilder builder(this);
3171-
for (int i = 0; i < frames->length(); ++i) {
3172-
DirectHandle<CallSiteInfo> frame(Cast<CallSiteInfo>(frames->get(i)), this);
3220+
uint32_t frame_count =
3221+
frames->length() / CallSiteInfo::Fields::kCount;
3222+
for (uint32_t i = 0; i < frame_count; ++i) {
3223+
DirectHandle<CallSiteInfo> frame =
3224+
CallSiteInfo::ConstructFromRawData(this, frames, i);
31733225

31743226
if (should_include_frame_callback) {
31753227
Tagged<Object> raw_script_name = frame->GetScriptNameOrSourceURL();
@@ -3193,7 +3245,7 @@ void Isolate::PrintCurrentStackTrace(
31933245
SerializeCallSiteInfo(this, frame, &builder);
31943246
}
31953247

3196-
if (i != frames->length() - 1) builder.AppendCharacter('\n');
3248+
if (i != frame_count - 1) builder.AppendCharacter('\n');
31973249
}
31983250

31993251
DirectHandle<String> stack_trace = builder.Finish().ToHandleChecked();

deps/v8/src/execution/messages.cc

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "src/parsing/parse-info.h"
2525
#include "src/parsing/parsing.h"
2626
#include "src/roots/roots.h"
27+
#include "src/sandbox/indirect-pointer-inl.h"
2728
#include "src/strings/string-builder-inl.h"
2829

2930
namespace v8 {
@@ -202,15 +203,16 @@ namespace {
202203

203204
// Convert the raw frames as written by Isolate::CaptureSimpleStackTrace into
204205
// a JSArray of JSCallSite objects.
205-
MaybeDirectHandle<JSArray> GetStackFrames(Isolate* isolate,
206-
DirectHandle<FixedArray> frames) {
207-
int frame_count = frames->length();
206+
MaybeDirectHandle<JSArray> GetStackFrames(
207+
Isolate* isolate, DirectHandle<FixedArray> raw_data_for_call_site_infos) {
208+
uint32_t frame_count = raw_data_for_call_site_infos->length() /
209+
CallSiteInfo::Fields::kCount;
208210
DirectHandle<JSFunction> constructor = isolate->callsite_function();
209211
DirectHandle<FixedArray> sites =
210212
isolate->factory()->NewFixedArray(frame_count);
211-
for (int i = 0; i < frame_count; ++i) {
212-
DirectHandle<CallSiteInfo> frame(Cast<CallSiteInfo>(frames->get(i)),
213-
isolate);
213+
for (uint32_t i = 0; i < frame_count; ++i) {
214+
DirectHandle<CallSiteInfo> frame = CallSiteInfo::ConstructFromRawData(
215+
isolate, raw_data_for_call_site_infos, i);
214216
DirectHandle<JSObject> site;
215217
ASSIGN_RETURN_ON_EXCEPTION(isolate, site,
216218
JSObject::New(constructor, constructor,
@@ -292,7 +294,7 @@ MaybeDirectHandle<Object> ErrorUtils::FormatStackTrace(
292294
return isolate->factory()->empty_string();
293295
}
294296
DCHECK(IsFixedArray(*raw_stack));
295-
auto elems = Cast<FixedArray>(raw_stack);
297+
auto raw_data_for_call_site_infos = Cast<FixedArray>(raw_stack);
296298

297299
const bool in_recursion = isolate->formatting_stack_trace();
298300
const bool has_overflowed = i::StackLimitCheck{isolate}.HasOverflowed();
@@ -303,8 +305,9 @@ MaybeDirectHandle<Object> ErrorUtils::FormatStackTrace(
303305
PrepareStackTraceScope scope(isolate);
304306

305307
DirectHandle<JSArray> sites;
306-
ASSIGN_RETURN_ON_EXCEPTION(isolate, sites,
307-
GetStackFrames(isolate, elems));
308+
ASSIGN_RETURN_ON_EXCEPTION(
309+
isolate, sites,
310+
GetStackFrames(isolate, raw_data_for_call_site_infos));
308311

309312
DirectHandle<Object> result;
310313
ASSIGN_RETURN_ON_EXCEPTION(
@@ -329,8 +332,9 @@ MaybeDirectHandle<Object> ErrorUtils::FormatStackTrace(
329332
isolate->CountUsage(v8::Isolate::kErrorPrepareStackTrace);
330333

331334
DirectHandle<JSArray> sites;
332-
ASSIGN_RETURN_ON_EXCEPTION(isolate, sites,
333-
GetStackFrames(isolate, elems));
335+
ASSIGN_RETURN_ON_EXCEPTION(
336+
isolate, sites,
337+
GetStackFrames(isolate, raw_data_for_call_site_infos));
334338

335339
constexpr int argc = 2;
336340
std::array<DirectHandle<Object>, argc> args;
@@ -359,12 +363,16 @@ MaybeDirectHandle<Object> ErrorUtils::FormatStackTrace(
359363

360364
RETURN_ON_EXCEPTION(isolate, AppendErrorString(isolate, error, &builder));
361365

362-
for (int i = 0; i < elems->length(); ++i) {
366+
int elems_len = raw_data_for_call_site_infos->length() /
367+
CallSiteInfo::Fields::kCount;
368+
for (int i = 0; i < elems_len; ++i) {
363369
builder.AppendCStringLiteral("\n at ");
364370

365-
DirectHandle<CallSiteInfo> frame(Cast<CallSiteInfo>(elems->get(i)),
366-
isolate);
371+
DirectHandle<CallSiteInfo> frame = CallSiteInfo::ConstructFromRawData(
372+
isolate, raw_data_for_call_site_infos, i);
367373

374+
// TODO(marja): Avoid CallSiteInfo creation since we serialize it right
375+
// away.
368376
v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
369377
SerializeCallSiteInfo(isolate, frame, &builder);
370378

@@ -1165,7 +1173,8 @@ MaybeDirectHandle<Object> ErrorUtils::GetFormattedStack(
11651173
isolate, formatted_stack,
11661174
FormatStackTrace(
11671175
isolate, error_object,
1168-
direct_handle(error_stack_data->call_site_infos(), isolate)));
1176+
direct_handle(error_stack_data->raw_data_for_call_site_infos(),
1177+
isolate)));
11691178
error_stack_data->set_formatted_stack(*formatted_stack);
11701179
return formatted_stack;
11711180
}

deps/v8/src/heap/factory.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,13 +1589,14 @@ DirectHandle<InterceptorInfo> Factory::NewInterceptorInfo(
15891589
}
15901590

15911591
DirectHandle<ErrorStackData> Factory::NewErrorStackData(
1592-
DirectHandle<UnionOf<JSAny, FixedArray>> call_site_infos_or_formatted_stack,
1592+
DirectHandle<UnionOf<JSAny, FixedArray>>
1593+
raw_data_for_call_site_infos_or_formatted_stack,
15931594
DirectHandle<StackTraceInfo> stack_trace) {
15941595
Tagged<ErrorStackData> error_stack_data = NewStructInternal<ErrorStackData>(
15951596
ERROR_STACK_DATA_TYPE, AllocationType::kYoung);
15961597
DisallowGarbageCollection no_gc;
1597-
error_stack_data->set_call_site_infos_or_formatted_stack(
1598-
*call_site_infos_or_formatted_stack, SKIP_WRITE_BARRIER);
1598+
error_stack_data->set_raw_data_for_call_site_infos_or_formatted_stack(
1599+
*raw_data_for_call_site_infos_or_formatted_stack, SKIP_WRITE_BARRIER);
15991600
error_stack_data->set_stack_trace(*stack_trace, SKIP_WRITE_BARRIER);
16001601
return direct_handle(error_stack_data, isolate());
16011602
}

deps/v8/src/heap/factory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
472472

473473
DirectHandle<ErrorStackData> NewErrorStackData(
474474
DirectHandle<UnionOf<JSAny, FixedArray>>
475-
call_site_infos_or_formatted_stack,
475+
raw_data_for_call_site_infos_or_formatted_stack,
476476
DirectHandle<StackTraceInfo> stack_trace);
477477

478478
Handle<Script> CloneScript(DirectHandle<Script> script,

deps/v8/src/objects/call-site-info.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,38 @@
1717

1818
namespace v8::internal {
1919

20+
// static
21+
DirectHandle<CallSiteInfo> CallSiteInfo::ConstructFromRawData(
22+
Isolate* isolate, DirectHandle<FixedArray> frames, int index) {
23+
int base_index = index * Fields::kCount;
24+
DirectHandle<Object> receiver(frames->get(base_index + Fields::kReceiver),
25+
isolate);
26+
DirectHandle<Object> function(frames->get(base_index + Fields::kFunction),
27+
isolate);
28+
DirectHandle<Object> code_obj(frames->get(base_index + Fields::kCode),
29+
isolate);
30+
DirectHandle<Union<Code, BytecodeArray, Undefined>> resolved_code;
31+
if (IsCodeWrapper(*code_obj)) {
32+
resolved_code = handle(Cast<CodeWrapper>(code_obj)->code(isolate), isolate);
33+
} else if (IsBytecodeWrapper(*code_obj)) {
34+
resolved_code =
35+
handle(Cast<BytecodeWrapper>(code_obj)->bytecode(isolate), isolate);
36+
} else if (IsUndefined(*code_obj)) {
37+
resolved_code = isolate->factory()->undefined_value();
38+
} else {
39+
UNREACHABLE();
40+
}
41+
42+
int offset = Smi::ToInt(frames->get(base_index + Fields::kOffset));
43+
DirectHandle<FixedArray> parameters(
44+
Cast<FixedArray>(frames->get(base_index + Fields::kParameters)), isolate);
45+
int flags = Smi::ToInt(frames->get(base_index + Fields::kFlags));
46+
47+
return isolate->factory()->NewCallSiteInfo(
48+
Cast<JSAny>(receiver), Cast<UnionOf<Smi, JSFunction>>(function),
49+
resolved_code, offset, flags, parameters);
50+
}
51+
2052
bool CallSiteInfo::IsPromiseAll() const {
2153
if (!IsAsync()) return false;
2254
Tagged<JSFunction> fun = Cast<JSFunction>(function());

deps/v8/src/objects/call-site-info.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@ V8_OBJECT class CallSiteInfo : public StructLayout {
8080
// Used to signal that the requested field is unknown.
8181
static constexpr int kUnknown = kNoSourcePosition;
8282

83+
// For delayed CallSiteInfo creation (storing the raw data for several
84+
// CallSiteInfos in a FixedArray).
85+
// kFlags must stay last (see CallSiteBuilder::AppendFrame).
86+
enum Fields {
87+
kCode = 0,
88+
kReceiver,
89+
kFunction,
90+
kOffset,
91+
kParameters,
92+
kFlags,
93+
kCount
94+
};
95+
96+
static DirectHandle<CallSiteInfo> ConstructFromRawData(
97+
Isolate* isolate, DirectHandle<FixedArray> frames, int index);
98+
8399
V8_EXPORT_PRIVATE static int GetLineNumber(DirectHandle<CallSiteInfo> info);
84100
V8_EXPORT_PRIVATE static int GetColumnNumber(DirectHandle<CallSiteInfo> info);
85101

0 commit comments

Comments
 (0)