Commit d205a6a7 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[ia32,root] Add ExternalOperand and some uncontroversial usages

This is the first CL in a series that removes the StaticVariable operand.

Change-Id: I2acdbf4a7481af43321b8af10dbe38f8f481bea8
Bug: v8:6666
Reviewed-on: https://chromium-review.googlesource.com/c/1276365
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56635}
parent e312281b
......@@ -336,7 +336,7 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
ExternalReference::address_of_real_stack_limit(masm->isolate());
// Compute the space that is left as a negative number in scratch. If
// we already overflowed, this will be a positive number.
__ mov(scratch, __ StaticVariable(real_stack_limit));
__ mov(scratch, __ ExternalReferenceAsOperand(real_stack_limit, scratch));
__ sub(scratch, esp);
// Add the size of the arguments.
static_assert(kPointerSize == 4,
......@@ -363,7 +363,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Setup the context (we need to use the caller context from the isolate).
ExternalReference context_address = ExternalReference::Create(
IsolateAddressId::kContextAddress, masm->isolate());
__ mov(esi, __ StaticVariable(context_address));
__ mov(esi, __ ExternalReferenceAsOperand(context_address, scratch1));
// Load the previous frame pointer (edx) to access C arguments
__ mov(scratch1, Operand(ebp, 0));
......@@ -470,13 +470,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
Label stepping_prepared;
ExternalReference debug_hook =
ExternalReference::debug_hook_on_function_call_address(masm->isolate());
__ cmpb(__ StaticVariable(debug_hook), Immediate(0));
__ cmpb(__ ExternalReferenceAsOperand(debug_hook, ecx), Immediate(0));
__ j(not_equal, &prepare_step_in_if_stepping);
// Flood function if we need to continue stepping in the suspended generator.
ExternalReference debug_suspended_generator =
ExternalReference::debug_suspended_generator_address(masm->isolate());
__ cmp(edx, __ StaticVariable(debug_suspended_generator));
__ cmp(edx, __ ExternalReferenceAsOperand(debug_suspended_generator, ecx));
__ j(equal, &prepare_step_in_suspended_generator);
__ bind(&stepping_prepared);
......@@ -2607,8 +2607,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// Call C function.
__ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 2 * kPointerSize),
Immediate(ExternalReference::isolate_address(masm->isolate())));
__ mov(ecx, Immediate(ExternalReference::isolate_address(masm->isolate())));
__ mov(Operand(esp, 2 * kPointerSize), ecx);
__ call(kRuntimeCallFunctionRegister);
// Result is in eax or edx:eax - do not destroy these registers!
......@@ -2626,7 +2626,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
Label okay;
ExternalReference pending_exception_address = ExternalReference::Create(
IsolateAddressId::kPendingExceptionAddress, masm->isolate());
__ cmp(edx, __ StaticVariable(pending_exception_address));
__ cmp(edx, __ ExternalReferenceAsOperand(pending_exception_address, ecx));
// Cannot use check here as it attempts to generate call into runtime.
__ j(equal, &okay, Label::kNear);
__ int3();
......@@ -2666,9 +2666,10 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
}
// Retrieve the handler context, SP and FP.
__ mov(esi, __ StaticVariable(pending_handler_context_address));
__ mov(esp, __ StaticVariable(pending_handler_sp_address));
__ mov(ebp, __ StaticVariable(pending_handler_fp_address));
__ mov(esp, __ ExternalReferenceAsOperand(pending_handler_sp_address, esi));
__ mov(ebp, __ ExternalReferenceAsOperand(pending_handler_fp_address, esi));
__ mov(esi,
__ ExternalReferenceAsOperand(pending_handler_context_address, esi));
// If the handler is a JS frame, restore the context to the frame. Note that
// the context will be set to (esi == 0) for non-JS frames.
......@@ -2690,7 +2691,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
#endif
// Compute the handler entry address and jump to it.
__ mov(edi, __ StaticVariable(pending_handler_entrypoint_address));
__ mov(edi, __ ExternalReferenceAsOperand(pending_handler_entrypoint_address,
edi));
__ jmp(edi);
}
......
......@@ -369,7 +369,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Setup the context (we need to use the caller context from the isolate).
ExternalReference context_address = ExternalReference::Create(
IsolateAddressId::kContextAddress, masm->isolate());
__ movp(rsi, masm->ExternalOperand(context_address));
__ movp(rsi, masm->ExternalReferenceAsOperand(context_address));
// Push the function and the receiver onto the stack.
__ Push(rdx);
......@@ -406,7 +406,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Setup the context (we need to use the caller context from the isolate).
ExternalReference context_address = ExternalReference::Create(
IsolateAddressId::kContextAddress, masm->isolate());
__ movp(rsi, masm->ExternalOperand(context_address));
__ movp(rsi, masm->ExternalReferenceAsOperand(context_address));
// Push the function and receiver onto the stack.
__ Push(rdi);
......@@ -516,7 +516,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
Label stepping_prepared;
ExternalReference debug_hook =
ExternalReference::debug_hook_on_function_call_address(masm->isolate());
Operand debug_hook_operand = masm->ExternalOperand(debug_hook);
Operand debug_hook_operand = masm->ExternalReferenceAsOperand(debug_hook);
__ cmpb(debug_hook_operand, Immediate(0));
__ j(not_equal, &prepare_step_in_if_stepping);
......@@ -524,7 +524,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
ExternalReference debug_suspended_generator =
ExternalReference::debug_suspended_generator_address(masm->isolate());
Operand debug_suspended_generator_operand =
masm->ExternalOperand(debug_suspended_generator);
masm->ExternalReferenceAsOperand(debug_suspended_generator);
__ cmpp(rdx, debug_suspended_generator_operand);
__ j(equal, &prepare_step_in_suspended_generator);
__ bind(&stepping_prepared);
......@@ -2467,7 +2467,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
ExternalReference pending_exception_address = ExternalReference::Create(
IsolateAddressId::kPendingExceptionAddress, masm->isolate());
Operand pending_exception_operand =
masm->ExternalOperand(pending_exception_address);
masm->ExternalReferenceAsOperand(pending_exception_address);
__ cmpp(r14, pending_exception_operand);
__ j(equal, &okay, Label::kNear);
__ int3();
......@@ -2504,9 +2504,10 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
__ CallCFunction(find_handler, 3);
}
// Retrieve the handler context, SP and FP.
__ movp(rsi, masm->ExternalOperand(pending_handler_context_address));
__ movp(rsp, masm->ExternalOperand(pending_handler_sp_address));
__ movp(rbp, masm->ExternalOperand(pending_handler_fp_address));
__ movp(rsi,
masm->ExternalReferenceAsOperand(pending_handler_context_address));
__ movp(rsp, masm->ExternalReferenceAsOperand(pending_handler_sp_address));
__ movp(rbp, masm->ExternalReferenceAsOperand(pending_handler_fp_address));
// If the handler is a JS frame, restore the context to the frame. Note that
// the context will be set to (rsi == 0) for non-JS frames.
......@@ -2523,7 +2524,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
__ ResetSpeculationPoisonRegister();
// Compute the handler entry address and jump to it.
__ movp(rdi, masm->ExternalOperand(pending_handler_entrypoint_address));
__ movp(rdi,
masm->ExternalReferenceAsOperand(pending_handler_entrypoint_address));
__ jmp(rdi);
}
......
......@@ -41,6 +41,8 @@ MacroAssembler::MacroAssembler(Isolate* isolate,
code_object_ = Handle<HeapObject>::New(
*isolate->factory()->NewSelfReferenceMarker(), isolate);
}
// TODO(jgruber, v8:6666): Remove once root register is always available.
set_root_array_available(FLAG_embedded_builtins);
}
void TurboAssembler::InitializeRootRegister() {
......@@ -131,6 +133,40 @@ void MacroAssembler::PushRoot(RootIndex index) {
}
}
Operand TurboAssembler::ExternalReferenceAsOperand(ExternalReference reference,
Register scratch) {
Assembler::AllowExplicitEbxAccessScope read_only_access(this);
if (root_array_available_ && options().enable_root_array_delta_access) {
intptr_t offset =
RootRegisterOffsetForExternalReference(isolate(), reference);
return Operand(kRootRegister, offset);
}
if (root_array_available_ && options().isolate_independent_code) {
if (IsAddressableThroughRootRegister(isolate(), reference)) {
// Some external references can be efficiently loaded as an offset from
// kRootRegister.
intptr_t offset =
RootRegisterOffsetForExternalReference(isolate(), reference);
return Operand(kRootRegister, offset);
} else {
// Otherwise, do a memory load from the external reference table.
// Encode as an index into the external reference table stored on the
// isolate.
ExternalReferenceEncoder encoder(isolate());
ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
CHECK(!v.is_from_api());
mov(scratch,
Operand(kRootRegister,
RootRegisterOffsetForExternalReferenceIndex(v.index())));
return Operand(scratch, 0);
}
}
Move(scratch, Immediate(reference));
return Operand(scratch, 0);
}
void TurboAssembler::LoadFromConstantsTable(Register destination,
int constant_index) {
DCHECK(!is_ebx_addressable_);
......@@ -421,7 +457,7 @@ void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
mov(eax, StaticVariable(restart_fp));
mov(eax, ExternalReferenceAsOperand(restart_fp, eax));
test(eax, eax);
j(not_zero, BUILTIN_CODE(isolate(), FrameDropperTrampoline),
RelocInfo::CODE_TARGET);
......
......@@ -237,6 +237,15 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void LoadRootRegisterOffset(Register destination, intptr_t offset) override;
void LoadRootRelative(Register destination, int32_t offset) override;
// Operand pointing to an external reference.
// May emit code to set up the scratch register. The operand is
// only guaranteed to be correct as long as the scratch register
// isn't changed.
// If the operand is used more than once, use a scratch register
// that is guaranteed not to be clobbered.
Operand ExternalReferenceAsOperand(ExternalReference reference,
Register scratch);
void LoadAddress(Register destination, ExternalReference source);
void PushRootRegister() {
......
......@@ -78,7 +78,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
ExternalReference c_entry_fp =
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate());
{
Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
Operand c_entry_fp_operand = masm->ExternalReferenceAsOperand(c_entry_fp);
__ Push(c_entry_fp_operand);
}
......@@ -134,7 +134,8 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ bind(&not_outermost_js_2);
// Restore the top frame descriptor from the stack.
{ Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
{
Operand c_entry_fp_operand = masm->ExternalReferenceAsOperand(c_entry_fp);
__ Pop(c_entry_fp_operand);
}
......
......@@ -80,21 +80,11 @@ MacroAssembler::MacroAssembler(Isolate* isolate,
}
}
static const int64_t kInvalidRootRegisterDelta = -1;
int64_t TurboAssembler::RootRegisterDelta(ExternalReference other) {
if (predictable_code_size() &&
(other.address() < reinterpret_cast<Address>(isolate()) ||
other.address() >= reinterpret_cast<Address>(isolate() + 1))) {
return kInvalidRootRegisterDelta;
}
return RootRegisterOffsetForExternalReference(isolate(), other);
}
void MacroAssembler::Load(Register destination, ExternalReference source) {
if (root_array_available_ && options().enable_root_array_delta_access) {
int64_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
intptr_t delta = RootRegisterOffsetForExternalReference(isolate(), source);
if (is_int32(delta)) {
movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
}
......@@ -118,8 +108,9 @@ void MacroAssembler::Load(Register destination, ExternalReference source) {
void MacroAssembler::Store(ExternalReference destination, Register source) {
if (root_array_available_ && options().enable_root_array_delta_access) {
int64_t delta = RootRegisterDelta(destination);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
intptr_t delta =
RootRegisterOffsetForExternalReference(isolate(), destination);
if (is_int32(delta)) {
movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
return;
}
......@@ -159,8 +150,8 @@ void TurboAssembler::LoadRootRelative(Register destination, int32_t offset) {
void TurboAssembler::LoadAddress(Register destination,
ExternalReference source) {
if (root_array_available_ && options().enable_root_array_delta_access) {
int64_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
intptr_t delta = RootRegisterOffsetForExternalReference(isolate(), source);
if (is_int32(delta)) {
leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
}
......@@ -175,15 +166,39 @@ void TurboAssembler::LoadAddress(Register destination,
Move(destination, source);
}
Operand TurboAssembler::ExternalOperand(ExternalReference target,
Register scratch) {
Operand TurboAssembler::ExternalReferenceAsOperand(ExternalReference reference,
Register scratch) {
if (root_array_available_ && options().enable_root_array_delta_access) {
int64_t delta = RootRegisterDelta(target);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
int64_t delta =
RootRegisterOffsetForExternalReference(isolate(), reference);
if (is_int32(delta)) {
return Operand(kRootRegister, static_cast<int32_t>(delta));
}
}
Move(scratch, target);
if (root_array_available_ && options().isolate_independent_code) {
if (IsAddressableThroughRootRegister(isolate(), reference)) {
// Some external references can be efficiently loaded as an offset from
// kRootRegister.
intptr_t offset =
RootRegisterOffsetForExternalReference(isolate(), reference);
CHECK(is_int32(offset));
return Operand(kRootRegister, static_cast<int32_t>(offset));
} else {
// Otherwise, do a memory load from the external reference table.
// Encode as an index into the external reference table stored on the
// isolate.
ExternalReferenceEncoder encoder(isolate());
ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
CHECK(!v.is_from_api());
movp(scratch,
Operand(kRootRegister,
RootRegisterOffsetForExternalReferenceIndex(v.index())));
return Operand(scratch, 0);
}
}
Move(scratch, reference);
return Operand(scratch, 0);
}
......@@ -1278,23 +1293,23 @@ void TurboAssembler::Move(XMMRegister dst, uint64_t src) {
// ----------------------------------------------------------------------------
void MacroAssembler::Absps(XMMRegister dst) {
Andps(dst,
ExternalOperand(ExternalReference::address_of_float_abs_constant()));
Andps(dst, ExternalReferenceAsOperand(
ExternalReference::address_of_float_abs_constant()));
}
void MacroAssembler::Negps(XMMRegister dst) {
Xorps(dst,
ExternalOperand(ExternalReference::address_of_float_neg_constant()));
Xorps(dst, ExternalReferenceAsOperand(
ExternalReference::address_of_float_neg_constant()));
}
void MacroAssembler::Abspd(XMMRegister dst) {
Andps(dst,
ExternalOperand(ExternalReference::address_of_double_abs_constant()));
Andps(dst, ExternalReferenceAsOperand(
ExternalReference::address_of_double_abs_constant()));
}
void MacroAssembler::Negpd(XMMRegister dst) {
Xorps(dst,
ExternalOperand(ExternalReference::address_of_double_neg_constant()));
Xorps(dst, ExternalReferenceAsOperand(
ExternalReference::address_of_double_neg_constant()));
}
void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
......@@ -1873,10 +1888,10 @@ void MacroAssembler::PushStackHandler() {
// Link the current handler as the next handler.
ExternalReference handler_address =
ExternalReference::Create(IsolateAddressId::kHandlerAddress, isolate());
Push(ExternalOperand(handler_address));
Push(ExternalReferenceAsOperand(handler_address));
// Set this new handler as the current one.
movp(ExternalOperand(handler_address), rsp);
movp(ExternalReferenceAsOperand(handler_address), rsp);
}
......@@ -1884,7 +1899,7 @@ void MacroAssembler::PopStackHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
ExternalReference handler_address =
ExternalReference::Create(IsolateAddressId::kHandlerAddress, isolate());
Pop(ExternalOperand(handler_address));
Pop(ExternalReferenceAsOperand(handler_address));
addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
}
......@@ -2042,7 +2057,7 @@ void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
DCHECK_GT(value, 0);
if (FLAG_native_code_counters && counter->Enabled()) {
Operand counter_operand =
ExternalOperand(ExternalReference::Create(counter));
ExternalReferenceAsOperand(ExternalReference::Create(counter));
if (value == 1) {
incl(counter_operand);
} else {
......@@ -2056,7 +2071,7 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
DCHECK_GT(value, 0);
if (FLAG_native_code_counters && counter->Enabled()) {
Operand counter_operand =
ExternalOperand(ExternalReference::Create(counter));
ExternalReferenceAsOperand(ExternalReference::Create(counter));
if (value == 1) {
decl(counter_operand);
} else {
......@@ -2271,7 +2286,8 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
Label skip_hook;
ExternalReference debug_hook_active =
ExternalReference::debug_hook_on_function_call_address(isolate());
Operand debug_hook_active_operand = ExternalOperand(debug_hook_active);
Operand debug_hook_active_operand =
ExternalReferenceAsOperand(debug_hook_active);
cmpb(debug_hook_active_operand, Immediate(0));
j(equal, &skip_hook);
......@@ -2488,7 +2504,7 @@ void MacroAssembler::LeaveExitFrameEpilogue() {
// Restore current context from top and clear it in debug mode.
ExternalReference context_address =
ExternalReference::Create(IsolateAddressId::kContextAddress, isolate());
Operand context_operand = ExternalOperand(context_address);
Operand context_operand = ExternalReferenceAsOperand(context_address);
movp(rsi, context_operand);
#ifdef DEBUG
movp(context_operand, Immediate(Context::kInvalidContext));
......@@ -2497,7 +2513,7 @@ void MacroAssembler::LeaveExitFrameEpilogue() {
// Clear the top frame.
ExternalReference c_entry_fp_address =
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate());
Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address);
Operand c_entry_fp_operand = ExternalReferenceAsOperand(c_entry_fp_address);
movp(c_entry_fp_operand, Immediate(0));
}
......
......@@ -377,8 +377,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// isn't changed.
// If the operand is used more than once, use a scratch register
// that is guaranteed not to be clobbered.
Operand ExternalOperand(ExternalReference reference,
Register scratch = kScratchRegister);
Operand ExternalReferenceAsOperand(ExternalReference reference,
Register scratch = kScratchRegister);
void Call(Register reg) { call(reg); }
void Call(Operand op);
......@@ -515,8 +515,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
int smi_count = 0;
int heap_object_count = 0;
int64_t RootRegisterDelta(ExternalReference other);
// Returns a register holding the smi value. The register MUST NOT be
// modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi* value);
......@@ -540,7 +538,7 @@ class MacroAssembler : public TurboAssembler {
// Special case code for load and store to take advantage of
// load_rax/store_rax if possible/necessary.
// For other operations, just use:
// Operand operand = ExternalOperand(extref);
// Operand operand = ExternalReferenceAsOperand(extref);
// operation(operand, ..);
void Load(Register destination, ExternalReference source);
void Store(ExternalReference destination, Register source);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment