Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: src/arm/codegen-arm.cc

Issue 2368001: Get rid of LoadAndSpill on ARM since Load() knows whether it is... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 4747)
+++ src/arm/codegen-arm.cc (working copy)
@@ -658,7 +658,6 @@
void CodeGenerator::LoadTypeofExpression(Expression* expr) {
// Special handling of identifiers as subexpressions of typeof.
- VirtualFrame::SpilledScope spilled_scope(frame_);
Variable* variable = expr->AsVariableProxy()->AsVariable();
if (variable != NULL && !variable->is_this() && variable->is_global()) {
// For a global variable we build the property reference
@@ -673,10 +672,9 @@
// For a variable that rewrites to a slot, we signal it is the immediate
// subexpression of a typeof.
LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
- frame_->SpillAll();
} else {
// Anything else can be handled normally.
- LoadAndSpill(expr);
+ Load(expr);
}
}
@@ -725,8 +723,7 @@
}
} else {
// Anything else is a runtime error.
- VirtualFrame::SpilledScope spilled_scope(frame_);
- LoadAndSpill(e);
+ Load(e);
frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
}
}
@@ -856,11 +853,9 @@
case Token::SAR: {
Register rhs = frame_->PopToRegister();
Register lhs = frame_->PopToRegister(rhs); // Don't pop to rhs register.
- {
- VirtualFrame::SpilledScope spilled_scope(frame_);
- GenericBinaryOpStub stub(op, overwrite_mode, lhs, rhs, constant_rhs);
- frame_->CallStub(&stub, 0);
- }
+ GenericBinaryOpStub stub(op, overwrite_mode, lhs, rhs, constant_rhs);
+ frame_->SpillAll();
+ frame_->CallStub(&stub, 0);
frame_->EmitPush(r0);
break;
}
@@ -1334,11 +1329,12 @@
void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
CallFunctionFlags flags,
int position) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
+ frame_->AssertIsSpilled();
+
// Push the arguments ("left-to-right") on the stack.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
// Record the position for debugging purposes.
@@ -1374,7 +1370,7 @@
// Load applicand.apply onto the stack. This will usually
// give us a megamorphic load site. Not super, but it works.
- LoadAndSpill(applicand);
+ Load(applicand);
Handle<String> name = Factory::LookupAsciiSymbol("apply");
frame_->Dup();
frame_->CallLoadIC(name, RelocInfo::CODE_TARGET);
@@ -1382,7 +1378,7 @@
// Load the receiver and the existing arguments object onto the
// expression stack. Avoid allocating the arguments object here.
- LoadAndSpill(receiver);
+ Load(receiver);
LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
// Emit the source position information after having loaded the
@@ -1674,12 +1670,11 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ ExpressionStatement");
CodeForStatementPosition(node);
Expression* expression = node->expression();
expression->MarkAsStatement();
- LoadAndSpill(expression);
+ Load(expression);
frame_->Drop();
ASSERT(frame_->height() == original_height);
}
@@ -1689,7 +1684,6 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "// EmptyStatement");
CodeForStatementPosition(node);
// nothing to do
@@ -1807,7 +1801,7 @@
Comment cmnt(masm_, "[ ReturnStatement");
CodeForStatementPosition(node);
- LoadAndSpill(node->expression());
+ Load(node->expression());
if (function_return_is_shadowed_) {
frame_->EmitPop(r0);
function_return_.Jump();
@@ -1829,7 +1823,7 @@
VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ WithEnterStatement");
CodeForStatementPosition(node);
- LoadAndSpill(node->expression());
+ Load(node->expression());
if (node->is_catch_block()) {
frame_->CallRuntime(Runtime::kPushCatchContext, 1);
} else {
@@ -1872,7 +1866,7 @@
CodeForStatementPosition(node);
node->break_target()->SetExpectedHeight();
- LoadAndSpill(node->tag());
+ Load(node->tag());
JumpTarget next_test;
JumpTarget fall_through;
@@ -2171,7 +2165,7 @@
JumpTarget exit;
// Get the object to enumerate over (converted to JSObject).
- LoadAndSpill(node->enumerable());
+ Load(node->enumerable());
// Both SpiderMonkey and kjs ignore null and undefined in contrast
// to the specification. 12.6.4 mandates a call to ToObject.
@@ -2696,7 +2690,6 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ DebuggerStatament");
CodeForStatementPosition(node);
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -2709,19 +2702,18 @@
void CodeGenerator::InstantiateFunction(
Handle<SharedFunctionInfo> function_info) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
- __ mov(r0, Operand(function_info));
// Use the fast case closure allocation code that allocates in new
// space for nested functions that don't need literals cloning.
if (scope()->is_function_scope() && function_info->num_literals() == 0) {
FastNewClosureStub stub;
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(function_info));
+ frame_->SpillAll();
frame_->CallStub(&stub, 1);
frame_->EmitPush(r0);
} else {
// Create a new closure.
frame_->EmitPush(cp);
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(function_info));
frame_->CallRuntime(Runtime::kNewClosure, 2);
frame_->EmitPush(r0);
}
@@ -2772,13 +2764,13 @@
}
if (has_valid_frame() || then.is_linked()) {
then.Bind();
- LoadAndSpill(node->then_expression());
+ Load(node->then_expression());
}
if (else_.is_linked()) {
JumpTarget exit;
if (has_valid_frame()) exit.Jump();
else_.Bind();
- LoadAndSpill(node->else_expression());
+ Load(node->else_expression());
if (exit.is_linked()) exit.Bind();
}
ASSERT_EQ(original_height + 1, frame_->height());
@@ -3198,7 +3190,7 @@
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
- LoadAndSpill(value);
+ Load(value);
frame_->EmitPop(r0);
__ mov(r2, Operand(key->handle()));
__ ldr(r1, frame_->Top()); // Load the receiver.
@@ -3209,28 +3201,28 @@
case ObjectLiteral::Property::PROTOTYPE: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0); // dup the result
- LoadAndSpill(key);
- LoadAndSpill(value);
+ Load(key);
+ Load(value);
frame_->CallRuntime(Runtime::kSetProperty, 3);
break;
}
case ObjectLiteral::Property::SETTER: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0);
- LoadAndSpill(key);
+ Load(key);
__ mov(r0, Operand(Smi::FromInt(1)));
frame_->EmitPush(r0);
- LoadAndSpill(value);
+ Load(value);
frame_->CallRuntime(Runtime::kDefineAccessor, 4);
break;
}
case ObjectLiteral::Property::GETTER: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0);
- LoadAndSpill(key);
+ Load(key);
__ mov(r0, Operand(Smi::FromInt(0)));
frame_->EmitPush(r0);
- LoadAndSpill(value);
+ Load(value);
frame_->CallRuntime(Runtime::kDefineAccessor, 4);
break;
}
@@ -3279,7 +3271,7 @@
if (CompileTimeValue::IsCompileTimeValue(value)) continue;
// The property must be set by generated code.
- LoadAndSpill(value);
+ Load(value);
frame_->EmitPop(r0);
// Fetch the object literal.
@@ -3303,12 +3295,11 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
// Call runtime routine to allocate the catch extension object and
// assign the exception value to the catch variable.
Comment cmnt(masm_, "[ CatchExtensionObject");
- LoadAndSpill(node->key());
- LoadAndSpill(node->value());
+ Load(node->key());
+ Load(node->value());
frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
frame_->EmitPush(r0);
ASSERT_EQ(original_height + 1, frame_->height());
@@ -3627,10 +3618,9 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ Throw");
- LoadAndSpill(node->exception());
+ Load(node->exception());
CodeForSourcePosition(node->position());
frame_->CallRuntime(Runtime::kThrow, 1);
frame_->EmitPush(r0);
@@ -3655,7 +3645,6 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ Call");
Expression* function = node->expression();
@@ -3676,6 +3665,7 @@
// ------------------------------------------------------------------------
if (var != NULL && var->is_possibly_eval()) {
+ VirtualFrame::SpilledScope spilled_scope(frame_);
// ----------------------------------
// JavaScript example: 'eval(arg)' // eval is not known to be shadowed
// ----------------------------------
@@ -3685,12 +3675,12 @@
// call. Then we call the resolved function using the given
// arguments.
// Prepare stack for call to resolved function.
- LoadAndSpill(function);
+ Load(function);
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
frame_->EmitPush(r2); // Slot for receiver
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
// Prepare stack for call to ResolvePossiblyDirectEval.
@@ -3738,9 +3728,10 @@
// Load the arguments.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
+ VirtualFrame::SpilledScope spilled_scope(frame_);
// Setup the name register and call the IC initialization code.
__ mov(r2, Operand(var->name()));
InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
@@ -3753,6 +3744,7 @@
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
+ VirtualFrame::SpilledScope spilled_scope(frame_);
// ----------------------------------
// JavaScript examples:
//
@@ -3830,13 +3822,14 @@
node->position());
} else {
- LoadAndSpill(property->obj()); // Receiver.
+ Load(property->obj()); // Receiver.
// Load the arguments.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
+ VirtualFrame::SpilledScope spilled_scope(frame_);
// Set the name register and call the IC initialization code.
__ mov(r2, Operand(name));
InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
@@ -3851,14 +3844,15 @@
// -------------------------------------------
// JavaScript example: 'array[index](1, 2, 3)'
// -------------------------------------------
+ VirtualFrame::SpilledScope spilled_scope(frame_);
- LoadAndSpill(property->obj());
+ Load(property->obj());
if (!property->is_synthetic()) {
// Duplicate receiver for later use.
__ ldr(r0, MemOperand(sp, 0));
frame_->EmitPush(r0);
}
- LoadAndSpill(property->key());
+ Load(property->key());
EmitKeyedLoad();
// Put the function below the receiver.
if (property->is_synthetic()) {
@@ -3883,8 +3877,10 @@
// ----------------------------------
// Load the function.
- LoadAndSpill(function);
+ Load(function);
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+
// Pass the global proxy as the receiver.
LoadGlobalReceiver(r0);
@@ -3900,7 +3896,6 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function
@@ -3912,16 +3907,18 @@
// Compute function to call and use the global object as the
// receiver. There is no need to use the global proxy here because
// it will always be replaced with a newly allocated object.
- LoadAndSpill(node->expression());
+ Load(node->expression());
LoadGlobal();
// Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = node->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+
// r0: the number of arguments.
__ mov(r0, Operand(arg_count));
// Load the function into r1 as per calling convention.
@@ -3945,7 +3942,7 @@
JumpTarget leave, null, function, non_function_constructor;
// Load the object into r0.
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
frame_->EmitPop(r0);
// If the object is a smi, we return null.
@@ -4003,7 +4000,7 @@
VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
JumpTarget leave;
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
frame_->EmitPop(r0); // r0 contains object.
// if (object->IsSmi()) return the object.
__ tst(r0, Operand(kSmiTagMask));
@@ -4022,8 +4019,8 @@
VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 2);
JumpTarget leave;
- LoadAndSpill(args->at(0)); // Load the object.
- LoadAndSpill(args->at(1)); // Load the value.
+ Load(args->at(0)); // Load the object.
+ Load(args->at(1)); // Load the value.
frame_->EmitPop(r0); // r0 contains value
frame_->EmitPop(r1); // r1 contains object
// if (object->IsSmi()) return object.
@@ -4059,8 +4056,6 @@
if (ShouldGenerateLog(args->at(0))) {
Load(args->at(1));
Load(args->at(2));
Søren Thygesen Gjesse 2010/05/28 10:15:47 Isn't SpillAll/AssertIsSpilled needed here? (I don
Erik Corry 2010/05/28 11:24:12 Well spotted! I think the real problem here is th
- frame_->SpillAll();
- VirtualFrame::SpilledScope spilled_scope(frame_);
__ CallRuntime(Runtime::kLog, 2);
}
#endif
@@ -4150,8 +4145,8 @@
Comment(masm_, "[ GenerateStringCharCodeAt");
ASSERT(args->length() == 2);
- LoadAndSpill(args->at(0));
- LoadAndSpill(args->at(1));
+ Load(args->at(0));
+ Load(args->at(1));
Register index = r1;
Register object = r2;
@@ -4200,7 +4195,7 @@
Comment(masm_, "[ GenerateStringCharFromCode");
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
Register code = r1;
Register result = r0;
@@ -4271,8 +4266,8 @@
Comment(masm_, "[ GenerateStringCharAt");
ASSERT(args->length() == 2);
- LoadAndSpill(args->at(0));
- LoadAndSpill(args->at(1));
+ Load(args->at(0));
+ Load(args->at(1));
Register index = r1;
Register object = r2;
@@ -4298,38 +4293,38 @@
void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
JumpTarget answer;
// We need the CC bits to come out as not_equal in the case where the
// object is a smi. This can't be done with the usual test opcode so
// we use XOR to get the right CC bits.
- frame_->EmitPop(r0);
- __ and_(r1, r0, Operand(kSmiTagMask));
- __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
+ Register possible_array = frame_->PopToRegister();
+ Register scratch = VirtualFrame::scratch0();
+ __ and_(scratch, possible_array, Operand(kSmiTagMask));
+ __ eor(scratch, scratch, Operand(kSmiTagMask), SetCC);
answer.Branch(ne);
// It is a heap object - get the map. Check if the object is a JS array.
- __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
+ __ CompareObjectType(possible_array, scratch, scratch, JS_ARRAY_TYPE);
answer.Bind();
cc_reg_ = eq;
}
void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
JumpTarget answer;
// We need the CC bits to come out as not_equal in the case where the
// object is a smi. This can't be done with the usual test opcode so
// we use XOR to get the right CC bits.
- frame_->EmitPop(r0);
- __ and_(r1, r0, Operand(kSmiTagMask));
- __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
+ Register possible_regexp = frame_->PopToRegister();
+ Register scratch = VirtualFrame::scratch0();
+ __ and_(scratch, possible_regexp, Operand(kSmiTagMask));
+ __ eor(scratch, scratch, Operand(kSmiTagMask), SetCC);
answer.Branch(ne);
// It is a heap object - get the map. Check if the object is a regexp.
- __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
+ __ CompareObjectType(possible_regexp, scratch, scratch, JS_REGEXP_TYPE);
answer.Bind();
cc_reg_ = eq;
}
@@ -4338,28 +4333,27 @@
void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
// This generates a fast version of:
// (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
- VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
- frame_->EmitPop(r1);
- __ tst(r1, Operand(kSmiTagMask));
+ Load(args->at(0));
+ Register possible_object = frame_->PopToRegister();
+ __ tst(possible_object, Operand(kSmiTagMask));
false_target()->Branch(eq);
__ LoadRoot(ip, Heap::kNullValueRootIndex);
- __ cmp(r1, ip);
+ __ cmp(possible_object, ip);
true_target()->Branch(eq);
- Register map_reg = r2;
- __ ldr(map_reg, FieldMemOperand(r1, HeapObject::kMapOffset));
+ Register map_reg = VirtualFrame::scratch0();
+ __ ldr(map_reg, FieldMemOperand(possible_object, HeapObject::kMapOffset));
// Undetectable objects behave like undefined when tested with typeof.
- __ ldrb(r1, FieldMemOperand(map_reg, Map::kBitFieldOffset));
- __ tst(r1, Operand(1 << Map::kIsUndetectable));
+ __ ldrb(possible_object, FieldMemOperand(map_reg, Map::kBitFieldOffset));
+ __ tst(possible_object, Operand(1 << Map::kIsUndetectable));
false_target()->Branch(ne);
- __ ldrb(r1, FieldMemOperand(map_reg, Map::kInstanceTypeOffset));
- __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ ldrb(possible_object, FieldMemOperand(map_reg, Map::kInstanceTypeOffset));
+ __ cmp(possible_object, Operand(FIRST_JS_OBJECT_TYPE));
false_target()->Branch(lt);
- __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
+ __ cmp(possible_object, Operand(LAST_JS_OBJECT_TYPE));
cc_reg_ = le;
}
@@ -4367,28 +4361,29 @@
void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
// This generates a fast version of:
// (%_ClassOf(arg) === 'Function')
- VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
- frame_->EmitPop(r0);
- __ tst(r0, Operand(kSmiTagMask));
+ Load(args->at(0));
+ Register possible_function = frame_->PopToRegister();
+ __ tst(possible_function, Operand(kSmiTagMask));
false_target()->Branch(eq);
- Register map_reg = r2;
- __ CompareObjectType(r0, map_reg, r1, JS_FUNCTION_TYPE);
+ Register map_reg = VirtualFrame::scratch0();
+ Register scratch = VirtualFrame::scratch1();
+ __ CompareObjectType(possible_function, map_reg, scratch, JS_FUNCTION_TYPE);
cc_reg_ = eq;
}
void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
- frame_->EmitPop(r0);
- __ tst(r0, Operand(kSmiTagMask));
+ Load(args->at(0));
+ Register possible_undetectable = frame_->PopToRegister();
+ __ tst(possible_undetectable, Operand(kSmiTagMask));
false_target()->Branch(eq);
- __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
- __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
- __ tst(r1, Operand(1 << Map::kIsUndetectable));
+ Register scratch = VirtualFrame::scratch0();
+ __ ldr(scratch,
+ FieldMemOperand(possible_undetectable, HeapObject::kMapOffset));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+ __ tst(scratch, Operand(1 << Map::kIsUndetectable));
cc_reg_ = ne;
}
@@ -4449,7 +4444,7 @@
// Satisfy contract with ArgumentsAccessStub:
// Load the key into r1 and the formal parameters count into r0.
- LoadAndSpill(args->at(0));
+ Load(args->at(0));
frame_->EmitPop(r1);
__ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
@@ -4521,6 +4516,7 @@
Load(args->at(1));
StringAddStub stub(NO_STRING_ADD_FLAGS);
+ frame_->SpillAll();
Søren Thygesen Gjesse 2010/05/28 10:15:47 How about moving the SpillAll to CallStub?
Erik Corry 2010/05/28 11:24:12 CallStub is common for the light targets and I wan
frame_->CallStub(&stub, 2);
frame_->EmitPush(r0);
}
@@ -4534,6 +4530,7 @@
Load(args->at(2));
SubStringStub stub;
+ frame_->SpillAll();
frame_->CallStub(&stub, 3);
frame_->EmitPush(r0);
}
@@ -4546,6 +4543,7 @@
Load(args->at(1));
StringCompareStub stub;
+ frame_->SpillAll();
frame_->CallStub(&stub, 2);
frame_->EmitPush(r0);
}
@@ -4559,6 +4557,7 @@
Load(args->at(2));
Load(args->at(3));
RegExpExecStub stub;
+ frame_->SpillAll();
frame_->CallStub(&stub, 4);
frame_->EmitPush(r0);
}
@@ -4693,12 +4692,14 @@
Top::global_context()->jsfunction_result_caches());
if (jsfunction_result_caches->length() <= cache_id) {
__ Abort("Attempt to use undefined cache.");
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
- frame_->EmitPush(r0);
+ frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex);
return;
}
Load(args->at(1));
+
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+
frame_->EmitPop(r2);
__ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX));
@@ -4734,6 +4735,7 @@
Load(args->at(0));
NumberToStringStub stub;
+ frame_->SpillAll();
frame_->CallStub(&stub, 1);
frame_->EmitPush(r0);
}
@@ -4770,6 +4772,8 @@
Load(args->at(1));
Load(args->at(2));
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+
Register index2 = r2;
Register index1 = r1;
Register object = r0;
@@ -4894,7 +4898,6 @@
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
if (CheckForInlineRuntimeCall(node)) {
ASSERT((has_cc() && frame_->height() == original_height) ||
(!has_cc() && frame_->height() == original_height + 1));
@@ -4908,17 +4911,21 @@
if (function == NULL) {
// Prepare stack for calling JS runtime function.
// Push the builtins object found in the current global object.
- __ ldr(r1, GlobalObject());
- __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
- frame_->EmitPush(r0);
+ Register scratch = VirtualFrame::scratch0();
+ __ ldr(scratch, GlobalObject());
+ Register builtins = frame_->GetTOSRegister();
+ __ ldr(builtins, FieldMemOperand(scratch, GlobalObject::kBuiltinsOffset));
+ frame_->EmitPush(builtins);
}
// Push the arguments ("left-to-right").
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+
if (function == NULL) {
// Call the JS runtime function.
__ mov(r2, Operand(node->name()));
@@ -4958,43 +4965,42 @@
Property* property = node->expression()->AsProperty();
Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
if (property != NULL) {
- LoadAndSpill(property->obj());
- LoadAndSpill(property->key());
+ Load(property->obj());
+ Load(property->key());
frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
+ frame_->EmitPush(r0);
} else if (variable != NULL) {
Slot* slot = variable->slot();
if (variable->is_global()) {
LoadGlobal();
- __ mov(r0, Operand(variable->name()));
+ frame_->EmitPush(Operand(variable->name()));
+ frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
frame_->EmitPush(r0);
- frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
// lookup the context holding the named variable
frame_->EmitPush(cp);
- __ mov(r0, Operand(variable->name()));
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(variable->name()));
frame_->CallRuntime(Runtime::kLookupContext, 2);
// r0: context
frame_->EmitPush(r0);
- __ mov(r0, Operand(variable->name()));
+ frame_->EmitPush(Operand(variable->name()));
+ frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
frame_->EmitPush(r0);
- frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
} else {
// Default: Result of deleting non-global, not dynamically
// introduced variables is false.
- __ LoadRoot(r0, Heap::kFalseValueRootIndex);
+ frame_->EmitPushRoot(Heap::kFalseValueRootIndex);
}
} else {
// Default: Result of deleting expressions is true.
- LoadAndSpill(node->expression()); // may have side-effects
+ Load(node->expression()); // may have side-effects
frame_->Drop();
- __ LoadRoot(r0, Heap::kTrueValueRootIndex);
+ frame_->EmitPushRoot(Heap::kTrueValueRootIndex);
}
- frame_->EmitPush(r0);
} else if (op == Token::TYPEOF) {
// Special case for loading the typeof expression; see comment on
@@ -5007,8 +5013,7 @@
bool overwrite =
(node->expression()->AsBinaryOperation() != NULL &&
node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
- LoadAndSpill(node->expression());
- frame_->EmitPop(r0);
+ Load(node->expression());
switch (op) {
case Token::NOT:
case Token::DELETE:
@@ -5017,13 +5022,18 @@
break;
case Token::SUB: {
+ VirtualFrame::SpilledScope spilled(frame_);
+ frame_->EmitPop(r0);
GenericUnaryOpStub stub(Token::SUB, overwrite);
frame_->CallStub(&stub, 0);
+ frame_->EmitPush(r0); // r0 has result
break;
}
case Token::BIT_NOT: {
// smi check
+ VirtualFrame::SpilledScope spilled(frame_);
+ frame_->EmitPop(r0);
JumpTarget smi_label;
JumpTarget continue_label;
__ tst(r0, Operand(kSmiTagMask));
@@ -5037,16 +5047,18 @@
__ mvn(r0, Operand(r0));
__ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag
continue_label.Bind();
+ frame_->EmitPush(r0); // r0 has result
break;
}
case Token::VOID:
- // since the stack top is cached in r0, popping and then
- // pushing a value can be done by just writing to r0.
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
+ frame_->Drop();
+ frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex);
break;
case Token::ADD: {
+ VirtualFrame::SpilledScope spilled(frame_);
+ frame_->EmitPop(r0);
// Smi check.
JumpTarget continue_label;
__ tst(r0, Operand(kSmiTagMask));
@@ -5054,12 +5066,12 @@
frame_->EmitPush(r0);
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
continue_label.Bind();
+ frame_->EmitPush(r0); // r0 has result
break;
}
default:
UNREACHABLE();
}
- frame_->EmitPush(r0); // r0 has result
}
ASSERT(!has_valid_frame() ||
(has_cc() && frame_->height() == original_height) ||
@@ -5209,7 +5221,7 @@
// Evaluate right side expression.
is_true.Bind();
- LoadAndSpill(node->right());
+ Load(node->right());
// Exit (always with a materialized value).
exit.Bind();
@@ -5255,7 +5267,7 @@
// Evaluate right side expression.
is_false.Bind();
- LoadAndSpill(node->right());
+ Load(node->right());
// Exit (always with a materialized value).
exit.Bind();
@@ -5537,8 +5549,8 @@
case Token::IN: {
VirtualFrame::SpilledScope scope(frame_);
- LoadAndSpill(left);
- LoadAndSpill(right);
+ Load(left);
+ Load(right);
frame_->InvokeBuiltin(Builtins::IN, CALL_JS, 2);
frame_->EmitPush(r0);
break;
@@ -5546,8 +5558,8 @@
case Token::INSTANCEOF: {
VirtualFrame::SpilledScope scope(frame_);
- LoadAndSpill(left);
- LoadAndSpill(right);
+ Load(left);
+ Load(right);
InstanceofStub stub;
frame_->CallStub(&stub, 2);
// At this point if instanceof succeeded then r0 == 0.
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698