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

Side by Side Diff: src/hydrogen.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698