The IC exposes a register definition.

Centralize a register definition in an IC that provides:
1) symbolic names for the register (like, edx == receiver)
2) defines ordering when passed on the stack

Code that implements or uses the IC should use this definition instead of "knowing" what the registers are. Or at least have the definition to validate it's assumptions.

As a side effect of avoiding runtime static initializers (enforced by tools/check-static-initializers.sh, neat), I gave ownership of the registers array to CodeStubInterfaceDescriptor. This prompted a cleanup of that struct.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/352583002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22011 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6f236862
This diff is collapsed.
......@@ -105,7 +105,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler_);
ApiFunction function(descriptor->deoptimization_handler());
ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
int params = descriptor->GetHandlerParameterCount();
......
......@@ -545,6 +545,13 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
// IC register specifications
const Register LoadIC::ReceiverRegister() { return r0; }
const Register LoadIC::NameRegister() { return r2; }
const Register KeyedLoadIC::ReceiverRegister() { return r1; }
const Register KeyedLoadIC::NameRegister() { return r0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- lr : return address
......
......@@ -1263,14 +1263,18 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { r0, r2, r3, r1, r4, r5 };
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, r3, r1, r4, r5 };
return registers;
}
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { r1, r0, r2, r3, r4, r5 };
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
static Register registers[] = { receiver, name, r2, r3, r4, r5 };
return registers;
}
......
This diff is collapsed.
......@@ -93,7 +93,7 @@ bool Deoptimizer::HasAlignmentPadding(JSFunction* function) {
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler_);
ApiFunction function(descriptor->deoptimization_handler());
ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
int params = descriptor->GetHandlerParameterCount();
......
......@@ -582,6 +582,13 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
// IC register specifications
const Register LoadIC::ReceiverRegister() { return x0; }
const Register LoadIC::NameRegister() { return x2; }
const Register KeyedLoadIC::ReceiverRegister() { return x1; }
const Register KeyedLoadIC::NameRegister() { return x0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- lr : return address
......
......@@ -1245,14 +1245,18 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { x0, x2, x3, x1, x4, x5 };
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, x3, x1, x4, x5 };
return registers;
}
Register* KeyedLoadStubCompiler::registers() {
// receiver, name/key, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { x1, x0, x2, x3, x4, x5 };
// receiver, name, scratch1, scratch2, scratch3, scratch4.
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
static Register registers[] = { receiver, name, x2, x3, x4, x5 };
return registers;
}
......
......@@ -39,14 +39,14 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
info_(stub, isolate),
context_(NULL) {
descriptor_ = stub->GetInterfaceDescriptor();
parameters_.Reset(new HParameter*[descriptor_->register_param_count_]);
parameters_.Reset(new HParameter*[descriptor_->register_param_count()]);
}
virtual bool BuildGraph();
protected:
virtual HValue* BuildCodeStub() = 0;
HParameter* GetParameter(int parameter) {
ASSERT(parameter < descriptor_->register_param_count_);
ASSERT(parameter < descriptor_->register_param_count());
return parameters_[parameter];
}
HValue* GetArgumentsLength() {
......@@ -116,19 +116,17 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
isolate()->GetHTracer()->TraceCompilation(&info_);
}
int param_count = descriptor_->register_param_count_;
int param_count = descriptor_->register_param_count();
HEnvironment* start_environment = graph()->start_environment();
HBasicBlock* next_block = CreateBasicBlock(start_environment);
Goto(next_block);
next_block->SetJoinId(BailoutId::StubEntry());
set_current_block(next_block);
bool runtime_stack_params = descriptor_->stack_parameter_count_.is_valid();
bool runtime_stack_params = descriptor_->stack_parameter_count().is_valid();
HInstruction* stack_parameter_count = NULL;
for (int i = 0; i < param_count; ++i) {
Representation r = descriptor_->register_param_representations_ == NULL
? Representation::Tagged()
: descriptor_->register_param_representations_[i];
Representation r = descriptor_->GetRegisterParameterRepresentation(i);
HParameter* param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r);
start_environment->Bind(i, param);
parameters_[i] = param;
......@@ -157,16 +155,16 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
// We might have extra expressions to pop from the stack in addition to the
// arguments above.
HInstruction* stack_pop_count = stack_parameter_count;
if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
if (descriptor_->function_mode() == JS_FUNCTION_STUB_MODE) {
if (!stack_parameter_count->IsConstant() &&
descriptor_->hint_stack_parameter_count_ < 0) {
descriptor_->hint_stack_parameter_count() < 0) {
HInstruction* constant_one = graph()->GetConstant1();
stack_pop_count = AddUncasted<HAdd>(stack_parameter_count, constant_one);
stack_pop_count->ClearFlag(HValue::kCanOverflow);
// TODO(mvstanton): verify that stack_parameter_count+1 really fits in a
// smi.
} else {
int count = descriptor_->hint_stack_parameter_count_;
int count = descriptor_->hint_stack_parameter_count();
stack_pop_count = Add<HConstant>(count);
}
}
......@@ -253,7 +251,7 @@ static Handle<Code> DoGenerateCode(Stub* stub) {
static_cast<HydrogenCodeStub*>(stub)->MajorKey();
CodeStubInterfaceDescriptor* descriptor =
isolate->code_stub_interface_descriptor(major_key);
if (descriptor->register_param_count_ < 0) {
if (!descriptor->initialized()) {
stub->InitializeInterfaceDescriptor(descriptor);
}
......@@ -261,7 +259,7 @@ static Handle<Code> DoGenerateCode(Stub* stub) {
// the runtime that is significantly faster than using the standard
// stub-failure deopt mechanism.
if (stub->IsUninitialized() && descriptor->has_miss_handler()) {
ASSERT(!descriptor->stack_parameter_count_.is_valid());
ASSERT(!descriptor->stack_parameter_count().is_valid());
return stub->GenerateLightweightMissCode();
}
ElapsedTimer timer;
......@@ -539,9 +537,14 @@ Handle<Code> CreateAllocationSiteStub::GenerateCode() {
template <>
HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() {
HInstruction* load = BuildUncheckedMonomorphicElementAccess(
GetParameter(0), GetParameter(1), NULL,
casted_stub()->is_js_array(), casted_stub()->elements_kind(),
LOAD, NEVER_RETURN_HOLE, STANDARD_STORE);
GetParameter(KeyedLoadIC::kReceiverIndex),
GetParameter(KeyedLoadIC::kNameIndex),
NULL,
casted_stub()->is_js_array(),
casted_stub()->elements_kind(),
LOAD,
NEVER_RETURN_HOLE,
STANDARD_STORE);
return load;
}
......@@ -1371,8 +1374,8 @@ Handle<Code> FastNewContextStub::GenerateCode() {
template<>
HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
HValue* receiver = GetParameter(0);
HValue* key = GetParameter(1);
HValue* receiver = GetParameter(KeyedLoadIC::kReceiverIndex);
HValue* key = GetParameter(KeyedLoadIC::kNameIndex);
Add<HCheckSmi>(key);
......@@ -1504,8 +1507,8 @@ void CodeStubGraphBuilder<
HValue* CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildCodeStub() {
HValue* receiver = GetParameter(0);
HValue* key = GetParameter(1);
HValue* receiver = GetParameter(KeyedLoadIC::kReceiverIndex);
HValue* key = GetParameter(KeyedLoadIC::kNameIndex);
// Split into a smi/integer case and unique string case.
HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
......
......@@ -21,14 +21,62 @@ CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
stack_parameter_count_(no_reg),
hint_stack_parameter_count_(-1),
function_mode_(NOT_JS_FUNCTION_STUB_MODE),
register_params_(NULL),
register_param_representations_(NULL),
deoptimization_handler_(NULL),
handler_arguments_mode_(DONT_PASS_ARGUMENTS),
miss_handler_(),
has_miss_handler_(false) { }
void CodeStubInterfaceDescriptor::Initialize(
int register_parameter_count,
Register* registers,
Address deoptimization_handler,
Representation* register_param_representations,
int hint_stack_parameter_count,
StubFunctionMode function_mode) {
// CodeStubInterfaceDescriptor owns a copy of the registers array.
register_param_count_ = register_parameter_count;
register_params_.Reset(NewArray<Register>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
register_params_[i] = registers[i];
}
// If a representations array is specified, then the descriptor owns that as
// well.
if (register_param_representations != NULL) {
register_param_representations_.Reset(
NewArray<Representation>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
register_param_representations_[i] = register_param_representations[i];
}
}
deoptimization_handler_ = deoptimization_handler;
hint_stack_parameter_count_ = hint_stack_parameter_count;
function_mode_ = function_mode;
}
void CodeStubInterfaceDescriptor::Initialize(
int register_parameter_count,
Register* registers,
Register stack_parameter_count,
Address deoptimization_handler,
Representation* register_param_representations,
int hint_stack_parameter_count,
StubFunctionMode function_mode,
HandlerArgumentsMode handler_mode) {
Initialize(register_parameter_count, registers,
deoptimization_handler,
register_param_representations,
hint_stack_parameter_count,
function_mode);
stack_parameter_count_ = stack_parameter_count;
handler_arguments_mode_ = handler_mode;
}
bool CodeStub::FindCodeInCache(Code** code_out) {
UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
int index = stubs->FindEntry(GetKey());
......@@ -512,6 +560,37 @@ void JSEntryStub::FinishCode(Handle<Code> code) {
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { KeyedLoadIC::ReceiverRegister(),
KeyedLoadIC::NameRegister() };
STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2);
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { KeyedLoadIC::ReceiverRegister(),
KeyedLoadIC::NameRegister() };
STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2);
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { KeyedLoadIC::ReceiverRegister(),
KeyedLoadIC::NameRegister() };
STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2);
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry);
}
void KeyedLoadDictionaryElementPlatformStub::Generate(
MacroAssembler* masm) {
KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
......
......@@ -266,25 +266,22 @@ class PlatformCodeStub : public CodeStub {
enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
struct CodeStubInterfaceDescriptor {
class CodeStubInterfaceDescriptor {
public:
CodeStubInterfaceDescriptor();
int register_param_count_;
Register stack_parameter_count_;
// if hint_stack_parameter_count_ > 0, the code stub can optimize the
// return sequence. Default value is -1, which means it is ignored.
int hint_stack_parameter_count_;
StubFunctionMode function_mode_;
Register* register_params_;
// Specifies Representations for the stub's parameter. Points to an array of
// Representations of the same length of the numbers of parameters to the
// stub, or if NULL (the default value), Representation of each parameter
// assumed to be Tagged()
Representation* register_param_representations_;
Address deoptimization_handler_;
HandlerArgumentsMode handler_arguments_mode_;
void Initialize(int register_parameter_count, Register* registers,
Address deoptimization_handler = NULL,
Representation* register_param_representations = NULL,
int hint_stack_parameter_count = -1,
StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
void Initialize(int register_parameter_count, Register* registers,
Register stack_parameter_count,
Address deoptimization_handler = NULL,
Representation* register_param_representations = NULL,
int hint_stack_parameter_count = -1,
StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE,
HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS);
bool initialized() const { return register_param_count_ >= 0; }
int environment_length() const {
......@@ -299,12 +296,12 @@ struct CodeStubInterfaceDescriptor {
ASSERT(!stack_parameter_count_.is_valid());
}
ExternalReference miss_handler() {
ExternalReference miss_handler() const {
ASSERT(has_miss_handler_);
return miss_handler_;
}
bool has_miss_handler() {
bool has_miss_handler() const {
return has_miss_handler_;
}
......@@ -312,11 +309,20 @@ struct CodeStubInterfaceDescriptor {
return register_params_[index];
}
bool IsParameterCountRegister(int index) {
Representation GetRegisterParameterRepresentation(int index) const {
ASSERT(index < register_param_count_);
if (register_param_representations_.get() == NULL) {
return Representation::Tagged();
}
return register_param_representations_[index];
}
bool IsParameterCountRegister(int index) const {
return GetParameterRegister(index).is(stack_parameter_count_);
}
int GetHandlerParameterCount() {
int GetHandlerParameterCount() const {
int params = environment_length();
if (handler_arguments_mode_ == PASS_ARGUMENTS) {
params += 1;
......@@ -324,9 +330,40 @@ struct CodeStubInterfaceDescriptor {
return params;
}
int register_param_count() const { return register_param_count_; }
int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
Register stack_parameter_count() const { return stack_parameter_count_; }
StubFunctionMode function_mode() const { return function_mode_; }
Address deoptimization_handler() const { return deoptimization_handler_; }
Representation* register_param_representations() const {
return register_param_representations_.get();
}
private:
int register_param_count_;
Register stack_parameter_count_;
// If hint_stack_parameter_count_ > 0, the code stub can optimize the
// return sequence. Default value is -1, which means it is ignored.
int hint_stack_parameter_count_;
StubFunctionMode function_mode_;
// The Register params are allocated dynamically by the
// CodeStubInterfaceDescriptor, and freed on destruction. This is because
// static arrays of Registers cause creation of runtime static initializers
// which we don't want.
SmartArrayPointer<Register> register_params_;
// Specifies Representations for the stub's parameter. Points to an array of
// Representations of the same length of the numbers of parameters to the
// stub, or if NULL (the default value), Representation of each parameter
// assumed to be Tagged().
SmartArrayPointer<Representation> register_param_representations_;
Address deoptimization_handler_;
HandlerArgumentsMode handler_arguments_mode_;
ExternalReference miss_handler_;
bool has_miss_handler_;
DISALLOW_COPY_AND_ASSIGN(CodeStubInterfaceDescriptor);
};
......
......@@ -1558,8 +1558,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// and the standard stack frame slots. Include space for an argument
// object to the callee and optionally the space to pass the argument
// object to the stub failure handler.
CHECK_GE(descriptor->register_param_count_, 0);
int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
CHECK_GE(descriptor->register_param_count(), 0);
int height_in_bytes = kPointerSize * descriptor->register_param_count() +
sizeof(Arguments) + kPointerSize;
int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
int input_frame_size = input_->GetFrameSize();
......@@ -1654,7 +1654,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
}
intptr_t caller_arg_count = 0;
bool arg_count_known = !descriptor->stack_parameter_count_.is_valid();
bool arg_count_known = !descriptor->stack_parameter_count().is_valid();
// Build the Arguments object for the caller's parameters and a pointer to it.
output_frame_offset -= kPointerSize;
......@@ -1702,7 +1702,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// Copy the register parameters to the failure frame.
int arguments_length_offset = -1;
for (int i = 0; i < descriptor->register_param_count_; ++i) {
for (int i = 0; i < descriptor->register_param_count(); ++i) {
output_frame_offset -= kPointerSize;
DoTranslateCommand(iterator, 0, output_frame_offset);
......@@ -1749,7 +1749,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// Compute this frame's PC, state, and continuation.
Code* trampoline = NULL;
StubFunctionMode function_mode = descriptor->function_mode_;
StubFunctionMode function_mode = descriptor->function_mode();
StubFailureTrampolineStub(isolate_,
function_mode).FindCodeInCache(&trampoline);
ASSERT(trampoline != NULL);
......
This diff is collapsed.
......@@ -199,7 +199,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
intptr_t handler =
reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_);
reinterpret_cast<intptr_t>(descriptor->deoptimization_handler());
int params = descriptor->GetHandlerParameterCount();
output_frame->SetRegister(eax.code(), params);
output_frame->SetRegister(ebx.code(), handler);
......
......@@ -1025,6 +1025,19 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
// IC register specifications
const Register LoadIC::ReceiverRegister() { return edx; }
const Register LoadIC::NameRegister() { return ecx; }
const Register KeyedLoadIC::ReceiverRegister() {
return LoadIC::ReceiverRegister();
}
const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- ecx : key
......
......@@ -1283,14 +1283,18 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
return registers;
}
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
return registers;
}
......
......@@ -398,6 +398,14 @@ class LoadIC: public IC {
class ContextualModeBits: public BitField<ContextualMode, 0, 1> {};
STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
enum RegisterInfo {
kReceiverIndex,
kNameIndex,
kRegisterArgumentCount
};
static const Register ReceiverRegister();
static const Register NameRegister();
static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
return ContextualModeBits::encode(contextual_mode);
}
......@@ -498,6 +506,9 @@ class KeyedLoadIC: public LoadIC {
ASSERT(target()->is_keyed_load_stub());
}
static const Register ReceiverRegister();
static const Register NameRegister();
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
Handle<Object> key);
......
......@@ -31,7 +31,7 @@ class Bootstrapper;
struct CallInterfaceDescriptor;
class CodeGenerator;
class CodeRange;
struct CodeStubInterfaceDescriptor;
class CodeStubInterfaceDescriptor;
class CodeTracer;
class CompilationCache;
class ConsStringIteratorOp;
......
This diff is collapsed.
......@@ -108,7 +108,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
intptr_t handler =
reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_);
reinterpret_cast<intptr_t>(descriptor->deoptimization_handler());
int params = descriptor->GetHandlerParameterCount();
output_frame->SetRegister(rax.code(), params);
output_frame->SetRegister(rbx.code(), handler);
......
......@@ -1052,6 +1052,13 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
}
// IC register specifications
const Register LoadIC::ReceiverRegister() { return rax; }
const Register LoadIC::NameRegister() { return rcx; }
const Register KeyedLoadIC::ReceiverRegister() { return rdx; }
const Register KeyedLoadIC::NameRegister() { return rax; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : key
......
......@@ -1222,14 +1222,18 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { rax, rcx, rdx, rbx, rdi, r8 };
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, rdx, rbx, rdi, r8 };
return registers;
}
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 };
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
static Register registers[] = { receiver, name, rbx, rcx, rdi, r8 };
return registers;
}
......
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