| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 new(zone()) HEnvironment(NULL, info->scope(), info->closure()); | 621 new(zone()) HEnvironment(NULL, info->scope(), info->closure()); |
| 622 start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 622 start_environment_->set_ast_id(AstNode::kFunctionEntryId); |
| 623 entry_block_ = CreateBasicBlock(); | 623 entry_block_ = CreateBasicBlock(); |
| 624 entry_block_->SetInitialEnvironment(start_environment_); | 624 entry_block_->SetInitialEnvironment(start_environment_); |
| 625 } | 625 } |
| 626 | 626 |
| 627 | 627 |
| 628 Handle<Code> HGraph::Compile(CompilationInfo* info) { | 628 Handle<Code> HGraph::Compile(CompilationInfo* info) { |
| 629 int values = GetMaximumValueID(); | 629 int values = GetMaximumValueID(); |
| 630 if (values > LAllocator::max_initial_value_ids()) { | 630 if (values > LAllocator::max_initial_value_ids()) { |
| 631 if (FLAG_trace_bailout) PrintF("Function is too big\n"); | 631 if (FLAG_trace_bailout) { |
| 632 SmartArrayPointer<char> name( |
| 633 info->shared_info()->DebugName()->ToCString()); |
| 634 PrintF("Function @\"%s\" is too big.\n", *name); |
| 635 } |
| 632 return Handle<Code>::null(); | 636 return Handle<Code>::null(); |
| 633 } | 637 } |
| 634 | 638 |
| 635 LAllocator allocator(values, this); | 639 LAllocator allocator(values, this); |
| 636 LChunkBuilder builder(info, this, &allocator); | 640 LChunkBuilder builder(info, this, &allocator); |
| 637 LChunk* chunk = builder.Build(); | 641 LChunk* chunk = builder.Build(); |
| 638 if (chunk == NULL) return Handle<Code>::null(); | 642 if (chunk == NULL) return Handle<Code>::null(); |
| 639 | 643 |
| 640 if (!FLAG_alloc_lithium) return Handle<Code>::null(); | 644 if (!FLAG_alloc_lithium) return Handle<Code>::null(); |
| 641 | 645 |
| (...skipping 1652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2294 | 2298 |
| 2295 { | 2299 { |
| 2296 HPhase phase("Block building"); | 2300 HPhase phase("Block building"); |
| 2297 current_block_ = graph()->entry_block(); | 2301 current_block_ = graph()->entry_block(); |
| 2298 | 2302 |
| 2299 Scope* scope = info()->scope(); | 2303 Scope* scope = info()->scope(); |
| 2300 if (scope->HasIllegalRedeclaration()) { | 2304 if (scope->HasIllegalRedeclaration()) { |
| 2301 Bailout("function with illegal redeclaration"); | 2305 Bailout("function with illegal redeclaration"); |
| 2302 return NULL; | 2306 return NULL; |
| 2303 } | 2307 } |
| 2304 SetupScope(scope); | 2308 SetUpScope(scope); |
| 2305 | 2309 |
| 2306 // Add an edge to the body entry. This is warty: the graph's start | 2310 // Add an edge to the body entry. This is warty: the graph's start |
| 2307 // environment will be used by the Lithium translation as the initial | 2311 // environment will be used by the Lithium translation as the initial |
| 2308 // environment on graph entry, but it has now been mutated by the | 2312 // environment on graph entry, but it has now been mutated by the |
| 2309 // Hydrogen translation of the instructions in the start block. This | 2313 // Hydrogen translation of the instructions in the start block. This |
| 2310 // environment uses values which have not been defined yet. These | 2314 // environment uses values which have not been defined yet. These |
| 2311 // Hydrogen instructions will then be replayed by the Lithium | 2315 // Hydrogen instructions will then be replayed by the Lithium |
| 2312 // translation, so they cannot have an environment effect. The edge to | 2316 // translation, so they cannot have an environment effect. The edge to |
| 2313 // the body's entry block (along with some special logic for the start | 2317 // the body's entry block (along with some special logic for the start |
| 2314 // block in HInstruction::InsertAfter) seals the start block from | 2318 // block in HInstruction::InsertAfter) seals the start block from |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 arguments.Add(Pop()); | 2462 arguments.Add(Pop()); |
| 2459 } | 2463 } |
| 2460 | 2464 |
| 2461 while (!arguments.is_empty()) { | 2465 while (!arguments.is_empty()) { |
| 2462 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 2466 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
| 2463 } | 2467 } |
| 2464 return call; | 2468 return call; |
| 2465 } | 2469 } |
| 2466 | 2470 |
| 2467 | 2471 |
| 2468 void HGraphBuilder::SetupScope(Scope* scope) { | 2472 void HGraphBuilder::SetUpScope(Scope* scope) { |
| 2469 HConstant* undefined_constant = new(zone()) HConstant( | 2473 HConstant* undefined_constant = new(zone()) HConstant( |
| 2470 isolate()->factory()->undefined_value(), Representation::Tagged()); | 2474 isolate()->factory()->undefined_value(), Representation::Tagged()); |
| 2471 AddInstruction(undefined_constant); | 2475 AddInstruction(undefined_constant); |
| 2472 graph_->set_undefined_constant(undefined_constant); | 2476 graph_->set_undefined_constant(undefined_constant); |
| 2473 | 2477 |
| 2474 // Set the initial values of parameters including "this". "This" has | 2478 // Set the initial values of parameters including "this". "This" has |
| 2475 // parameter index 0. | 2479 // parameter index 0. |
| 2476 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 2480 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
| 2477 | 2481 |
| 2478 for (int i = 0; i < environment()->parameter_count(); ++i) { | 2482 for (int i = 0; i < environment()->parameter_count(); ++i) { |
| (...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3565 | 3569 |
| 3566 | 3570 |
| 3567 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 3571 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
| 3568 Handle<String> name, | 3572 Handle<String> name, |
| 3569 HValue* value, | 3573 HValue* value, |
| 3570 Handle<Map> type, | 3574 Handle<Map> type, |
| 3571 LookupResult* lookup, | 3575 LookupResult* lookup, |
| 3572 bool smi_and_map_check) { | 3576 bool smi_and_map_check) { |
| 3573 if (smi_and_map_check) { | 3577 if (smi_and_map_check) { |
| 3574 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3578 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 3575 AddInstruction(new(zone()) HCheckMap(object, type)); | 3579 AddInstruction(new(zone()) HCheckMap(object, type, NULL, |
| 3580 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 3576 } | 3581 } |
| 3577 | 3582 |
| 3578 int index = ComputeStoredFieldIndex(type, name, lookup); | 3583 int index = ComputeStoredFieldIndex(type, name, lookup); |
| 3579 bool is_in_object = index < 0; | 3584 bool is_in_object = index < 0; |
| 3580 int offset = index * kPointerSize; | 3585 int offset = index * kPointerSize; |
| 3581 if (index < 0) { | 3586 if (index < 0) { |
| 3582 // Negative property indices are in-object properties, indexed | 3587 // Negative property indices are in-object properties, indexed |
| 3583 // from the end of the fixed part of the object. | 3588 // from the end of the fixed part of the object. |
| 3584 offset += type->instance_size(); | 3589 offset += type->instance_size(); |
| 3585 } else { | 3590 } else { |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4110 } | 4115 } |
| 4111 | 4116 |
| 4112 | 4117 |
| 4113 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 4118 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
| 4114 Property* expr, | 4119 Property* expr, |
| 4115 Handle<Map> type, | 4120 Handle<Map> type, |
| 4116 LookupResult* lookup, | 4121 LookupResult* lookup, |
| 4117 bool smi_and_map_check) { | 4122 bool smi_and_map_check) { |
| 4118 if (smi_and_map_check) { | 4123 if (smi_and_map_check) { |
| 4119 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4124 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 4120 AddInstruction(new(zone()) HCheckMap(object, type)); | 4125 AddInstruction(new(zone()) HCheckMap(object, type, NULL, |
| 4126 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 4121 } | 4127 } |
| 4122 | 4128 |
| 4123 int index = lookup->GetLocalFieldIndexFromMap(*type); | 4129 int index = lookup->GetLocalFieldIndexFromMap(*type); |
| 4124 if (index < 0) { | 4130 if (index < 0) { |
| 4125 // Negative property indices are in-object properties, indexed | 4131 // Negative property indices are in-object properties, indexed |
| 4126 // from the end of the fixed part of the object. | 4132 // from the end of the fixed part of the object. |
| 4127 int offset = (index * kPointerSize) + type->instance_size(); | 4133 int offset = (index * kPointerSize) + type->instance_size(); |
| 4128 return new(zone()) HLoadNamedField(object, true, offset); | 4134 return new(zone()) HLoadNamedField(object, true, offset); |
| 4129 } else { | 4135 } else { |
| 4130 // Non-negative property indices are in the properties array. | 4136 // Non-negative property indices are in the properties array. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4150 LookupResult lookup(isolate()); | 4156 LookupResult lookup(isolate()); |
| 4151 map->LookupInDescriptors(NULL, *name, &lookup); | 4157 map->LookupInDescriptors(NULL, *name, &lookup); |
| 4152 if (lookup.IsProperty() && lookup.type() == FIELD) { | 4158 if (lookup.IsProperty() && lookup.type() == FIELD) { |
| 4153 return BuildLoadNamedField(obj, | 4159 return BuildLoadNamedField(obj, |
| 4154 expr, | 4160 expr, |
| 4155 map, | 4161 map, |
| 4156 &lookup, | 4162 &lookup, |
| 4157 true); | 4163 true); |
| 4158 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { | 4164 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
| 4159 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 4165 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
| 4160 AddInstruction(new(zone()) HCheckMap(obj, map)); | 4166 AddInstruction(new(zone()) HCheckMap(obj, map, NULL, |
| 4167 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 4161 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 4168 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
| 4162 return new(zone()) HConstant(function, Representation::Tagged()); | 4169 return new(zone()) HConstant(function, Representation::Tagged()); |
| 4163 } else { | 4170 } else { |
| 4164 return BuildLoadNamedGeneric(obj, expr); | 4171 return BuildLoadNamedGeneric(obj, expr); |
| 4165 } | 4172 } |
| 4166 } | 4173 } |
| 4167 | 4174 |
| 4168 | 4175 |
| 4169 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 4176 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| 4170 HValue* key) { | 4177 HValue* key) { |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4645 | 4652 |
| 4646 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 4653 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
| 4647 HValue* receiver, | 4654 HValue* receiver, |
| 4648 Handle<Map> receiver_map, | 4655 Handle<Map> receiver_map, |
| 4649 bool smi_and_map_check) { | 4656 bool smi_and_map_check) { |
| 4650 // Constant functions have the nice property that the map will change if they | 4657 // Constant functions have the nice property that the map will change if they |
| 4651 // are overwritten. Therefore it is enough to check the map of the holder and | 4658 // are overwritten. Therefore it is enough to check the map of the holder and |
| 4652 // its prototypes. | 4659 // its prototypes. |
| 4653 if (smi_and_map_check) { | 4660 if (smi_and_map_check) { |
| 4654 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 4661 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
| 4655 AddInstruction(new(zone()) HCheckMap(receiver, receiver_map)); | 4662 AddInstruction(new(zone()) HCheckMap(receiver, receiver_map, NULL, |
| 4663 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 4656 } | 4664 } |
| 4657 if (!expr->holder().is_null()) { | 4665 if (!expr->holder().is_null()) { |
| 4658 AddInstruction(new(zone()) HCheckPrototypeMaps( | 4666 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 4659 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 4667 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
| 4660 expr->holder())); | 4668 expr->holder())); |
| 4661 } | 4669 } |
| 4662 } | 4670 } |
| 4663 | 4671 |
| 4664 | 4672 |
| 4665 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, | 4673 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5117 result = new(zone()) HMul(context, left, left); | 5125 result = new(zone()) HMul(context, left, left); |
| 5118 } | 5126 } |
| 5119 | 5127 |
| 5120 if (result == NULL) { | 5128 if (result == NULL) { |
| 5121 result = new(zone()) HPower(left, right); | 5129 result = new(zone()) HPower(left, right); |
| 5122 } | 5130 } |
| 5123 ast_context()->ReturnInstruction(result, expr->id()); | 5131 ast_context()->ReturnInstruction(result, expr->id()); |
| 5124 return true; | 5132 return true; |
| 5125 } | 5133 } |
| 5126 break; | 5134 break; |
| 5135 case kMathRandom: |
| 5136 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
| 5137 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
| 5138 Drop(1); |
| 5139 HValue* context = environment()->LookupContext(); |
| 5140 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 5141 AddInstruction(global_object); |
| 5142 HRandom* result = new(zone()) HRandom(global_object); |
| 5143 ast_context()->ReturnInstruction(result, expr->id()); |
| 5144 return true; |
| 5145 } |
| 5146 break; |
| 5147 case kMathMax: |
| 5148 case kMathMin: |
| 5149 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
| 5150 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
| 5151 HValue* right = Pop(); |
| 5152 HValue* left = Pop(); |
| 5153 // Do not inline if the return representation is not certain. |
| 5154 if (!left->representation().Equals(right->representation())) { |
| 5155 Push(left); |
| 5156 Push(right); |
| 5157 return false; |
| 5158 } |
| 5159 |
| 5160 Pop(); // Pop receiver. |
| 5161 Token::Value op = (id == kMathMin) ? Token::LT : Token::GT; |
| 5162 HCompareIDAndBranch* compare = NULL; |
| 5163 |
| 5164 if (left->representation().IsTagged()) { |
| 5165 HChange* left_cvt = |
| 5166 new(zone()) HChange(left, Representation::Double(), false, true); |
| 5167 left_cvt->SetFlag(HValue::kBailoutOnMinusZero); |
| 5168 AddInstruction(left_cvt); |
| 5169 HChange* right_cvt = |
| 5170 new(zone()) HChange(right, Representation::Double(), false, true); |
| 5171 right_cvt->SetFlag(HValue::kBailoutOnMinusZero); |
| 5172 AddInstruction(right_cvt); |
| 5173 compare = new(zone()) HCompareIDAndBranch(left_cvt, right_cvt, op); |
| 5174 compare->SetInputRepresentation(Representation::Double()); |
| 5175 } else { |
| 5176 compare = new(zone()) HCompareIDAndBranch(left, right, op); |
| 5177 compare->SetInputRepresentation(left->representation()); |
| 5178 } |
| 5179 |
| 5180 HBasicBlock* return_left = graph()->CreateBasicBlock(); |
| 5181 HBasicBlock* return_right = graph()->CreateBasicBlock(); |
| 5182 |
| 5183 compare->SetSuccessorAt(0, return_left); |
| 5184 compare->SetSuccessorAt(1, return_right); |
| 5185 current_block()->Finish(compare); |
| 5186 |
| 5187 set_current_block(return_left); |
| 5188 Push(left); |
| 5189 set_current_block(return_right); |
| 5190 Push(right); |
| 5191 |
| 5192 HBasicBlock* join = CreateJoin(return_left, return_right, expr->id()); |
| 5193 set_current_block(join); |
| 5194 ast_context()->ReturnValue(Pop()); |
| 5195 return true; |
| 5196 } |
| 5197 break; |
| 5127 default: | 5198 default: |
| 5128 // Not yet supported for inlining. | 5199 // Not yet supported for inlining. |
| 5129 break; | 5200 break; |
| 5130 } | 5201 } |
| 5131 return false; | 5202 return false; |
| 5132 } | 5203 } |
| 5133 | 5204 |
| 5134 | 5205 |
| 5135 bool HGraphBuilder::TryCallApply(Call* expr) { | 5206 bool HGraphBuilder::TryCallApply(Call* expr) { |
| 5136 Expression* callee = expr->expression(); | 5207 Expression* callee = expr->expression(); |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6188 result->set_position(expr->position()); | 6259 result->set_position(expr->position()); |
| 6189 return ast_context()->ReturnInstruction(result, expr->id()); | 6260 return ast_context()->ReturnInstruction(result, expr->id()); |
| 6190 } else if (type_info.IsNonPrimitive()) { | 6261 } else if (type_info.IsNonPrimitive()) { |
| 6191 switch (op) { | 6262 switch (op) { |
| 6192 case Token::EQ: | 6263 case Token::EQ: |
| 6193 case Token::EQ_STRICT: { | 6264 case Token::EQ_STRICT: { |
| 6194 // Can we get away with map check and not instance type check? | 6265 // Can we get away with map check and not instance type check? |
| 6195 Handle<Map> map = oracle()->GetCompareMap(expr); | 6266 Handle<Map> map = oracle()->GetCompareMap(expr); |
| 6196 if (!map.is_null()) { | 6267 if (!map.is_null()) { |
| 6197 AddInstruction(new(zone()) HCheckNonSmi(left)); | 6268 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 6198 AddInstruction(new(zone()) HCheckMap(left, map)); | 6269 AddInstruction(new(zone()) HCheckMap(left, map, NULL, |
| 6270 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 6199 AddInstruction(new(zone()) HCheckNonSmi(right)); | 6271 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 6200 AddInstruction(new(zone()) HCheckMap(right, map)); | 6272 AddInstruction(new(zone()) HCheckMap(right, map, NULL, |
| 6273 ALLOW_ELEMENT_TRANSITION_MAPS)); |
| 6201 HCompareObjectEqAndBranch* result = | 6274 HCompareObjectEqAndBranch* result = |
| 6202 new(zone()) HCompareObjectEqAndBranch(left, right); | 6275 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 6203 result->set_position(expr->position()); | 6276 result->set_position(expr->position()); |
| 6204 return ast_context()->ReturnControl(result, expr->id()); | 6277 return ast_context()->ReturnControl(result, expr->id()); |
| 6205 } else { | 6278 } else { |
| 6206 AddInstruction(new(zone()) HCheckNonSmi(left)); | 6279 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 6207 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 6280 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); |
| 6208 AddInstruction(new(zone()) HCheckNonSmi(right)); | 6281 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 6209 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 6282 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); |
| 6210 HCompareObjectEqAndBranch* result = | 6283 HCompareObjectEqAndBranch* result = |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6562 | 6635 |
| 6563 | 6636 |
| 6564 void HGraphBuilder::GenerateLog(CallRuntime* call) { | 6637 void HGraphBuilder::GenerateLog(CallRuntime* call) { |
| 6565 // %_Log is ignored in optimized code. | 6638 // %_Log is ignored in optimized code. |
| 6566 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 6639 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 6567 } | 6640 } |
| 6568 | 6641 |
| 6569 | 6642 |
| 6570 // Fast support for Math.random(). | 6643 // Fast support for Math.random(). |
| 6571 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 6644 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
| 6572 return Bailout("inlined runtime function: RandomHeapNumber"); | 6645 HValue* context = environment()->LookupContext(); |
| 6646 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 6647 AddInstruction(global_object); |
| 6648 HRandom* result = new(zone()) HRandom(global_object); |
| 6649 return ast_context()->ReturnInstruction(result, call->id()); |
| 6573 } | 6650 } |
| 6574 | 6651 |
| 6575 | 6652 |
| 6576 // Fast support for StringAdd. | 6653 // Fast support for StringAdd. |
| 6577 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 6654 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
| 6578 ASSERT_EQ(2, call->arguments()->length()); | 6655 ASSERT_EQ(2, call->arguments()->length()); |
| 6579 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 6656 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 6580 HValue* context = environment()->LookupContext(); | 6657 HValue* context = environment()->LookupContext(); |
| 6581 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); | 6658 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); |
| 6582 Drop(2); | 6659 Drop(2); |
| (...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7311 } | 7388 } |
| 7312 } | 7389 } |
| 7313 | 7390 |
| 7314 #ifdef DEBUG | 7391 #ifdef DEBUG |
| 7315 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7392 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 7316 if (allocator_ != NULL) allocator_->Verify(); | 7393 if (allocator_ != NULL) allocator_->Verify(); |
| 7317 #endif | 7394 #endif |
| 7318 } | 7395 } |
| 7319 | 7396 |
| 7320 } } // namespace v8::internal | 7397 } } // namespace v8::internal |
| OLD | NEW |