Skip to content

Commit fb698ce

Browse files
schuayCommit Bot
authored andcommitted
[isolate-data] Move hot fields closer to isolate_root
In generated code, we access fields inside IsolateData through the root-register. On some platforms it is significantly cheaper to access things that are close to the root-register value than things that are located far away. The motivation for this CL was a 5% difference in Octane/Mandreel scores between // Part of the stack check. cmpq rsp,[r13+0x9ea8] and cmpq rsp,[r13-0x30] // Mandreel score improved by 5%. This moves the StackGuard up to fix Mandreel. As a drive-by, also move two more fields up that are accessed by each CallCFunction. Tbr: [email protected] Bug: v8:9534,chromium:993264 Change-Id: I5418b63d40274a138e285fa3c99b96e33a814fb1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1751345 Reviewed-by: Jakob Gruber <[email protected]> Reviewed-by: Yang Guo <[email protected]> Auto-Submit: Jakob Gruber <[email protected]> Commit-Queue: Yang Guo <[email protected]> Cr-Commit-Position: refs/heads/master@{#63187}
1 parent a1982f0 commit fb698ce

3 files changed

Lines changed: 37 additions & 16 deletions

File tree

include/v8-internal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,22 @@ class Internals {
152152

153153
static const uint32_t kNumIsolateDataSlots = 4;
154154

155+
// IsolateData layout guarantees.
155156
static const int kIsolateEmbedderDataOffset = 0;
156157
static const int kExternalMemoryOffset =
157158
kNumIsolateDataSlots * kApiSystemPointerSize;
158159
static const int kExternalMemoryLimitOffset =
159160
kExternalMemoryOffset + kApiInt64Size;
160161
static const int kExternalMemoryAtLastMarkCompactOffset =
161162
kExternalMemoryLimitOffset + kApiInt64Size;
162-
static const int kIsolateRootsOffset =
163+
static const int kIsolateFastCCallCallerFpOffset =
163164
kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size;
165+
static const int kIsolateFastCCallCallerPcOffset =
166+
kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize;
167+
static const int kIsolateStackGuardOffset =
168+
kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize;
169+
static const int kIsolateRootsOffset =
170+
kIsolateStackGuardOffset + 7 * kApiSystemPointerSize;
164171

165172
static const int kUndefinedValueRootIndex = 4;
166173
static const int kTheHoleValueRootIndex = 5;

src/execution/isolate-data.h

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,27 @@ class IsolateData final {
111111
Address* builtins() { return builtins_; }
112112

113113
private:
114-
// Static layout definition.
114+
// Static layout definition.
115+
//
116+
// Note: The location of fields within IsolateData is significant. The
117+
// closer they are to the value of kRootRegister (i.e.: isolate_root()), the
118+
// cheaper it is to access them. See also: https://crbug.com/993264.
119+
// The recommend guideline is to put frequently-accessed fields close to the
120+
// beginning of IsolateData.
115121
#define FIELDS(V) \
116122
V(kEmbedderDataOffset, Internals::kNumIsolateDataSlots* kSystemPointerSize) \
117123
V(kExternalMemoryOffset, kInt64Size) \
118124
V(kExternalMemoryLlimitOffset, kInt64Size) \
119125
V(kExternalMemoryAtLastMarkCompactOffset, kInt64Size) \
126+
V(kFastCCallCallerFPOffset, kSystemPointerSize) \
127+
V(kFastCCallCallerPCOffset, kSystemPointerSize) \
128+
V(kStackGuardOffset, StackGuard::kSizeInBytes) \
120129
V(kRootsTableOffset, RootsTable::kEntriesCount* kSystemPointerSize) \
121130
V(kExternalReferenceTableOffset, ExternalReferenceTable::kSizeInBytes) \
122131
V(kThreadLocalTopOffset, ThreadLocalTop::kSizeInBytes) \
123132
V(kBuiltinEntryTableOffset, Builtins::builtin_count* kSystemPointerSize) \
124133
V(kBuiltinsTableOffset, Builtins::builtin_count* kSystemPointerSize) \
125134
V(kVirtualCallTargetRegisterOffset, kSystemPointerSize) \
126-
V(kFastCCallCallerFPOffset, kSystemPointerSize) \
127-
V(kFastCCallCallerPCOffset, kSystemPointerSize) \
128-
V(kStackGuardOffset, StackGuard::kSizeInBytes) \
129135
V(kStackIsIterableOffset, kUInt8Size) \
130136
/* This padding aligns IsolateData size by 8 bytes. */ \
131137
V(kPaddingOffset, \
@@ -153,6 +159,17 @@ class IsolateData final {
153159
// Caches the amount of external memory registered at the last MC.
154160
int64_t external_memory_at_last_mark_compact_ = 0;
155161

162+
// Stores the state of the caller for TurboAssembler::CallCFunction so that
163+
// the sampling CPU profiler can iterate the stack during such calls. These
164+
// are stored on IsolateData so that they can be stored to with only one move
165+
// instruction in compiled code.
166+
Address fast_c_call_caller_fp_ = kNullAddress;
167+
Address fast_c_call_caller_pc_ = kNullAddress;
168+
169+
// Fields related to the system and JS stack. In particular, this contains the
170+
// stack limit used by stack checks in generated code.
171+
StackGuard stack_guard_;
172+
156173
RootsTable roots_;
157174

158175
ExternalReferenceTable external_reference_table_;
@@ -172,17 +189,6 @@ class IsolateData final {
172189
// ia32 (otherwise the arguments adaptor call runs out of registers).
173190
void* virtual_call_target_register_ = nullptr;
174191

175-
// Stores the state of the caller for TurboAssembler::CallCFunction so that
176-
// the sampling CPU profiler can iterate the stack during such calls. These
177-
// are stored on IsolateData so that they can be stored to with only one move
178-
// instruction in compiled code.
179-
Address fast_c_call_caller_fp_ = kNullAddress;
180-
Address fast_c_call_caller_pc_ = kNullAddress;
181-
182-
// Fields related to the system and JS stack. In particular, this contains the
183-
// stack limit used by stack checks in generated code.
184-
StackGuard stack_guard_;
185-
186192
// Whether the SafeStackFrameIterator can successfully iterate the current
187193
// stack. Only valid values are 0 or 1.
188194
uint8_t stack_is_iterable_ = 1;

src/execution/isolate.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2926,6 +2926,14 @@ void Isolate::CheckIsolateLayout() {
29262926
CHECK_EQ(OFFSET_OF(Isolate, isolate_data_), 0);
29272927
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.embedder_data_)),
29282928
Internals::kIsolateEmbedderDataOffset);
2929+
CHECK_EQ(static_cast<int>(
2930+
OFFSET_OF(Isolate, isolate_data_.fast_c_call_caller_fp_)),
2931+
Internals::kIsolateFastCCallCallerFpOffset);
2932+
CHECK_EQ(static_cast<int>(
2933+
OFFSET_OF(Isolate, isolate_data_.fast_c_call_caller_pc_)),
2934+
Internals::kIsolateFastCCallCallerPcOffset);
2935+
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.stack_guard_)),
2936+
Internals::kIsolateStackGuardOffset);
29292937
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.roots_)),
29302938
Internals::kIsolateRootsOffset);
29312939
CHECK_EQ(Internals::kExternalMemoryOffset % 8, 0);

0 commit comments

Comments
 (0)