Remove much of the register allocation overhead from ARM. When
registers are required for calls, explicitly construct a Result with the needed register rather than allocating it. For returns from calls, let the return value in r0 be implicit rather than explicitly allocated. Review URL: http://codereview.chromium.org/164316 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2659 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
9024b946e7
commit
d1f846cb2b
@ -1036,11 +1036,7 @@ void CodeGenerator::Comparison(Condition cc,
|
|||||||
// We call with 0 args because there are 0 on the stack.
|
// We call with 0 args because there are 0 on the stack.
|
||||||
CompareStub stub(cc, strict);
|
CompareStub stub(cc, strict);
|
||||||
frame_->CallStub(&stub, 0);
|
frame_->CallStub(&stub, 0);
|
||||||
|
__ cmp(r0, Operand(0));
|
||||||
Result result = allocator_->Allocate(r0);
|
|
||||||
ASSERT(result.is_valid());
|
|
||||||
__ cmp(result.reg(), Operand(0));
|
|
||||||
result.Unuse();
|
|
||||||
exit.Jump();
|
exit.Jump();
|
||||||
|
|
||||||
// Do smi comparisons by pointer comparison.
|
// Do smi comparisons by pointer comparison.
|
||||||
@ -1749,9 +1745,8 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
|
|||||||
|
|
||||||
primitive.Bind();
|
primitive.Bind();
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(0));
|
||||||
__ mov(arg_count.reg(), Operand(0));
|
|
||||||
frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1);
|
frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1);
|
||||||
|
|
||||||
jsobject.Bind();
|
jsobject.Bind();
|
||||||
@ -1832,15 +1827,10 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
|
|||||||
__ ldr(r0, frame_->ElementAt(4)); // push enumerable
|
__ ldr(r0, frame_->ElementAt(4)); // push enumerable
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
frame_->EmitPush(r3); // push entry
|
frame_->EmitPush(r3); // push entry
|
||||||
Result arg_count_register = allocator_->Allocate(r0);
|
Result arg_count_reg(r0);
|
||||||
ASSERT(arg_count_register.is_valid());
|
__ mov(r0, Operand(1));
|
||||||
__ mov(arg_count_register.reg(), Operand(1));
|
frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, &arg_count_reg, 2);
|
||||||
Result result = frame_->InvokeBuiltin(Builtins::FILTER_KEY,
|
__ mov(r3, Operand(r0));
|
||||||
CALL_JS,
|
|
||||||
&arg_count_register,
|
|
||||||
2);
|
|
||||||
__ mov(r3, Operand(result.reg()));
|
|
||||||
result.Unuse();
|
|
||||||
|
|
||||||
// If the property has been removed while iterating, we just skip it.
|
// If the property has been removed while iterating, we just skip it.
|
||||||
__ cmp(r3, Operand(Factory::null_value()));
|
__ cmp(r3, Operand(Factory::null_value()));
|
||||||
@ -2433,9 +2423,8 @@ void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot,
|
|||||||
// Load the global object.
|
// Load the global object.
|
||||||
LoadGlobal();
|
LoadGlobal();
|
||||||
// Setup the name register.
|
// Setup the name register.
|
||||||
Result name = allocator_->Allocate(r2);
|
Result name(r2);
|
||||||
ASSERT(name.is_valid()); // We are in spilled code.
|
__ mov(r2, Operand(slot->var()->name()));
|
||||||
__ mov(name.reg(), Operand(slot->var()->name()));
|
|
||||||
// Call IC stub.
|
// Call IC stub.
|
||||||
if (typeof_state == INSIDE_TYPEOF) {
|
if (typeof_state == INSIDE_TYPEOF) {
|
||||||
frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &name, 0);
|
frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &name, 0);
|
||||||
@ -2775,9 +2764,8 @@ void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
|
|||||||
Comment cmnt(masm_, "[ CatchExtensionObject");
|
Comment cmnt(masm_, "[ CatchExtensionObject");
|
||||||
LoadAndSpill(node->key());
|
LoadAndSpill(node->key());
|
||||||
LoadAndSpill(node->value());
|
LoadAndSpill(node->value());
|
||||||
Result result =
|
frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
|
||||||
frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
|
frame_->EmitPush(r0);
|
||||||
frame_->EmitPush(result.reg());
|
|
||||||
ASSERT(frame_->height() == original_height + 1);
|
ASSERT(frame_->height() == original_height + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3117,24 +3105,22 @@ void CodeGenerator::VisitCallNew(CallNew* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// r0: the number of arguments.
|
// r0: the number of arguments.
|
||||||
Result num_args = allocator_->Allocate(r0);
|
Result num_args(r0);
|
||||||
ASSERT(num_args.is_valid());
|
__ mov(r0, Operand(arg_count));
|
||||||
__ mov(num_args.reg(), Operand(arg_count));
|
|
||||||
|
|
||||||
// Load the function into r1 as per calling convention.
|
// Load the function into r1 as per calling convention.
|
||||||
Result function = allocator_->Allocate(r1);
|
Result function(r1);
|
||||||
ASSERT(function.is_valid());
|
__ ldr(r1, frame_->ElementAt(arg_count + 1));
|
||||||
__ ldr(function.reg(), frame_->ElementAt(arg_count + 1));
|
|
||||||
|
|
||||||
// Call the construct call builtin that handles allocation and
|
// Call the construct call builtin that handles allocation and
|
||||||
// constructor invocation.
|
// constructor invocation.
|
||||||
CodeForSourcePosition(node->position());
|
CodeForSourcePosition(node->position());
|
||||||
Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
|
Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
|
||||||
Result result = frame_->CallCodeObject(ic,
|
frame_->CallCodeObject(ic,
|
||||||
RelocInfo::CONSTRUCT_CALL,
|
RelocInfo::CONSTRUCT_CALL,
|
||||||
&num_args,
|
&num_args,
|
||||||
&function,
|
&function,
|
||||||
arg_count + 1);
|
arg_count + 1);
|
||||||
|
|
||||||
// Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
|
// Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
|
||||||
__ str(r0, frame_->Top());
|
__ str(r0, frame_->Top());
|
||||||
@ -3477,9 +3463,8 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
|
|||||||
if (property != NULL) {
|
if (property != NULL) {
|
||||||
LoadAndSpill(property->obj());
|
LoadAndSpill(property->obj());
|
||||||
LoadAndSpill(property->key());
|
LoadAndSpill(property->key());
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(1)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(1)); // not counting receiver
|
|
||||||
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
||||||
|
|
||||||
} else if (variable != NULL) {
|
} else if (variable != NULL) {
|
||||||
@ -3488,9 +3473,8 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
|
|||||||
LoadGlobal();
|
LoadGlobal();
|
||||||
__ mov(r0, Operand(variable->name()));
|
__ mov(r0, Operand(variable->name()));
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(1)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(1)); // not counting receiver
|
|
||||||
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
||||||
|
|
||||||
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
||||||
@ -3503,9 +3487,8 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
|
|||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
__ mov(r0, Operand(variable->name()));
|
__ mov(r0, Operand(variable->name()));
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(1)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(1)); // not counting receiver
|
|
||||||
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -3556,9 +3539,8 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
|
|||||||
smi_label.Branch(eq);
|
smi_label.Branch(eq);
|
||||||
|
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(0)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(0)); // not counting receiver
|
|
||||||
frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1);
|
frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1);
|
||||||
|
|
||||||
continue_label.Jump();
|
continue_label.Jump();
|
||||||
@ -3581,9 +3563,8 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
|
|||||||
__ tst(r0, Operand(kSmiTagMask));
|
__ tst(r0, Operand(kSmiTagMask));
|
||||||
continue_label.Branch(eq);
|
continue_label.Branch(eq);
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(0)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(0)); // not counting receiver
|
|
||||||
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
|
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
|
||||||
continue_label.Bind();
|
continue_label.Bind();
|
||||||
break;
|
break;
|
||||||
@ -3669,9 +3650,8 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
|
|||||||
{
|
{
|
||||||
// Convert the operand to a number.
|
// Convert the operand to a number.
|
||||||
frame_->EmitPush(r0);
|
frame_->EmitPush(r0);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(0));
|
||||||
__ mov(arg_count.reg(), Operand(0));
|
|
||||||
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
|
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
|
||||||
}
|
}
|
||||||
if (is_postfix) {
|
if (is_postfix) {
|
||||||
@ -4048,14 +4028,10 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
|
|||||||
case Token::IN: {
|
case Token::IN: {
|
||||||
LoadAndSpill(left);
|
LoadAndSpill(left);
|
||||||
LoadAndSpill(right);
|
LoadAndSpill(right);
|
||||||
Result arg_count = allocator_->Allocate(r0);
|
Result arg_count(r0);
|
||||||
ASSERT(arg_count.is_valid());
|
__ mov(r0, Operand(1)); // not counting receiver
|
||||||
__ mov(arg_count.reg(), Operand(1)); // not counting receiver
|
frame_->InvokeBuiltin(Builtins::IN, CALL_JS, &arg_count, 2);
|
||||||
Result result = frame_->InvokeBuiltin(Builtins::IN,
|
frame_->EmitPush(r0);
|
||||||
CALL_JS,
|
|
||||||
&arg_count,
|
|
||||||
2);
|
|
||||||
frame_->EmitPush(result.reg());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4063,9 +4039,9 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
|
|||||||
LoadAndSpill(left);
|
LoadAndSpill(left);
|
||||||
LoadAndSpill(right);
|
LoadAndSpill(right);
|
||||||
InstanceofStub stub;
|
InstanceofStub stub;
|
||||||
Result result = frame_->CallStub(&stub, 2);
|
frame_->CallStub(&stub, 2);
|
||||||
// At this point if instanceof succeeded then r0 == 0.
|
// At this point if instanceof succeeded then r0 == 0.
|
||||||
__ tst(result.reg(), Operand(result.reg()));
|
__ tst(r0, Operand(r0));
|
||||||
cc_reg_ = eq;
|
cc_reg_ = eq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4135,15 +4111,14 @@ void Reference::GetValue(TypeofState typeof_state) {
|
|||||||
Variable* var = expression_->AsVariableProxy()->AsVariable();
|
Variable* var = expression_->AsVariableProxy()->AsVariable();
|
||||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||||
// Setup the name register.
|
// Setup the name register.
|
||||||
Result name_reg = cgen_->allocator()->Allocate(r2);
|
Result name_reg(r2);
|
||||||
ASSERT(name_reg.is_valid());
|
__ mov(r2, Operand(name));
|
||||||
__ mov(name_reg.reg(), Operand(name));
|
|
||||||
ASSERT(var == NULL || var->is_global());
|
ASSERT(var == NULL || var->is_global());
|
||||||
RelocInfo::Mode rmode = (var == NULL)
|
RelocInfo::Mode rmode = (var == NULL)
|
||||||
? RelocInfo::CODE_TARGET
|
? RelocInfo::CODE_TARGET
|
||||||
: RelocInfo::CODE_TARGET_CONTEXT;
|
: RelocInfo::CODE_TARGET_CONTEXT;
|
||||||
Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0);
|
frame->CallCodeObject(ic, rmode, &name_reg, 0);
|
||||||
frame->EmitPush(answer.reg());
|
frame->EmitPush(r0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4162,8 +4137,8 @@ void Reference::GetValue(TypeofState typeof_state) {
|
|||||||
RelocInfo::Mode rmode = (var == NULL)
|
RelocInfo::Mode rmode = (var == NULL)
|
||||||
? RelocInfo::CODE_TARGET
|
? RelocInfo::CODE_TARGET
|
||||||
: RelocInfo::CODE_TARGET_CONTEXT;
|
: RelocInfo::CODE_TARGET_CONTEXT;
|
||||||
Result answer = frame->CallCodeObject(ic, rmode, 0);
|
frame->CallCodeObject(ic, rmode, 0);
|
||||||
frame->EmitPush(answer.reg());
|
frame->EmitPush(r0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4272,20 +4247,18 @@ void Reference::SetValue(InitState init_state) {
|
|||||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||||
Handle<String> name(GetName());
|
Handle<String> name(GetName());
|
||||||
|
|
||||||
Result value = cgen_->allocator()->Allocate(r0);
|
Result value(r0);
|
||||||
ASSERT(value.is_valid());
|
frame->EmitPop(r0);
|
||||||
frame->EmitPop(value.reg());
|
|
||||||
|
|
||||||
// Setup the name register.
|
// Setup the name register.
|
||||||
Result property_name = cgen_->allocator()->Allocate(r2);
|
Result property_name(r2);
|
||||||
ASSERT(property_name.is_valid());
|
__ mov(r2, Operand(name));
|
||||||
__ mov(property_name.reg(), Operand(name));
|
frame->CallCodeObject(ic,
|
||||||
Result answer = frame->CallCodeObject(ic,
|
RelocInfo::CODE_TARGET,
|
||||||
RelocInfo::CODE_TARGET,
|
&value,
|
||||||
&value,
|
&property_name,
|
||||||
&property_name,
|
0);
|
||||||
0);
|
frame->EmitPush(r0);
|
||||||
frame->EmitPush(answer.reg());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4298,12 +4271,10 @@ void Reference::SetValue(InitState init_state) {
|
|||||||
// Call IC code.
|
// Call IC code.
|
||||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||||
// TODO(1222589): Make the IC grab the values from the stack.
|
// TODO(1222589): Make the IC grab the values from the stack.
|
||||||
Result value = cgen_->allocator()->Allocate(r0);
|
Result value(r0);
|
||||||
ASSERT(value.is_valid());
|
frame->EmitPop(r0); // value
|
||||||
frame->EmitPop(value.reg()); // value
|
frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0);
|
||||||
Result result =
|
frame->EmitPush(r0);
|
||||||
frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0);
|
|
||||||
frame->EmitPush(result.reg());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,76 +186,62 @@ void VirtualFrame::PushTryHandler(HandlerType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::RawCallStub(CodeStub* stub) {
|
void VirtualFrame::RawCallStub(CodeStub* stub) {
|
||||||
ASSERT(cgen()->HasValidEntryRegisters());
|
ASSERT(cgen()->HasValidEntryRegisters());
|
||||||
__ CallStub(stub);
|
__ CallStub(stub);
|
||||||
Result result = cgen()->allocator()->Allocate(r0);
|
|
||||||
ASSERT(result.is_valid());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallStub(CodeStub* stub, Result* arg) {
|
void VirtualFrame::CallStub(CodeStub* stub, Result* arg) {
|
||||||
PrepareForCall(0, 0);
|
PrepareForCall(0, 0);
|
||||||
arg->Unuse();
|
arg->Unuse();
|
||||||
return RawCallStub(stub);
|
RawCallStub(stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) {
|
void VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) {
|
||||||
PrepareForCall(0, 0);
|
PrepareForCall(0, 0);
|
||||||
arg0->Unuse();
|
arg0->Unuse();
|
||||||
arg1->Unuse();
|
arg1->Unuse();
|
||||||
return RawCallStub(stub);
|
RawCallStub(stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
|
void VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
|
||||||
PrepareForCall(arg_count, arg_count);
|
PrepareForCall(arg_count, arg_count);
|
||||||
ASSERT(cgen()->HasValidEntryRegisters());
|
ASSERT(cgen()->HasValidEntryRegisters());
|
||||||
__ CallRuntime(f, arg_count);
|
__ CallRuntime(f, arg_count);
|
||||||
Result result = cgen()->allocator()->Allocate(r0);
|
|
||||||
ASSERT(result.is_valid());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
|
void VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
|
||||||
PrepareForCall(arg_count, arg_count);
|
PrepareForCall(arg_count, arg_count);
|
||||||
ASSERT(cgen()->HasValidEntryRegisters());
|
ASSERT(cgen()->HasValidEntryRegisters());
|
||||||
__ CallRuntime(id, arg_count);
|
__ CallRuntime(id, arg_count);
|
||||||
Result result = cgen()->allocator()->Allocate(r0);
|
|
||||||
ASSERT(result.is_valid());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
|
void VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
|
||||||
InvokeJSFlags flags,
|
InvokeJSFlags flags,
|
||||||
Result* arg_count_register,
|
Result* arg_count_register,
|
||||||
int arg_count) {
|
int arg_count) {
|
||||||
ASSERT(arg_count_register->reg().is(r0));
|
ASSERT(arg_count_register->reg().is(r0));
|
||||||
PrepareForCall(arg_count, arg_count);
|
PrepareForCall(arg_count, arg_count);
|
||||||
arg_count_register->Unuse();
|
arg_count_register->Unuse();
|
||||||
__ InvokeBuiltin(id, flags);
|
__ InvokeBuiltin(id, flags);
|
||||||
Result result = cgen()->allocator()->Allocate(r0);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
|
void VirtualFrame::RawCallCodeObject(Handle<Code> code,
|
||||||
RelocInfo::Mode rmode) {
|
RelocInfo::Mode rmode) {
|
||||||
ASSERT(cgen()->HasValidEntryRegisters());
|
ASSERT(cgen()->HasValidEntryRegisters());
|
||||||
__ Call(code, rmode);
|
__ Call(code, rmode);
|
||||||
Result result = cgen()->allocator()->Allocate(r0);
|
|
||||||
ASSERT(result.is_valid());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
void VirtualFrame::CallCodeObject(Handle<Code> code,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
int dropped_args) {
|
int dropped_args) {
|
||||||
int spilled_args = 0;
|
int spilled_args = 0;
|
||||||
switch (code->kind()) {
|
switch (code->kind()) {
|
||||||
case Code::CALL_IC:
|
case Code::CALL_IC:
|
||||||
@ -276,14 +262,14 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PrepareForCall(spilled_args, dropped_args);
|
PrepareForCall(spilled_args, dropped_args);
|
||||||
return RawCallCodeObject(code, rmode);
|
RawCallCodeObject(code, rmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
void VirtualFrame::CallCodeObject(Handle<Code> code,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
Result* arg,
|
Result* arg,
|
||||||
int dropped_args) {
|
int dropped_args) {
|
||||||
int spilled_args = 0;
|
int spilled_args = 0;
|
||||||
switch (code->kind()) {
|
switch (code->kind()) {
|
||||||
case Code::LOAD_IC:
|
case Code::LOAD_IC:
|
||||||
@ -304,15 +290,15 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
|||||||
}
|
}
|
||||||
PrepareForCall(spilled_args, dropped_args);
|
PrepareForCall(spilled_args, dropped_args);
|
||||||
arg->Unuse();
|
arg->Unuse();
|
||||||
return RawCallCodeObject(code, rmode);
|
RawCallCodeObject(code, rmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
void VirtualFrame::CallCodeObject(Handle<Code> code,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
Result* arg0,
|
Result* arg0,
|
||||||
Result* arg1,
|
Result* arg1,
|
||||||
int dropped_args) {
|
int dropped_args) {
|
||||||
int spilled_args = 1;
|
int spilled_args = 1;
|
||||||
switch (code->kind()) {
|
switch (code->kind()) {
|
||||||
case Code::STORE_IC:
|
case Code::STORE_IC:
|
||||||
@ -336,7 +322,7 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code,
|
|||||||
PrepareForCall(spilled_args, dropped_args);
|
PrepareForCall(spilled_args, dropped_args);
|
||||||
arg0->Unuse();
|
arg0->Unuse();
|
||||||
arg1->Unuse();
|
arg1->Unuse();
|
||||||
return RawCallCodeObject(code, rmode);
|
RawCallCodeObject(code, rmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,46 +283,46 @@ class VirtualFrame : public ZoneObject {
|
|||||||
|
|
||||||
// Call stub given the number of arguments it expects on (and
|
// Call stub given the number of arguments it expects on (and
|
||||||
// removes from) the stack.
|
// removes from) the stack.
|
||||||
Result CallStub(CodeStub* stub, int arg_count) {
|
void CallStub(CodeStub* stub, int arg_count) {
|
||||||
PrepareForCall(arg_count, arg_count);
|
PrepareForCall(arg_count, arg_count);
|
||||||
return RawCallStub(stub);
|
RawCallStub(stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call stub that expects its argument in r0. The argument is given
|
// Call stub that expects its argument in r0. The argument is given
|
||||||
// as a result which must be the register r0.
|
// as a result which must be the register r0.
|
||||||
Result CallStub(CodeStub* stub, Result* arg);
|
void CallStub(CodeStub* stub, Result* arg);
|
||||||
|
|
||||||
// Call stub that expects its arguments in r1 and r0. The arguments
|
// Call stub that expects its arguments in r1 and r0. The arguments
|
||||||
// are given as results which must be the appropriate registers.
|
// are given as results which must be the appropriate registers.
|
||||||
Result CallStub(CodeStub* stub, Result* arg0, Result* arg1);
|
void CallStub(CodeStub* stub, Result* arg0, Result* arg1);
|
||||||
|
|
||||||
// Call runtime given the number of arguments expected on (and
|
// Call runtime given the number of arguments expected on (and
|
||||||
// removed from) the stack.
|
// removed from) the stack.
|
||||||
Result CallRuntime(Runtime::Function* f, int arg_count);
|
void CallRuntime(Runtime::Function* f, int arg_count);
|
||||||
Result CallRuntime(Runtime::FunctionId id, int arg_count);
|
void CallRuntime(Runtime::FunctionId id, int arg_count);
|
||||||
|
|
||||||
// Invoke builtin given the number of arguments it expects on (and
|
// Invoke builtin given the number of arguments it expects on (and
|
||||||
// removes from) the stack.
|
// removes from) the stack.
|
||||||
Result InvokeBuiltin(Builtins::JavaScript id,
|
void InvokeBuiltin(Builtins::JavaScript id,
|
||||||
InvokeJSFlags flag,
|
InvokeJSFlags flag,
|
||||||
Result* arg_count_register,
|
Result* arg_count_register,
|
||||||
int arg_count);
|
int arg_count);
|
||||||
|
|
||||||
// Call into an IC stub given the number of arguments it removes
|
// Call into an IC stub given the number of arguments it removes
|
||||||
// from the stack. Register arguments are passed as results and
|
// from the stack. Register arguments are passed as results and
|
||||||
// consumed by the call.
|
// consumed by the call.
|
||||||
Result CallCodeObject(Handle<Code> ic,
|
void CallCodeObject(Handle<Code> ic,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
int dropped_args);
|
int dropped_args);
|
||||||
Result CallCodeObject(Handle<Code> ic,
|
void CallCodeObject(Handle<Code> ic,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
Result* arg,
|
Result* arg,
|
||||||
int dropped_args);
|
int dropped_args);
|
||||||
Result CallCodeObject(Handle<Code> ic,
|
void CallCodeObject(Handle<Code> ic,
|
||||||
RelocInfo::Mode rmode,
|
RelocInfo::Mode rmode,
|
||||||
Result* arg0,
|
Result* arg0,
|
||||||
Result* arg1,
|
Result* arg1,
|
||||||
int dropped_args);
|
int dropped_args);
|
||||||
|
|
||||||
// Drop a number of elements from the top of the expression stack. May
|
// Drop a number of elements from the top of the expression stack. May
|
||||||
// emit code to affect the physical frame. Does not clobber any registers
|
// emit code to affect the physical frame. Does not clobber any registers
|
||||||
@ -506,11 +506,11 @@ class VirtualFrame : public ZoneObject {
|
|||||||
|
|
||||||
// Call a code stub that has already been prepared for calling (via
|
// Call a code stub that has already been prepared for calling (via
|
||||||
// PrepareForCall).
|
// PrepareForCall).
|
||||||
Result RawCallStub(CodeStub* stub);
|
void RawCallStub(CodeStub* stub);
|
||||||
|
|
||||||
// Calls a code object which has already been prepared for calling
|
// Calls a code object which has already been prepared for calling
|
||||||
// (via PrepareForCall).
|
// (via PrepareForCall).
|
||||||
Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode);
|
void RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode);
|
||||||
|
|
||||||
bool Equals(VirtualFrame* other);
|
bool Equals(VirtualFrame* other);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user