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