Index: src/hydrogen.cc |
=================================================================== |
--- src/hydrogen.cc (revision 8141) |
+++ src/hydrogen.cc (working copy) |
@@ -68,7 +68,8 @@ |
last_instruction_index_(-1), |
deleted_phis_(4), |
parent_loop_header_(NULL), |
- is_inline_return_target_(false) { } |
+ is_inline_return_target_(false) { |
+} |
void HBasicBlock::AttachLoopInformation() { |
@@ -4305,22 +4306,21 @@ |
if (inlined_test_context() != NULL) { |
HBasicBlock* if_true = inlined_test_context()->if_true(); |
HBasicBlock* if_false = inlined_test_context()->if_false(); |
- |
- // Pop the return test context from the expression context stack. |
+ if_true->SetJoinId(expr->id()); |
+ if_false->SetJoinId(expr->id()); |
ASSERT(ast_context() == inlined_test_context()); |
+ // Pop the return test context from the expression context stack. |
ClearInlinedTestContext(); |
// Forward to the real test context. |
- if (if_true->HasPredecessor()) { |
- if_true->SetJoinId(expr->id()); |
- HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); |
- if_true->Goto(true_target, false); |
- } |
- if (if_false->HasPredecessor()) { |
- if_false->SetJoinId(expr->id()); |
- HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); |
- if_false->Goto(false_target, false); |
- } |
+ HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); |
+ HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); |
+ if_true->Goto(true_target, false); |
+ if_false->Goto(false_target, false); |
+ |
+ // TODO(kmillikin): Come up with a better way to handle this. It is too |
+ // subtle. NULL here indicates that the enclosing context has no control |
+ // flow to handle. |
set_current_block(NULL); |
} else if (function_return()->HasPredecessor()) { |
@@ -4787,10 +4787,6 @@ |
HValue* value = Pop(); |
HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); |
TypeInfo info = oracle()->UnaryType(expr); |
- if (info.IsUninitialized()) { |
- AddInstruction(new(zone()) HSoftDeoptimize); |
- info = TypeInfo::Unknown(); |
- } |
Representation rep = ToRepresentation(info); |
TraceRepresentation(expr->op(), info, instr, rep); |
instr->AssumeRepresentation(rep); |
@@ -4801,10 +4797,6 @@ |
void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
CHECK_ALIVE(VisitForValue(expr->expression())); |
HValue* value = Pop(); |
- TypeInfo info = oracle()->UnaryType(expr); |
- if (info.IsUninitialized()) { |
- AddInstruction(new(zone()) HSoftDeoptimize); |
- } |
HInstruction* instr = new(zone()) HBitNot(value); |
ast_context()->ReturnInstruction(instr, expr->id()); |
} |
@@ -5036,57 +5028,7 @@ |
HValue* left, |
HValue* right) { |
TypeInfo info = oracle()->BinaryType(expr); |
- if (info.IsUninitialized()) { |
- AddInstruction(new(zone()) HSoftDeoptimize); |
- info = TypeInfo::Unknown(); |
- } |
- HInstruction* instr = NULL; |
- switch (expr->op()) { |
- case Token::ADD: |
- if (info.IsString()) { |
- AddInstruction(new(zone()) HCheckNonSmi(left)); |
- AddInstruction(HCheckInstanceType::NewIsString(left)); |
- AddInstruction(new(zone()) HCheckNonSmi(right)); |
- AddInstruction(HCheckInstanceType::NewIsString(right)); |
- instr = new(zone()) HStringAdd(left, right); |
- } else { |
- instr = new(zone()) HAdd(left, right); |
- } |
- break; |
- case Token::SUB: |
- instr = new(zone()) HSub(left, right); |
- break; |
- case Token::MUL: |
- instr = new(zone()) HMul(left, right); |
- break; |
- case Token::MOD: |
- instr = new(zone()) HMod(left, right); |
- break; |
- case Token::DIV: |
- instr = new(zone()) HDiv(left, right); |
- break; |
- case Token::BIT_XOR: |
- instr = new(zone()) HBitXor(left, right); |
- break; |
- case Token::BIT_AND: |
- instr = new(zone()) HBitAnd(left, right); |
- break; |
- case Token::BIT_OR: |
- instr = new(zone()) HBitOr(left, right); |
- break; |
- case Token::SAR: |
- instr = new(zone()) HSar(left, right); |
- break; |
- case Token::SHR: |
- instr = new(zone()) HShr(left, right); |
- break; |
- case Token::SHL: |
- instr = new(zone()) HShl(left, right); |
- break; |
- default: |
- UNREACHABLE(); |
- } |
- |
+ HInstruction* instr = BuildBinaryOperation(expr->op(), left, right, info); |
// If we hit an uninitialized binary op stub we will get type info |
// for a smi operation. If one of the operands is a constant string |
// do not generate code assuming it is a smi operation. |
@@ -5106,6 +5048,36 @@ |
} |
+HInstruction* HGraphBuilder::BuildBinaryOperation( |
+ Token::Value op, HValue* left, HValue* right, TypeInfo info) { |
+ switch (op) { |
+ case Token::ADD: |
+ if (info.IsString()) { |
+ AddInstruction(new(zone()) HCheckNonSmi(left)); |
+ AddInstruction(HCheckInstanceType::NewIsString(left)); |
+ AddInstruction(new(zone()) HCheckNonSmi(right)); |
+ AddInstruction(HCheckInstanceType::NewIsString(right)); |
+ return new(zone()) HStringAdd(left, right); |
+ } else { |
+ return new(zone()) HAdd(left, right); |
+ } |
+ case Token::SUB: return new(zone()) HSub(left, right); |
+ case Token::MUL: return new(zone()) HMul(left, right); |
+ case Token::MOD: return new(zone()) HMod(left, right); |
+ case Token::DIV: return new(zone()) HDiv(left, right); |
+ case Token::BIT_XOR: return new(zone()) HBitXor(left, right); |
+ case Token::BIT_AND: return new(zone()) HBitAnd(left, right); |
+ case Token::BIT_OR: return new(zone()) HBitOr(left, right); |
+ case Token::SAR: return new(zone()) HSar(left, right); |
+ case Token::SHR: return new(zone()) HShr(left, right); |
+ case Token::SHL: return new(zone()) HShl(left, right); |
+ default: |
+ UNREACHABLE(); |
+ return NULL; |
+ } |
+} |
+ |
+ |
// Check for the form (%_ClassOf(foo) === 'BarClass'). |
static bool IsClassOfTest(CompareOperation* expr) { |
if (expr->op() != Token::EQ_STRICT) return false; |
@@ -5303,13 +5275,6 @@ |
return; |
} |
- TypeInfo type_info = oracle()->CompareType(expr); |
- // Check if this expression was ever executed according to type feedback. |
- if (type_info.IsUninitialized()) { |
- AddInstruction(new(zone()) HSoftDeoptimize); |
- type_info = TypeInfo::Unknown(); |
- } |
- |
CHECK_ALIVE(VisitForValue(expr->left())); |
CHECK_ALIVE(VisitForValue(expr->right())); |
@@ -5317,6 +5282,7 @@ |
HValue* left = Pop(); |
Token::Value op = expr->op(); |
+ TypeInfo type_info = oracle()->CompareType(expr); |
HInstruction* instr = NULL; |
if (op == Token::INSTANCEOF) { |
// Check to see if the rhs of the instanceof is a global function not |