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

Side by Side Diff: src/hydrogen.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix presubmit Created 9 years, 7 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 3967 matching lines...) Expand 10 before | Expand all | Expand 10 after
3978 PrintF("Did not inline %s called from %s (%s).\n", 3978 PrintF("Did not inline %s called from %s (%s).\n",
3979 *callee, *caller, reason); 3979 *callee, *caller, reason);
3980 } 3980 }
3981 } 3981 }
3982 } 3982 }
3983 3983
3984 3984
3985 bool HGraphBuilder::TryInline(Call* expr) { 3985 bool HGraphBuilder::TryInline(Call* expr) {
3986 if (!FLAG_use_inlining) return false; 3986 if (!FLAG_use_inlining) return false;
3987 3987
3988 // The function call we are inlining has an explicit receiver if it
3989 // is a property call.
3990 ReceiverType receiver_type = (expr->expression()->AsProperty() == NULL)
3991 ? IMPLICIT_RECEIVER
3992 : EXPLICIT_RECEIVER;
3993
3988 // Precondition: call is monomorphic and we have found a target with the 3994 // Precondition: call is monomorphic and we have found a target with the
3989 // appropriate arity. 3995 // appropriate arity.
3990 Handle<JSFunction> target = expr->target(); 3996 Handle<JSFunction> target = expr->target();
3991 3997
3992 // Do a quick check on source code length to avoid parsing large 3998 // Do a quick check on source code length to avoid parsing large
3993 // inlining candidates. 3999 // inlining candidates.
3994 if (FLAG_limit_inlining && target->shared()->SourceSize() > kMaxSourceSize) { 4000 if (FLAG_limit_inlining && target->shared()->SourceSize() > kMaxSourceSize) {
3995 TraceInline(target, "target text too big"); 4001 TraceInline(target, "target text too big");
3996 return false; 4002 return false;
3997 } 4003 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 TypeFeedbackOracle target_oracle( 4118 TypeFeedbackOracle target_oracle(
4113 Handle<Code>(target_shared->code()), 4119 Handle<Code>(target_shared->code()),
4114 Handle<Context>(target->context()->global_context())); 4120 Handle<Context>(target->context()->global_context()));
4115 FunctionState target_state(this, &target_info, &target_oracle); 4121 FunctionState target_state(this, &target_info, &target_oracle);
4116 4122
4117 HConstant* undefined = graph()->GetConstantUndefined(); 4123 HConstant* undefined = graph()->GetConstantUndefined();
4118 HEnvironment* inner_env = 4124 HEnvironment* inner_env =
4119 environment()->CopyForInlining(target, 4125 environment()->CopyForInlining(target,
4120 function, 4126 function,
4121 HEnvironment::HYDROGEN, 4127 HEnvironment::HYDROGEN,
4122 undefined); 4128 undefined,
4129 receiver_type);
4123 HBasicBlock* body_entry = CreateBasicBlock(inner_env); 4130 HBasicBlock* body_entry = CreateBasicBlock(inner_env);
4124 current_block()->Goto(body_entry); 4131 current_block()->Goto(body_entry);
4125 4132
4126 body_entry->SetJoinId(expr->ReturnId()); 4133 body_entry->SetJoinId(expr->ReturnId());
4127 set_current_block(body_entry); 4134 set_current_block(body_entry);
4128 AddInstruction(new(zone()) HEnterInlined(target, function)); 4135 AddInstruction(new(zone()) HEnterInlined(target,
4136 function,
4137 receiver_type));
4129 VisitStatements(function->body()); 4138 VisitStatements(function->body());
4130 if (HasStackOverflow()) { 4139 if (HasStackOverflow()) {
4131 // Bail out if the inline function did, as we cannot residualize a call 4140 // Bail out if the inline function did, as we cannot residualize a call
4132 // instead. 4141 // instead.
4133 TraceInline(target, "inline graph construction failed"); 4142 TraceInline(target, "inline graph construction failed");
4134 return true; 4143 return true;
4135 } 4144 }
4136 4145
4137 // Update inlined nodes count. 4146 // Update inlined nodes count.
4138 inlined_count_ += nodes_added; 4147 inlined_count_ += nodes_added;
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
4362 HValue* context = environment()->LookupContext(); 4371 HValue* context = environment()->LookupContext();
4363 call = PreProcessCall( 4372 call = PreProcessCall(
4364 new(zone()) HCallKeyed(context, key, argument_count)); 4373 new(zone()) HCallKeyed(context, key, argument_count));
4365 call->set_position(expr->position()); 4374 call->set_position(expr->position());
4366 Drop(1); // Key. 4375 Drop(1); // Key.
4367 ast_context()->ReturnInstruction(call, expr->id()); 4376 ast_context()->ReturnInstruction(call, expr->id());
4368 return; 4377 return;
4369 } 4378 }
4370 4379
4371 // Named function call. 4380 // Named function call.
4372 expr->RecordTypeFeedback(oracle()); 4381 expr->RecordTypeFeedback(oracle(), EXPLICIT_RECEIVER);
4373 4382
4374 if (TryCallApply(expr)) return; 4383 if (TryCallApply(expr)) return;
4375 4384
4376 CHECK_ALIVE(VisitForValue(prop->obj())); 4385 CHECK_ALIVE(VisitForValue(prop->obj()));
4377 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4386 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4378 4387
4379 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4388 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4380 4389
4381 expr->RecordTypeFeedback(oracle());
4382 ZoneMapList* types = expr->GetReceiverTypes(); 4390 ZoneMapList* types = expr->GetReceiverTypes();
4383 4391
4384 HValue* receiver = 4392 HValue* receiver =
4385 environment()->ExpressionStackAt(expr->arguments()->length()); 4393 environment()->ExpressionStackAt(expr->arguments()->length());
4386 if (expr->IsMonomorphic()) { 4394 if (expr->IsMonomorphic()) {
4387 Handle<Map> receiver_map = 4395 Handle<Map> receiver_map =
4388 (types == NULL) ? Handle<Map>::null() : types->first(); 4396 (types == NULL) ? Handle<Map>::null() : types->first();
4389 if (TryInlineBuiltinFunction(expr, 4397 if (TryInlineBuiltinFunction(expr,
4390 receiver, 4398 receiver,
4391 receiver_map, 4399 receiver_map,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4465 4473
4466 if (TryInline(expr)) return; 4474 if (TryInline(expr)) return;
4467 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 4475 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
4468 argument_count)); 4476 argument_count));
4469 } else { 4477 } else {
4470 HValue* context = environment()->LookupContext(); 4478 HValue* context = environment()->LookupContext();
4471 PushAndAdd(new(zone()) HGlobalObject(context)); 4479 PushAndAdd(new(zone()) HGlobalObject(context));
4472 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4480 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4473 4481
4474 call = PreProcessCall(new(zone()) HCallGlobal(context, 4482 call = PreProcessCall(new(zone()) HCallGlobal(context,
4475 var->name(), 4483 var->name(),
4476 argument_count)); 4484 argument_count));
4477 } 4485 }
4478 4486
4479 } else { 4487 } else {
4480 HValue* context = environment()->LookupContext(); 4488 HValue* context = environment()->LookupContext();
4481 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4489 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4482 AddInstruction(global_object); 4490 AddInstruction(global_object);
4483 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); 4491 PushAndAdd(new(zone()) HGlobalReceiver(global_object));
4484 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4492 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4485 4493
4486 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); 4494 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count));
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
5770 HPhi* phi = new(loop_header->zone()) HPhi(i); 5778 HPhi* phi = new(loop_header->zone()) HPhi(i);
5771 phi->AddInput(values_[i]); 5779 phi->AddInput(values_[i]);
5772 new_env->values_[i] = phi; 5780 new_env->values_[i] = phi;
5773 loop_header->AddPhi(phi); 5781 loop_header->AddPhi(phi);
5774 } 5782 }
5775 new_env->ClearHistory(); 5783 new_env->ClearHistory();
5776 return new_env; 5784 return new_env;
5777 } 5785 }
5778 5786
5779 5787
5780 HEnvironment* HEnvironment::CopyForInlining(Handle<JSFunction> target, 5788 HEnvironment* HEnvironment::CopyForInlining(
5781 FunctionLiteral* function, 5789 Handle<JSFunction> target,
5782 CompilationPhase compilation_phase, 5790 FunctionLiteral* function,
5783 HConstant* undefined) const { 5791 CompilationPhase compilation_phase,
5792 HConstant* undefined,
5793 ReceiverType receiver_type) const {
5784 // Outer environment is a copy of this one without the arguments. 5794 // Outer environment is a copy of this one without the arguments.
5785 int arity = function->scope()->num_parameters(); 5795 int arity = function->scope()->num_parameters();
5786 HEnvironment* outer = Copy(); 5796 HEnvironment* outer = Copy();
5787 outer->Drop(arity + 1); // Including receiver. 5797 outer->Drop(arity + 1); // Including receiver.
5788 outer->ClearHistory(); 5798 outer->ClearHistory();
5789 Zone* zone = closure()->GetIsolate()->zone(); 5799 Zone* zone = closure()->GetIsolate()->zone();
5790 HEnvironment* inner = 5800 HEnvironment* inner =
5791 new(zone) HEnvironment(outer, function->scope(), target); 5801 new(zone) HEnvironment(outer, function->scope(), target);
5792 // Get the argument values from the original environment. 5802 // Get the argument values from the original environment.
5793 if (compilation_phase == HYDROGEN) { 5803 if (compilation_phase == HYDROGEN) {
5794 for (int i = 0; i <= arity; ++i) { // Include receiver. 5804 for (int i = 0; i <= arity; ++i) { // Include receiver.
5795 HValue* push = ExpressionStackAt(arity - i); 5805 HValue* push = ExpressionStackAt(arity - i);
5796 inner->SetValueAt(i, push); 5806 inner->SetValueAt(i, push);
5797 } 5807 }
5798 } else { 5808 } else {
5799 ASSERT(compilation_phase == LITHIUM); 5809 ASSERT(compilation_phase == LITHIUM);
5800 for (int i = 0; i <= arity; ++i) { // Include receiver. 5810 for (int i = 0; i <= arity; ++i) { // Include receiver.
5801 HValue* push = ExpressionStackAt(arity - i); 5811 HValue* push = ExpressionStackAt(arity - i);
5802 inner->SetValueAt(i, push); 5812 inner->SetValueAt(i, push);
5803 } 5813 }
5804 } 5814 }
5815 // If the function we are inlining is a strict mode function, pass
5816 // undefined as the implicit receiver.
5817 if (function->strict_mode() && receiver_type == IMPLICIT_RECEIVER) {
5818 inner->SetValueAt(0, undefined);
5819 }
5805 inner->SetValueAt(arity + 1, outer->LookupContext()); 5820 inner->SetValueAt(arity + 1, outer->LookupContext());
5806 for (int i = arity + 2; i < inner->length(); ++i) { 5821 for (int i = arity + 2; i < inner->length(); ++i) {
5807 inner->SetValueAt(i, undefined); 5822 inner->SetValueAt(i, undefined);
5808 } 5823 }
5809 5824
5810 inner->set_ast_id(AstNode::kFunctionEntryId); 5825 inner->set_ast_id(AstNode::kFunctionEntryId);
5811 return inner; 5826 return inner;
5812 } 5827 }
5813 5828
5814 5829
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
6142 } 6157 }
6143 } 6158 }
6144 6159
6145 #ifdef DEBUG 6160 #ifdef DEBUG
6146 if (graph_ != NULL) graph_->Verify(); 6161 if (graph_ != NULL) graph_->Verify();
6147 if (allocator_ != NULL) allocator_->Verify(); 6162 if (allocator_ != NULL) allocator_->Verify();
6148 #endif 6163 #endif
6149 } 6164 }
6150 6165
6151 } } // namespace v8::internal 6166 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/ia32/builtins-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698