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

Side by Side Diff: src/hydrogen.cc

Issue 8258012: Fix a number of bugs with inlining calls as function. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 2 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 | « no previous file | src/ia32/full-codegen-ia32.cc » ('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 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 4521 matching lines...) Expand 10 before | Expand all | Expand 10 after
4532 TraceInline(target, caller, "target text too big"); 4532 TraceInline(target, caller, "target text too big");
4533 return false; 4533 return false;
4534 } 4534 }
4535 4535
4536 // Target must be inlineable. 4536 // Target must be inlineable.
4537 if (!target->IsInlineable()) { 4537 if (!target->IsInlineable()) {
4538 TraceInline(target, caller, "target not inlineable"); 4538 TraceInline(target, caller, "target not inlineable");
4539 return false; 4539 return false;
4540 } 4540 }
4541 4541
4542 CompilationInfo* outer_info = info();
4543 #if !defined(V8_TARGET_ARCH_IA32) 4542 #if !defined(V8_TARGET_ARCH_IA32)
4544 // Target must be able to use caller's context. 4543 // Target must be able to use caller's context.
4544 CompilationInfo* outer_info = info();
4545 if (target->context() != outer_info->closure()->context() || 4545 if (target->context() != outer_info->closure()->context() ||
4546 outer_info->scope()->contains_with() || 4546 outer_info->scope()->contains_with() ||
4547 outer_info->scope()->num_heap_slots() > 0) { 4547 outer_info->scope()->num_heap_slots() > 0) {
4548 TraceInline(target, caller, "target requires context change"); 4548 TraceInline(target, caller, "target requires context change");
4549 return false; 4549 return false;
4550 } 4550 }
4551 #endif 4551 #endif
4552 4552
4553 4553
4554 // Don't inline deeper than kMaxInliningLevels calls. 4554 // Don't inline deeper than kMaxInliningLevels calls.
4555 HEnvironment* env = environment(); 4555 HEnvironment* env = environment();
4556 int current_level = 1; 4556 int current_level = 1;
4557 while (env->outer() != NULL) { 4557 while (env->outer() != NULL) {
4558 if (current_level == (FLAG_limit_inlining 4558 if (current_level == (FLAG_limit_inlining
4559 ? Compiler::kMaxInliningLevels 4559 ? Compiler::kMaxInliningLevels
4560 : 2 * Compiler::kMaxInliningLevels)) { 4560 : 2 * Compiler::kMaxInliningLevels)) {
4561 TraceInline(target, caller, "inline depth limit reached"); 4561 TraceInline(target, caller, "inline depth limit reached");
4562 return false; 4562 return false;
4563 } 4563 }
4564 current_level++; 4564 current_level++;
4565 env = env->outer(); 4565 env = env->outer();
4566 } 4566 }
4567 4567
4568 // Don't inline recursive functions. 4568 // Don't inline recursive functions.
4569 if (*target_shared == outer_info->closure()->shared()) { 4569 for (FunctionState* state = function_state();
4570 TraceInline(target, caller, "target is recursive"); 4570 state != NULL;
4571 return false; 4571 state = state->outer()) {
4572 if (state->compilation_info()->closure()->shared() == *target_shared) {
4573 TraceInline(target, caller, "target is recursive");
4574 return false;
4575 }
4572 } 4576 }
4573 4577
4574 // We don't want to add more than a certain number of nodes from inlining. 4578 // We don't want to add more than a certain number of nodes from inlining.
4575 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) { 4579 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) {
4576 TraceInline(target, caller, "cumulative AST node limit reached"); 4580 TraceInline(target, caller, "cumulative AST node limit reached");
4577 return false; 4581 return false;
4578 } 4582 }
4579 4583
4580 int count_before = AstNode::Count(); 4584 int count_before = AstNode::Count();
4581 4585
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
5066 HGlobalObject* global = new(zone()) HGlobalObject(context); 5070 HGlobalObject* global = new(zone()) HGlobalObject(context);
5067 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); 5071 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global);
5068 AddInstruction(global); 5072 AddInstruction(global);
5069 PushAndAdd(receiver); 5073 PushAndAdd(receiver);
5070 CHECK_ALIVE(VisitExpressions(expr->arguments())); 5074 CHECK_ALIVE(VisitExpressions(expr->arguments()));
5071 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); 5075 AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
5072 if (TryInline(expr)) { 5076 if (TryInline(expr)) {
5073 // The function is lingering in the deoptimization environment. 5077 // The function is lingering in the deoptimization environment.
5074 // Handle it by case analysis on the AST context. 5078 // Handle it by case analysis on the AST context.
5075 if (ast_context()->IsEffect()) { 5079 if (ast_context()->IsEffect()) {
5080 if (current_block() == NULL) return;
5081 ASSERT(Top() == function);
5076 Drop(1); 5082 Drop(1);
5077 } else if (ast_context()->IsValue()) { 5083 } else if (ast_context()->IsValue()) {
5084 if (current_block() == NULL) return;
5078 HValue* result = Pop(); 5085 HValue* result = Pop();
5086 ASSERT(Top() == function);
5079 Drop(1); 5087 Drop(1);
5080 Push(result); 5088 Push(result);
5081 } else if (ast_context()->IsTest()) { 5089 } else if (ast_context()->IsTest()) {
5090 ASSERT(current_block() == NULL);
5082 TestContext* context = TestContext::cast(ast_context()); 5091 TestContext* context = TestContext::cast(ast_context());
5083 if (context->if_true()->HasPredecessor()) { 5092 if (context->if_true()->HasPredecessor() &&
5093 context->if_true()->last_environment()->Top() == function) {
5084 context->if_true()->last_environment()->Drop(1); 5094 context->if_true()->last_environment()->Drop(1);
5085 } 5095 }
5086 if (context->if_false()->HasPredecessor()) { 5096 if (context->if_false()->HasPredecessor() &&
5087 context->if_true()->last_environment()->Drop(1); 5097 context->if_false()->last_environment()->Top() == function) {
5098 context->if_false()->last_environment()->Drop(1);
5088 } 5099 }
5089 } else { 5100 } else {
5090 UNREACHABLE(); 5101 UNREACHABLE();
5091 } 5102 }
5092 return; 5103 return;
5093 } else { 5104 } else {
5094 call = PreProcessCall(new(zone()) HInvokeFunction(context, 5105 call = PreProcessCall(new(zone()) HInvokeFunction(context,
5095 function, 5106 function,
5096 argument_count)); 5107 argument_count));
5097 Drop(1); // The function. 5108 Drop(1); // The function.
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
5297 if (info.IsUninitialized()) { 5308 if (info.IsUninitialized()) {
5298 AddInstruction(new(zone()) HSoftDeoptimize); 5309 AddInstruction(new(zone()) HSoftDeoptimize);
5299 current_block()->MarkAsDeoptimizing(); 5310 current_block()->MarkAsDeoptimizing();
5300 } 5311 }
5301 HInstruction* instr = new(zone()) HBitNot(value); 5312 HInstruction* instr = new(zone()) HBitNot(value);
5302 return ast_context()->ReturnInstruction(instr, expr->id()); 5313 return ast_context()->ReturnInstruction(instr, expr->id());
5303 } 5314 }
5304 5315
5305 5316
5306 void HGraphBuilder::VisitNot(UnaryOperation* expr) { 5317 void HGraphBuilder::VisitNot(UnaryOperation* expr) {
5307 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here.
5308 if (ast_context()->IsTest()) { 5318 if (ast_context()->IsTest()) {
5309 TestContext* context = TestContext::cast(ast_context()); 5319 TestContext* context = TestContext::cast(ast_context());
5310 VisitForControl(expr->expression(), 5320 VisitForControl(expr->expression(),
5311 context->if_false(), 5321 context->if_false(),
5312 context->if_true()); 5322 context->if_true());
5313 return; 5323 return;
5314 } 5324 }
5315 5325
5316 if (ast_context()->IsEffect()) { 5326 if (ast_context()->IsEffect()) {
5317 VisitForEffect(expr->expression()); 5327 VisitForEffect(expr->expression());
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after
6939 } 6949 }
6940 } 6950 }
6941 6951
6942 #ifdef DEBUG 6952 #ifdef DEBUG
6943 if (graph_ != NULL) graph_->Verify(false); // No full verify. 6953 if (graph_ != NULL) graph_->Verify(false); // No full verify.
6944 if (allocator_ != NULL) allocator_->Verify(); 6954 if (allocator_ != NULL) allocator_->Verify();
6945 #endif 6955 #endif
6946 } 6956 }
6947 6957
6948 } } // namespace v8::internal 6958 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698