OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 HPhase phase("Block building"); | 2207 HPhase phase("Block building"); |
2208 current_block_ = graph()->entry_block(); | 2208 current_block_ = graph()->entry_block(); |
2209 | 2209 |
2210 Scope* scope = info()->scope(); | 2210 Scope* scope = info()->scope(); |
2211 if (scope->HasIllegalRedeclaration()) { | 2211 if (scope->HasIllegalRedeclaration()) { |
2212 Bailout("function with illegal redeclaration"); | 2212 Bailout("function with illegal redeclaration"); |
2213 return NULL; | 2213 return NULL; |
2214 } | 2214 } |
2215 SetupScope(scope); | 2215 SetupScope(scope); |
2216 VisitDeclarations(scope->declarations()); | 2216 VisitDeclarations(scope->declarations()); |
2217 AddInstruction(new(zone()) HStackCheck(HStackCheck::kFunctionEntry)); | 2217 HValue* context = environment()->LookupContext(); |
| 2218 AddInstruction( |
| 2219 » new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
2218 | 2220 |
2219 // Add an edge to the body entry. This is warty: the graph's start | 2221 // Add an edge to the body entry. This is warty: the graph's start |
2220 // environment will be used by the Lithium translation as the initial | 2222 // environment will be used by the Lithium translation as the initial |
2221 // environment on graph entry, but it has now been mutated by the | 2223 // environment on graph entry, but it has now been mutated by the |
2222 // Hydrogen translation of the instructions in the start block. This | 2224 // Hydrogen translation of the instructions in the start block. This |
2223 // environment uses values which have not been defined yet. These | 2225 // environment uses values which have not been defined yet. These |
2224 // Hydrogen instructions will then be replayed by the Lithium | 2226 // Hydrogen instructions will then be replayed by the Lithium |
2225 // translation, so they cannot have an environment effect. The edge to | 2227 // translation, so they cannot have an environment effect. The edge to |
2226 // the body's entry block (along with some special logic for the start | 2228 // the body's entry block (along with some special logic for the start |
2227 // block in HInstruction::InsertAfter) seals the start block from | 2229 // block in HInstruction::InsertAfter) seals the start block from |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2614 // Finish with deoptimize and add uses of enviroment values to | 2616 // Finish with deoptimize and add uses of enviroment values to |
2615 // account for invisible uses. | 2617 // account for invisible uses. |
2616 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 2618 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
2617 set_current_block(NULL); | 2619 set_current_block(NULL); |
2618 break; | 2620 break; |
2619 } | 2621 } |
2620 | 2622 |
2621 // Otherwise generate a compare and branch. | 2623 // Otherwise generate a compare and branch. |
2622 CHECK_ALIVE(VisitForValue(clause->label())); | 2624 CHECK_ALIVE(VisitForValue(clause->label())); |
2623 HValue* label_value = Pop(); | 2625 HValue* label_value = Pop(); |
| 2626 HValue* context = environment()->LookupContext(); |
2624 HCompare* compare = | 2627 HCompare* compare = |
2625 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT); | 2628 new(zone()) HCompare(context, tag_value, label_value, Token::EQ_STRICT); |
2626 compare->SetInputRepresentation(Representation::Integer32()); | 2629 compare->SetInputRepresentation(Representation::Integer32()); |
2627 ASSERT(!compare->HasSideEffects()); | 2630 ASSERT(!compare->HasSideEffects()); |
2628 AddInstruction(compare); | 2631 AddInstruction(compare); |
2629 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 2632 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
2630 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 2633 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
2631 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block); | 2634 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block); |
2632 current_block()->Finish(branch); | 2635 current_block()->Finish(branch); |
2633 set_current_block(next_test_block); | 2636 set_current_block(next_test_block); |
2634 } | 2637 } |
2635 | 2638 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2740 current_block()->Goto(loop_predecessor); | 2743 current_block()->Goto(loop_predecessor); |
2741 loop_predecessor->SetJoinId(statement->EntryId()); | 2744 loop_predecessor->SetJoinId(statement->EntryId()); |
2742 set_current_block(loop_predecessor); | 2745 set_current_block(loop_predecessor); |
2743 } | 2746 } |
2744 | 2747 |
2745 | 2748 |
2746 void HGraphBuilder::VisitLoopBody(Statement* body, | 2749 void HGraphBuilder::VisitLoopBody(Statement* body, |
2747 HBasicBlock* loop_entry, | 2750 HBasicBlock* loop_entry, |
2748 BreakAndContinueInfo* break_info) { | 2751 BreakAndContinueInfo* break_info) { |
2749 BreakAndContinueScope push(break_info, this); | 2752 BreakAndContinueScope push(break_info, this); |
| 2753 HValue* context = environment()->LookupContext(); |
2750 HStackCheck* stack_check = | 2754 HStackCheck* stack_check = |
2751 new(zone()) HStackCheck(HStackCheck::kBackwardsBranch); | 2755 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
2752 AddInstruction(stack_check); | 2756 AddInstruction(stack_check); |
2753 ASSERT(loop_entry->IsLoopHeader()); | 2757 ASSERT(loop_entry->IsLoopHeader()); |
2754 loop_entry->loop_information()->set_stack_check(stack_check); | 2758 loop_entry->loop_information()->set_stack_check(stack_check); |
2755 CHECK_BAILOUT(Visit(body)); | 2759 CHECK_BAILOUT(Visit(body)); |
2756 } | 2760 } |
2757 | 2761 |
2758 | 2762 |
2759 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2763 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
2760 ASSERT(!HasStackOverflow()); | 2764 ASSERT(!HasStackOverflow()); |
2761 ASSERT(current_block() != NULL); | 2765 ASSERT(current_block() != NULL); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2950 ASSERT(current_block() != NULL); | 2954 ASSERT(current_block() != NULL); |
2951 ASSERT(current_block()->HasPredecessor()); | 2955 ASSERT(current_block()->HasPredecessor()); |
2952 Handle<SharedFunctionInfo> shared_info = | 2956 Handle<SharedFunctionInfo> shared_info = |
2953 SearchSharedFunctionInfo(info()->shared_info()->code(), | 2957 SearchSharedFunctionInfo(info()->shared_info()->code(), |
2954 expr); | 2958 expr); |
2955 if (shared_info.is_null()) { | 2959 if (shared_info.is_null()) { |
2956 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 2960 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); |
2957 } | 2961 } |
2958 // We also have a stack overflow if the recursive compilation did. | 2962 // We also have a stack overflow if the recursive compilation did. |
2959 if (HasStackOverflow()) return; | 2963 if (HasStackOverflow()) return; |
| 2964 HValue* context = environment()->LookupContext(); |
2960 HFunctionLiteral* instr = | 2965 HFunctionLiteral* instr = |
2961 new(zone()) HFunctionLiteral(shared_info, expr->pretenure()); | 2966 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
2962 ast_context()->ReturnInstruction(instr, expr->id()); | 2967 ast_context()->ReturnInstruction(instr, expr->id()); |
2963 } | 2968 } |
2964 | 2969 |
2965 | 2970 |
2966 void HGraphBuilder::VisitSharedFunctionInfoLiteral( | 2971 void HGraphBuilder::VisitSharedFunctionInfoLiteral( |
2967 SharedFunctionInfoLiteral* expr) { | 2972 SharedFunctionInfoLiteral* expr) { |
2968 ASSERT(!HasStackOverflow()); | 2973 ASSERT(!HasStackOverflow()); |
2969 ASSERT(current_block() != NULL); | 2974 ASSERT(current_block() != NULL); |
2970 ASSERT(current_block()->HasPredecessor()); | 2975 ASSERT(current_block()->HasPredecessor()); |
2971 return Bailout("SharedFunctionInfoLiteral"); | 2976 return Bailout("SharedFunctionInfoLiteral"); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 HConstant* instr = | 3109 HConstant* instr = |
3105 new(zone()) HConstant(expr->handle(), Representation::Tagged()); | 3110 new(zone()) HConstant(expr->handle(), Representation::Tagged()); |
3106 ast_context()->ReturnInstruction(instr, expr->id()); | 3111 ast_context()->ReturnInstruction(instr, expr->id()); |
3107 } | 3112 } |
3108 | 3113 |
3109 | 3114 |
3110 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 3115 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
3111 ASSERT(!HasStackOverflow()); | 3116 ASSERT(!HasStackOverflow()); |
3112 ASSERT(current_block() != NULL); | 3117 ASSERT(current_block() != NULL); |
3113 ASSERT(current_block()->HasPredecessor()); | 3118 ASSERT(current_block()->HasPredecessor()); |
3114 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(), | 3119 HValue* context = environment()->LookupContext(); |
| 3120 |
| 3121 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
| 3122 expr->pattern(), |
3115 expr->flags(), | 3123 expr->flags(), |
3116 expr->literal_index()); | 3124 expr->literal_index()); |
3117 ast_context()->ReturnInstruction(instr, expr->id()); | 3125 ast_context()->ReturnInstruction(instr, expr->id()); |
3118 } | 3126 } |
3119 | 3127 |
3120 | 3128 |
3121 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 3129 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
3122 ASSERT(!HasStackOverflow()); | 3130 ASSERT(!HasStackOverflow()); |
3123 ASSERT(current_block() != NULL); | 3131 ASSERT(current_block() != NULL); |
3124 ASSERT(current_block()->HasPredecessor()); | 3132 ASSERT(current_block()->HasPredecessor()); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 } | 3198 } |
3191 } | 3199 } |
3192 | 3200 |
3193 | 3201 |
3194 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 3202 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
3195 ASSERT(!HasStackOverflow()); | 3203 ASSERT(!HasStackOverflow()); |
3196 ASSERT(current_block() != NULL); | 3204 ASSERT(current_block() != NULL); |
3197 ASSERT(current_block()->HasPredecessor()); | 3205 ASSERT(current_block()->HasPredecessor()); |
3198 ZoneList<Expression*>* subexprs = expr->values(); | 3206 ZoneList<Expression*>* subexprs = expr->values(); |
3199 int length = subexprs->length(); | 3207 int length = subexprs->length(); |
| 3208 HValue* context = environment()->LookupContext(); |
3200 | 3209 |
3201 HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(), | 3210 HArrayLiteral* literal = new(zone()) HArrayLiteral(context, |
| 3211 expr->constant_elements(), |
3202 length, | 3212 length, |
3203 expr->literal_index(), | 3213 expr->literal_index(), |
3204 expr->depth()); | 3214 expr->depth()); |
3205 // The array is expected in the bailout environment during computation | 3215 // The array is expected in the bailout environment during computation |
3206 // of the property values and is the value of the entire expression. | 3216 // of the property values and is the value of the entire expression. |
3207 PushAndAdd(literal); | 3217 PushAndAdd(literal); |
3208 | 3218 |
3209 HLoadElements* elements = NULL; | 3219 HLoadElements* elements = NULL; |
3210 | 3220 |
3211 for (int i = 0; i < length; i++) { | 3221 for (int i = 0; i < length; i++) { |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3716 void HGraphBuilder::VisitThrow(Throw* expr) { | 3726 void HGraphBuilder::VisitThrow(Throw* expr) { |
3717 ASSERT(!HasStackOverflow()); | 3727 ASSERT(!HasStackOverflow()); |
3718 ASSERT(current_block() != NULL); | 3728 ASSERT(current_block() != NULL); |
3719 ASSERT(current_block()->HasPredecessor()); | 3729 ASSERT(current_block()->HasPredecessor()); |
3720 // We don't optimize functions with invalid left-hand sides in | 3730 // We don't optimize functions with invalid left-hand sides in |
3721 // assignments, count operations, or for-in. Consequently throw can | 3731 // assignments, count operations, or for-in. Consequently throw can |
3722 // currently only occur in an effect context. | 3732 // currently only occur in an effect context. |
3723 ASSERT(ast_context()->IsEffect()); | 3733 ASSERT(ast_context()->IsEffect()); |
3724 CHECK_ALIVE(VisitForValue(expr->exception())); | 3734 CHECK_ALIVE(VisitForValue(expr->exception())); |
3725 | 3735 |
| 3736 HValue* context = environment()->LookupContext(); |
3726 HValue* value = environment()->Pop(); | 3737 HValue* value = environment()->Pop(); |
3727 HThrow* instr = new(zone()) HThrow(value); | 3738 HThrow* instr = new(zone()) HThrow(context, value); |
3728 instr->set_position(expr->position()); | 3739 instr->set_position(expr->position()); |
3729 AddInstruction(instr); | 3740 AddInstruction(instr); |
3730 AddSimulate(expr->id()); | 3741 AddSimulate(expr->id()); |
3731 current_block()->FinishExit(new(zone()) HAbnormalExit); | 3742 current_block()->FinishExit(new(zone()) HAbnormalExit); |
3732 set_current_block(NULL); | 3743 set_current_block(NULL); |
3733 } | 3744 } |
3734 | 3745 |
3735 | 3746 |
3736 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 3747 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
3737 Property* expr, | 3748 Property* expr, |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4125 | 4136 |
4126 } else if (expr->IsStringLength()) { | 4137 } else if (expr->IsStringLength()) { |
4127 HValue* string = Pop(); | 4138 HValue* string = Pop(); |
4128 AddInstruction(new(zone()) HCheckNonSmi(string)); | 4139 AddInstruction(new(zone()) HCheckNonSmi(string)); |
4129 AddInstruction(HCheckInstanceType::NewIsString(string)); | 4140 AddInstruction(HCheckInstanceType::NewIsString(string)); |
4130 instr = new(zone()) HStringLength(string); | 4141 instr = new(zone()) HStringLength(string); |
4131 } else if (expr->IsStringAccess()) { | 4142 } else if (expr->IsStringAccess()) { |
4132 CHECK_ALIVE(VisitForValue(expr->key())); | 4143 CHECK_ALIVE(VisitForValue(expr->key())); |
4133 HValue* index = Pop(); | 4144 HValue* index = Pop(); |
4134 HValue* string = Pop(); | 4145 HValue* string = Pop(); |
4135 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 4146 HValue* context = environment()->LookupContext(); |
| 4147 HStringCharCodeAt* char_code = |
| 4148 BuildStringCharCodeAt(context, string, index); |
4136 AddInstruction(char_code); | 4149 AddInstruction(char_code); |
4137 instr = new(zone()) HStringCharFromCode(char_code); | 4150 instr = new(zone()) HStringCharFromCode(context, char_code); |
4138 | 4151 |
4139 } else if (expr->IsFunctionPrototype()) { | 4152 } else if (expr->IsFunctionPrototype()) { |
4140 HValue* function = Pop(); | 4153 HValue* function = Pop(); |
4141 AddInstruction(new(zone()) HCheckNonSmi(function)); | 4154 AddInstruction(new(zone()) HCheckNonSmi(function)); |
4142 instr = new(zone()) HLoadFunctionPrototype(function); | 4155 instr = new(zone()) HLoadFunctionPrototype(function); |
4143 | 4156 |
4144 } else if (expr->key()->IsPropertyName()) { | 4157 } else if (expr->key()->IsPropertyName()) { |
4145 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 4158 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
4146 ZoneMapList* types = expr->GetReceiverTypes(); | 4159 ZoneMapList* types = expr->GetReceiverTypes(); |
4147 | 4160 |
4148 HValue* obj = Pop(); | 4161 HValue* obj = Pop(); |
4149 if (expr->IsMonomorphic()) { | 4162 if (expr->IsMonomorphic()) { |
4150 instr = BuildLoadNamed(obj, expr, types->first(), name); | 4163 instr = BuildLoadNamed(obj, expr, types->first(), name); |
4151 } else if (types != NULL && types->length() > 1) { | 4164 } else if (types != NULL && types->length() > 1) { |
4152 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 4165 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
4153 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); | 4166 HValue* context = environment()->LookupContext(); |
| 4167 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); |
4154 } else { | 4168 } else { |
4155 instr = BuildLoadNamedGeneric(obj, expr); | 4169 instr = BuildLoadNamedGeneric(obj, expr); |
4156 } | 4170 } |
4157 | 4171 |
4158 } else { | 4172 } else { |
4159 CHECK_ALIVE(VisitForValue(expr->key())); | 4173 CHECK_ALIVE(VisitForValue(expr->key())); |
4160 | 4174 |
4161 HValue* key = Pop(); | 4175 HValue* key = Pop(); |
4162 HValue* obj = Pop(); | 4176 HValue* obj = Pop(); |
4163 | 4177 |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4542 // Try to inline calls like Math.* as operations in the calling function. | 4556 // Try to inline calls like Math.* as operations in the calling function. |
4543 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 4557 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
4544 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 4558 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
4545 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 4559 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
4546 switch (id) { | 4560 switch (id) { |
4547 case kStringCharCodeAt: | 4561 case kStringCharCodeAt: |
4548 case kStringCharAt: | 4562 case kStringCharAt: |
4549 if (argument_count == 2 && check_type == STRING_CHECK) { | 4563 if (argument_count == 2 && check_type == STRING_CHECK) { |
4550 HValue* index = Pop(); | 4564 HValue* index = Pop(); |
4551 HValue* string = Pop(); | 4565 HValue* string = Pop(); |
| 4566 HValue* context = environment()->LookupContext(); |
4552 ASSERT(!expr->holder().is_null()); | 4567 ASSERT(!expr->holder().is_null()); |
4553 AddInstruction(new(zone()) HCheckPrototypeMaps( | 4568 AddInstruction(new(zone()) HCheckPrototypeMaps( |
4554 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), | 4569 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), |
4555 expr->holder())); | 4570 expr->holder())); |
4556 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 4571 HStringCharCodeAt* char_code = |
| 4572 » BuildStringCharCodeAt(context, string, index); |
4557 if (id == kStringCharCodeAt) { | 4573 if (id == kStringCharCodeAt) { |
4558 ast_context()->ReturnInstruction(char_code, expr->id()); | 4574 ast_context()->ReturnInstruction(char_code, expr->id()); |
4559 return true; | 4575 return true; |
4560 } | 4576 } |
4561 AddInstruction(char_code); | 4577 AddInstruction(char_code); |
4562 HStringCharFromCode* result = | 4578 HStringCharFromCode* result = |
4563 new(zone()) HStringCharFromCode(char_code); | 4579 » new(zone()) HStringCharFromCode(context, char_code); |
4564 ast_context()->ReturnInstruction(result, expr->id()); | 4580 ast_context()->ReturnInstruction(result, expr->id()); |
4565 return true; | 4581 return true; |
4566 } | 4582 } |
4567 break; | 4583 break; |
4568 case kMathRound: | 4584 case kMathRound: |
4569 case kMathFloor: | 4585 case kMathFloor: |
4570 case kMathAbs: | 4586 case kMathAbs: |
4571 case kMathSqrt: | 4587 case kMathSqrt: |
4572 case kMathLog: | 4588 case kMathLog: |
4573 case kMathSin: | 4589 case kMathSin: |
4574 case kMathCos: | 4590 case kMathCos: |
4575 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 4591 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
4576 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4592 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
4577 HValue* argument = Pop(); | 4593 HValue* argument = Pop(); |
| 4594 HValue* context = environment()->LookupContext(); |
4578 Drop(1); // Receiver. | 4595 Drop(1); // Receiver. |
4579 HUnaryMathOperation* op = new(zone()) HUnaryMathOperation(argument, id); | 4596 HUnaryMathOperation* op = |
| 4597 new(zone()) HUnaryMathOperation(context, argument, id); |
4580 op->set_position(expr->position()); | 4598 op->set_position(expr->position()); |
4581 ast_context()->ReturnInstruction(op, expr->id()); | 4599 ast_context()->ReturnInstruction(op, expr->id()); |
4582 return true; | 4600 return true; |
4583 } | 4601 } |
4584 break; | 4602 break; |
4585 case kMathPow: | 4603 case kMathPow: |
4586 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 4604 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
4587 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4605 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
4588 HValue* right = Pop(); | 4606 HValue* right = Pop(); |
4589 HValue* left = Pop(); | 4607 HValue* left = Pop(); |
4590 Pop(); // Pop receiver. | 4608 Pop(); // Pop receiver. |
| 4609 HValue* context = environment()->LookupContext(); |
4591 HInstruction* result = NULL; | 4610 HInstruction* result = NULL; |
4592 // Use sqrt() if exponent is 0.5 or -0.5. | 4611 // Use sqrt() if exponent is 0.5 or -0.5. |
4593 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 4612 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
4594 double exponent = HConstant::cast(right)->DoubleValue(); | 4613 double exponent = HConstant::cast(right)->DoubleValue(); |
4595 if (exponent == 0.5) { | 4614 if (exponent == 0.5) { |
4596 result = new(zone()) HUnaryMathOperation(left, kMathPowHalf); | 4615 result = |
| 4616 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
4597 } else if (exponent == -0.5) { | 4617 } else if (exponent == -0.5) { |
4598 HConstant* double_one = | 4618 HConstant* double_one = |
4599 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 4619 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
4600 Representation::Double()); | 4620 Representation::Double()); |
4601 AddInstruction(double_one); | 4621 AddInstruction(double_one); |
4602 HUnaryMathOperation* square_root = | 4622 HUnaryMathOperation* square_root = |
4603 new(zone()) HUnaryMathOperation(left, kMathPowHalf); | 4623 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
4604 AddInstruction(square_root); | 4624 AddInstruction(square_root); |
4605 // MathPowHalf doesn't have side effects so there's no need for | 4625 // MathPowHalf doesn't have side effects so there's no need for |
4606 // an environment simulation here. | 4626 // an environment simulation here. |
4607 ASSERT(!square_root->HasSideEffects()); | 4627 ASSERT(!square_root->HasSideEffects()); |
4608 result = new(zone()) HDiv(double_one, square_root); | 4628 result = new(zone()) HDiv(context, double_one, square_root); |
4609 } else if (exponent == 2.0) { | 4629 } else if (exponent == 2.0) { |
4610 result = new(zone()) HMul(left, left); | 4630 result = new(zone()) HMul(context, left, left); |
4611 } | 4631 } |
4612 } else if (right->IsConstant() && | 4632 } else if (right->IsConstant() && |
4613 HConstant::cast(right)->HasInteger32Value() && | 4633 HConstant::cast(right)->HasInteger32Value() && |
4614 HConstant::cast(right)->Integer32Value() == 2) { | 4634 HConstant::cast(right)->Integer32Value() == 2) { |
4615 result = new(zone()) HMul(left, left); | 4635 result = new(zone()) HMul(context, left, left); |
4616 } | 4636 } |
4617 | 4637 |
4618 if (result == NULL) { | 4638 if (result == NULL) { |
4619 result = new(zone()) HPower(left, right); | 4639 result = new(zone()) HPower(left, right); |
4620 } | 4640 } |
4621 ast_context()->ReturnInstruction(result, expr->id()); | 4641 ast_context()->ReturnInstruction(result, expr->id()); |
4622 return true; | 4642 return true; |
4623 } | 4643 } |
4624 break; | 4644 break; |
4625 default: | 4645 default: |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 ASSERT(static_cast<size_t>(lookup_index) < | 4911 ASSERT(static_cast<size_t>(lookup_index) < |
4892 ARRAY_SIZE(kInlineFunctionGenerators)); | 4912 ARRAY_SIZE(kInlineFunctionGenerators)); |
4893 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 4913 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
4894 | 4914 |
4895 // Call the inline code generator using the pointer-to-member. | 4915 // Call the inline code generator using the pointer-to-member. |
4896 (this->*generator)(expr); | 4916 (this->*generator)(expr); |
4897 } else { | 4917 } else { |
4898 ASSERT(function->intrinsic_type == Runtime::RUNTIME); | 4918 ASSERT(function->intrinsic_type == Runtime::RUNTIME); |
4899 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 4919 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
4900 | 4920 |
| 4921 HValue* context = environment()->LookupContext(); |
4901 Handle<String> name = expr->name(); | 4922 Handle<String> name = expr->name(); |
4902 int argument_count = expr->arguments()->length(); | 4923 int argument_count = expr->arguments()->length(); |
4903 HCallRuntime* call = | 4924 HCallRuntime* call = |
4904 new(zone()) HCallRuntime(name, function, argument_count); | 4925 new(zone()) HCallRuntime(context, name, function, argument_count); |
4905 call->set_position(RelocInfo::kNoPosition); | 4926 call->set_position(RelocInfo::kNoPosition); |
4906 Drop(argument_count); | 4927 Drop(argument_count); |
4907 ast_context()->ReturnInstruction(call, expr->id()); | 4928 ast_context()->ReturnInstruction(call, expr->id()); |
4908 } | 4929 } |
4909 } | 4930 } |
4910 | 4931 |
4911 | 4932 |
4912 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 4933 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
4913 ASSERT(!HasStackOverflow()); | 4934 ASSERT(!HasStackOverflow()); |
4914 ASSERT(current_block() != NULL); | 4935 ASSERT(current_block() != NULL); |
(...skipping 28 matching lines...) Expand all Loading... |
4943 } else if (prop != NULL) { | 4964 } else if (prop != NULL) { |
4944 if (prop->is_synthetic()) { | 4965 if (prop->is_synthetic()) { |
4945 // Result of deleting parameters is false, even when they rewrite | 4966 // Result of deleting parameters is false, even when they rewrite |
4946 // to accesses on the arguments object. | 4967 // to accesses on the arguments object. |
4947 ast_context()->ReturnValue(graph()->GetConstantFalse()); | 4968 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
4948 } else { | 4969 } else { |
4949 CHECK_ALIVE(VisitForValue(prop->obj())); | 4970 CHECK_ALIVE(VisitForValue(prop->obj())); |
4950 CHECK_ALIVE(VisitForValue(prop->key())); | 4971 CHECK_ALIVE(VisitForValue(prop->key())); |
4951 HValue* key = Pop(); | 4972 HValue* key = Pop(); |
4952 HValue* obj = Pop(); | 4973 HValue* obj = Pop(); |
4953 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); | 4974 HValue* context = environment()->LookupContext(); |
| 4975 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); |
4954 ast_context()->ReturnInstruction(instr, expr->id()); | 4976 ast_context()->ReturnInstruction(instr, expr->id()); |
4955 } | 4977 } |
4956 } else if (var->is_global()) { | 4978 } else if (var->is_global()) { |
4957 Bailout("delete with global variable"); | 4979 Bailout("delete with global variable"); |
4958 } else { | 4980 } else { |
4959 Bailout("delete with non-global variable"); | 4981 Bailout("delete with non-global variable"); |
4960 } | 4982 } |
4961 } | 4983 } |
4962 | 4984 |
4963 | 4985 |
4964 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { | 4986 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { |
4965 CHECK_ALIVE(VisitForEffect(expr->expression())); | 4987 CHECK_ALIVE(VisitForEffect(expr->expression())); |
4966 ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 4988 ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
4967 } | 4989 } |
4968 | 4990 |
4969 | 4991 |
4970 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 4992 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
4971 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 4993 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
4972 HValue* value = Pop(); | 4994 HValue* value = Pop(); |
4973 ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id()); | 4995 HValue* context = environment()->LookupContext(); |
| 4996 HInstruction* instr = new(zone()) HTypeof(context, value); |
| 4997 ast_context()->ReturnInstruction(instr, expr->id()); |
4974 } | 4998 } |
4975 | 4999 |
4976 | 5000 |
4977 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { | 5001 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { |
4978 CHECK_ALIVE(VisitForValue(expr->expression())); | 5002 CHECK_ALIVE(VisitForValue(expr->expression())); |
4979 HValue* value = Pop(); | 5003 HValue* value = Pop(); |
4980 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1()); | 5004 HValue* context = environment()->LookupContext(); |
| 5005 HInstruction* instr = |
| 5006 new(zone()) HMul(context, value, graph_->GetConstant1()); |
4981 ast_context()->ReturnInstruction(instr, expr->id()); | 5007 ast_context()->ReturnInstruction(instr, expr->id()); |
4982 } | 5008 } |
4983 | 5009 |
4984 | 5010 |
4985 void HGraphBuilder::VisitSub(UnaryOperation* expr) { | 5011 void HGraphBuilder::VisitSub(UnaryOperation* expr) { |
4986 CHECK_ALIVE(VisitForValue(expr->expression())); | 5012 CHECK_ALIVE(VisitForValue(expr->expression())); |
4987 HValue* value = Pop(); | 5013 HValue* value = Pop(); |
4988 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); | 5014 HValue* context = environment()->LookupContext(); |
| 5015 HInstruction* instr = |
| 5016 new(zone()) HMul(context, value, graph_->GetConstantMinus1()); |
4989 TypeInfo info = oracle()->UnaryType(expr); | 5017 TypeInfo info = oracle()->UnaryType(expr); |
4990 if (info.IsUninitialized()) { | 5018 if (info.IsUninitialized()) { |
4991 AddInstruction(new(zone()) HSoftDeoptimize); | 5019 AddInstruction(new(zone()) HSoftDeoptimize); |
4992 current_block()->MarkAsDeoptimizing(); | 5020 current_block()->MarkAsDeoptimizing(); |
4993 info = TypeInfo::Unknown(); | 5021 info = TypeInfo::Unknown(); |
4994 } | 5022 } |
4995 Representation rep = ToRepresentation(info); | 5023 Representation rep = ToRepresentation(info); |
4996 TraceRepresentation(expr->op(), info, instr, rep); | 5024 TraceRepresentation(expr->op(), info, instr, rep); |
4997 instr->AssumeRepresentation(rep); | 5025 instr->AssumeRepresentation(rep); |
4998 ast_context()->ReturnInstruction(instr, expr->id()); | 5026 ast_context()->ReturnInstruction(instr, expr->id()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5075 AddInstruction(number_input); | 5103 AddInstruction(number_input); |
5076 Push(number_input); | 5104 Push(number_input); |
5077 } | 5105 } |
5078 | 5106 |
5079 // The addition has no side effects, so we do not need | 5107 // The addition has no side effects, so we do not need |
5080 // to simulate the expression stack after this instruction. | 5108 // to simulate the expression stack after this instruction. |
5081 // Any later failures deopt to the load of the input or earlier. | 5109 // Any later failures deopt to the load of the input or earlier. |
5082 HConstant* delta = (expr->op() == Token::INC) | 5110 HConstant* delta = (expr->op() == Token::INC) |
5083 ? graph_->GetConstant1() | 5111 ? graph_->GetConstant1() |
5084 : graph_->GetConstantMinus1(); | 5112 : graph_->GetConstantMinus1(); |
5085 HInstruction* instr = new(zone()) HAdd(Top(), delta); | 5113 HValue* context = environment()->LookupContext(); |
| 5114 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); |
5086 TraceRepresentation(expr->op(), info, instr, rep); | 5115 TraceRepresentation(expr->op(), info, instr, rep); |
5087 instr->AssumeRepresentation(rep); | 5116 instr->AssumeRepresentation(rep); |
5088 AddInstruction(instr); | 5117 AddInstruction(instr); |
5089 return instr; | 5118 return instr; |
5090 } | 5119 } |
5091 | 5120 |
5092 | 5121 |
5093 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { | 5122 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
5094 ASSERT(!HasStackOverflow()); | 5123 ASSERT(!HasStackOverflow()); |
5095 ASSERT(current_block() != NULL); | 5124 ASSERT(current_block() != NULL); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5225 ASSERT(has_side_effects); // Stores always have side effects. | 5254 ASSERT(has_side_effects); // Stores always have side effects. |
5226 AddSimulate(expr->AssignmentId()); | 5255 AddSimulate(expr->AssignmentId()); |
5227 } | 5256 } |
5228 } | 5257 } |
5229 | 5258 |
5230 Drop(returns_original_input ? 2 : 1); | 5259 Drop(returns_original_input ? 2 : 1); |
5231 ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 5260 ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
5232 } | 5261 } |
5233 | 5262 |
5234 | 5263 |
5235 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, | 5264 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
| 5265 HValue* string, |
5236 HValue* index) { | 5266 HValue* index) { |
5237 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5267 AddInstruction(new(zone()) HCheckNonSmi(string)); |
5238 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5268 AddInstruction(HCheckInstanceType::NewIsString(string)); |
5239 HStringLength* length = new(zone()) HStringLength(string); | 5269 HStringLength* length = new(zone()) HStringLength(string); |
5240 AddInstruction(length); | 5270 AddInstruction(length); |
5241 HInstruction* checked_index = | 5271 HInstruction* checked_index = |
5242 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 5272 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
5243 return new(zone()) HStringCharCodeAt(string, checked_index); | 5273 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
5244 } | 5274 } |
5245 | 5275 |
5246 | 5276 |
5247 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 5277 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
5248 HValue* left, | 5278 HValue* left, |
5249 HValue* right) { | 5279 HValue* right) { |
| 5280 HValue* context = environment()->LookupContext(); |
5250 TypeInfo info = oracle()->BinaryType(expr); | 5281 TypeInfo info = oracle()->BinaryType(expr); |
5251 if (info.IsUninitialized()) { | 5282 if (info.IsUninitialized()) { |
5252 AddInstruction(new(zone()) HSoftDeoptimize); | 5283 AddInstruction(new(zone()) HSoftDeoptimize); |
5253 current_block()->MarkAsDeoptimizing(); | 5284 current_block()->MarkAsDeoptimizing(); |
5254 info = TypeInfo::Unknown(); | 5285 info = TypeInfo::Unknown(); |
5255 } | 5286 } |
5256 HInstruction* instr = NULL; | 5287 HInstruction* instr = NULL; |
5257 switch (expr->op()) { | 5288 switch (expr->op()) { |
5258 case Token::ADD: | 5289 case Token::ADD: |
5259 if (info.IsString()) { | 5290 if (info.IsString()) { |
5260 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5291 AddInstruction(new(zone()) HCheckNonSmi(left)); |
5261 AddInstruction(HCheckInstanceType::NewIsString(left)); | 5292 AddInstruction(HCheckInstanceType::NewIsString(left)); |
5262 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5293 AddInstruction(new(zone()) HCheckNonSmi(right)); |
5263 AddInstruction(HCheckInstanceType::NewIsString(right)); | 5294 AddInstruction(HCheckInstanceType::NewIsString(right)); |
5264 instr = new(zone()) HStringAdd(left, right); | 5295 instr = new(zone()) HStringAdd(context, left, right); |
5265 } else { | 5296 } else { |
5266 instr = new(zone()) HAdd(left, right); | 5297 instr = new(zone()) HAdd(context, left, right); |
5267 } | 5298 } |
5268 break; | 5299 break; |
5269 case Token::SUB: | 5300 case Token::SUB: |
5270 instr = new(zone()) HSub(left, right); | 5301 instr = new(zone()) HSub(context, left, right); |
5271 break; | 5302 break; |
5272 case Token::MUL: | 5303 case Token::MUL: |
5273 instr = new(zone()) HMul(left, right); | 5304 instr = new(zone()) HMul(context, left, right); |
5274 break; | 5305 break; |
5275 case Token::MOD: | 5306 case Token::MOD: |
5276 instr = new(zone()) HMod(left, right); | 5307 instr = new(zone()) HMod(context, left, right); |
5277 break; | 5308 break; |
5278 case Token::DIV: | 5309 case Token::DIV: |
5279 instr = new(zone()) HDiv(left, right); | 5310 instr = new(zone()) HDiv(context, left, right); |
5280 break; | 5311 break; |
5281 case Token::BIT_XOR: | 5312 case Token::BIT_XOR: |
5282 instr = new(zone()) HBitXor(left, right); | 5313 instr = new(zone()) HBitXor(context, left, right); |
5283 break; | 5314 break; |
5284 case Token::BIT_AND: | 5315 case Token::BIT_AND: |
5285 instr = new(zone()) HBitAnd(left, right); | 5316 instr = new(zone()) HBitAnd(context, left, right); |
5286 break; | 5317 break; |
5287 case Token::BIT_OR: | 5318 case Token::BIT_OR: |
5288 instr = new(zone()) HBitOr(left, right); | 5319 instr = new(zone()) HBitOr(context, left, right); |
5289 break; | 5320 break; |
5290 case Token::SAR: | 5321 case Token::SAR: |
5291 instr = new(zone()) HSar(left, right); | 5322 instr = new(zone()) HSar(context, left, right); |
5292 break; | 5323 break; |
5293 case Token::SHR: | 5324 case Token::SHR: |
5294 instr = new(zone()) HShr(left, right); | 5325 instr = new(zone()) HShr(context, left, right); |
5295 break; | 5326 break; |
5296 case Token::SHL: | 5327 case Token::SHL: |
5297 instr = new(zone()) HShl(left, right); | 5328 instr = new(zone()) HShl(context, left, right); |
5298 break; | 5329 break; |
5299 default: | 5330 default: |
5300 UNREACHABLE(); | 5331 UNREACHABLE(); |
5301 } | 5332 } |
5302 | 5333 |
5303 // If we hit an uninitialized binary op stub we will get type info | 5334 // If we hit an uninitialized binary op stub we will get type info |
5304 // for a smi operation. If one of the operands is a constant string | 5335 // for a smi operation. If one of the operands is a constant string |
5305 // do not generate code assuming it is a smi operation. | 5336 // do not generate code assuming it is a smi operation. |
5306 if (info.IsSmi() && | 5337 if (info.IsSmi() && |
5307 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || | 5338 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5574 // If the function is in new space we assume it's more likely to | 5605 // If the function is in new space we assume it's more likely to |
5575 // change and thus prefer the general IC code. | 5606 // change and thus prefer the general IC code. |
5576 if (!isolate()->heap()->InNewSpace(*candidate)) { | 5607 if (!isolate()->heap()->InNewSpace(*candidate)) { |
5577 target = candidate; | 5608 target = candidate; |
5578 } | 5609 } |
5579 } | 5610 } |
5580 } | 5611 } |
5581 | 5612 |
5582 // If the target is not null we have found a known global function that is | 5613 // If the target is not null we have found a known global function that is |
5583 // assumed to stay the same for this instanceof. | 5614 // assumed to stay the same for this instanceof. |
| 5615 HValue* context = environment()->LookupContext(); |
5584 if (target.is_null()) { | 5616 if (target.is_null()) { |
5585 HValue* context = environment()->LookupContext(); | |
5586 instr = new(zone()) HInstanceOf(context, left, right); | 5617 instr = new(zone()) HInstanceOf(context, left, right); |
5587 } else { | 5618 } else { |
5588 AddInstruction(new(zone()) HCheckFunction(right, target)); | 5619 AddInstruction(new(zone()) HCheckFunction(right, target)); |
5589 instr = new(zone()) HInstanceOfKnownGlobal(left, target); | 5620 instr = new(zone()) HInstanceOfKnownGlobal(context, left, target); |
5590 } | 5621 } |
5591 } else if (op == Token::IN) { | 5622 } else if (op == Token::IN) { |
5592 instr = new(zone()) HIn(left, right); | 5623 instr = new(zone()) HIn(left, right); |
5593 } else if (type_info.IsNonPrimitive()) { | 5624 } else if (type_info.IsNonPrimitive()) { |
5594 switch (op) { | 5625 switch (op) { |
5595 case Token::EQ: | 5626 case Token::EQ: |
5596 case Token::EQ_STRICT: { | 5627 case Token::EQ_STRICT: { |
5597 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5628 AddInstruction(new(zone()) HCheckNonSmi(left)); |
5598 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 5629 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); |
5599 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5630 AddInstruction(new(zone()) HCheckNonSmi(right)); |
5600 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 5631 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); |
5601 instr = new(zone()) HCompareObjectEq(left, right); | 5632 instr = new(zone()) HCompareObjectEq(left, right); |
5602 break; | 5633 break; |
5603 } | 5634 } |
5604 default: | 5635 default: |
5605 return Bailout("Unsupported non-primitive compare"); | 5636 return Bailout("Unsupported non-primitive compare"); |
5606 break; | 5637 break; |
5607 } | 5638 } |
5608 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 5639 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
5609 (op == Token::EQ || op == Token::EQ_STRICT)) { | 5640 (op == Token::EQ || op == Token::EQ_STRICT)) { |
5610 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5641 AddInstruction(new(zone()) HCheckNonSmi(left)); |
5611 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 5642 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); |
5612 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5643 AddInstruction(new(zone()) HCheckNonSmi(right)); |
5613 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 5644 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); |
5614 instr = new(zone()) HCompareObjectEq(left, right); | 5645 instr = new(zone()) HCompareObjectEq(left, right); |
5615 } else { | 5646 } else { |
5616 HCompare* compare = new(zone()) HCompare(left, right, op); | 5647 HValue* context = environment()->LookupContext(); |
| 5648 HCompare* compare = new(zone()) HCompare(context, left, right, op); |
5617 Representation r = ToRepresentation(type_info); | 5649 Representation r = ToRepresentation(type_info); |
5618 compare->SetInputRepresentation(r); | 5650 compare->SetInputRepresentation(r); |
5619 instr = compare; | 5651 instr = compare; |
5620 } | 5652 } |
5621 instr->set_position(expr->position()); | 5653 instr->set_position(expr->position()); |
5622 ast_context()->ReturnInstruction(instr, expr->id()); | 5654 ast_context()->ReturnInstruction(instr, expr->id()); |
5623 } | 5655 } |
5624 | 5656 |
5625 | 5657 |
5626 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { | 5658 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5814 } | 5846 } |
5815 | 5847 |
5816 | 5848 |
5817 // Fast support for charCodeAt(n). | 5849 // Fast support for charCodeAt(n). |
5818 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 5850 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
5819 ASSERT(call->arguments()->length() == 2); | 5851 ASSERT(call->arguments()->length() == 2); |
5820 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5852 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5821 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5853 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
5822 HValue* index = Pop(); | 5854 HValue* index = Pop(); |
5823 HValue* string = Pop(); | 5855 HValue* string = Pop(); |
5824 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); | 5856 HValue* context = environment()->LookupContext(); |
| 5857 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); |
5825 ast_context()->ReturnInstruction(result, call->id()); | 5858 ast_context()->ReturnInstruction(result, call->id()); |
5826 } | 5859 } |
5827 | 5860 |
5828 | 5861 |
5829 // Fast support for string.charAt(n) and string[n]. | 5862 // Fast support for string.charAt(n) and string[n]. |
5830 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 5863 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
5831 ASSERT(call->arguments()->length() == 1); | 5864 ASSERT(call->arguments()->length() == 1); |
5832 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5865 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5833 HValue* char_code = Pop(); | 5866 HValue* char_code = Pop(); |
5834 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); | 5867 HValue* context = environment()->LookupContext(); |
| 5868 HStringCharFromCode* result = |
| 5869 new(zone()) HStringCharFromCode(context, char_code); |
5835 ast_context()->ReturnInstruction(result, call->id()); | 5870 ast_context()->ReturnInstruction(result, call->id()); |
5836 } | 5871 } |
5837 | 5872 |
5838 | 5873 |
5839 // Fast support for string.charAt(n) and string[n]. | 5874 // Fast support for string.charAt(n) and string[n]. |
5840 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 5875 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
5841 ASSERT(call->arguments()->length() == 2); | 5876 ASSERT(call->arguments()->length() == 2); |
5842 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5877 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5843 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5878 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
5844 HValue* index = Pop(); | 5879 HValue* index = Pop(); |
5845 HValue* string = Pop(); | 5880 HValue* string = Pop(); |
5846 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 5881 HValue* context = environment()->LookupContext(); |
| 5882 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); |
5847 AddInstruction(char_code); | 5883 AddInstruction(char_code); |
5848 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); | 5884 HStringCharFromCode* result = |
| 5885 new(zone()) HStringCharFromCode(context, char_code); |
5849 ast_context()->ReturnInstruction(result, call->id()); | 5886 ast_context()->ReturnInstruction(result, call->id()); |
5850 } | 5887 } |
5851 | 5888 |
5852 | 5889 |
5853 // Fast support for object equality testing. | 5890 // Fast support for object equality testing. |
5854 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 5891 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
5855 ASSERT(call->arguments()->length() == 2); | 5892 ASSERT(call->arguments()->length() == 2); |
5856 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5893 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5857 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5894 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
5858 HValue* right = Pop(); | 5895 HValue* right = Pop(); |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6573 } | 6610 } |
6574 } | 6611 } |
6575 | 6612 |
6576 #ifdef DEBUG | 6613 #ifdef DEBUG |
6577 if (graph_ != NULL) graph_->Verify(); | 6614 if (graph_ != NULL) graph_->Verify(); |
6578 if (allocator_ != NULL) allocator_->Verify(); | 6615 if (allocator_ != NULL) allocator_->Verify(); |
6579 #endif | 6616 #endif |
6580 } | 6617 } |
6581 | 6618 |
6582 } } // namespace v8::internal | 6619 } } // namespace v8::internal |
OLD | NEW |