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

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

Issue 3152042: Simplified the full codegens by removing the Expression::kTestValue... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 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 | « no previous file | src/ast.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/full-codegen-arm.cc
===================================================================
--- src/arm/full-codegen-arm.cc (revision 5316)
+++ src/arm/full-codegen-arm.cc (working copy)
@@ -266,16 +266,10 @@
}
break;
- case Expression::kValueTest:
- case Expression::kTestValue:
- // Push an extra copy of the value in case it's needed.
- __ push(reg);
- // Fall through.
-
case Expression::kTest:
- // We always call the runtime on ARM, so push the value as argument.
- __ push(reg);
- DoTest(context);
+ // For simplicity we always test the accumulator register.
+ if (!reg.is(result_register())) __ mov(result_register(), reg);
+ DoTest(true_label_, false_label_, NULL);
break;
}
}
@@ -290,8 +284,6 @@
break;
case Expression::kValue:
case Expression::kTest:
- case Expression::kValueTest:
- case Expression::kTestValue:
// On ARM we have to move the value into a register to do anything
// with it.
Move(result_register(), slot);
@@ -310,8 +302,6 @@
// Nothing to do.
case Expression::kValue:
case Expression::kTest:
- case Expression::kValueTest:
- case Expression::kTestValue:
// On ARM we have to move the value into a register to do anything
// with it.
__ mov(result_register(), Operand(lit->handle()));
@@ -340,15 +330,9 @@
}
break;
- case Expression::kValueTest:
- case Expression::kTestValue:
- // Duplicate the value on the stack in case it's needed.
- __ ldr(ip, MemOperand(sp));
- __ push(ip);
- // Fall through.
-
case Expression::kTest:
- DoTest(context);
+ __ pop(result_register());
+ DoTest(true_label_, false_label_, NULL);
break;
}
}
@@ -381,23 +365,10 @@
break;
case Expression::kTest:
- if (count > 1) __ Drop(count - 1);
- __ str(reg, MemOperand(sp));
- DoTest(context);
+ __ Drop(count);
+ if (!reg.is(result_register())) __ mov(result_register(), reg);
+ DoTest(true_label_, false_label_, NULL);
break;
-
- case Expression::kValueTest:
- case Expression::kTestValue:
- if (count == 1) {
- __ str(reg, MemOperand(sp));
- __ push(reg);
- } else { // count > 1
- __ Drop(count - 2);
- __ str(reg, MemOperand(sp, kPointerSize));
- __ str(reg, MemOperand(sp));
- }
- DoTest(context);
- break;
}
}
@@ -422,14 +393,6 @@
*if_true = true_label_;
*if_false = false_label_;
break;
- case Expression::kValueTest:
- *if_true = materialize_true;
- *if_false = false_label_;
- break;
- case Expression::kTestValue:
- *if_true = true_label_;
- *if_false = materialize_false;
- break;
}
}
@@ -471,34 +434,6 @@
case Expression::kTest:
break;
-
- case Expression::kValueTest:
- __ bind(materialize_true);
- switch (location_) {
- case kAccumulator:
- __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
- break;
- case kStack:
- __ LoadRoot(ip, Heap::kTrueValueRootIndex);
- __ push(ip);
- break;
- }
- __ jmp(true_label_);
- break;
-
- case Expression::kTestValue:
- __ bind(materialize_false);
- switch (location_) {
- case kAccumulator:
- __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
- break;
- case kStack:
- __ LoadRoot(ip, Heap::kFalseValueRootIndex);
- __ push(ip);
- break;
- }
- __ jmp(false_label_);
- break;
}
}
@@ -529,101 +464,34 @@
case Expression::kTest:
__ b(flag ? true_label_ : false_label_);
break;
- case Expression::kTestValue:
- switch (location_) {
- case kAccumulator:
- // If value is false it's needed.
- if (!flag) __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
- break;
- case kStack:
- // If value is false it's needed.
- if (!flag) {
- __ LoadRoot(ip, Heap::kFalseValueRootIndex);
- __ push(ip);
- }
- break;
- }
- __ b(flag ? true_label_ : false_label_);
- break;
- case Expression::kValueTest:
- switch (location_) {
- case kAccumulator:
- // If value is true it's needed.
- if (flag) __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
- break;
- case kStack:
- // If value is true it's needed.
- if (flag) {
- __ LoadRoot(ip, Heap::kTrueValueRootIndex);
- __ push(ip);
- }
- break;
- }
- __ b(flag ? true_label_ : false_label_);
- break;
}
}
-void FullCodeGenerator::DoTest(Expression::Context context) {
- // The value to test is pushed on the stack, and duplicated on the stack
- // if necessary (for value/test and test/value contexts).
- ASSERT_NE(NULL, true_label_);
- ASSERT_NE(NULL, false_label_);
-
+void FullCodeGenerator::DoTest(Label* if_true,
+ Label* if_false,
+ Label* fall_through) {
// Call the runtime to find the boolean value of the source and then
// translate it into control flow to the pair of labels.
+ __ push(result_register());
__ CallRuntime(Runtime::kToBool, 1);
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
__ cmp(r0, ip);
+ Split(eq, if_true, if_false, fall_through);
+}
- // Complete based on the context.
- switch (context) {
- case Expression::kUninitialized:
- case Expression::kEffect:
- case Expression::kValue:
- UNREACHABLE();
- case Expression::kTest:
- __ b(eq, true_label_);
- __ jmp(false_label_);
- break;
-
- case Expression::kValueTest: {
- Label discard;
- switch (location_) {
- case kAccumulator:
- __ b(ne, &discard);
- __ pop(result_register());
- __ jmp(true_label_);
- break;
- case kStack:
- __ b(eq, true_label_);
- break;
- }
- __ bind(&discard);
- __ Drop(1);
- __ jmp(false_label_);
- break;
- }
-
- case Expression::kTestValue: {
- Label discard;
- switch (location_) {
- case kAccumulator:
- __ b(eq, &discard);
- __ pop(result_register());
- __ jmp(false_label_);
- break;
- case kStack:
- __ b(ne, false_label_);
- break;
- }
- __ bind(&discard);
- __ Drop(1);
- __ jmp(true_label_);
- break;
- }
+void FullCodeGenerator::Split(Condition cc,
+ Label* if_true,
+ Label* if_false,
+ Label* fall_through) {
+ if (if_false == fall_through) {
+ __ b(cc, if_true);
+ } else if (if_true == fall_through) {
+ __ b(NegateCondition(cc), if_false);
+ } else {
+ __ b(cc, if_true);
+ __ b(if_false);
}
}
@@ -1107,28 +975,33 @@
// r2 = RegExp pattern
// r1 = RegExp flags
// r0 = temp + materialized value (RegExp literal)
- __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
+ __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
int literal_offset =
- FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+ FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
__ ldr(r0, FieldMemOperand(r4, literal_offset));
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
__ cmp(r0, ip);
__ b(ne, &materialized);
+
+ // Create regexp literal using runtime function.
+ // Result will be in r0.
__ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
__ mov(r2, Operand(expr->pattern()));
__ mov(r1, Operand(expr->flags()));
__ Push(r4, r3, r2, r1);
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
+
__ bind(&materialized);
int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
__ push(r0);
__ mov(r0, Operand(Smi::FromInt(size)));
__ push(r0);
__ CallRuntime(Runtime::kAllocateInNewSpace, 1);
+
// After this, registers are used as follows:
// r0: Newly allocated regexp.
- // r1: Materialized regexp
+ // r1: Materialized regexp.
// r2: temp.
__ pop(r1);
__ CopyFields(r0, r1, r2.bit(), size / kPointerSize);
@@ -1885,8 +1758,7 @@
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
__ tst(r0, Operand(kSmiTagMask | 0x80000000));
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -1914,8 +1786,7 @@
__ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
__ b(lt, if_false);
__ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
- __ b(le, if_true);
- __ b(if_false);
+ Split(le, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -1933,8 +1804,7 @@
__ BranchOnSmi(r0, if_false);
__ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
- __ b(ge, if_true);
- __ b(if_false);
+ Split(ge, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -1954,8 +1824,7 @@
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
__ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
__ tst(r1, Operand(1 << Map::kIsUndetectable));
- __ b(ne, if_true);
- __ b(if_false);
+ Split(ne, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -1993,8 +1862,7 @@
__ BranchOnSmi(r0, if_false);
__ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -2012,8 +1880,7 @@
__ BranchOnSmi(r0, if_false);
__ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -2031,8 +1898,7 @@
__ BranchOnSmi(r0, if_false);
__ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -2061,8 +1927,7 @@
__ bind(&check_frame_marker);
__ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
__ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -2082,8 +1947,7 @@
__ pop(r1);
__ cmp(r0, r1);
- __ b(eq, if_true);
- __ b(if_false);
+ Split(eq, if_true, if_false, NULL);
Apply(context_, if_true, if_false);
}
@@ -2752,19 +2616,7 @@
break;
}
break;
- case Expression::kTestValue:
- // Value is false so it's needed.
- __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex);
- switch (location_) {
- case kAccumulator:
- break;
- case kStack:
- __ push(result_register());
- break;
- }
- // Fall through.
case Expression::kTest:
- case Expression::kValueTest:
__ jmp(false_label_);
break;
}
@@ -2945,8 +2797,6 @@
break;
case Expression::kValue:
case Expression::kTest:
- case Expression::kValueTest:
- case Expression::kTestValue:
// Save the result on the stack. If we have a named or keyed property
// we store the result under the receiver that is currently on top
// of the stack.
@@ -3034,41 +2884,6 @@
}
-void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
- Comment cmnt(masm_, "[ BinaryOperation");
- switch (expr->op()) {
- case Token::COMMA:
- VisitForEffect(expr->left());
- Visit(expr->right());
- break;
-
- case Token::OR:
- case Token::AND:
- EmitLogicalOperation(expr);
- break;
-
- case Token::ADD:
- case Token::SUB:
- case Token::DIV:
- case Token::MOD:
- case Token::MUL:
- case Token::BIT_OR:
- case Token::BIT_AND:
- case Token::BIT_XOR:
- case Token::SHL:
- case Token::SHR:
- case Token::SAR:
- VisitForValue(expr->left(), kStack);
- VisitForValue(expr->right(), kAccumulator);
- EmitBinaryOp(expr->op(), context_);
- break;
-
- default:
- UNREACHABLE();
- }
-}
-
-
void FullCodeGenerator::EmitNullCompare(bool strict,
Register obj,
Register null_const,
@@ -3077,7 +2892,7 @@
Register scratch) {
__ cmp(obj, null_const);
if (strict) {
- __ b(eq, if_true);
+ Split(eq, if_true, if_false, NULL);
} else {
__ b(eq, if_true);
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
@@ -3088,9 +2903,8 @@
__ ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
__ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ tst(scratch, Operand(1 << Map::kIsUndetectable));
- __ b(ne, if_true);
+ Split(ne, if_true, if_false, NULL);
}
- __ jmp(if_false);
}
@@ -3112,17 +2926,16 @@
__ InvokeBuiltin(Builtins::IN, CALL_JS);
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
__ cmp(r0, ip);
- __ b(eq, if_true);
- __ jmp(if_false);
+ Split(eq, if_true, if_false, NULL);
break;
case Token::INSTANCEOF: {
VisitForValue(expr->right(), kStack);
InstanceofStub stub;
__ CallStub(&stub);
+ // The stub returns 0 for true.
__ tst(r0, r0);
- __ b(eq, if_true); // The stub returns 0 for true.
- __ jmp(if_false);
+ Split(eq, if_true, if_false, NULL);
break;
}
@@ -3191,8 +3004,7 @@
CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0);
__ CallStub(&stub);
__ cmp(r0, Operand(0));
- __ b(cc, if_true);
- __ jmp(if_false);
+ Split(cc, if_true, if_false, NULL);
}
}
« no previous file with comments | « no previous file | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698