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
This commit is contained in:
mvstanton@chromium.org 2014-06-25 12:32:12 +00:00
parent 6f2368627c
commit addd35df56
22 changed files with 661 additions and 723 deletions

View File

@ -17,181 +17,128 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry;
Register registers[] = { r2 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry);
}
void FastNewContextStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void ToNumberStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void NumberToStringStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry;
Register registers[] = { r0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry);
}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r3, r2, r1 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
static Representation representations[] = {
Register registers[] = { r3, r2, r1 };
Representation representations[] = {
Representation::Tagged(),
Representation::Smi(),
Representation::Tagged() };
descriptor->register_param_representations_ = representations;
descriptor->deoptimization_handler_ =
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry;
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry,
representations);
}
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r3, r2, r1, r0 };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry;
Register registers[] = { r3, r2, r1, r0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry);
}
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r3 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
Register registers[] = { r2, r3 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry;
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry;
Register registers[] = { r2, r1, r0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry);
}
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r2 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r0, r2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { r1, r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
Register registers[] = { r2, r1, r0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r1 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
Register registers[] = { r0, r1 };
Address entry =
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(entry);
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(entry));
}
void CompareNilICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
Register registers[] = { r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
@ -204,29 +151,31 @@ static void InitializeArrayConstructorDescriptor(
// r0 -- number of arguments
// r1 -- function
// r2 -- allocation site with elements kind
static Register registers_variable_args[] = { r1, r2, r0 };
static Register registers_no_args[] = { r1, r2 };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_no_args;
Register registers[] = { r1, r2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = r0;
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { r1, r2, r0 };
Representation representations[] = {
Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
r0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry;
}
@ -236,28 +185,30 @@ static void InitializeInternalArrayConstructorDescriptor(
// register state
// r0 -- number of arguments
// r1 -- constructor function
static Register registers_variable_args[] = { r1, r0 };
static Register registers_no_args[] = { r1 };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers_no_args;
Register registers[] = { r1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = r0;
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { r1, r0 };
Representation representations[] = {
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
r0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry;
}
@ -281,11 +232,9 @@ void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void ToBooleanStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
Register registers[] = { r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ToBooleanIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
@ -311,30 +260,25 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r2, r0 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
Register registers[] = { r1, r2, r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r3, r1, r2 };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
Register registers[] = { r0, r3, r1, r2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
}
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
Register registers[] = { r1, r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
@ -342,21 +286,18 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
Register registers[] = { r2, r1, r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
}
void StringAddStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry;
Register registers[] = { r1, r0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry);
}
@ -477,18 +418,18 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
isolate()->counters()->code_stubs()->Increment();
CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
int param_count = descriptor->register_param_count();
{
// Call the runtime system in a fresh internal frame.
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
ASSERT(descriptor->register_param_count_ == 0 ||
r0.is(descriptor->register_params_[param_count - 1]));
ASSERT(descriptor->register_param_count() == 0 ||
r0.is(descriptor->GetParameterRegister(param_count - 1)));
// Push arguments
for (int i = 0; i < param_count; ++i) {
__ push(descriptor->register_params_[i]);
__ push(descriptor->GetParameterRegister(i));
}
ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, descriptor->register_param_count_);
__ CallExternalReference(miss, descriptor->register_param_count());
}
__ Ret();

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -14,46 +14,39 @@
namespace v8 {
namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x2: function info
static Register registers[] = { x2 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry;
Register registers[] = { x2 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry);
}
void FastNewContextStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: function
static Register registers[] = { x1 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void ToNumberStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void NumberToStringStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry;
Register registers[] = { x0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry);
}
@ -62,17 +55,16 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
// x3: array literals array
// x2: array literal index
// x1: constant elements
static Register registers[] = { x3, x2, x1 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
static Representation representations[] = {
Register registers[] = { x3, x2, x1 };
Representation representations[] = {
Representation::Tagged(),
Representation::Smi(),
Representation::Tagged() };
descriptor->register_param_representations_ = representations;
descriptor->deoptimization_handler_ =
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry;
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry,
representations);
}
@ -82,11 +74,10 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
// x2: object literal index
// x1: constant properties
// x0: object literal flags
static Register registers[] = { x3, x2, x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry;
Register registers[] = { x3, x2, x1, x0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry);
}
@ -94,44 +85,8 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x2: feedback vector
// x3: call feedback slot
static Register registers[] = { x2, x3 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry;
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
// x0: key
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
// x0: key
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
Register registers[] = { x2, x3 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
@ -140,49 +95,40 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
// x2: length
// x1: index (of last match)
// x0: string
static Register registers[] = { x2, x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry;
Register registers[] = { x2, x1, x0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry);
}
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: receiver
static Register registers[] = { x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
static Register registers[] = { x1 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { x0, x2 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x0, x2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { x1, x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
@ -191,11 +137,10 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
// x2: receiver
// x1: key
// x0: value
static Register registers[] = { x2, x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
Register registers[] = { x2, x1, x0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
@ -203,23 +148,20 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value (js_array)
// x1: to_map
static Register registers[] = { x0, x1 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
Register registers[] = { x0, x1 };
Address entry =
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(entry);
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(entry));
}
void CompareNilICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value to compare
static Register registers[] = { x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
Register registers[] = { x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
@ -231,31 +173,31 @@ static void InitializeArrayConstructorDescriptor(
// x1: function
// x2: allocation site with elements kind
// x0: number of arguments to the constructor function
static Register registers_variable_args[] = { x1, x2, x0 };
static Register registers_no_args[] = { x1, x2 };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ =
sizeof(registers_no_args) / sizeof(registers_no_args[0]);
descriptor->register_params_ = registers_no_args;
Register registers[] = { x1, x2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = x0;
descriptor->register_param_count_ =
sizeof(registers_variable_args) / sizeof(registers_variable_args[0]);
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { x1, x2, x0 };
Representation representations[] = {
Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
x0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry;
}
@ -282,30 +224,30 @@ static void InitializeInternalArrayConstructorDescriptor(
int constant_stack_parameter_count) {
// x1: constructor function
// x0: number of arguments to the constructor function
static Register registers_variable_args[] = { x1, x0 };
static Register registers_no_args[] = { x1 };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ =
sizeof(registers_no_args) / sizeof(registers_no_args[0]);
descriptor->register_params_ = registers_no_args;
Register registers[] = { x1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = x0;
descriptor->register_param_count_ =
sizeof(registers_variable_args) / sizeof(registers_variable_args[0]);
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { x1, x0 };
Representation representations[] = {
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
x0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry;
}
@ -330,10 +272,9 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void ToBooleanStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(ToBooleanIC_Miss);
Register registers[] = { x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ToBooleanIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
@ -344,11 +285,9 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
// x1: receiver
// x2: key (unused)
// x0: value
static Register registers[] = { x1, x2, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
Register registers[] = { x1, x2, x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
@ -358,11 +297,9 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
// x3: target map
// x1: key
// x2: receiver
static Register registers[] = { x0, x3, x1, x2 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
Register registers[] = { x0, x3, x1, x2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
}
@ -370,10 +307,9 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
// x0: right operand
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
Register registers[] = { x1, x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
@ -384,11 +320,9 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
// x2: allocation site
// x1: left operand
// x0: right operand
static Register registers[] = { x2, x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
Register registers[] = { x2, x1, x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
}
@ -396,11 +330,10 @@ void StringAddStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
// x0: right operand
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry;
Register registers[] = { x1, x0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry);
}
@ -507,22 +440,22 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
isolate()->counters()->code_stubs()->Increment();
CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
int param_count = descriptor->register_param_count();
{
// Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL);
ASSERT((descriptor->register_param_count_ == 0) ||
x0.Is(descriptor->register_params_[param_count - 1]));
ASSERT((descriptor->register_param_count() == 0) ||
x0.Is(descriptor->GetParameterRegister(param_count - 1)));
// Push arguments
MacroAssembler::PushPopQueue queue(masm);
for (int i = 0; i < param_count; ++i) {
queue.Queue(descriptor->register_params_[i]);
queue.Queue(descriptor->GetParameterRegister(i));
}
queue.PushQueued();
ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, descriptor->register_param_count_);
__ CallExternalReference(miss, descriptor->register_param_count());
}
__ Ret();

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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(),

View File

@ -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);

View File

@ -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);
};

View File

@ -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);

View File

@ -22,170 +22,120 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ebx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry;
Register registers[] = { ebx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry);
}
void FastNewContextStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edi };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { edi };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void ToNumberStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void NumberToStringStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry;
Register registers[] = { eax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry);
}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
static Representation representations[] = {
Register registers[] = { eax, ebx, ecx };
Representation representations[] = {
Representation::Tagged(),
Representation::Smi(),
Representation::Tagged() };
descriptor->register_param_representations_ = representations;
descriptor->deoptimization_handler_ =
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry;
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry,
representations);
}
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx, edx };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry;
Register registers[] = { eax, ebx, ecx, edx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry);
}
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ebx, edx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
Register registers[] = { ebx, edx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ecx, ebx, eax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry;
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry;
Register registers[] = { ecx, ebx, eax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry);
}
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { edx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { edx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { edx, ecx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { edx, ecx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx, eax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
Register registers[] = { edx, ecx, eax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
Register registers[] = { eax, ebx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry);
}
@ -197,29 +147,31 @@ static void InitializeArrayConstructorDescriptor(
// eax -- number of arguments
// edi -- function
// ebx -- allocation site with elements kind
static Register registers_variable_args[] = { edi, ebx, eax };
static Register registers_no_args[] = { edi, ebx };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_no_args;
Register registers[] = { edi, ebx };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = eax;
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { edi, ebx, eax };
Representation representations[] = {
Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
eax,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry;
}
@ -229,28 +181,30 @@ static void InitializeInternalArrayConstructorDescriptor(
// register state
// eax -- number of arguments
// edi -- constructor function
static Register registers_variable_args[] = { edi, eax };
static Register registers_no_args[] = { edi };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers_no_args;
Register registers[] = { edi };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = eax;
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { edi, eax };
Representation representations[] = {
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
eax,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry;
}
@ -292,22 +246,18 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void CompareNilICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
Register registers[] = { eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
void ToBooleanStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
Register registers[] = { eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ToBooleanIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
@ -315,30 +265,25 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx, eax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
Register registers[] = { edx, ecx, eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx, edx };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
Register registers[] = { eax, ebx, ecx, edx };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
}
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
Register registers[] = { edx, eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
@ -346,21 +291,18 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ecx, edx, eax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
Register registers[] = { ecx, edx, eax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
}
void StringAddStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry;
Register registers[] = { edx, eax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry);
}
@ -456,18 +398,18 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
isolate()->counters()->code_stubs()->Increment();
CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
int param_count = descriptor->register_param_count();
{
// Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL);
ASSERT(descriptor->register_param_count_ == 0 ||
eax.is(descriptor->register_params_[param_count - 1]));
ASSERT(descriptor->register_param_count() == 0 ||
eax.is(descriptor->GetParameterRegister(param_count - 1)));
// Push arguments
for (int i = 0; i < param_count; ++i) {
__ push(descriptor->register_params_[i]);
__ push(descriptor->GetParameterRegister(i));
}
ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, descriptor->register_param_count_);
__ CallExternalReference(miss, descriptor->register_param_count());
}
__ ret(0);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -31,7 +31,7 @@ class Bootstrapper;
struct CallInterfaceDescriptor;
class CodeGenerator;
class CodeRange;
struct CodeStubInterfaceDescriptor;
class CodeStubInterfaceDescriptor;
class CodeTracer;
class CompilationCache;
class ConsStringIteratorOp;

View File

@ -18,170 +18,120 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rbx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry;
Register registers[] = { rbx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry);
}
void FastNewContextStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdi };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rdi };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void ToNumberStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void NumberToStringStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry;
Register registers[] = { rax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry);
}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
static Representation representations[] = {
Register registers[] = { rax, rbx, rcx };
Representation representations[] = {
Representation::Tagged(),
Representation::Smi(),
Representation::Tagged() };
descriptor->register_param_representations_ = representations;
descriptor->deoptimization_handler_ =
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry;
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry,
representations);
}
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx, rdx };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry;
Register registers[] = { rax, rbx, rcx, rdx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry);
}
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rbx, rdx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
Register registers[] = { rbx, rdx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rcx, rbx, rax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry;
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry;
Register registers[] = { rcx, rbx, rax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry);
}
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rdx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rcx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rax, rcx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
Register registers[] = { rdx, rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rcx, rax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
Register registers[] = { rdx, rcx, rax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
Register registers[] = { rax, rbx };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry);
}
@ -192,29 +142,31 @@ static void InitializeArrayConstructorDescriptor(
// rax -- number of arguments
// rdi -- function
// rbx -- allocation site with elements kind
static Register registers_variable_args[] = { rdi, rbx, rax };
static Register registers_no_args[] = { rdi, rbx };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_no_args;
Register registers[] = { rdi, rbx };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = rax;
descriptor->register_param_count_ = 3;
static Representation representations[] = {
Register registers[] = { rdi, rbx, rax };
Representation representations[] = {
Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->register_params_ = registers_variable_args;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
rax,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry;
}
@ -224,28 +176,30 @@ static void InitializeInternalArrayConstructorDescriptor(
// register state
// rax -- number of arguments
// rdi -- constructor function
static Register registers_variable_args[] = { rdi, rax };
static Register registers_no_args[] = { rdi };
Address deopt_handler = Runtime::FunctionForId(
Runtime::kHiddenInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers_no_args;
Register registers[] = { rdi };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
// stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
descriptor->stack_parameter_count_ = rax;
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Register registers[] = { rdi, rax };
Representation representations[] = {
Representation::Tagged(),
Representation::Integer32() };
descriptor->register_param_representations_ = representations;
descriptor->Initialize(ARRAY_SIZE(registers), registers,
rax,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry;
}
@ -287,11 +241,9 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void CompareNilICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
Register registers[] = { rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
@ -299,11 +251,9 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
void ToBooleanStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
Register registers[] = { rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ToBooleanIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
@ -311,30 +261,25 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rcx, rax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
Register registers[] = { rdx, rcx, rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx, rdx };
descriptor->register_param_count_ = 4;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
Register registers[] = { rax, rbx, rcx, rdx };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
}
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
Register registers[] = { rdx, rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_Miss));
descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
@ -342,21 +287,18 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rcx, rdx, rax };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
Register registers[] = { rcx, rdx, rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
}
void StringAddStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry;
Register registers[] = { rdx, rax };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry);
}
@ -452,18 +394,18 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
isolate()->counters()->code_stubs()->Increment();
CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
int param_count = descriptor->register_param_count();
{
// Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL);
ASSERT(descriptor->register_param_count_ == 0 ||
rax.is(descriptor->register_params_[param_count - 1]));
ASSERT(descriptor->register_param_count() == 0 ||
rax.is(descriptor->GetParameterRegister(param_count - 1)));
// Push arguments
for (int i = 0; i < param_count; ++i) {
__ Push(descriptor->register_params_[i]);
__ Push(descriptor->GetParameterRegister(i));
}
ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, descriptor->register_param_count_);
__ CallExternalReference(miss, descriptor->register_param_count());
}
__ Ret();

View File

@ -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);

View File

@ -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

View File

@ -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;
}