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

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: Address comments. 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
« 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 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 4036 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 PrintF("Did not inline %s called from %s (%s).\n", 4047 PrintF("Did not inline %s called from %s (%s).\n",
4048 *target_name, *caller_name, reason); 4048 *target_name, *caller_name, reason);
4049 } 4049 }
4050 } 4050 }
4051 } 4051 }
4052 4052
4053 4053
4054 bool HGraphBuilder::TryInline(Call* expr) { 4054 bool HGraphBuilder::TryInline(Call* expr) {
4055 if (!FLAG_use_inlining) return false; 4055 if (!FLAG_use_inlining) return false;
4056 4056
4057 // The function call we are inlining is a method call if the call
4058 // is a property call.
4059 CallKind call_kind = (expr->expression()->AsProperty() == NULL)
4060 ? CALL_AS_FUNCTION
4061 : CALL_AS_METHOD;
4062
4057 // Precondition: call is monomorphic and we have found a target with the 4063 // Precondition: call is monomorphic and we have found a target with the
4058 // appropriate arity. 4064 // appropriate arity.
4059 Handle<JSFunction> caller = info()->closure(); 4065 Handle<JSFunction> caller = info()->closure();
4060 Handle<JSFunction> target = expr->target(); 4066 Handle<JSFunction> target = expr->target();
4061 Handle<SharedFunctionInfo> target_shared(target->shared()); 4067 Handle<SharedFunctionInfo> target_shared(target->shared());
4062 4068
4063 // Do a quick check on source code length to avoid parsing large 4069 // Do a quick check on source code length to avoid parsing large
4064 // inlining candidates. 4070 // inlining candidates.
4065 if (FLAG_limit_inlining && target->shared()->SourceSize() > kMaxSourceSize) { 4071 if (FLAG_limit_inlining && target->shared()->SourceSize() > kMaxSourceSize) {
4066 TraceInline(target, caller, "target text too big"); 4072 TraceInline(target, caller, "target text too big");
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
4182 TypeFeedbackOracle target_oracle( 4188 TypeFeedbackOracle target_oracle(
4183 Handle<Code>(target_shared->code()), 4189 Handle<Code>(target_shared->code()),
4184 Handle<Context>(target->context()->global_context())); 4190 Handle<Context>(target->context()->global_context()));
4185 FunctionState target_state(this, &target_info, &target_oracle); 4191 FunctionState target_state(this, &target_info, &target_oracle);
4186 4192
4187 HConstant* undefined = graph()->GetConstantUndefined(); 4193 HConstant* undefined = graph()->GetConstantUndefined();
4188 HEnvironment* inner_env = 4194 HEnvironment* inner_env =
4189 environment()->CopyForInlining(target, 4195 environment()->CopyForInlining(target,
4190 function, 4196 function,
4191 HEnvironment::HYDROGEN, 4197 HEnvironment::HYDROGEN,
4192 undefined); 4198 undefined,
4199 call_kind);
4193 HBasicBlock* body_entry = CreateBasicBlock(inner_env); 4200 HBasicBlock* body_entry = CreateBasicBlock(inner_env);
4194 current_block()->Goto(body_entry); 4201 current_block()->Goto(body_entry);
4195 4202
4196 body_entry->SetJoinId(expr->ReturnId()); 4203 body_entry->SetJoinId(expr->ReturnId());
4197 set_current_block(body_entry); 4204 set_current_block(body_entry);
4198 AddInstruction(new(zone()) HEnterInlined(target, function)); 4205 AddInstruction(new(zone()) HEnterInlined(target,
4206 function,
4207 call_kind));
4199 VisitStatements(function->body()); 4208 VisitStatements(function->body());
4200 if (HasStackOverflow()) { 4209 if (HasStackOverflow()) {
4201 // Bail out if the inline function did, as we cannot residualize a call 4210 // Bail out if the inline function did, as we cannot residualize a call
4202 // instead. 4211 // instead.
4203 TraceInline(target, caller, "inline graph construction failed"); 4212 TraceInline(target, caller, "inline graph construction failed");
4204 target_shared->DisableOptimization(*target); 4213 target_shared->DisableOptimization(*target);
4205 inline_bailout_ = true; 4214 inline_bailout_ = true;
4206 return true; 4215 return true;
4207 } 4216 }
4208 4217
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
4434 HValue* context = environment()->LookupContext(); 4443 HValue* context = environment()->LookupContext();
4435 call = PreProcessCall( 4444 call = PreProcessCall(
4436 new(zone()) HCallKeyed(context, key, argument_count)); 4445 new(zone()) HCallKeyed(context, key, argument_count));
4437 call->set_position(expr->position()); 4446 call->set_position(expr->position());
4438 Drop(1); // Key. 4447 Drop(1); // Key.
4439 ast_context()->ReturnInstruction(call, expr->id()); 4448 ast_context()->ReturnInstruction(call, expr->id());
4440 return; 4449 return;
4441 } 4450 }
4442 4451
4443 // Named function call. 4452 // Named function call.
4444 expr->RecordTypeFeedback(oracle()); 4453 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
4445 4454
4446 if (TryCallApply(expr)) return; 4455 if (TryCallApply(expr)) return;
4447 4456
4448 CHECK_ALIVE(VisitForValue(prop->obj())); 4457 CHECK_ALIVE(VisitForValue(prop->obj()));
4449 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4458 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4450 4459
4451 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4460 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4452 4461
4453 expr->RecordTypeFeedback(oracle());
4454 ZoneMapList* types = expr->GetReceiverTypes(); 4462 ZoneMapList* types = expr->GetReceiverTypes();
4455 4463
4456 HValue* receiver = 4464 HValue* receiver =
4457 environment()->ExpressionStackAt(expr->arguments()->length()); 4465 environment()->ExpressionStackAt(expr->arguments()->length());
4458 if (expr->IsMonomorphic()) { 4466 if (expr->IsMonomorphic()) {
4459 Handle<Map> receiver_map = 4467 Handle<Map> receiver_map =
4460 (types == NULL) ? Handle<Map>::null() : types->first(); 4468 (types == NULL) ? Handle<Map>::null() : types->first();
4461 if (TryInlineBuiltinFunction(expr, 4469 if (TryInlineBuiltinFunction(expr,
4462 receiver, 4470 receiver,
4463 receiver_map, 4471 receiver_map,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4537 4545
4538 if (TryInline(expr)) return; 4546 if (TryInline(expr)) return;
4539 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 4547 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
4540 argument_count)); 4548 argument_count));
4541 } else { 4549 } else {
4542 HValue* context = environment()->LookupContext(); 4550 HValue* context = environment()->LookupContext();
4543 PushAndAdd(new(zone()) HGlobalObject(context)); 4551 PushAndAdd(new(zone()) HGlobalObject(context));
4544 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4552 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4545 4553
4546 call = PreProcessCall(new(zone()) HCallGlobal(context, 4554 call = PreProcessCall(new(zone()) HCallGlobal(context,
4547 var->name(), 4555 var->name(),
4548 argument_count)); 4556 argument_count));
4549 } 4557 }
4550 4558
4551 } else { 4559 } else {
4552 HValue* context = environment()->LookupContext(); 4560 HValue* context = environment()->LookupContext();
4553 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4561 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4554 AddInstruction(global_object); 4562 AddInstruction(global_object);
4555 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); 4563 PushAndAdd(new(zone()) HGlobalReceiver(global_object));
4556 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4564 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4557 4565
4558 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); 4566 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count));
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
5842 HPhi* phi = new(loop_header->zone()) HPhi(i); 5850 HPhi* phi = new(loop_header->zone()) HPhi(i);
5843 phi->AddInput(values_[i]); 5851 phi->AddInput(values_[i]);
5844 new_env->values_[i] = phi; 5852 new_env->values_[i] = phi;
5845 loop_header->AddPhi(phi); 5853 loop_header->AddPhi(phi);
5846 } 5854 }
5847 new_env->ClearHistory(); 5855 new_env->ClearHistory();
5848 return new_env; 5856 return new_env;
5849 } 5857 }
5850 5858
5851 5859
5852 HEnvironment* HEnvironment::CopyForInlining(Handle<JSFunction> target, 5860 HEnvironment* HEnvironment::CopyForInlining(
5853 FunctionLiteral* function, 5861 Handle<JSFunction> target,
5854 CompilationPhase compilation_phase, 5862 FunctionLiteral* function,
5855 HConstant* undefined) const { 5863 CompilationPhase compilation_phase,
5864 HConstant* undefined,
5865 CallKind call_kind) const {
5856 // Outer environment is a copy of this one without the arguments. 5866 // Outer environment is a copy of this one without the arguments.
5857 int arity = function->scope()->num_parameters(); 5867 int arity = function->scope()->num_parameters();
5858 HEnvironment* outer = Copy(); 5868 HEnvironment* outer = Copy();
5859 outer->Drop(arity + 1); // Including receiver. 5869 outer->Drop(arity + 1); // Including receiver.
5860 outer->ClearHistory(); 5870 outer->ClearHistory();
5861 Zone* zone = closure()->GetIsolate()->zone(); 5871 Zone* zone = closure()->GetIsolate()->zone();
5862 HEnvironment* inner = 5872 HEnvironment* inner =
5863 new(zone) HEnvironment(outer, function->scope(), target); 5873 new(zone) HEnvironment(outer, function->scope(), target);
5864 // Get the argument values from the original environment. 5874 // Get the argument values from the original environment.
5865 if (compilation_phase == HYDROGEN) { 5875 if (compilation_phase == HYDROGEN) {
5866 for (int i = 0; i <= arity; ++i) { // Include receiver. 5876 for (int i = 0; i <= arity; ++i) { // Include receiver.
5867 HValue* push = ExpressionStackAt(arity - i); 5877 HValue* push = ExpressionStackAt(arity - i);
5868 inner->SetValueAt(i, push); 5878 inner->SetValueAt(i, push);
5869 } 5879 }
5870 } else { 5880 } else {
5871 ASSERT(compilation_phase == LITHIUM); 5881 ASSERT(compilation_phase == LITHIUM);
5872 for (int i = 0; i <= arity; ++i) { // Include receiver. 5882 for (int i = 0; i <= arity; ++i) { // Include receiver.
5873 HValue* push = ExpressionStackAt(arity - i); 5883 HValue* push = ExpressionStackAt(arity - i);
5874 inner->SetValueAt(i, push); 5884 inner->SetValueAt(i, push);
5875 } 5885 }
5876 } 5886 }
5887 // If the function we are inlining is a strict mode function, pass
5888 // undefined as the receiver for function calls (instead of the
5889 // global receiver).
5890 if (function->strict_mode() && call_kind == CALL_AS_FUNCTION) {
5891 inner->SetValueAt(0, undefined);
5892 }
5877 inner->SetValueAt(arity + 1, outer->LookupContext()); 5893 inner->SetValueAt(arity + 1, outer->LookupContext());
5878 for (int i = arity + 2; i < inner->length(); ++i) { 5894 for (int i = arity + 2; i < inner->length(); ++i) {
5879 inner->SetValueAt(i, undefined); 5895 inner->SetValueAt(i, undefined);
5880 } 5896 }
5881 5897
5882 inner->set_ast_id(AstNode::kFunctionEntryId); 5898 inner->set_ast_id(AstNode::kFunctionEntryId);
5883 return inner; 5899 return inner;
5884 } 5900 }
5885 5901
5886 5902
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
6214 } 6230 }
6215 } 6231 }
6216 6232
6217 #ifdef DEBUG 6233 #ifdef DEBUG
6218 if (graph_ != NULL) graph_->Verify(); 6234 if (graph_ != NULL) graph_->Verify();
6219 if (allocator_ != NULL) allocator_->Verify(); 6235 if (allocator_ != NULL) allocator_->Verify();
6220 #endif 6236 #endif
6221 } 6237 }
6222 6238
6223 } } // namespace v8::internal 6239 } } // 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