Index: src/arm/fast-codegen-arm.cc |
=================================================================== |
--- src/arm/fast-codegen-arm.cc (revision 3576) |
+++ src/arm/fast-codegen-arm.cc (working copy) |
@@ -214,56 +214,100 @@ |
} |
-void FastCodeGenerator::Move(Expression::Context context, Register source) { |
+void FastCodeGenerator::Apply(Expression::Context context, |
+ Slot* slot, |
+ Register scratch) { |
switch (context) { |
case Expression::kUninitialized: |
UNREACHABLE(); |
case Expression::kEffect: |
break; |
case Expression::kValue: |
- __ push(source); |
+ case Expression::kTest: |
+ case Expression::kValueTest: |
+ case Expression::kTestValue: |
+ Move(scratch, slot); |
+ Apply(context, scratch); |
break; |
+ } |
+} |
+ |
+ |
+void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { |
+ switch (context) { |
+ case Expression::kUninitialized: |
+ UNREACHABLE(); |
+ case Expression::kEffect: |
+ break; |
+ case Expression::kValue: |
case Expression::kTest: |
- TestAndBranch(source, true_label_, false_label_); |
+ case Expression::kValueTest: |
+ case Expression::kTestValue: |
+ __ mov(ip, Operand(lit->handle())); |
+ Apply(context, ip); |
break; |
+ } |
+} |
+ |
+ |
+void FastCodeGenerator::ApplyTOS(Expression::Context context) { |
+ switch (context) { |
+ case Expression::kUninitialized: |
+ UNREACHABLE(); |
+ case Expression::kEffect: |
+ __ Drop(1); |
+ break; |
+ case Expression::kValue: |
+ break; |
+ case Expression::kTest: |
+ __ pop(r0); |
+ TestAndBranch(r0, true_label_, false_label_); |
+ break; |
case Expression::kValueTest: { |
Label discard; |
- __ push(source); |
- TestAndBranch(source, true_label_, &discard); |
+ __ ldr(r0, MemOperand(sp, 0)); |
+ TestAndBranch(r0, true_label_, &discard); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(false_label_); |
break; |
} |
case Expression::kTestValue: { |
Label discard; |
- __ push(source); |
- TestAndBranch(source, &discard, false_label_); |
+ __ ldr(r0, MemOperand(sp, 0)); |
+ TestAndBranch(r0, &discard, false_label_); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(true_label_); |
} |
} |
} |
-void FastCodeGenerator::MoveTOS(Expression::Context context) { |
+void FastCodeGenerator::DropAndApply(int count, |
+ Expression::Context context, |
+ Register reg) { |
+ ASSERT(count > 0); |
+ ASSERT(!reg.is(sp)); |
switch (context) { |
case Expression::kUninitialized: |
UNREACHABLE(); |
case Expression::kEffect: |
- __ Drop(1); |
+ __ Drop(count); |
break; |
case Expression::kValue: |
+ if (count > 1) __ Drop(count - 1); |
+ __ str(reg, MemOperand(sp)); |
break; |
case Expression::kTest: |
- __ pop(r0); |
- TestAndBranch(r0, true_label_, false_label_); |
+ __ Drop(count); |
+ TestAndBranch(reg, true_label_, false_label_); |
break; |
case Expression::kValueTest: { |
Label discard; |
- __ ldr(r0, MemOperand(sp, 0)); |
- TestAndBranch(r0, true_label_, &discard); |
+ if (count > 1) __ Drop(count - 1); |
+ __ str(reg, MemOperand(sp)); |
+ TestAndBranch(reg, true_label_, &discard); |
__ bind(&discard); |
__ Drop(1); |
__ jmp(false_label_); |
@@ -271,11 +315,13 @@ |
} |
case Expression::kTestValue: { |
Label discard; |
- __ ldr(r0, MemOperand(sp, 0)); |
- TestAndBranch(r0, &discard, false_label_); |
+ if (count > 1) __ Drop(count - 1); |
+ __ str(reg, MemOperand(sp)); |
+ TestAndBranch(reg, &discard, false_label_); |
__ bind(&discard); |
__ Drop(1); |
__ jmp(true_label_); |
+ break; |
} |
} |
} |
@@ -308,42 +354,6 @@ |
-void FastCodeGenerator::Move(Expression::Context context, |
- Slot* source, |
- Register scratch) { |
- switch (context) { |
- case Expression::kUninitialized: |
- UNREACHABLE(); |
- case Expression::kEffect: |
- break; |
- case Expression::kValue: |
- case Expression::kTest: |
- case Expression::kValueTest: |
- case Expression::kTestValue: |
- Move(scratch, source); |
- Move(context, scratch); |
- break; |
- } |
-} |
- |
- |
-void FastCodeGenerator::Move(Expression::Context context, Literal* expr) { |
- switch (context) { |
- case Expression::kUninitialized: |
- UNREACHABLE(); |
- case Expression::kEffect: |
- break; |
- case Expression::kValue: |
- case Expression::kTest: |
- case Expression::kValueTest: |
- case Expression::kTestValue: |
- __ mov(ip, Operand(expr->handle())); |
- Move(context, ip); |
- break; |
- } |
-} |
- |
- |
void FastCodeGenerator::Move(Slot* dst, |
Register src, |
Register scratch1, |
@@ -361,55 +371,6 @@ |
-void FastCodeGenerator::DropAndMove(Expression::Context context, |
- Register source, |
- int drop_count) { |
- ASSERT(drop_count > 0); |
- switch (context) { |
- case Expression::kUninitialized: |
- UNREACHABLE(); |
- case Expression::kEffect: |
- __ add(sp, sp, Operand(drop_count * kPointerSize)); |
- break; |
- case Expression::kValue: |
- if (drop_count > 1) { |
- __ add(sp, sp, Operand((drop_count - 1) * kPointerSize)); |
- } |
- __ str(source, MemOperand(sp)); |
- break; |
- case Expression::kTest: |
- ASSERT(!source.is(sp)); |
- __ add(sp, sp, Operand(drop_count * kPointerSize)); |
- TestAndBranch(source, true_label_, false_label_); |
- break; |
- case Expression::kValueTest: { |
- Label discard; |
- if (drop_count > 1) { |
- __ add(sp, sp, Operand((drop_count - 1) * kPointerSize)); |
- } |
- __ str(source, MemOperand(sp)); |
- TestAndBranch(source, true_label_, &discard); |
- __ bind(&discard); |
- __ pop(); |
- __ jmp(false_label_); |
- break; |
- } |
- case Expression::kTestValue: { |
- Label discard; |
- if (drop_count > 1) { |
- __ add(sp, sp, Operand((drop_count - 1) * kPointerSize)); |
- } |
- __ str(source, MemOperand(sp)); |
- TestAndBranch(source, &discard, false_label_); |
- __ bind(&discard); |
- __ pop(); |
- __ jmp(true_label_); |
- break; |
- } |
- } |
-} |
- |
- |
void FastCodeGenerator::TestAndBranch(Register source, |
Label* true_label, |
Label* false_label) { |
@@ -524,7 +485,7 @@ |
// Value in r0 is ignored (declarations are statements). Receiver |
// and key on stack are discarded. |
- __ add(sp, sp, Operand(2 * kPointerSize)); |
+ __ Drop(2); |
} |
} |
} |
@@ -555,7 +516,7 @@ |
__ mov(r0, Operand(boilerplate)); |
__ stm(db_w, sp, cp.bit() | r0.bit()); |
__ CallRuntime(Runtime::kNewClosure, 2); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
} |
@@ -578,7 +539,7 @@ |
__ mov(r2, Operand(var->name())); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
- DropAndMove(context, r0); |
+ DropAndApply(1, context, r0); |
} else if (rewrite->AsSlot() != NULL) { |
Slot* slot = rewrite->AsSlot(); |
if (FLAG_debug_code) { |
@@ -597,17 +558,18 @@ |
break; |
} |
} |
- Move(context, slot, r0); |
+ Apply(context, slot, r0); |
} else { |
- // A variable has been rewritten into an explicit access to |
- // an object property. |
+ Comment cmnt(masm_, "Variable rewritten to property"); |
+ // A variable has been rewritten into an explicit access to an object |
+ // property. |
Property* property = rewrite->AsProperty(); |
ASSERT_NOT_NULL(property); |
- // Currently the only parameter expressions that can occur are |
- // on the form "slot[literal]". |
+ // The only property expressions that can occur are of the form |
+ // "slot[literal]". |
- // Check that the object is in a slot. |
+ // Assert that the object is in a slot. |
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
ASSERT_NOT_NULL(object_var); |
Slot* object_slot = object_var->slot(); |
@@ -616,7 +578,7 @@ |
// Load the object. |
Move(r2, object_slot); |
- // Check that the key is a smi. |
+ // Assert that the key is a smi. |
Literal* key_literal = property->key()->AsLiteral(); |
ASSERT_NOT_NULL(key_literal); |
ASSERT(key_literal->handle()->IsSmi()); |
@@ -627,12 +589,12 @@ |
// Push both as arguments to ic. |
__ stm(db_w, sp, r2.bit() | r1.bit()); |
- // Do a KEYED property load. |
+ // Do a keyed property load. |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
// Drop key and object left on the stack by IC, and push the result. |
- DropAndMove(context, r0, 2); |
+ DropAndApply(2, context, r0); |
} |
} |
@@ -660,7 +622,7 @@ |
__ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); |
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
__ bind(&done); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
} |
@@ -742,7 +704,7 @@ |
case Expression::kUninitialized: |
UNREACHABLE(); |
case Expression::kEffect: |
- if (result_saved) __ pop(); |
+ if (result_saved) __ Drop(1); |
break; |
case Expression::kValue: |
if (!result_saved) __ push(r0); |
@@ -756,7 +718,7 @@ |
if (!result_saved) __ push(r0); |
TestAndBranch(r0, true_label_, &discard); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(false_label_); |
break; |
} |
@@ -765,7 +727,7 @@ |
if (!result_saved) __ push(r0); |
TestAndBranch(r0, &discard, false_label_); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(true_label_); |
break; |
} |
@@ -824,7 +786,7 @@ |
case Expression::kUninitialized: |
UNREACHABLE(); |
case Expression::kEffect: |
- if (result_saved) __ pop(); |
+ if (result_saved) __ Drop(1); |
break; |
case Expression::kValue: |
if (!result_saved) __ push(r0); |
@@ -838,7 +800,7 @@ |
if (!result_saved) __ push(r0); |
TestAndBranch(r0, true_label_, &discard); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(false_label_); |
break; |
} |
@@ -847,7 +809,7 @@ |
if (!result_saved) __ push(r0); |
TestAndBranch(r0, &discard, false_label_); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(true_label_); |
break; |
} |
@@ -862,7 +824,7 @@ |
__ mov(r2, Operand(key->handle())); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
- Move(context, r0); |
+ Apply(context, r0); |
} |
@@ -871,7 +833,7 @@ |
SetSourcePosition(prop->position()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
- Move(context, r0); |
+ Apply(context, r0); |
} |
@@ -882,7 +844,7 @@ |
GenericBinaryOpStub stub(op, |
NO_OVERWRITE); |
__ CallStub(&stub); |
- Move(context, r0); |
+ Apply(context, r0); |
} |
@@ -901,7 +863,7 @@ |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
// Overwrite the global object on the stack with the result if needed. |
- DropAndMove(context, r0); |
+ DropAndApply(1, context, r0); |
} else if (var->slot() != NULL) { |
Slot* slot = var->slot(); |
@@ -934,7 +896,7 @@ |
__ str(r0, target); |
TestAndBranch(r0, true_label_, &discard); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(false_label_); |
break; |
} |
@@ -944,7 +906,7 @@ |
__ str(r0, target); |
TestAndBranch(r0, &discard, false_label_); |
__ bind(&discard); |
- __ pop(); |
+ __ Drop(1); |
__ jmp(true_label_); |
break; |
} |
@@ -976,7 +938,7 @@ |
__ RecordWrite(r1, r2, r0); |
__ bind(&exit); |
if (context != Expression::kEffect && context != Expression::kValue) { |
- Move(context, r3); |
+ Apply(context, r3); |
} |
break; |
} |
@@ -1022,7 +984,7 @@ |
__ pop(r0); |
} |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} |
@@ -1054,15 +1016,13 @@ |
} |
// Receiver and key are still on stack. |
- __ add(sp, sp, Operand(2 * kPointerSize)); |
- Move(expr->context(), r0); |
+ DropAndApply(2, expr->context(), r0); |
} |
void FastCodeGenerator::VisitProperty(Property* expr) { |
Comment cmnt(masm_, "[ Property"); |
Expression* key = expr->key(); |
- uint32_t dummy; |
// Record the source position for the property load. |
SetSourcePosition(expr->position()); |
@@ -1070,22 +1030,21 @@ |
// Evaluate receiver. |
Visit(expr->obj()); |
- if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && |
- !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { |
- // Do a NAMED property load. |
- // The IC expects the property name in r2 and the receiver on the stack. |
+ if (key->IsPropertyName()) { |
+ // Do a named property load. The IC expects the property name in r2 and |
+ // the receiver on the stack. |
__ mov(r2, Operand(key->AsLiteral()->handle())); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
+ DropAndApply(1, expr->context(), r0); |
} else { |
- // Do a KEYED property load. |
+ // Do a keyed property load. |
Visit(expr->key()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
__ Call(ic, RelocInfo::CODE_TARGET); |
// Drop key and receiver left on the stack by IC. |
- __ pop(); |
+ DropAndApply(2, expr->context(), r0); |
} |
- DropAndMove(expr->context(), r0); |
} |
void FastCodeGenerator::EmitCallWithIC(Call* expr, |
@@ -1107,7 +1066,7 @@ |
// Restore context register. |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
// Discard the function left on TOS. |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} |
@@ -1125,7 +1084,7 @@ |
// Restore context register. |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
// Discard the function left on TOS. |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} |
@@ -1234,7 +1193,7 @@ |
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
// Replace function on TOS with result in r0, or pop it. |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} |
@@ -1265,11 +1224,11 @@ |
// Restore context register. |
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
// Discard the function left on TOS. |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} else { |
// Call the C runtime function. |
__ CallRuntime(expr->function(), arg_count); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
} |
} |
@@ -1398,7 +1357,7 @@ |
} |
__ CallRuntime(Runtime::kTypeof, 1); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
break; |
} |
@@ -1499,7 +1458,7 @@ |
// For all contexts except kEffect: We have the result on |
// top of the stack. |
if (expr->context() != Expression::kEffect) { |
- MoveTOS(expr->context()); |
+ ApplyTOS(expr->context()); |
} |
} else { |
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
@@ -1513,10 +1472,10 @@ |
if (expr->is_postfix()) { |
__ Drop(1); // Result is on the stack under the receiver. |
if (expr->context() != Expression::kEffect) { |
- MoveTOS(expr->context()); |
+ ApplyTOS(expr->context()); |
} |
} else { |
- DropAndMove(expr->context(), r0); |
+ DropAndApply(1, expr->context(), r0); |
} |
break; |
} |
@@ -1526,10 +1485,10 @@ |
if (expr->is_postfix()) { |
__ Drop(2); // Result is on the stack under the key and the receiver. |
if (expr->context() != Expression::kEffect) { |
- MoveTOS(expr->context()); |
+ ApplyTOS(expr->context()); |
} |
} else { |
- DropAndMove(expr->context(), r0, 2); |
+ DropAndApply(2, expr->context(), r0); |
} |
break; |
} |
@@ -1573,7 +1532,7 @@ |
GenericBinaryOpStub stub(expr->op(), |
NO_OVERWRITE); |
__ CallStub(&stub); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
break; |
} |
@@ -1748,7 +1707,7 @@ |
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
- Move(expr->context(), r0); |
+ Apply(expr->context(), r0); |
} |