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

Side by Side Diff: src/hydrogen.cc

Issue 6993057: Version 3.4.2 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 6 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/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 3559 matching lines...) Expand 10 before | Expand all | Expand 10 after
3570 if (expr->is_compound()) { 3570 if (expr->is_compound()) {
3571 HandleCompoundAssignment(expr); 3571 HandleCompoundAssignment(expr);
3572 return; 3572 return;
3573 } 3573 }
3574 3574
3575 if (var != NULL) { 3575 if (var != NULL) {
3576 if (var->mode() == Variable::CONST) { 3576 if (var->mode() == Variable::CONST) {
3577 if (expr->op() != Token::INIT_CONST) { 3577 if (expr->op() != Token::INIT_CONST) {
3578 return Bailout("non-initializer assignment to const"); 3578 return Bailout("non-initializer assignment to const");
3579 } 3579 }
3580 if (!var->IsStackAllocated()) {
3581 return Bailout("assignment to const context slot");
3582 }
3580 // We insert a use of the old value to detect unsupported uses of const 3583 // We insert a use of the old value to detect unsupported uses of const
3581 // variables (e.g. initialization inside a loop). 3584 // variables (e.g. initialization inside a loop).
3582 HValue* old_value = environment()->Lookup(var); 3585 HValue* old_value = environment()->Lookup(var);
3583 AddInstruction(new HUseConst(old_value)); 3586 AddInstruction(new HUseConst(old_value));
3584 } 3587 }
3585 3588
3586 if (proxy->IsArguments()) return Bailout("assignment to arguments"); 3589 if (proxy->IsArguments()) return Bailout("assignment to arguments");
3587 3590
3588 // Handle the assignment. 3591 // Handle the assignment.
3589 if (var->IsStackAllocated()) { 3592 if (var->IsStackAllocated()) {
3590 // We do not allow the arguments object to occur in a context where it 3593 // We do not allow the arguments object to occur in a context where it
3591 // may escape, but assignments to stack-allocated locals are 3594 // may escape, but assignments to stack-allocated locals are
3592 // permitted. 3595 // permitted.
3593 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 3596 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
3594 HValue* value = Pop(); 3597 HValue* value = Pop();
3595 Bind(var, value); 3598 Bind(var, value);
3596 ast_context()->ReturnValue(value); 3599 ast_context()->ReturnValue(value);
3597 3600
3598 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { 3601 } else if (var->IsContextSlot()) {
3602 ASSERT(var->mode() != Variable::CONST);
3599 CHECK_ALIVE(VisitForValue(expr->value())); 3603 CHECK_ALIVE(VisitForValue(expr->value()));
3600 HValue* context = BuildContextChainWalk(var); 3604 HValue* context = BuildContextChainWalk(var);
3601 int index = var->AsSlot()->index(); 3605 int index = var->AsSlot()->index();
3602 HStoreContextSlot* instr = 3606 HStoreContextSlot* instr =
3603 new(zone()) HStoreContextSlot(context, index, Top()); 3607 new(zone()) HStoreContextSlot(context, index, Top());
3604 AddInstruction(instr); 3608 AddInstruction(instr);
3605 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3609 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3606 ast_context()->ReturnValue(Pop()); 3610 ast_context()->ReturnValue(Pop());
3607 3611
3608 } else if (var->is_global()) { 3612 } else if (var->is_global()) {
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
4184 } 4188 }
4185 FunctionLiteral* function = target_info.function(); 4189 FunctionLiteral* function = target_info.function();
4186 4190
4187 // Count the number of AST nodes added by inlining this call. 4191 // Count the number of AST nodes added by inlining this call.
4188 int nodes_added = AstNode::Count() - count_before; 4192 int nodes_added = AstNode::Count() - count_before;
4189 if (FLAG_limit_inlining && nodes_added > kMaxInlinedSize) { 4193 if (FLAG_limit_inlining && nodes_added > kMaxInlinedSize) {
4190 TraceInline(target, caller, "target AST is too large"); 4194 TraceInline(target, caller, "target AST is too large");
4191 return false; 4195 return false;
4192 } 4196 }
4193 4197
4194 // Check if we can handle all declarations in the inlined functions.
4195 VisitDeclarations(target_info.scope()->declarations());
4196 if (HasStackOverflow()) {
4197 TraceInline(target, caller, "target has non-trivial declaration");
4198 ClearStackOverflow();
4199 return false;
4200 }
4201
4202 // Don't inline functions that uses the arguments object or that 4198 // Don't inline functions that uses the arguments object or that
4203 // have a mismatching number of parameters. 4199 // have a mismatching number of parameters.
4204 int arity = expr->arguments()->length(); 4200 int arity = expr->arguments()->length();
4205 if (function->scope()->arguments() != NULL || 4201 if (function->scope()->arguments() != NULL ||
4206 arity != target_shared->formal_parameter_count()) { 4202 arity != target_shared->formal_parameter_count()) {
4207 TraceInline(target, caller, "target requires special argument handling"); 4203 TraceInline(target, caller, "target requires special argument handling");
4208 return false; 4204 return false;
4209 } 4205 }
4210 4206
4207 // All declarations must be inlineable.
4208 ZoneList<Declaration*>* decls = target_info.scope()->declarations();
4209 int decl_count = decls->length();
4210 for (int i = 0; i < decl_count; ++i) {
4211 if (!decls->at(i)->IsInlineable()) {
4212 TraceInline(target, caller, "target has non-trivial declaration");
4213 return false;
4214 }
4215 }
4211 // All statements in the body must be inlineable. 4216 // All statements in the body must be inlineable.
4212 for (int i = 0, count = function->body()->length(); i < count; ++i) { 4217 for (int i = 0, count = function->body()->length(); i < count; ++i) {
4213 if (!function->body()->at(i)->IsInlineable()) { 4218 if (!function->body()->at(i)->IsInlineable()) {
4214 TraceInline(target, caller, "target contains unsupported syntax"); 4219 TraceInline(target, caller, "target contains unsupported syntax");
4215 return false; 4220 return false;
4216 } 4221 }
4217 } 4222 }
4218 4223
4219 // Generate the deoptimization data for the unoptimized version of 4224 // Generate the deoptimization data for the unoptimized version of
4220 // the target function if we don't already have it. 4225 // the target function if we don't already have it.
4221 if (!target_shared->has_deoptimization_support()) { 4226 if (!target_shared->has_deoptimization_support()) {
4222 // Note that we compile here using the same AST that we will use for 4227 // Note that we compile here using the same AST that we will use for
4223 // generating the optimized inline code. 4228 // generating the optimized inline code.
4224 target_info.EnableDeoptimizationSupport(); 4229 target_info.EnableDeoptimizationSupport();
4225 if (!FullCodeGenerator::MakeCode(&target_info)) { 4230 if (!FullCodeGenerator::MakeCode(&target_info)) {
4226 TraceInline(target, caller, "could not generate deoptimization info"); 4231 TraceInline(target, caller, "could not generate deoptimization info");
4227 return false; 4232 return false;
4228 } 4233 }
4229 target_shared->EnableDeoptimizationSupport(*target_info.code()); 4234 target_shared->EnableDeoptimizationSupport(*target_info.code());
4230 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, 4235 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
4231 &target_info, 4236 &target_info,
4232 target_shared); 4237 target_shared);
4233 } 4238 }
4234 4239
4235 // ---------------------------------------------------------------- 4240 // ----------------------------------------------------------------
4241 // After this point, we've made a decision to inline this function (so
4242 // TryInline should always return true).
4243
4236 // Save the pending call context and type feedback oracle. Set up new ones 4244 // Save the pending call context and type feedback oracle. Set up new ones
4237 // for the inlined function. 4245 // for the inlined function.
4238 ASSERT(target_shared->has_deoptimization_support()); 4246 ASSERT(target_shared->has_deoptimization_support());
4239 TypeFeedbackOracle target_oracle( 4247 TypeFeedbackOracle target_oracle(
4240 Handle<Code>(target_shared->code()), 4248 Handle<Code>(target_shared->code()),
4241 Handle<Context>(target->context()->global_context())); 4249 Handle<Context>(target->context()->global_context()));
4242 FunctionState target_state(this, &target_info, &target_oracle); 4250 FunctionState target_state(this, &target_info, &target_oracle);
4243 4251
4244 HConstant* undefined = graph()->GetConstantUndefined(); 4252 HConstant* undefined = graph()->GetConstantUndefined();
4245 HEnvironment* inner_env = 4253 HEnvironment* inner_env =
4246 environment()->CopyForInlining(target, 4254 environment()->CopyForInlining(target,
4247 function, 4255 function,
4248 HEnvironment::HYDROGEN, 4256 HEnvironment::HYDROGEN,
4249 undefined, 4257 undefined,
4250 call_kind); 4258 call_kind);
4251 HBasicBlock* body_entry = CreateBasicBlock(inner_env); 4259 HBasicBlock* body_entry = CreateBasicBlock(inner_env);
4252 current_block()->Goto(body_entry); 4260 current_block()->Goto(body_entry);
4253
4254 body_entry->SetJoinId(expr->ReturnId()); 4261 body_entry->SetJoinId(expr->ReturnId());
4255 set_current_block(body_entry); 4262 set_current_block(body_entry);
4256 AddInstruction(new(zone()) HEnterInlined(target, 4263 AddInstruction(new(zone()) HEnterInlined(target,
4257 function, 4264 function,
4258 call_kind)); 4265 call_kind));
4266 VisitDeclarations(target_info.scope()->declarations());
4259 VisitStatements(function->body()); 4267 VisitStatements(function->body());
4260 if (HasStackOverflow()) { 4268 if (HasStackOverflow()) {
4261 // Bail out if the inline function did, as we cannot residualize a call 4269 // Bail out if the inline function did, as we cannot residualize a call
4262 // instead. 4270 // instead.
4263 TraceInline(target, caller, "inline graph construction failed"); 4271 TraceInline(target, caller, "inline graph construction failed");
4264 target_shared->DisableOptimization(*target); 4272 target_shared->DisableOptimization(*target);
4265 inline_bailout_ = true; 4273 inline_bailout_ = true;
4266 return true; 4274 return true;
4267 } 4275 }
4268 4276
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
5086 ASSERT(call->arguments()->length() == 1); 5094 ASSERT(call->arguments()->length() == 1);
5087 return true; 5095 return true;
5088 } 5096 }
5089 5097
5090 5098
5091 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 5099 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
5092 ASSERT(!HasStackOverflow()); 5100 ASSERT(!HasStackOverflow());
5093 ASSERT(current_block() != NULL); 5101 ASSERT(current_block() != NULL);
5094 ASSERT(current_block()->HasPredecessor()); 5102 ASSERT(current_block()->HasPredecessor());
5095 switch (expr->op()) { 5103 switch (expr->op()) {
5096 case Token::COMMA: return VisitComma(expr); 5104 case Token::COMMA:
5097 case Token::OR: return VisitAndOr(expr, false); 5105 return VisitComma(expr);
5098 case Token::AND: return VisitAndOr(expr, true); 5106 case Token::OR:
5099 default: return VisitCommon(expr); 5107 case Token::AND:
5108 return VisitLogicalExpression(expr);
5109 default:
5110 return VisitArithmeticExpression(expr);
5100 } 5111 }
5101 } 5112 }
5102 5113
5103 5114
5104 void HGraphBuilder::VisitComma(BinaryOperation* expr) { 5115 void HGraphBuilder::VisitComma(BinaryOperation* expr) {
5105 CHECK_ALIVE(VisitForEffect(expr->left())); 5116 CHECK_ALIVE(VisitForEffect(expr->left()));
5106 // Visit the right subexpression in the same AST context as the entire 5117 // Visit the right subexpression in the same AST context as the entire
5107 // expression. 5118 // expression.
5108 Visit(expr->right()); 5119 Visit(expr->right());
5109 } 5120 }
5110 5121
5111 5122
5112 void HGraphBuilder::VisitAndOr(BinaryOperation* expr, bool is_logical_and) { 5123 void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
5124 bool is_logical_and = expr->op() == Token::AND;
5113 if (ast_context()->IsTest()) { 5125 if (ast_context()->IsTest()) {
5114 TestContext* context = TestContext::cast(ast_context()); 5126 TestContext* context = TestContext::cast(ast_context());
5115 // Translate left subexpression. 5127 // Translate left subexpression.
5116 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 5128 HBasicBlock* eval_right = graph()->CreateBasicBlock();
5117 if (is_logical_and) { 5129 if (is_logical_and) {
5118 CHECK_BAILOUT(VisitForControl(expr->left(), 5130 CHECK_BAILOUT(VisitForControl(expr->left(),
5119 eval_right, 5131 eval_right,
5120 context->if_false())); 5132 context->if_false()));
5121 } else { 5133 } else {
5122 CHECK_BAILOUT(VisitForControl(expr->left(), 5134 CHECK_BAILOUT(VisitForControl(expr->left(),
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
5189 5201
5190 HBasicBlock* join_block = 5202 HBasicBlock* join_block =
5191 CreateJoin(empty_block, right_block, expr->id()); 5203 CreateJoin(empty_block, right_block, expr->id());
5192 set_current_block(join_block); 5204 set_current_block(join_block);
5193 // We did not materialize any value in the predecessor environments, 5205 // We did not materialize any value in the predecessor environments,
5194 // so there is no need to handle it here. 5206 // so there is no need to handle it here.
5195 } 5207 }
5196 } 5208 }
5197 5209
5198 5210
5199 void HGraphBuilder::VisitCommon(BinaryOperation* expr) { 5211 void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
5200 CHECK_ALIVE(VisitForValue(expr->left())); 5212 CHECK_ALIVE(VisitForValue(expr->left()));
5201 CHECK_ALIVE(VisitForValue(expr->right())); 5213 CHECK_ALIVE(VisitForValue(expr->right()));
5202 HValue* right = Pop(); 5214 HValue* right = Pop();
5203 HValue* left = Pop(); 5215 HValue* left = Pop();
5204 HInstruction* instr = BuildBinaryOperation(expr, left, right); 5216 HInstruction* instr = BuildBinaryOperation(expr, left, right);
5205 instr->set_position(expr->position()); 5217 instr->set_position(expr->position());
5206 ast_context()->ReturnInstruction(instr, expr->id()); 5218 ast_context()->ReturnInstruction(instr, expr->id());
5207 } 5219 }
5208 5220
5209 5221
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5357 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 5369 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5358 ASSERT(!HasStackOverflow()); 5370 ASSERT(!HasStackOverflow());
5359 ASSERT(current_block() != NULL); 5371 ASSERT(current_block() != NULL);
5360 ASSERT(current_block()->HasPredecessor()); 5372 ASSERT(current_block()->HasPredecessor());
5361 HThisFunction* self = new(zone()) HThisFunction; 5373 HThisFunction* self = new(zone()) HThisFunction;
5362 return ast_context()->ReturnInstruction(self, expr->id()); 5374 return ast_context()->ReturnInstruction(self, expr->id());
5363 } 5375 }
5364 5376
5365 5377
5366 void HGraphBuilder::VisitDeclaration(Declaration* decl) { 5378 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
5367 // We allow only declarations that do not require code generation. 5379 // We support only declarations that do not require code generation.
5368 // The following all require code generation: global variables,
5369 // functions, and variables with slot type LOOKUP
5370 Variable* var = decl->proxy()->var(); 5380 Variable* var = decl->proxy()->var();
5371 Slot* slot = var->AsSlot(); 5381 if (!var->IsStackAllocated() || decl->fun() != NULL) {
5372 if (var->is_global() ||
5373 !var->IsStackAllocated() ||
5374 (slot != NULL && slot->type() == Slot::LOOKUP) ||
5375 decl->fun() != NULL) {
5376 return Bailout("unsupported declaration"); 5382 return Bailout("unsupported declaration");
5377 } 5383 }
5378 5384
5379 if (decl->mode() == Variable::CONST) { 5385 if (decl->mode() == Variable::CONST) {
5386 ASSERT(var->IsStackAllocated());
5380 environment()->Bind(var, graph()->GetConstantHole()); 5387 environment()->Bind(var, graph()->GetConstantHole());
5381 } 5388 }
5382 } 5389 }
5383 5390
5384 5391
5385 // Generators for inline runtime functions. 5392 // Generators for inline runtime functions.
5386 // Support for types. 5393 // Support for types.
5387 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { 5394 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
5388 ASSERT(call->arguments()->length() == 1); 5395 ASSERT(call->arguments()->length() == 1);
5389 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5396 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
6306 } 6313 }
6307 } 6314 }
6308 6315
6309 #ifdef DEBUG 6316 #ifdef DEBUG
6310 if (graph_ != NULL) graph_->Verify(); 6317 if (graph_ != NULL) graph_->Verify();
6311 if (allocator_ != NULL) allocator_->Verify(); 6318 if (allocator_ != NULL) allocator_->Verify();
6312 #endif 6319 #endif
6313 } 6320 }
6314 6321
6315 } } // namespace v8::internal 6322 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698