| 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 2239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 HPhase phase("Block building"); | 2250 HPhase phase("Block building"); |
| 2251 current_block_ = graph()->entry_block(); | 2251 current_block_ = graph()->entry_block(); |
| 2252 | 2252 |
| 2253 Scope* scope = info()->scope(); | 2253 Scope* scope = info()->scope(); |
| 2254 if (scope->HasIllegalRedeclaration()) { | 2254 if (scope->HasIllegalRedeclaration()) { |
| 2255 Bailout("function with illegal redeclaration"); | 2255 Bailout("function with illegal redeclaration"); |
| 2256 return NULL; | 2256 return NULL; |
| 2257 } | 2257 } |
| 2258 SetupScope(scope); | 2258 SetupScope(scope); |
| 2259 VisitDeclarations(scope->declarations()); | 2259 VisitDeclarations(scope->declarations()); |
| 2260 AddInstruction(new(zone()) HStackCheck(HStackCheck::kFunctionEntry)); | 2260 HValue* context = environment()->LookupContext(); |
| 2261 AddInstruction( |
| 2262 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
| 2261 | 2263 |
| 2262 // Add an edge to the body entry. This is warty: the graph's start | 2264 // Add an edge to the body entry. This is warty: the graph's start |
| 2263 // environment will be used by the Lithium translation as the initial | 2265 // environment will be used by the Lithium translation as the initial |
| 2264 // environment on graph entry, but it has now been mutated by the | 2266 // environment on graph entry, but it has now been mutated by the |
| 2265 // Hydrogen translation of the instructions in the start block. This | 2267 // Hydrogen translation of the instructions in the start block. This |
| 2266 // environment uses values which have not been defined yet. These | 2268 // environment uses values which have not been defined yet. These |
| 2267 // Hydrogen instructions will then be replayed by the Lithium | 2269 // Hydrogen instructions will then be replayed by the Lithium |
| 2268 // translation, so they cannot have an environment effect. The edge to | 2270 // translation, so they cannot have an environment effect. The edge to |
| 2269 // the body's entry block (along with some special logic for the start | 2271 // the body's entry block (along with some special logic for the start |
| 2270 // block in HInstruction::InsertAfter) seals the start block from | 2272 // block in HInstruction::InsertAfter) seals the start block from |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2784 current_block()->Goto(loop_predecessor); | 2786 current_block()->Goto(loop_predecessor); |
| 2785 loop_predecessor->SetJoinId(statement->EntryId()); | 2787 loop_predecessor->SetJoinId(statement->EntryId()); |
| 2786 set_current_block(loop_predecessor); | 2788 set_current_block(loop_predecessor); |
| 2787 } | 2789 } |
| 2788 | 2790 |
| 2789 | 2791 |
| 2790 void HGraphBuilder::VisitLoopBody(Statement* body, | 2792 void HGraphBuilder::VisitLoopBody(Statement* body, |
| 2791 HBasicBlock* loop_entry, | 2793 HBasicBlock* loop_entry, |
| 2792 BreakAndContinueInfo* break_info) { | 2794 BreakAndContinueInfo* break_info) { |
| 2793 BreakAndContinueScope push(break_info, this); | 2795 BreakAndContinueScope push(break_info, this); |
| 2796 HValue* context = environment()->LookupContext(); |
| 2794 HStackCheck* stack_check = | 2797 HStackCheck* stack_check = |
| 2795 new(zone()) HStackCheck(HStackCheck::kBackwardsBranch); | 2798 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
| 2796 AddInstruction(stack_check); | 2799 AddInstruction(stack_check); |
| 2797 ASSERT(loop_entry->IsLoopHeader()); | 2800 ASSERT(loop_entry->IsLoopHeader()); |
| 2798 loop_entry->loop_information()->set_stack_check(stack_check); | 2801 loop_entry->loop_information()->set_stack_check(stack_check); |
| 2799 CHECK_BAILOUT(Visit(body)); | 2802 CHECK_BAILOUT(Visit(body)); |
| 2800 } | 2803 } |
| 2801 | 2804 |
| 2802 | 2805 |
| 2803 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2806 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 2804 ASSERT(!HasStackOverflow()); | 2807 ASSERT(!HasStackOverflow()); |
| 2805 ASSERT(current_block() != NULL); | 2808 ASSERT(current_block() != NULL); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2994 ASSERT(current_block() != NULL); | 2997 ASSERT(current_block() != NULL); |
| 2995 ASSERT(current_block()->HasPredecessor()); | 2998 ASSERT(current_block()->HasPredecessor()); |
| 2996 Handle<SharedFunctionInfo> shared_info = | 2999 Handle<SharedFunctionInfo> shared_info = |
| 2997 SearchSharedFunctionInfo(info()->shared_info()->code(), | 3000 SearchSharedFunctionInfo(info()->shared_info()->code(), |
| 2998 expr); | 3001 expr); |
| 2999 if (shared_info.is_null()) { | 3002 if (shared_info.is_null()) { |
| 3000 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 3003 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); |
| 3001 } | 3004 } |
| 3002 // We also have a stack overflow if the recursive compilation did. | 3005 // We also have a stack overflow if the recursive compilation did. |
| 3003 if (HasStackOverflow()) return; | 3006 if (HasStackOverflow()) return; |
| 3007 HValue* context = environment()->LookupContext(); |
| 3004 HFunctionLiteral* instr = | 3008 HFunctionLiteral* instr = |
| 3005 new(zone()) HFunctionLiteral(shared_info, expr->pretenure()); | 3009 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
| 3006 return ast_context()->ReturnInstruction(instr, expr->id()); | 3010 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 3007 } | 3011 } |
| 3008 | 3012 |
| 3009 | 3013 |
| 3010 void HGraphBuilder::VisitSharedFunctionInfoLiteral( | 3014 void HGraphBuilder::VisitSharedFunctionInfoLiteral( |
| 3011 SharedFunctionInfoLiteral* expr) { | 3015 SharedFunctionInfoLiteral* expr) { |
| 3012 ASSERT(!HasStackOverflow()); | 3016 ASSERT(!HasStackOverflow()); |
| 3013 ASSERT(current_block() != NULL); | 3017 ASSERT(current_block() != NULL); |
| 3014 ASSERT(current_block()->HasPredecessor()); | 3018 ASSERT(current_block()->HasPredecessor()); |
| 3015 return Bailout("SharedFunctionInfoLiteral"); | 3019 return Bailout("SharedFunctionInfoLiteral"); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3148 HConstant* instr = | 3152 HConstant* instr = |
| 3149 new(zone()) HConstant(expr->handle(), Representation::Tagged()); | 3153 new(zone()) HConstant(expr->handle(), Representation::Tagged()); |
| 3150 return ast_context()->ReturnInstruction(instr, expr->id()); | 3154 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 3151 } | 3155 } |
| 3152 | 3156 |
| 3153 | 3157 |
| 3154 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 3158 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 3155 ASSERT(!HasStackOverflow()); | 3159 ASSERT(!HasStackOverflow()); |
| 3156 ASSERT(current_block() != NULL); | 3160 ASSERT(current_block() != NULL); |
| 3157 ASSERT(current_block()->HasPredecessor()); | 3161 ASSERT(current_block()->HasPredecessor()); |
| 3158 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(), | 3162 HValue* context = environment()->LookupContext(); |
| 3163 |
| 3164 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
| 3165 expr->pattern(), |
| 3159 expr->flags(), | 3166 expr->flags(), |
| 3160 expr->literal_index()); | 3167 expr->literal_index()); |
| 3161 return ast_context()->ReturnInstruction(instr, expr->id()); | 3168 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 3162 } | 3169 } |
| 3163 | 3170 |
| 3164 | 3171 |
| 3165 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 3172 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 3166 ASSERT(!HasStackOverflow()); | 3173 ASSERT(!HasStackOverflow()); |
| 3167 ASSERT(current_block() != NULL); | 3174 ASSERT(current_block() != NULL); |
| 3168 ASSERT(current_block()->HasPredecessor()); | 3175 ASSERT(current_block()->HasPredecessor()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3234 } | 3241 } |
| 3235 } | 3242 } |
| 3236 | 3243 |
| 3237 | 3244 |
| 3238 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 3245 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| 3239 ASSERT(!HasStackOverflow()); | 3246 ASSERT(!HasStackOverflow()); |
| 3240 ASSERT(current_block() != NULL); | 3247 ASSERT(current_block() != NULL); |
| 3241 ASSERT(current_block()->HasPredecessor()); | 3248 ASSERT(current_block()->HasPredecessor()); |
| 3242 ZoneList<Expression*>* subexprs = expr->values(); | 3249 ZoneList<Expression*>* subexprs = expr->values(); |
| 3243 int length = subexprs->length(); | 3250 int length = subexprs->length(); |
| 3251 HValue* context = environment()->LookupContext(); |
| 3244 | 3252 |
| 3245 HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(), | 3253 HArrayLiteral* literal = new(zone()) HArrayLiteral(context, |
| 3254 expr->constant_elements(), |
| 3246 length, | 3255 length, |
| 3247 expr->literal_index(), | 3256 expr->literal_index(), |
| 3248 expr->depth()); | 3257 expr->depth()); |
| 3249 // The array is expected in the bailout environment during computation | 3258 // The array is expected in the bailout environment during computation |
| 3250 // of the property values and is the value of the entire expression. | 3259 // of the property values and is the value of the entire expression. |
| 3251 PushAndAdd(literal); | 3260 PushAndAdd(literal); |
| 3252 | 3261 |
| 3253 HLoadElements* elements = NULL; | 3262 HLoadElements* elements = NULL; |
| 3254 | 3263 |
| 3255 for (int i = 0; i < length; i++) { | 3264 for (int i = 0; i < length; i++) { |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3758 void HGraphBuilder::VisitThrow(Throw* expr) { | 3767 void HGraphBuilder::VisitThrow(Throw* expr) { |
| 3759 ASSERT(!HasStackOverflow()); | 3768 ASSERT(!HasStackOverflow()); |
| 3760 ASSERT(current_block() != NULL); | 3769 ASSERT(current_block() != NULL); |
| 3761 ASSERT(current_block()->HasPredecessor()); | 3770 ASSERT(current_block()->HasPredecessor()); |
| 3762 // We don't optimize functions with invalid left-hand sides in | 3771 // We don't optimize functions with invalid left-hand sides in |
| 3763 // assignments, count operations, or for-in. Consequently throw can | 3772 // assignments, count operations, or for-in. Consequently throw can |
| 3764 // currently only occur in an effect context. | 3773 // currently only occur in an effect context. |
| 3765 ASSERT(ast_context()->IsEffect()); | 3774 ASSERT(ast_context()->IsEffect()); |
| 3766 CHECK_ALIVE(VisitForValue(expr->exception())); | 3775 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 3767 | 3776 |
| 3777 HValue* context = environment()->LookupContext(); |
| 3768 HValue* value = environment()->Pop(); | 3778 HValue* value = environment()->Pop(); |
| 3769 HThrow* instr = new(zone()) HThrow(value); | 3779 HThrow* instr = new(zone()) HThrow(context, value); |
| 3770 instr->set_position(expr->position()); | 3780 instr->set_position(expr->position()); |
| 3771 AddInstruction(instr); | 3781 AddInstruction(instr); |
| 3772 AddSimulate(expr->id()); | 3782 AddSimulate(expr->id()); |
| 3773 current_block()->FinishExit(new(zone()) HAbnormalExit); | 3783 current_block()->FinishExit(new(zone()) HAbnormalExit); |
| 3774 set_current_block(NULL); | 3784 set_current_block(NULL); |
| 3775 } | 3785 } |
| 3776 | 3786 |
| 3777 | 3787 |
| 3778 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 3788 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
| 3779 Property* expr, | 3789 Property* expr, |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4175 | 4185 |
| 4176 } else if (expr->IsStringLength()) { | 4186 } else if (expr->IsStringLength()) { |
| 4177 HValue* string = Pop(); | 4187 HValue* string = Pop(); |
| 4178 AddInstruction(new(zone()) HCheckNonSmi(string)); | 4188 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 4179 AddInstruction(HCheckInstanceType::NewIsString(string)); | 4189 AddInstruction(HCheckInstanceType::NewIsString(string)); |
| 4180 instr = new(zone()) HStringLength(string); | 4190 instr = new(zone()) HStringLength(string); |
| 4181 } else if (expr->IsStringAccess()) { | 4191 } else if (expr->IsStringAccess()) { |
| 4182 CHECK_ALIVE(VisitForValue(expr->key())); | 4192 CHECK_ALIVE(VisitForValue(expr->key())); |
| 4183 HValue* index = Pop(); | 4193 HValue* index = Pop(); |
| 4184 HValue* string = Pop(); | 4194 HValue* string = Pop(); |
| 4185 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 4195 HValue* context = environment()->LookupContext(); |
| 4196 HStringCharCodeAt* char_code = |
| 4197 BuildStringCharCodeAt(context, string, index); |
| 4186 AddInstruction(char_code); | 4198 AddInstruction(char_code); |
| 4187 instr = new(zone()) HStringCharFromCode(char_code); | 4199 instr = new(zone()) HStringCharFromCode(context, char_code); |
| 4188 | 4200 |
| 4189 } else if (expr->IsFunctionPrototype()) { | 4201 } else if (expr->IsFunctionPrototype()) { |
| 4190 HValue* function = Pop(); | 4202 HValue* function = Pop(); |
| 4191 AddInstruction(new(zone()) HCheckNonSmi(function)); | 4203 AddInstruction(new(zone()) HCheckNonSmi(function)); |
| 4192 instr = new(zone()) HLoadFunctionPrototype(function); | 4204 instr = new(zone()) HLoadFunctionPrototype(function); |
| 4193 | 4205 |
| 4194 } else if (expr->key()->IsPropertyName()) { | 4206 } else if (expr->key()->IsPropertyName()) { |
| 4195 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 4207 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 4196 ZoneMapList* types = expr->GetReceiverTypes(); | 4208 ZoneMapList* types = expr->GetReceiverTypes(); |
| 4197 | 4209 |
| 4198 HValue* obj = Pop(); | 4210 HValue* obj = Pop(); |
| 4199 if (expr->IsMonomorphic()) { | 4211 if (expr->IsMonomorphic()) { |
| 4200 instr = BuildLoadNamed(obj, expr, types->first(), name); | 4212 instr = BuildLoadNamed(obj, expr, types->first(), name); |
| 4201 } else if (types != NULL && types->length() > 1) { | 4213 } else if (types != NULL && types->length() > 1) { |
| 4202 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 4214 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
| 4203 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); | 4215 HValue* context = environment()->LookupContext(); |
| 4216 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); |
| 4204 } else { | 4217 } else { |
| 4205 instr = BuildLoadNamedGeneric(obj, expr); | 4218 instr = BuildLoadNamedGeneric(obj, expr); |
| 4206 } | 4219 } |
| 4207 | 4220 |
| 4208 } else { | 4221 } else { |
| 4209 CHECK_ALIVE(VisitForValue(expr->key())); | 4222 CHECK_ALIVE(VisitForValue(expr->key())); |
| 4210 | 4223 |
| 4211 HValue* key = Pop(); | 4224 HValue* key = Pop(); |
| 4212 HValue* obj = Pop(); | 4225 HValue* obj = Pop(); |
| 4213 | 4226 |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4597 // Try to inline calls like Math.* as operations in the calling function. | 4610 // Try to inline calls like Math.* as operations in the calling function. |
| 4598 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 4611 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
| 4599 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 4612 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| 4600 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 4613 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 4601 switch (id) { | 4614 switch (id) { |
| 4602 case kStringCharCodeAt: | 4615 case kStringCharCodeAt: |
| 4603 case kStringCharAt: | 4616 case kStringCharAt: |
| 4604 if (argument_count == 2 && check_type == STRING_CHECK) { | 4617 if (argument_count == 2 && check_type == STRING_CHECK) { |
| 4605 HValue* index = Pop(); | 4618 HValue* index = Pop(); |
| 4606 HValue* string = Pop(); | 4619 HValue* string = Pop(); |
| 4620 HValue* context = environment()->LookupContext(); |
| 4607 ASSERT(!expr->holder().is_null()); | 4621 ASSERT(!expr->holder().is_null()); |
| 4608 AddInstruction(new(zone()) HCheckPrototypeMaps( | 4622 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 4609 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), | 4623 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), |
| 4610 expr->holder())); | 4624 expr->holder())); |
| 4611 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 4625 HStringCharCodeAt* char_code = |
| 4626 BuildStringCharCodeAt(context, string, index); |
| 4612 if (id == kStringCharCodeAt) { | 4627 if (id == kStringCharCodeAt) { |
| 4613 ast_context()->ReturnInstruction(char_code, expr->id()); | 4628 ast_context()->ReturnInstruction(char_code, expr->id()); |
| 4614 return true; | 4629 return true; |
| 4615 } | 4630 } |
| 4616 AddInstruction(char_code); | 4631 AddInstruction(char_code); |
| 4617 HStringCharFromCode* result = | 4632 HStringCharFromCode* result = |
| 4618 new(zone()) HStringCharFromCode(char_code); | 4633 new(zone()) HStringCharFromCode(context, char_code); |
| 4619 ast_context()->ReturnInstruction(result, expr->id()); | 4634 ast_context()->ReturnInstruction(result, expr->id()); |
| 4620 return true; | 4635 return true; |
| 4621 } | 4636 } |
| 4622 break; | 4637 break; |
| 4623 case kMathRound: | 4638 case kMathRound: |
| 4624 case kMathFloor: | 4639 case kMathFloor: |
| 4625 case kMathAbs: | 4640 case kMathAbs: |
| 4626 case kMathSqrt: | 4641 case kMathSqrt: |
| 4627 case kMathLog: | 4642 case kMathLog: |
| 4628 case kMathSin: | 4643 case kMathSin: |
| 4629 case kMathCos: | 4644 case kMathCos: |
| 4630 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 4645 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
| 4631 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4646 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
| 4632 HValue* argument = Pop(); | 4647 HValue* argument = Pop(); |
| 4648 HValue* context = environment()->LookupContext(); |
| 4633 Drop(1); // Receiver. | 4649 Drop(1); // Receiver. |
| 4634 HUnaryMathOperation* op = new(zone()) HUnaryMathOperation(argument, id); | 4650 HUnaryMathOperation* op = |
| 4651 new(zone()) HUnaryMathOperation(context, argument, id); |
| 4635 op->set_position(expr->position()); | 4652 op->set_position(expr->position()); |
| 4636 ast_context()->ReturnInstruction(op, expr->id()); | 4653 ast_context()->ReturnInstruction(op, expr->id()); |
| 4637 return true; | 4654 return true; |
| 4638 } | 4655 } |
| 4639 break; | 4656 break; |
| 4640 case kMathPow: | 4657 case kMathPow: |
| 4641 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 4658 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
| 4642 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4659 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
| 4643 HValue* right = Pop(); | 4660 HValue* right = Pop(); |
| 4644 HValue* left = Pop(); | 4661 HValue* left = Pop(); |
| 4645 Pop(); // Pop receiver. | 4662 Pop(); // Pop receiver. |
| 4663 HValue* context = environment()->LookupContext(); |
| 4646 HInstruction* result = NULL; | 4664 HInstruction* result = NULL; |
| 4647 // Use sqrt() if exponent is 0.5 or -0.5. | 4665 // Use sqrt() if exponent is 0.5 or -0.5. |
| 4648 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 4666 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
| 4649 double exponent = HConstant::cast(right)->DoubleValue(); | 4667 double exponent = HConstant::cast(right)->DoubleValue(); |
| 4650 if (exponent == 0.5) { | 4668 if (exponent == 0.5) { |
| 4651 result = new(zone()) HUnaryMathOperation(left, kMathPowHalf); | 4669 result = |
| 4670 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
| 4652 } else if (exponent == -0.5) { | 4671 } else if (exponent == -0.5) { |
| 4653 HConstant* double_one = | 4672 HConstant* double_one = |
| 4654 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 4673 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
| 4655 Representation::Double()); | 4674 Representation::Double()); |
| 4656 AddInstruction(double_one); | 4675 AddInstruction(double_one); |
| 4657 HUnaryMathOperation* square_root = | 4676 HUnaryMathOperation* square_root = |
| 4658 new(zone()) HUnaryMathOperation(left, kMathPowHalf); | 4677 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
| 4659 AddInstruction(square_root); | 4678 AddInstruction(square_root); |
| 4660 // MathPowHalf doesn't have side effects so there's no need for | 4679 // MathPowHalf doesn't have side effects so there's no need for |
| 4661 // an environment simulation here. | 4680 // an environment simulation here. |
| 4662 ASSERT(!square_root->HasSideEffects()); | 4681 ASSERT(!square_root->HasSideEffects()); |
| 4663 result = new(zone()) HDiv(double_one, square_root); | 4682 result = new(zone()) HDiv(context, double_one, square_root); |
| 4664 } else if (exponent == 2.0) { | 4683 } else if (exponent == 2.0) { |
| 4665 result = new(zone()) HMul(left, left); | 4684 result = new(zone()) HMul(context, left, left); |
| 4666 } | 4685 } |
| 4667 } else if (right->IsConstant() && | 4686 } else if (right->IsConstant() && |
| 4668 HConstant::cast(right)->HasInteger32Value() && | 4687 HConstant::cast(right)->HasInteger32Value() && |
| 4669 HConstant::cast(right)->Integer32Value() == 2) { | 4688 HConstant::cast(right)->Integer32Value() == 2) { |
| 4670 result = new(zone()) HMul(left, left); | 4689 result = new(zone()) HMul(context, left, left); |
| 4671 } | 4690 } |
| 4672 | 4691 |
| 4673 if (result == NULL) { | 4692 if (result == NULL) { |
| 4674 result = new(zone()) HPower(left, right); | 4693 result = new(zone()) HPower(left, right); |
| 4675 } | 4694 } |
| 4676 ast_context()->ReturnInstruction(result, expr->id()); | 4695 ast_context()->ReturnInstruction(result, expr->id()); |
| 4677 return true; | 4696 return true; |
| 4678 } | 4697 } |
| 4679 break; | 4698 break; |
| 4680 default: | 4699 default: |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4946 ASSERT(static_cast<size_t>(lookup_index) < | 4965 ASSERT(static_cast<size_t>(lookup_index) < |
| 4947 ARRAY_SIZE(kInlineFunctionGenerators)); | 4966 ARRAY_SIZE(kInlineFunctionGenerators)); |
| 4948 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 4967 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
| 4949 | 4968 |
| 4950 // Call the inline code generator using the pointer-to-member. | 4969 // Call the inline code generator using the pointer-to-member. |
| 4951 (this->*generator)(expr); | 4970 (this->*generator)(expr); |
| 4952 } else { | 4971 } else { |
| 4953 ASSERT(function->intrinsic_type == Runtime::RUNTIME); | 4972 ASSERT(function->intrinsic_type == Runtime::RUNTIME); |
| 4954 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 4973 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 4955 | 4974 |
| 4975 HValue* context = environment()->LookupContext(); |
| 4956 Handle<String> name = expr->name(); | 4976 Handle<String> name = expr->name(); |
| 4957 int argument_count = expr->arguments()->length(); | 4977 int argument_count = expr->arguments()->length(); |
| 4958 HCallRuntime* call = | 4978 HCallRuntime* call = |
| 4959 new(zone()) HCallRuntime(name, function, argument_count); | 4979 new(zone()) HCallRuntime(context, name, function, argument_count); |
| 4960 call->set_position(RelocInfo::kNoPosition); | 4980 call->set_position(RelocInfo::kNoPosition); |
| 4961 Drop(argument_count); | 4981 Drop(argument_count); |
| 4962 return ast_context()->ReturnInstruction(call, expr->id()); | 4982 return ast_context()->ReturnInstruction(call, expr->id()); |
| 4963 } | 4983 } |
| 4964 } | 4984 } |
| 4965 | 4985 |
| 4966 | 4986 |
| 4967 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 4987 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| 4968 ASSERT(!HasStackOverflow()); | 4988 ASSERT(!HasStackOverflow()); |
| 4969 ASSERT(current_block() != NULL); | 4989 ASSERT(current_block() != NULL); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4998 } else if (prop != NULL) { | 5018 } else if (prop != NULL) { |
| 4999 if (prop->is_synthetic()) { | 5019 if (prop->is_synthetic()) { |
| 5000 // Result of deleting parameters is false, even when they rewrite | 5020 // Result of deleting parameters is false, even when they rewrite |
| 5001 // to accesses on the arguments object. | 5021 // to accesses on the arguments object. |
| 5002 return ast_context()->ReturnValue(graph()->GetConstantFalse()); | 5022 return ast_context()->ReturnValue(graph()->GetConstantFalse()); |
| 5003 } else { | 5023 } else { |
| 5004 CHECK_ALIVE(VisitForValue(prop->obj())); | 5024 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5005 CHECK_ALIVE(VisitForValue(prop->key())); | 5025 CHECK_ALIVE(VisitForValue(prop->key())); |
| 5006 HValue* key = Pop(); | 5026 HValue* key = Pop(); |
| 5007 HValue* obj = Pop(); | 5027 HValue* obj = Pop(); |
| 5008 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); | 5028 HValue* context = environment()->LookupContext(); |
| 5029 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); |
| 5009 return ast_context()->ReturnInstruction(instr, expr->id()); | 5030 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5010 } | 5031 } |
| 5011 } else if (var->is_global()) { | 5032 } else if (var->is_global()) { |
| 5012 Bailout("delete with global variable"); | 5033 Bailout("delete with global variable"); |
| 5013 } else { | 5034 } else { |
| 5014 Bailout("delete with non-global variable"); | 5035 Bailout("delete with non-global variable"); |
| 5015 } | 5036 } |
| 5016 } | 5037 } |
| 5017 | 5038 |
| 5018 | 5039 |
| 5019 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { | 5040 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { |
| 5020 CHECK_ALIVE(VisitForEffect(expr->expression())); | 5041 CHECK_ALIVE(VisitForEffect(expr->expression())); |
| 5021 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 5042 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 5022 } | 5043 } |
| 5023 | 5044 |
| 5024 | 5045 |
| 5025 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 5046 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
| 5026 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 5047 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
| 5027 HValue* value = Pop(); | 5048 HValue* value = Pop(); |
| 5028 return ast_context()->ReturnInstruction(new(zone()) HTypeof(value), | 5049 HValue* context = environment()->LookupContext(); |
| 5029 expr->id()); | 5050 HInstruction* instr = new(zone()) HTypeof(context, value); |
| 5051 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5030 } | 5052 } |
| 5031 | 5053 |
| 5032 | 5054 |
| 5033 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { | 5055 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { |
| 5034 CHECK_ALIVE(VisitForValue(expr->expression())); | 5056 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 5035 HValue* value = Pop(); | 5057 HValue* value = Pop(); |
| 5036 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1()); | 5058 HValue* context = environment()->LookupContext(); |
| 5059 HInstruction* instr = |
| 5060 new(zone()) HMul(context, value, graph_->GetConstant1()); |
| 5037 return ast_context()->ReturnInstruction(instr, expr->id()); | 5061 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5038 } | 5062 } |
| 5039 | 5063 |
| 5040 | 5064 |
| 5041 void HGraphBuilder::VisitSub(UnaryOperation* expr) { | 5065 void HGraphBuilder::VisitSub(UnaryOperation* expr) { |
| 5042 CHECK_ALIVE(VisitForValue(expr->expression())); | 5066 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 5043 HValue* value = Pop(); | 5067 HValue* value = Pop(); |
| 5044 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); | 5068 HValue* context = environment()->LookupContext(); |
| 5069 HInstruction* instr = |
| 5070 new(zone()) HMul(context, value, graph_->GetConstantMinus1()); |
| 5045 TypeInfo info = oracle()->UnaryType(expr); | 5071 TypeInfo info = oracle()->UnaryType(expr); |
| 5046 if (info.IsUninitialized()) { | 5072 if (info.IsUninitialized()) { |
| 5047 AddInstruction(new(zone()) HSoftDeoptimize); | 5073 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5048 current_block()->MarkAsDeoptimizing(); | 5074 current_block()->MarkAsDeoptimizing(); |
| 5049 info = TypeInfo::Unknown(); | 5075 info = TypeInfo::Unknown(); |
| 5050 } | 5076 } |
| 5051 Representation rep = ToRepresentation(info); | 5077 Representation rep = ToRepresentation(info); |
| 5052 TraceRepresentation(expr->op(), info, instr, rep); | 5078 TraceRepresentation(expr->op(), info, instr, rep); |
| 5053 instr->AssumeRepresentation(rep); | 5079 instr->AssumeRepresentation(rep); |
| 5054 return ast_context()->ReturnInstruction(instr, expr->id()); | 5080 return ast_context()->ReturnInstruction(instr, expr->id()); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5131 AddInstruction(number_input); | 5157 AddInstruction(number_input); |
| 5132 Push(number_input); | 5158 Push(number_input); |
| 5133 } | 5159 } |
| 5134 | 5160 |
| 5135 // The addition has no side effects, so we do not need | 5161 // The addition has no side effects, so we do not need |
| 5136 // to simulate the expression stack after this instruction. | 5162 // to simulate the expression stack after this instruction. |
| 5137 // Any later failures deopt to the load of the input or earlier. | 5163 // Any later failures deopt to the load of the input or earlier. |
| 5138 HConstant* delta = (expr->op() == Token::INC) | 5164 HConstant* delta = (expr->op() == Token::INC) |
| 5139 ? graph_->GetConstant1() | 5165 ? graph_->GetConstant1() |
| 5140 : graph_->GetConstantMinus1(); | 5166 : graph_->GetConstantMinus1(); |
| 5141 HInstruction* instr = new(zone()) HAdd(Top(), delta); | 5167 HValue* context = environment()->LookupContext(); |
| 5168 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); |
| 5142 TraceRepresentation(expr->op(), info, instr, rep); | 5169 TraceRepresentation(expr->op(), info, instr, rep); |
| 5143 instr->AssumeRepresentation(rep); | 5170 instr->AssumeRepresentation(rep); |
| 5144 AddInstruction(instr); | 5171 AddInstruction(instr); |
| 5145 return instr; | 5172 return instr; |
| 5146 } | 5173 } |
| 5147 | 5174 |
| 5148 | 5175 |
| 5149 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { | 5176 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| 5150 ASSERT(!HasStackOverflow()); | 5177 ASSERT(!HasStackOverflow()); |
| 5151 ASSERT(current_block() != NULL); | 5178 ASSERT(current_block() != NULL); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5281 ASSERT(has_side_effects); // Stores always have side effects. | 5308 ASSERT(has_side_effects); // Stores always have side effects. |
| 5282 AddSimulate(expr->AssignmentId()); | 5309 AddSimulate(expr->AssignmentId()); |
| 5283 } | 5310 } |
| 5284 } | 5311 } |
| 5285 | 5312 |
| 5286 Drop(returns_original_input ? 2 : 1); | 5313 Drop(returns_original_input ? 2 : 1); |
| 5287 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 5314 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
| 5288 } | 5315 } |
| 5289 | 5316 |
| 5290 | 5317 |
| 5291 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, | 5318 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
| 5319 HValue* string, |
| 5292 HValue* index) { | 5320 HValue* index) { |
| 5293 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5321 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 5294 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5322 AddInstruction(HCheckInstanceType::NewIsString(string)); |
| 5295 HStringLength* length = new(zone()) HStringLength(string); | 5323 HStringLength* length = new(zone()) HStringLength(string); |
| 5296 AddInstruction(length); | 5324 AddInstruction(length); |
| 5297 HInstruction* checked_index = | 5325 HInstruction* checked_index = |
| 5298 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 5326 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
| 5299 return new(zone()) HStringCharCodeAt(string, checked_index); | 5327 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 5300 } | 5328 } |
| 5301 | 5329 |
| 5302 | 5330 |
| 5303 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 5331 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
| 5304 HValue* left, | 5332 HValue* left, |
| 5305 HValue* right) { | 5333 HValue* right) { |
| 5334 HValue* context = environment()->LookupContext(); |
| 5306 TypeInfo info = oracle()->BinaryType(expr); | 5335 TypeInfo info = oracle()->BinaryType(expr); |
| 5307 if (info.IsUninitialized()) { | 5336 if (info.IsUninitialized()) { |
| 5308 AddInstruction(new(zone()) HSoftDeoptimize); | 5337 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5309 current_block()->MarkAsDeoptimizing(); | 5338 current_block()->MarkAsDeoptimizing(); |
| 5310 info = TypeInfo::Unknown(); | 5339 info = TypeInfo::Unknown(); |
| 5311 } | 5340 } |
| 5312 HInstruction* instr = NULL; | 5341 HInstruction* instr = NULL; |
| 5313 switch (expr->op()) { | 5342 switch (expr->op()) { |
| 5314 case Token::ADD: | 5343 case Token::ADD: |
| 5315 if (info.IsString()) { | 5344 if (info.IsString()) { |
| 5316 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5345 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 5317 AddInstruction(HCheckInstanceType::NewIsString(left)); | 5346 AddInstruction(HCheckInstanceType::NewIsString(left)); |
| 5318 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5347 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 5319 AddInstruction(HCheckInstanceType::NewIsString(right)); | 5348 AddInstruction(HCheckInstanceType::NewIsString(right)); |
| 5320 instr = new(zone()) HStringAdd(left, right); | 5349 instr = new(zone()) HStringAdd(context, left, right); |
| 5321 } else { | 5350 } else { |
| 5322 instr = new(zone()) HAdd(left, right); | 5351 instr = new(zone()) HAdd(context, left, right); |
| 5323 } | 5352 } |
| 5324 break; | 5353 break; |
| 5325 case Token::SUB: | 5354 case Token::SUB: |
| 5326 instr = new(zone()) HSub(left, right); | 5355 instr = new(zone()) HSub(context, left, right); |
| 5327 break; | 5356 break; |
| 5328 case Token::MUL: | 5357 case Token::MUL: |
| 5329 instr = new(zone()) HMul(left, right); | 5358 instr = new(zone()) HMul(context, left, right); |
| 5330 break; | 5359 break; |
| 5331 case Token::MOD: | 5360 case Token::MOD: |
| 5332 instr = new(zone()) HMod(left, right); | 5361 instr = new(zone()) HMod(context, left, right); |
| 5333 break; | 5362 break; |
| 5334 case Token::DIV: | 5363 case Token::DIV: |
| 5335 instr = new(zone()) HDiv(left, right); | 5364 instr = new(zone()) HDiv(context, left, right); |
| 5336 break; | 5365 break; |
| 5337 case Token::BIT_XOR: | 5366 case Token::BIT_XOR: |
| 5338 instr = new(zone()) HBitXor(left, right); | 5367 instr = new(zone()) HBitXor(context, left, right); |
| 5339 break; | 5368 break; |
| 5340 case Token::BIT_AND: | 5369 case Token::BIT_AND: |
| 5341 instr = new(zone()) HBitAnd(left, right); | 5370 instr = new(zone()) HBitAnd(context, left, right); |
| 5342 break; | 5371 break; |
| 5343 case Token::BIT_OR: | 5372 case Token::BIT_OR: |
| 5344 instr = new(zone()) HBitOr(left, right); | 5373 instr = new(zone()) HBitOr(context, left, right); |
| 5345 break; | 5374 break; |
| 5346 case Token::SAR: | 5375 case Token::SAR: |
| 5347 instr = new(zone()) HSar(left, right); | 5376 instr = new(zone()) HSar(context, left, right); |
| 5348 break; | 5377 break; |
| 5349 case Token::SHR: | 5378 case Token::SHR: |
| 5350 instr = new(zone()) HShr(left, right); | 5379 instr = new(zone()) HShr(context, left, right); |
| 5351 break; | 5380 break; |
| 5352 case Token::SHL: | 5381 case Token::SHL: |
| 5353 instr = new(zone()) HShl(left, right); | 5382 instr = new(zone()) HShl(context, left, right); |
| 5354 break; | 5383 break; |
| 5355 default: | 5384 default: |
| 5356 UNREACHABLE(); | 5385 UNREACHABLE(); |
| 5357 } | 5386 } |
| 5358 | 5387 |
| 5359 // If we hit an uninitialized binary op stub we will get type info | 5388 // If we hit an uninitialized binary op stub we will get type info |
| 5360 // for a smi operation. If one of the operands is a constant string | 5389 // for a smi operation. If one of the operands is a constant string |
| 5361 // do not generate code assuming it is a smi operation. | 5390 // do not generate code assuming it is a smi operation. |
| 5362 if (info.IsSmi() && | 5391 if (info.IsSmi() && |
| 5363 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || | 5392 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5598 // Check if this expression was ever executed according to type feedback. | 5627 // Check if this expression was ever executed according to type feedback. |
| 5599 if (type_info.IsUninitialized()) { | 5628 if (type_info.IsUninitialized()) { |
| 5600 AddInstruction(new(zone()) HSoftDeoptimize); | 5629 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5601 current_block()->MarkAsDeoptimizing(); | 5630 current_block()->MarkAsDeoptimizing(); |
| 5602 type_info = TypeInfo::Unknown(); | 5631 type_info = TypeInfo::Unknown(); |
| 5603 } | 5632 } |
| 5604 | 5633 |
| 5605 CHECK_ALIVE(VisitForValue(expr->left())); | 5634 CHECK_ALIVE(VisitForValue(expr->left())); |
| 5606 CHECK_ALIVE(VisitForValue(expr->right())); | 5635 CHECK_ALIVE(VisitForValue(expr->right())); |
| 5607 | 5636 |
| 5637 HValue* context = environment()->LookupContext(); |
| 5608 HValue* right = Pop(); | 5638 HValue* right = Pop(); |
| 5609 HValue* left = Pop(); | 5639 HValue* left = Pop(); |
| 5610 Token::Value op = expr->op(); | 5640 Token::Value op = expr->op(); |
| 5611 | 5641 |
| 5612 if (op == Token::INSTANCEOF) { | 5642 if (op == Token::INSTANCEOF) { |
| 5613 // Check to see if the rhs of the instanceof is a global function not | 5643 // Check to see if the rhs of the instanceof is a global function not |
| 5614 // residing in new space. If it is we assume that the function will stay the | 5644 // residing in new space. If it is we assume that the function will stay the |
| 5615 // same. | 5645 // same. |
| 5616 Handle<JSFunction> target = Handle<JSFunction>::null(); | 5646 Handle<JSFunction> target = Handle<JSFunction>::null(); |
| 5617 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); | 5647 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5631 // change and thus prefer the general IC code. | 5661 // change and thus prefer the general IC code. |
| 5632 if (!isolate()->heap()->InNewSpace(*candidate)) { | 5662 if (!isolate()->heap()->InNewSpace(*candidate)) { |
| 5633 target = candidate; | 5663 target = candidate; |
| 5634 } | 5664 } |
| 5635 } | 5665 } |
| 5636 } | 5666 } |
| 5637 | 5667 |
| 5638 // If the target is not null we have found a known global function that is | 5668 // If the target is not null we have found a known global function that is |
| 5639 // assumed to stay the same for this instanceof. | 5669 // assumed to stay the same for this instanceof. |
| 5640 if (target.is_null()) { | 5670 if (target.is_null()) { |
| 5641 HValue* context = environment()->LookupContext(); | |
| 5642 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); | 5671 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); |
| 5643 result->set_position(expr->position()); | 5672 result->set_position(expr->position()); |
| 5644 return ast_context()->ReturnInstruction(result, expr->id()); | 5673 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5645 } else { | 5674 } else { |
| 5646 AddInstruction(new(zone()) HCheckFunction(right, target)); | 5675 AddInstruction(new(zone()) HCheckFunction(right, target)); |
| 5647 HInstanceOfKnownGlobal* result = | 5676 HInstanceOfKnownGlobal* result = |
| 5648 new(zone()) HInstanceOfKnownGlobal(left, target); | 5677 new(zone()) HInstanceOfKnownGlobal(context, left, target); |
| 5649 result->set_position(expr->position()); | 5678 result->set_position(expr->position()); |
| 5650 return ast_context()->ReturnInstruction(result, expr->id()); | 5679 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5651 } | 5680 } |
| 5652 } else if (op == Token::IN) { | 5681 } else if (op == Token::IN) { |
| 5653 HIn* result = new(zone()) HIn(left, right); | 5682 HIn* result = new(zone()) HIn(context, left, right); |
| 5654 result->set_position(expr->position()); | 5683 result->set_position(expr->position()); |
| 5655 return ast_context()->ReturnInstruction(result, expr->id()); | 5684 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5656 } else if (type_info.IsNonPrimitive()) { | 5685 } else if (type_info.IsNonPrimitive()) { |
| 5657 switch (op) { | 5686 switch (op) { |
| 5658 case Token::EQ: | 5687 case Token::EQ: |
| 5659 case Token::EQ_STRICT: { | 5688 case Token::EQ_STRICT: { |
| 5660 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5689 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 5661 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 5690 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); |
| 5662 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5691 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 5663 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 5692 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5675 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 5704 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); |
| 5676 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5705 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 5677 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 5706 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); |
| 5678 HCompareObjectEqAndBranch* result = | 5707 HCompareObjectEqAndBranch* result = |
| 5679 new(zone()) HCompareObjectEqAndBranch(left, right); | 5708 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 5680 result->set_position(expr->position()); | 5709 result->set_position(expr->position()); |
| 5681 return ast_context()->ReturnControl(result, expr->id()); | 5710 return ast_context()->ReturnControl(result, expr->id()); |
| 5682 } else { | 5711 } else { |
| 5683 Representation r = ToRepresentation(type_info); | 5712 Representation r = ToRepresentation(type_info); |
| 5684 if (r.IsTagged()) { | 5713 if (r.IsTagged()) { |
| 5685 HCompareGeneric* result = new(zone()) HCompareGeneric(left, right, op); | 5714 HCompareGeneric* result = |
| 5715 new(zone()) HCompareGeneric(context, left, right, op); |
| 5686 result->set_position(expr->position()); | 5716 result->set_position(expr->position()); |
| 5687 return ast_context()->ReturnInstruction(result, expr->id()); | 5717 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5688 } else { | 5718 } else { |
| 5689 HCompareIDAndBranch* result = | 5719 HCompareIDAndBranch* result = |
| 5690 new(zone()) HCompareIDAndBranch(left, right, op); | 5720 new(zone()) HCompareIDAndBranch(left, right, op); |
| 5691 result->set_position(expr->position()); | 5721 result->set_position(expr->position()); |
| 5692 result->SetInputRepresentation(r); | 5722 result->SetInputRepresentation(r); |
| 5693 return ast_context()->ReturnControl(result, expr->id()); | 5723 return ast_context()->ReturnControl(result, expr->id()); |
| 5694 } | 5724 } |
| 5695 } | 5725 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5891 } | 5921 } |
| 5892 | 5922 |
| 5893 | 5923 |
| 5894 // Fast support for charCodeAt(n). | 5924 // Fast support for charCodeAt(n). |
| 5895 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 5925 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
| 5896 ASSERT(call->arguments()->length() == 2); | 5926 ASSERT(call->arguments()->length() == 2); |
| 5897 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5927 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 5898 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5928 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 5899 HValue* index = Pop(); | 5929 HValue* index = Pop(); |
| 5900 HValue* string = Pop(); | 5930 HValue* string = Pop(); |
| 5901 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); | 5931 HValue* context = environment()->LookupContext(); |
| 5932 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); |
| 5902 return ast_context()->ReturnInstruction(result, call->id()); | 5933 return ast_context()->ReturnInstruction(result, call->id()); |
| 5903 } | 5934 } |
| 5904 | 5935 |
| 5905 | 5936 |
| 5906 // Fast support for string.charAt(n) and string[n]. | 5937 // Fast support for string.charAt(n) and string[n]. |
| 5907 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 5938 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
| 5908 ASSERT(call->arguments()->length() == 1); | 5939 ASSERT(call->arguments()->length() == 1); |
| 5909 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5940 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 5910 HValue* char_code = Pop(); | 5941 HValue* char_code = Pop(); |
| 5911 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); | 5942 HValue* context = environment()->LookupContext(); |
| 5943 HStringCharFromCode* result = |
| 5944 new(zone()) HStringCharFromCode(context, char_code); |
| 5912 return ast_context()->ReturnInstruction(result, call->id()); | 5945 return ast_context()->ReturnInstruction(result, call->id()); |
| 5913 } | 5946 } |
| 5914 | 5947 |
| 5915 | 5948 |
| 5916 // Fast support for string.charAt(n) and string[n]. | 5949 // Fast support for string.charAt(n) and string[n]. |
| 5917 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 5950 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
| 5918 ASSERT(call->arguments()->length() == 2); | 5951 ASSERT(call->arguments()->length() == 2); |
| 5919 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5952 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 5920 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5953 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 5921 HValue* index = Pop(); | 5954 HValue* index = Pop(); |
| 5922 HValue* string = Pop(); | 5955 HValue* string = Pop(); |
| 5923 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); | 5956 HValue* context = environment()->LookupContext(); |
| 5957 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); |
| 5924 AddInstruction(char_code); | 5958 AddInstruction(char_code); |
| 5925 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); | 5959 HStringCharFromCode* result = |
| 5960 new(zone()) HStringCharFromCode(context, char_code); |
| 5926 return ast_context()->ReturnInstruction(result, call->id()); | 5961 return ast_context()->ReturnInstruction(result, call->id()); |
| 5927 } | 5962 } |
| 5928 | 5963 |
| 5929 | 5964 |
| 5930 // Fast support for object equality testing. | 5965 // Fast support for object equality testing. |
| 5931 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 5966 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
| 5932 ASSERT(call->arguments()->length() == 2); | 5967 ASSERT(call->arguments()->length() == 2); |
| 5933 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5968 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 5934 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5969 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 5935 HValue* right = Pop(); | 5970 HValue* right = Pop(); |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6656 } | 6691 } |
| 6657 } | 6692 } |
| 6658 | 6693 |
| 6659 #ifdef DEBUG | 6694 #ifdef DEBUG |
| 6660 if (graph_ != NULL) graph_->Verify(); | 6695 if (graph_ != NULL) graph_->Verify(); |
| 6661 if (allocator_ != NULL) allocator_->Verify(); | 6696 if (allocator_ != NULL) allocator_->Verify(); |
| 6662 #endif | 6697 #endif |
| 6663 } | 6698 } |
| 6664 | 6699 |
| 6665 } } // namespace v8::internal | 6700 } } // namespace v8::internal |
| OLD | NEW |