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

Side by Side Diff: src/hydrogen.cc

Issue 7739018: Inline functions with different contexts in the optimizing code generator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase to current tip-of-tree. Created 9 years, 3 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
OLDNEW
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 4456 matching lines...) Expand 10 before | Expand all | Expand 10 after
4467 TraceInline(target, caller, "target text too big"); 4467 TraceInline(target, caller, "target text too big");
4468 return false; 4468 return false;
4469 } 4469 }
4470 4470
4471 // Target must be inlineable. 4471 // Target must be inlineable.
4472 if (!target->IsInlineable()) { 4472 if (!target->IsInlineable()) {
4473 TraceInline(target, caller, "target not inlineable"); 4473 TraceInline(target, caller, "target not inlineable");
4474 return false; 4474 return false;
4475 } 4475 }
4476 4476
4477 // No context change required.
4478 CompilationInfo* outer_info = info(); 4477 CompilationInfo* outer_info = info();
4479 if (target->context() != outer_info->closure()->context() || 4478 bool context_changed = target->context() != outer_info->closure()->context()
4480 outer_info->scope()->contains_with() || 4479 || outer_info->scope()->contains_with()
4481 outer_info->scope()->num_heap_slots() > 0) { 4480 || outer_info->scope()->num_heap_slots() > 0;
4481
4482 if (context_changed && !kInlineContextChangeAllowed) {
4482 TraceInline(target, caller, "target requires context change"); 4483 TraceInline(target, caller, "target requires context change");
4483 return false; 4484 return false;
4484 } 4485 }
4485 4486
4486 // Don't inline deeper than kMaxInliningLevels calls. 4487 // Don't inline deeper than kMaxInliningLevels calls.
4487 HEnvironment* env = environment(); 4488 HEnvironment* env = environment();
4488 int current_level = 1; 4489 int current_level = 1;
4489 while (env->outer() != NULL) { 4490 while (env->outer() != NULL) {
4490 if (current_level == Compiler::kMaxInliningLevels) { 4491 if (current_level == Compiler::kMaxInliningLevels) {
4491 TraceInline(target, caller, "inline depth limit reached"); 4492 TraceInline(target, caller, "inline depth limit reached");
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4594 TypeFeedbackOracle target_oracle( 4595 TypeFeedbackOracle target_oracle(
4595 Handle<Code>(target_shared->code()), 4596 Handle<Code>(target_shared->code()),
4596 Handle<Context>(target->context()->global_context())); 4597 Handle<Context>(target->context()->global_context()));
4597 FunctionState target_state(this, &target_info, &target_oracle); 4598 FunctionState target_state(this, &target_info, &target_oracle);
4598 4599
4599 HConstant* undefined = graph()->GetConstantUndefined(); 4600 HConstant* undefined = graph()->GetConstantUndefined();
4600 HEnvironment* inner_env = 4601 HEnvironment* inner_env =
4601 environment()->CopyForInlining(target, 4602 environment()->CopyForInlining(target,
4602 function, 4603 function,
4603 undefined, 4604 undefined,
4604 call_kind); 4605 call_kind,
4606 context_changed);
4605 HBasicBlock* body_entry = CreateBasicBlock(inner_env); 4607 HBasicBlock* body_entry = CreateBasicBlock(inner_env);
4606 current_block()->Goto(body_entry); 4608 current_block()->Goto(body_entry);
4607 body_entry->SetJoinId(expr->ReturnId()); 4609 body_entry->SetJoinId(expr->ReturnId());
4608 set_current_block(body_entry); 4610 set_current_block(body_entry);
4609 AddInstruction(new(zone()) HEnterInlined(target, 4611 AddInstruction(new(zone()) HEnterInlined(target,
4610 function, 4612 function,
4611 call_kind)); 4613 call_kind,
4614 context_changed));
4612 VisitDeclarations(target_info.scope()->declarations()); 4615 VisitDeclarations(target_info.scope()->declarations());
4616 if (context_changed) {
4617 AddInstruction(HInstruction::cast(inner_env->LookupContext()));
4618 }
4613 VisitStatements(function->body()); 4619 VisitStatements(function->body());
4614 if (HasStackOverflow()) { 4620 if (HasStackOverflow()) {
4615 // Bail out if the inline function did, as we cannot residualize a call 4621 // Bail out if the inline function did, as we cannot residualize a call
4616 // instead. 4622 // instead.
4617 TraceInline(target, caller, "inline graph construction failed"); 4623 TraceInline(target, caller, "inline graph construction failed");
4618 target_shared->DisableOptimization(*target); 4624 target_shared->DisableOptimization(*target);
4619 inline_bailout_ = true; 4625 inline_bailout_ = true;
4620 return true; 4626 return true;
4621 } 4627 }
4622 4628
(...skipping 1828 matching lines...) Expand 10 before | Expand all | Expand 10 after
6451 } 6457 }
6452 new_env->ClearHistory(); 6458 new_env->ClearHistory();
6453 return new_env; 6459 return new_env;
6454 } 6460 }
6455 6461
6456 6462
6457 HEnvironment* HEnvironment::CopyForInlining( 6463 HEnvironment* HEnvironment::CopyForInlining(
6458 Handle<JSFunction> target, 6464 Handle<JSFunction> target,
6459 FunctionLiteral* function, 6465 FunctionLiteral* function,
6460 HConstant* undefined, 6466 HConstant* undefined,
6461 CallKind call_kind) const { 6467 CallKind call_kind,
6468 bool context_changed) const {
6462 // Outer environment is a copy of this one without the arguments. 6469 // Outer environment is a copy of this one without the arguments.
6463 int arity = function->scope()->num_parameters(); 6470 int arity = function->scope()->num_parameters();
6464 HEnvironment* outer = Copy(); 6471 HEnvironment* outer = Copy();
6465 outer->Drop(arity + 1); // Including receiver. 6472 outer->Drop(arity + 1); // Including receiver.
6466 outer->ClearHistory(); 6473 outer->ClearHistory();
6467 Zone* zone = closure()->GetIsolate()->zone(); 6474 Zone* zone = closure()->GetIsolate()->zone();
6468 HEnvironment* inner = 6475 HEnvironment* inner =
6469 new(zone) HEnvironment(outer, function->scope(), target); 6476 new(zone) HEnvironment(outer, function->scope(), target);
6470 // Get the argument values from the original environment. 6477 // Get the argument values from the original environment.
6471 for (int i = 0; i <= arity; ++i) { // Include receiver. 6478 for (int i = 0; i <= arity; ++i) { // Include receiver.
6472 HValue* push = ExpressionStackAt(arity - i); 6479 HValue* push = ExpressionStackAt(arity - i);
6473 inner->SetValueAt(i, push); 6480 inner->SetValueAt(i, push);
6474 } 6481 }
6475 // If the function we are inlining is a strict mode function or a 6482 // If the function we are inlining is a strict mode function or a
6476 // builtin function, pass undefined as the receiver for function 6483 // builtin function, pass undefined as the receiver for function
6477 // calls (instead of the global receiver). 6484 // calls (instead of the global receiver).
6478 if ((target->shared()->native() || function->strict_mode()) && 6485 if ((target->shared()->native() || function->strict_mode()) &&
6479 call_kind == CALL_AS_FUNCTION) { 6486 call_kind == CALL_AS_FUNCTION) {
6480 inner->SetValueAt(0, undefined); 6487 inner->SetValueAt(0, undefined);
6481 } 6488 }
6482 inner->SetValueAt(arity + 1, outer->LookupContext()); 6489 if (context_changed) {
6490 HInlinedContext* context = new(zone) HInlinedContext(target);
6491 inner->SetValueAt(arity + 1, context);
6492 } else {
6493 inner->SetValueAt(arity + 1, LookupContext());
6494 }
6483 for (int i = arity + 2; i < inner->length(); ++i) { 6495 for (int i = arity + 2; i < inner->length(); ++i) {
6484 inner->SetValueAt(i, undefined); 6496 inner->SetValueAt(i, undefined);
6485 } 6497 }
6486 6498
6487 inner->set_ast_id(AstNode::kFunctionEntryId); 6499 inner->set_ast_id(AstNode::kFunctionEntryId);
6488 return inner; 6500 return inner;
6489 } 6501 }
6490 6502
6491 6503
6492 void HEnvironment::PrintTo(StringStream* stream) { 6504 void HEnvironment::PrintTo(StringStream* stream) {
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
6821 } 6833 }
6822 } 6834 }
6823 6835
6824 #ifdef DEBUG 6836 #ifdef DEBUG
6825 if (graph_ != NULL) graph_->Verify(); 6837 if (graph_ != NULL) graph_->Verify();
6826 if (allocator_ != NULL) allocator_->Verify(); 6838 if (allocator_ != NULL) allocator_->Verify();
6827 #endif 6839 #endif
6828 } 6840 }
6829 6841
6830 } } // namespace v8::internal 6842 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698