[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: yangguo@chromium.org Bug: v8:9534,chromium:993264 Change-Id: I5418b63d40274a138e285fa3c99b96e33a814fb1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1751345 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Auto-Submit: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#63187}
This commit is contained in:
parent
a1982f0b8c
commit
fb698cec37
@ -152,6 +152,7 @@ class Internals {
|
||||
|
||||
static const uint32_t kNumIsolateDataSlots = 4;
|
||||
|
||||
// IsolateData layout guarantees.
|
||||
static const int kIsolateEmbedderDataOffset = 0;
|
||||
static const int kExternalMemoryOffset =
|
||||
kNumIsolateDataSlots * kApiSystemPointerSize;
|
||||
@ -159,8 +160,14 @@ class Internals {
|
||||
kExternalMemoryOffset + kApiInt64Size;
|
||||
static const int kExternalMemoryAtLastMarkCompactOffset =
|
||||
kExternalMemoryLimitOffset + kApiInt64Size;
|
||||
static const int kIsolateRootsOffset =
|
||||
static const int kIsolateFastCCallCallerFpOffset =
|
||||
kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size;
|
||||
static const int kIsolateFastCCallCallerPcOffset =
|
||||
kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize;
|
||||
static const int kIsolateStackGuardOffset =
|
||||
kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize;
|
||||
static const int kIsolateRootsOffset =
|
||||
kIsolateStackGuardOffset + 7 * kApiSystemPointerSize;
|
||||
|
||||
static const int kUndefinedValueRootIndex = 4;
|
||||
static const int kTheHoleValueRootIndex = 5;
|
||||
|
@ -111,21 +111,27 @@ class IsolateData final {
|
||||
Address* builtins() { return builtins_; }
|
||||
|
||||
private:
|
||||
// Static layout definition.
|
||||
// Static layout definition.
|
||||
//
|
||||
// Note: The location of fields within IsolateData is significant. The
|
||||
// closer they are to the value of kRootRegister (i.e.: isolate_root()), the
|
||||
// cheaper it is to access them. See also: https://crbug.com/993264.
|
||||
// The recommend guideline is to put frequently-accessed fields close to the
|
||||
// beginning of IsolateData.
|
||||
#define FIELDS(V) \
|
||||
V(kEmbedderDataOffset, Internals::kNumIsolateDataSlots* kSystemPointerSize) \
|
||||
V(kExternalMemoryOffset, kInt64Size) \
|
||||
V(kExternalMemoryLlimitOffset, kInt64Size) \
|
||||
V(kExternalMemoryAtLastMarkCompactOffset, kInt64Size) \
|
||||
V(kFastCCallCallerFPOffset, kSystemPointerSize) \
|
||||
V(kFastCCallCallerPCOffset, kSystemPointerSize) \
|
||||
V(kStackGuardOffset, StackGuard::kSizeInBytes) \
|
||||
V(kRootsTableOffset, RootsTable::kEntriesCount* kSystemPointerSize) \
|
||||
V(kExternalReferenceTableOffset, ExternalReferenceTable::kSizeInBytes) \
|
||||
V(kThreadLocalTopOffset, ThreadLocalTop::kSizeInBytes) \
|
||||
V(kBuiltinEntryTableOffset, Builtins::builtin_count* kSystemPointerSize) \
|
||||
V(kBuiltinsTableOffset, Builtins::builtin_count* kSystemPointerSize) \
|
||||
V(kVirtualCallTargetRegisterOffset, kSystemPointerSize) \
|
||||
V(kFastCCallCallerFPOffset, kSystemPointerSize) \
|
||||
V(kFastCCallCallerPCOffset, kSystemPointerSize) \
|
||||
V(kStackGuardOffset, StackGuard::kSizeInBytes) \
|
||||
V(kStackIsIterableOffset, kUInt8Size) \
|
||||
/* This padding aligns IsolateData size by 8 bytes. */ \
|
||||
V(kPaddingOffset, \
|
||||
@ -153,6 +159,17 @@ class IsolateData final {
|
||||
// Caches the amount of external memory registered at the last MC.
|
||||
int64_t external_memory_at_last_mark_compact_ = 0;
|
||||
|
||||
// Stores the state of the caller for TurboAssembler::CallCFunction so that
|
||||
// the sampling CPU profiler can iterate the stack during such calls. These
|
||||
// are stored on IsolateData so that they can be stored to with only one move
|
||||
// instruction in compiled code.
|
||||
Address fast_c_call_caller_fp_ = kNullAddress;
|
||||
Address fast_c_call_caller_pc_ = kNullAddress;
|
||||
|
||||
// Fields related to the system and JS stack. In particular, this contains the
|
||||
// stack limit used by stack checks in generated code.
|
||||
StackGuard stack_guard_;
|
||||
|
||||
RootsTable roots_;
|
||||
|
||||
ExternalReferenceTable external_reference_table_;
|
||||
@ -172,17 +189,6 @@ class IsolateData final {
|
||||
// ia32 (otherwise the arguments adaptor call runs out of registers).
|
||||
void* virtual_call_target_register_ = nullptr;
|
||||
|
||||
// Stores the state of the caller for TurboAssembler::CallCFunction so that
|
||||
// the sampling CPU profiler can iterate the stack during such calls. These
|
||||
// are stored on IsolateData so that they can be stored to with only one move
|
||||
// instruction in compiled code.
|
||||
Address fast_c_call_caller_fp_ = kNullAddress;
|
||||
Address fast_c_call_caller_pc_ = kNullAddress;
|
||||
|
||||
// Fields related to the system and JS stack. In particular, this contains the
|
||||
// stack limit used by stack checks in generated code.
|
||||
StackGuard stack_guard_;
|
||||
|
||||
// Whether the SafeStackFrameIterator can successfully iterate the current
|
||||
// stack. Only valid values are 0 or 1.
|
||||
uint8_t stack_is_iterable_ = 1;
|
||||
|
@ -2926,6 +2926,14 @@ void Isolate::CheckIsolateLayout() {
|
||||
CHECK_EQ(OFFSET_OF(Isolate, isolate_data_), 0);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.embedder_data_)),
|
||||
Internals::kIsolateEmbedderDataOffset);
|
||||
CHECK_EQ(static_cast<int>(
|
||||
OFFSET_OF(Isolate, isolate_data_.fast_c_call_caller_fp_)),
|
||||
Internals::kIsolateFastCCallCallerFpOffset);
|
||||
CHECK_EQ(static_cast<int>(
|
||||
OFFSET_OF(Isolate, isolate_data_.fast_c_call_caller_pc_)),
|
||||
Internals::kIsolateFastCCallCallerPcOffset);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.stack_guard_)),
|
||||
Internals::kIsolateStackGuardOffset);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.roots_)),
|
||||
Internals::kIsolateRootsOffset);
|
||||
CHECK_EQ(Internals::kExternalMemoryOffset % 8, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user