[builtins] Make ContinueToBuiltinHelper skip off-heap builtin trampolines
This changes Generate_ContinueToBuiltinHelper to generate code to load the builtin address directly from the builtins table rather than going via the executable code in the trampoline's code object. The set up for Generate_ContinueToBuiltinHelper is changed so that the builtin index is stored on the stack in place of the builtin Code object which is no longer needed. Bug: v8:9338 Change-Id: I83f66af99fb27f131fc39ff426fdca4b1d674b70 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1648155 Commit-Queue: Dan Elphick <delphick@chromium.org> Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#62170}
This commit is contained in:
parent
76d33a174e
commit
7b48dd55e1
@ -1509,13 +1509,16 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
||||
__ ldr(fp, MemOperand(
|
||||
sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
||||
|
||||
// Load builtin index (stored as a Smi) and use it to get the builtin start
|
||||
// address from the builtins table.
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ Pop(scratch);
|
||||
Register builtin = temps.Acquire();
|
||||
__ Pop(builtin);
|
||||
__ add(sp, sp,
|
||||
Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
||||
__ Pop(lr);
|
||||
__ add(pc, scratch, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ LoadEntryFromBuiltinIndex(builtin);
|
||||
__ bx(builtin);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1683,18 +1683,20 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
||||
|
||||
if (java_script_builtin) __ SmiUntag(kJavaScriptCallArgCountRegister);
|
||||
|
||||
// Load builtin object.
|
||||
// Load builtin index (stored as a Smi) and use it to get the builtin start
|
||||
// address from the builtins table.
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register builtin = temps.AcquireX();
|
||||
__ Ldr(builtin,
|
||||
MemOperand(fp, BuiltinContinuationFrameConstants::kBuiltinOffset));
|
||||
__ Ldr(
|
||||
builtin,
|
||||
MemOperand(fp, BuiltinContinuationFrameConstants::kBuiltinIndexOffset));
|
||||
|
||||
// Restore fp, lr.
|
||||
__ Mov(sp, fp);
|
||||
__ Pop(fp, lr);
|
||||
|
||||
// Call builtin.
|
||||
__ JumpCodeObject(builtin);
|
||||
__ LoadEntryFromBuiltinIndex(builtin);
|
||||
__ Jump(builtin);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1534,6 +1534,15 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
||||
BuiltinContinuationFrameConstants::kFixedFrameSize),
|
||||
eax);
|
||||
}
|
||||
|
||||
// Replace the builtin index Smi on the stack with the start address of the
|
||||
// builtin loaded from the builtins table. The ret below will return to this
|
||||
// address.
|
||||
int offset_to_builtin_index = allocatable_register_count * kSystemPointerSize;
|
||||
__ mov(eax, Operand(esp, offset_to_builtin_index));
|
||||
__ LoadEntryFromBuiltinIndex(eax);
|
||||
__ mov(Operand(esp, offset_to_builtin_index), eax);
|
||||
|
||||
for (int i = allocatable_register_count - 1; i >= 0; --i) {
|
||||
int code = config->GetAllocatableGeneralCode(i);
|
||||
__ pop(Register::from_code(code));
|
||||
@ -1549,7 +1558,6 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
||||
kSystemPointerSize;
|
||||
__ pop(Operand(esp, offsetToPC));
|
||||
__ Drop(offsetToPC / kSystemPointerSize);
|
||||
__ add(Operand(esp, 0), Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ ret(0);
|
||||
}
|
||||
} // namespace
|
||||
|
@ -1562,7 +1562,15 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
||||
kSystemPointerSize;
|
||||
__ popq(Operand(rsp, offsetToPC));
|
||||
__ Drop(offsetToPC / kSystemPointerSize);
|
||||
__ addq(Operand(rsp, 0), Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
|
||||
// Replace the builtin index Smi on the stack with the instruction start
|
||||
// address of the builtin from the builtins table, and then Ret to this
|
||||
// address
|
||||
__ movq(kScratchRegister, Operand(rsp, 0));
|
||||
__ movq(kScratchRegister,
|
||||
__ EntryFromBuiltinIndexAsOperand(kScratchRegister));
|
||||
__ movq(Operand(rsp, 0), kScratchRegister);
|
||||
|
||||
__ Ret();
|
||||
}
|
||||
} // namespace
|
||||
|
@ -303,7 +303,7 @@ void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode,
|
||||
Call(code.address(), rmode, cond, mode);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) {
|
||||
STATIC_ASSERT(kSystemPointerSize == 4);
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
@ -316,6 +316,10 @@ void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
add(builtin_index, builtin_index,
|
||||
Operand(IsolateData::builtin_entry_table_offset()));
|
||||
ldr(builtin_index, MemOperand(kRootRegister, builtin_index));
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
LoadEntryFromBuiltinIndex(builtin_index);
|
||||
Call(builtin_index);
|
||||
}
|
||||
|
||||
|
@ -300,6 +300,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
bool check_constant_pool = true);
|
||||
void Call(Label* target);
|
||||
|
||||
// Load the builtin given by the Smi in |builtin_index| into the same
|
||||
// register.
|
||||
void LoadEntryFromBuiltinIndex(Register builtin_index);
|
||||
void CallBuiltinByIndex(Register builtin_index) override;
|
||||
|
||||
void LoadCodeObjectEntry(Register destination, Register code_object) override;
|
||||
|
@ -1925,7 +1925,7 @@ void TurboAssembler::Call(ExternalReference target) {
|
||||
Call(temp);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) {
|
||||
STATIC_ASSERT(kSystemPointerSize == 8);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
@ -1941,6 +1941,10 @@ void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
#endif
|
||||
Add(builtin_index, builtin_index, IsolateData::builtin_entry_table_offset());
|
||||
Ldr(builtin_index, MemOperand(kRootRegister, builtin_index));
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
LoadEntryFromBuiltinIndex(builtin_index);
|
||||
Call(builtin_index);
|
||||
}
|
||||
|
||||
|
@ -852,6 +852,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
// Generate an indirect call (for when a direct call's range is not adequate).
|
||||
void IndirectCall(Address target, RelocInfo::Mode rmode);
|
||||
|
||||
// Load the builtin given by the Smi in |builtin_index| into the same
|
||||
// register.
|
||||
void LoadEntryFromBuiltinIndex(Register builtin_index);
|
||||
void CallBuiltinByIndex(Register builtin_index) override;
|
||||
|
||||
void LoadCodeObjectEntry(Register destination, Register code_object) override;
|
||||
|
@ -1887,7 +1887,7 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
|
||||
call(code_object, rmode);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) {
|
||||
STATIC_ASSERT(kSystemPointerSize == 4);
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
@ -1900,6 +1900,10 @@ void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
mov(builtin_index,
|
||||
Operand(kRootRegister, builtin_index, times_half_system_pointer_size,
|
||||
IsolateData::builtin_entry_table_offset()));
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
LoadEntryFromBuiltinIndex(builtin_index);
|
||||
call(builtin_index);
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
void Call(Label* target) { call(target); }
|
||||
void Call(Handle<Code> code_object, RelocInfo::Mode rmode);
|
||||
|
||||
// Load the builtin given by the Smi in |builtin_index| into the same
|
||||
// register.
|
||||
void LoadEntryFromBuiltinIndex(Register builtin_index);
|
||||
void CallBuiltinByIndex(Register builtin_index) override;
|
||||
|
||||
void LoadCodeObjectEntry(Register destination, Register code_object) override;
|
||||
|
@ -1608,7 +1608,7 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
|
||||
call(code_object, rmode);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) {
|
||||
#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH)
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
@ -1617,8 +1617,8 @@ void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
// The builtin_index register contains the builtin index as a Smi.
|
||||
// Untagging is folded into the indexing operand below (we use times_4 instead
|
||||
// of times_8 since smis are already shifted by one).
|
||||
Call(Operand(kRootRegister, builtin_index, times_4,
|
||||
IsolateData::builtin_entry_table_offset()));
|
||||
return Operand(kRootRegister, builtin_index, times_4,
|
||||
IsolateData::builtin_entry_table_offset());
|
||||
#else // defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH)
|
||||
STATIC_ASSERT(kSmiShiftSize == 31);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
@ -1626,11 +1626,15 @@ void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
|
||||
// The builtin_index register contains the builtin index as a Smi.
|
||||
SmiUntag(builtin_index, builtin_index);
|
||||
Call(Operand(kRootRegister, builtin_index, times_8,
|
||||
IsolateData::builtin_entry_table_offset()));
|
||||
return Operand(kRootRegister, builtin_index, times_8,
|
||||
IsolateData::builtin_entry_table_offset());
|
||||
#endif // defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH)
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
Call(EntryFromBuiltinIndexAsOperand(builtin_index));
|
||||
}
|
||||
|
||||
void TurboAssembler::LoadCodeObjectEntry(Register destination,
|
||||
Register code_object) {
|
||||
// Code objects are called differently depending on whether we are generating
|
||||
|
@ -344,6 +344,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
void Call(ExternalReference ext);
|
||||
void Call(Label* target) { call(target); }
|
||||
|
||||
Operand EntryFromBuiltinIndexAsOperand(Register builtin_index);
|
||||
void CallBuiltinByIndex(Register builtin_index) override;
|
||||
|
||||
void LoadCodeObjectEntry(Register destination, Register code_object) override;
|
||||
|
@ -1424,7 +1424,7 @@ Builtins::Name Deoptimizer::TrampolineForBuiltinContinuation(
|
||||
// +-------------------------+
|
||||
// | context |<- this non-standard context slot contains
|
||||
// +-------------------------+ the context, even for non-JS builtins.
|
||||
// | builtin address |
|
||||
// | builtin index |
|
||||
// +-------------------------+
|
||||
// | builtin input GPR reg0 |<- populated from deopt FrameState using
|
||||
// +-------------------------+ the builtin's CallInterfaceDescriptor
|
||||
@ -1649,7 +1649,8 @@ void Deoptimizer::DoComputeBuiltinContinuation(
|
||||
"builtin JavaScript context\n");
|
||||
|
||||
// The builtin to continue to.
|
||||
frame_writer.PushRawObject(builtin, "builtin address\n");
|
||||
frame_writer.PushRawObject(Smi::FromInt(builtin.builtin_index()),
|
||||
"builtin index\n");
|
||||
|
||||
for (int i = 0; i < allocatable_register_count; ++i) {
|
||||
int code = config->GetAllocatableGeneralCode(i);
|
||||
|
@ -271,7 +271,7 @@ class BuiltinContinuationFrameConstants : public TypedFrameConstants {
|
||||
TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
||||
static constexpr int kBuiltinContextOffset =
|
||||
TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
|
||||
static constexpr int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
|
||||
static constexpr int kBuiltinIndexOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
|
||||
|
||||
// The argument count is in the first allocatable register, stored below the
|
||||
// fixed part of the frame and therefore is not part of the fixed frame size.
|
||||
|
Loading…
Reference in New Issue
Block a user