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

Side by Side Diff: src/hydrogen.cc

Issue 131663003: Make the strict-mode calling convention for contextual calls the default one. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix arm port Created 6 years, 11 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 4669 matching lines...) Expand 10 before | Expand all | Expand 10 after
4680 HValue* context = environment()->context(); 4680 HValue* context = environment()->context();
4681 int length = current_info()->scope()->ContextChainLength(var->scope()); 4681 int length = current_info()->scope()->ContextChainLength(var->scope());
4682 while (length-- > 0) { 4682 while (length-- > 0) {
4683 context = Add<HOuterContext>(context); 4683 context = Add<HOuterContext>(context);
4684 } 4684 }
4685 return context; 4685 return context;
4686 } 4686 }
4687 4687
4688 4688
4689 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 4689 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
4690 if (expr->is_this()) {
4691 current_info()->set_this_has_uses(true);
4692 }
4693
4690 ASSERT(!HasStackOverflow()); 4694 ASSERT(!HasStackOverflow());
4691 ASSERT(current_block() != NULL); 4695 ASSERT(current_block() != NULL);
4692 ASSERT(current_block()->HasPredecessor()); 4696 ASSERT(current_block()->HasPredecessor());
4693 Variable* variable = expr->var(); 4697 Variable* variable = expr->var();
4694 switch (variable->location()) { 4698 switch (variable->location()) {
4695 case Variable::UNALLOCATED: { 4699 case Variable::UNALLOCATED: {
4696 if (IsLexicalVariableMode(variable->mode())) { 4700 if (IsLexicalVariableMode(variable->mode())) {
4697 // TODO(rossberg): should this be an ASSERT? 4701 // TODO(rossberg): should this be an ASSERT?
4698 return Bailout(kReferenceToGlobalLexicalVariable); 4702 return Bailout(kReferenceToGlobalLexicalVariable);
4699 } 4703 }
(...skipping 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after
7203 ASSERT(target_shared->has_deoptimization_support()); 7207 ASSERT(target_shared->has_deoptimization_support());
7204 AstTyper::Run(&target_info); 7208 AstTyper::Run(&target_info);
7205 7209
7206 // Save the pending call context. Set up new one for the inlined function. 7210 // Save the pending call context. Set up new one for the inlined function.
7207 // The function state is new-allocated because we need to delete it 7211 // The function state is new-allocated because we need to delete it
7208 // in two different places. 7212 // in two different places.
7209 FunctionState* target_state = new FunctionState( 7213 FunctionState* target_state = new FunctionState(
7210 this, &target_info, inlining_kind); 7214 this, &target_info, inlining_kind);
7211 7215
7212 HConstant* undefined = graph()->GetConstantUndefined(); 7216 HConstant* undefined = graph()->GetConstantUndefined();
7213 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( 7217
7214 target, function, call_kind, inlining_kind);
7215 HEnvironment* inner_env = 7218 HEnvironment* inner_env =
7216 environment()->CopyForInlining(target, 7219 environment()->CopyForInlining(target,
7217 arguments_count, 7220 arguments_count,
7218 function, 7221 function,
7219 undefined, 7222 undefined,
7220 function_state()->inlining_kind(), 7223 function_state()->inlining_kind());
7221 undefined_receiver);
7222 7224
7223 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 7225 HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
7224 inner_env->BindContext(context); 7226 inner_env->BindContext(context);
7225 7227
7226 Add<HSimulate>(return_id); 7228 Add<HSimulate>(return_id);
7227 current_block()->UpdateEnvironment(inner_env); 7229 current_block()->UpdateEnvironment(inner_env);
7228 HArgumentsObject* arguments_object = NULL; 7230 HArgumentsObject* arguments_object = NULL;
7229 7231
7230 // If the function uses arguments object create and bind one, also copy 7232 // If the function uses arguments object create and bind one, also copy
7231 // current arguments values to use them for materialization. 7233 // current arguments values to use them for materialization.
7232 if (function->scope()->arguments() != NULL) { 7234 if (function->scope()->arguments() != NULL) {
7233 ASSERT(function->scope()->arguments()->IsStackAllocated()); 7235 ASSERT(function->scope()->arguments()->IsStackAllocated());
7234 HEnvironment* arguments_env = inner_env->arguments_environment(); 7236 HEnvironment* arguments_env = inner_env->arguments_environment();
7235 int arguments_count = arguments_env->parameter_count(); 7237 int arguments_count = arguments_env->parameter_count();
7236 arguments_object = Add<HArgumentsObject>(arguments_count); 7238 arguments_object = Add<HArgumentsObject>(arguments_count);
7237 inner_env->Bind(function->scope()->arguments(), arguments_object); 7239 inner_env->Bind(function->scope()->arguments(), arguments_object);
7238 for (int i = 0; i < arguments_count; i++) { 7240 for (int i = 0; i < arguments_count; i++) {
7239 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 7241 arguments_object->AddArgument(arguments_env->Lookup(i), zone());
7240 } 7242 }
7241 } 7243 }
7242 7244
7243 HEnterInlined* enter_inlined = 7245 HEnterInlined* enter_inlined =
7244 Add<HEnterInlined>(target, arguments_count, function, 7246 Add<HEnterInlined>(target, arguments_count, function,
7245 function_state()->inlining_kind(), 7247 function_state()->inlining_kind(),
7246 function->scope()->arguments(), 7248 function->scope()->arguments(),
7247 arguments_object, undefined_receiver); 7249 arguments_object);
7248 function_state()->set_entry(enter_inlined); 7250 function_state()->set_entry(enter_inlined);
7249 7251
7250 VisitDeclarations(target_info.scope()->declarations()); 7252 VisitDeclarations(target_info.scope()->declarations());
7251 VisitStatements(function->body()); 7253 VisitStatements(function->body());
7252 if (HasStackOverflow()) { 7254 if (HasStackOverflow()) {
7253 // Bail out if the inline function did, as we cannot residualize a call 7255 // Bail out if the inline function did, as we cannot residualize a call
7254 // instead. 7256 // instead.
7255 TraceInline(target, caller, "inline graph construction failed"); 7257 TraceInline(target, caller, "inline graph construction failed");
7256 target_shared->DisableOptimization(kInliningBailedOut); 7258 target_shared->DisableOptimization(kInliningBailedOut);
7257 inline_bailout_ = true; 7259 inline_bailout_ = true;
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
7660 HInvokeFunction* call = New<HInvokeFunction>(function, 7662 HInvokeFunction* call = New<HInvokeFunction>(function,
7661 known_function, 7663 known_function,
7662 arguments_count); 7664 arguments_count);
7663 Drop(arguments_count); 7665 Drop(arguments_count);
7664 ast_context()->ReturnInstruction(call, expr->id()); 7666 ast_context()->ReturnInstruction(call, expr->id());
7665 return true; 7667 return true;
7666 } 7668 }
7667 } 7669 }
7668 7670
7669 7671
7670 void HOptimizedGraphBuilder::InstallGlobalReceiverInExpressionStack( 7672 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
7671 int receiver_index, 7673 Handle<JSFunction> target) {
7672 Handle<JSFunction> function) { 7674 SharedFunctionInfo* shared = target->shared();
7673 // TODO(dcarney): Fix deserializer to be able to hookup the global receiver 7675 if (shared->is_classic_mode() && !shared->native()) {
7674 // and object during deserialization and embed the global receiver here 7676 HValue* context = Add<HLoadNamedField>(
7675 // directly. 7677 function,
7676 // Install global receiver on stack. 7678 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset));
7677 HValue* function_constant = Add<HConstant>(function); 7679 HValue* global_object = Add<HLoadNamedField>(
7678 HValue* context = Add<HLoadNamedField>( 7680 context,
7679 function_constant, 7681 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
7680 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); 7682 return Add<HLoadNamedField>(
7681 HValue* global_object = Add<HLoadNamedField>( 7683 global_object,
7682 context, 7684 HObjectAccess::ForJSObjectOffset(
7683 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 7685 GlobalObject::kGlobalReceiverOffset));
7684 HValue* global_receiver = Add<HLoadNamedField>( 7686 }
7685 global_object, 7687 return graph()->GetConstantUndefined();
7686 HObjectAccess::ForJSObjectOffset(GlobalObject::kGlobalReceiverOffset));
7687 environment()->SetExpressionStackAt(receiver_index, global_receiver);
7688 } 7688 }
7689 7689
7690 7690
7691 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 7691 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
7692 ASSERT(!HasStackOverflow()); 7692 ASSERT(!HasStackOverflow());
7693 ASSERT(current_block() != NULL); 7693 ASSERT(current_block() != NULL);
7694 ASSERT(current_block()->HasPredecessor()); 7694 ASSERT(current_block()->HasPredecessor());
7695 Expression* callee = expr->expression(); 7695 Expression* callee = expr->expression();
7696 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 7696 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
7697 HInstruction* call = NULL; 7697 HInstruction* call = NULL;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
7795 if (type == kUseCell && 7795 if (type == kUseCell &&
7796 !current_info()->global_object()->IsAccessCheckNeeded()) { 7796 !current_info()->global_object()->IsAccessCheckNeeded()) {
7797 Handle<GlobalObject> global(current_info()->global_object()); 7797 Handle<GlobalObject> global(current_info()->global_object());
7798 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 7798 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
7799 } 7799 }
7800 if (known_global_function) { 7800 if (known_global_function) {
7801 // Push the global object instead of the global receiver because 7801 // Push the global object instead of the global receiver because
7802 // code generated by the full code generator expects it. 7802 // code generated by the full code generator expects it.
7803 HGlobalObject* global_object = Add<HGlobalObject>(); 7803 HGlobalObject* global_object = Add<HGlobalObject>();
7804 Push(global_object); 7804 Push(global_object);
7805
7805 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7806 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7806 7807
7807 CHECK_ALIVE(VisitForValue(expr->expression())); 7808 CHECK_ALIVE(VisitForValue(expr->expression()));
7808 HValue* function = Pop(); 7809 HValue* function = Pop();
7809 Add<HCheckValue>(function, expr->target()); 7810 Add<HCheckValue>(function, expr->target());
7810 7811
7811 // Install global receiver on stack. 7812 // Patch the global object on the stack by the expected receiver.
7813 HValue* receiver = ImplicitReceiverFor(function, expr->target());
7812 const int receiver_index = argument_count - 1; 7814 const int receiver_index = argument_count - 1;
7813 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 7815 environment()->SetExpressionStackAt(receiver_index, receiver);
7814 IsGlobalObject());
7815 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target());
7816 7816
7817 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. 7817 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
7818 if (FLAG_trace_inlining) { 7818 if (FLAG_trace_inlining) {
7819 PrintF("Inlining builtin "); 7819 PrintF("Inlining builtin ");
7820 expr->target()->ShortPrint(); 7820 expr->target()->ShortPrint();
7821 PrintF("\n"); 7821 PrintF("\n");
7822 } 7822 }
7823 return; 7823 return;
7824 } 7824 }
7825 if (TryInlineCall(expr)) return; 7825 if (TryInlineCall(expr)) return;
7826 7826
7827 if (expr->target().is_identical_to(current_info()->closure())) { 7827 if (expr->target().is_identical_to(current_info()->closure())) {
7828 graph()->MarkRecursive(); 7828 graph()->MarkRecursive();
7829 } 7829 }
7830 7830
7831 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { 7831 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
7832 // We're about to install a contextual IC, which expects the global 7832 // We're about to install a contextual IC, which expects the global
7833 // object as receiver rather than the global proxy. 7833 // object as receiver rather than the global proxy.
7834 HGlobalObject* global_object = Add<HGlobalObject>();
7835 const int receiver_index = argument_count - 1;
7834 environment()->SetExpressionStackAt(receiver_index, global_object); 7836 environment()->SetExpressionStackAt(receiver_index, global_object);
7835 // When the target has a custom call IC generator, use the IC, 7837 // When the target has a custom call IC generator, use the IC,
7836 // because it is likely to generate better code. 7838 // because it is likely to generate better code.
7837 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count)); 7839 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count));
7838 } else { 7840 } else {
7839 call = PreProcessCall(New<HCallKnownGlobal>( 7841 call = PreProcessCall(New<HCallKnownGlobal>(
7840 expr->target(), argument_count)); 7842 expr->target(), argument_count));
7841 } 7843 }
7842 } else { 7844 } else {
7843 HGlobalObject* receiver = Add<HGlobalObject>(); 7845 HGlobalObject* receiver = Add<HGlobalObject>();
7844 Push(Add<HPushArgument>(receiver)); 7846 Push(Add<HPushArgument>(receiver));
7845 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7847 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7846 7848
7847 call = New<HCallGlobal>(var->name(), argument_count); 7849 call = New<HCallGlobal>(var->name(), argument_count);
7848 Drop(argument_count); 7850 Drop(argument_count);
7849 } 7851 }
7850 7852
7851 } else if (expr->IsMonomorphic()) { 7853 } else if (expr->IsMonomorphic()) {
7852 // The function is on the stack in the unoptimized code during 7854 // The function is on the stack in the unoptimized code during
7853 // evaluation of the arguments. 7855 // evaluation of the arguments.
7854 CHECK_ALIVE(VisitForValue(expr->expression())); 7856 CHECK_ALIVE(VisitForValue(expr->expression()));
7855 HValue* function = Top(); 7857 HValue* function = Top();
7856 HGlobalObject* global = Add<HGlobalObject>(); 7858
7857 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global);
7858 Push(receiver);
7859 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7860 Add<HCheckValue>(function, expr->target()); 7859 Add<HCheckValue>(function, expr->target());
7861 7860
7862 // Install global receiver on stack. 7861 HValue* receiver = ImplicitReceiverFor(function, expr->target());
7863 const int receiver_index = argument_count - 1; 7862 Push(receiver);
7864 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 7863
7865 IsGlobalReceiver()); 7864 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7866 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target());
7867 7865
7868 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. 7866 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
7869 if (FLAG_trace_inlining) { 7867 if (FLAG_trace_inlining) {
7870 PrintF("Inlining builtin "); 7868 PrintF("Inlining builtin ");
7871 expr->target()->ShortPrint(); 7869 expr->target()->ShortPrint();
7872 PrintF("\n"); 7870 PrintF("\n");
7873 } 7871 }
7874 return; 7872 return;
7875 } 7873 }
7876 7874
7877 if (TryInlineCall(expr, true)) { // Drop function from environment. 7875 if (TryInlineCall(expr, true)) { // Drop function from environment.
7878 return; 7876 return;
7879 } else { 7877 } else {
7880 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), 7878 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(),
7881 argument_count)); 7879 argument_count));
7882 Drop(1); // The function. 7880 Drop(1); // The function.
7883 } 7881 }
7884 7882
7885 } else { 7883 } else {
7886 CHECK_ALIVE(VisitForValue(expr->expression())); 7884 CHECK_ALIVE(VisitForValue(expr->expression()));
7887 HValue* function = Top(); 7885 HValue* function = Top();
7888 HValue* receiver = graph()->GetConstantHole(); 7886 HValue* receiver = graph()->GetConstantUndefined();
7889 Push(Add<HPushArgument>(receiver)); 7887 Push(Add<HPushArgument>(receiver));
7890 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7888 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7891 call = New<HCallFunction>( 7889 call = New<HCallFunction>(
7892 function, argument_count, NORMAL_CONTEXTUAL_CALL); 7890 function, argument_count, NORMAL_CONTEXTUAL_CALL);
7893 Drop(argument_count + 1); 7891 Drop(argument_count + 1);
7894 } 7892 }
7895 } 7893 }
7896 7894
7897 return ast_context()->ReturnInstruction(call, expr->id()); 7895 return ast_context()->ReturnInstruction(call, expr->id());
7898 } 7896 }
(...skipping 2665 matching lines...) Expand 10 before | Expand all | Expand 10 after
10564 new_env->ClearHistory(); 10562 new_env->ClearHistory();
10565 return new_env; 10563 return new_env;
10566 } 10564 }
10567 10565
10568 10566
10569 HEnvironment* HEnvironment::CopyForInlining( 10567 HEnvironment* HEnvironment::CopyForInlining(
10570 Handle<JSFunction> target, 10568 Handle<JSFunction> target,
10571 int arguments, 10569 int arguments,
10572 FunctionLiteral* function, 10570 FunctionLiteral* function,
10573 HConstant* undefined, 10571 HConstant* undefined,
10574 InliningKind inlining_kind, 10572 InliningKind inlining_kind) const {
10575 bool undefined_receiver) const {
10576 ASSERT(frame_type() == JS_FUNCTION); 10573 ASSERT(frame_type() == JS_FUNCTION);
10577 10574
10578 // Outer environment is a copy of this one without the arguments. 10575 // Outer environment is a copy of this one without the arguments.
10579 int arity = function->scope()->num_parameters(); 10576 int arity = function->scope()->num_parameters();
10580 10577
10581 HEnvironment* outer = Copy(); 10578 HEnvironment* outer = Copy();
10582 outer->Drop(arguments + 1); // Including receiver. 10579 outer->Drop(arguments + 1); // Including receiver.
10583 outer->ClearHistory(); 10580 outer->ClearHistory();
10584 10581
10585 if (inlining_kind == CONSTRUCT_CALL_RETURN) { 10582 if (inlining_kind == CONSTRUCT_CALL_RETURN) {
(...skipping 17 matching lines...) Expand all
10603 } 10600 }
10604 10601
10605 HEnvironment* inner = 10602 HEnvironment* inner =
10606 new(zone()) HEnvironment(outer, function->scope(), target, zone()); 10603 new(zone()) HEnvironment(outer, function->scope(), target, zone());
10607 // Get the argument values from the original environment. 10604 // Get the argument values from the original environment.
10608 for (int i = 0; i <= arity; ++i) { // Include receiver. 10605 for (int i = 0; i <= arity; ++i) { // Include receiver.
10609 HValue* push = (i <= arguments) ? 10606 HValue* push = (i <= arguments) ?
10610 ExpressionStackAt(arguments - i) : undefined; 10607 ExpressionStackAt(arguments - i) : undefined;
10611 inner->SetValueAt(i, push); 10608 inner->SetValueAt(i, push);
10612 } 10609 }
10613 // If the function we are inlining is a strict mode function or a
10614 // builtin function, pass undefined as the receiver for function
10615 // calls (instead of the global receiver).
10616 if (undefined_receiver) {
10617 inner->SetValueAt(0, undefined);
10618 }
10619 inner->SetValueAt(arity + 1, context()); 10610 inner->SetValueAt(arity + 1, context());
10620 for (int i = arity + 2; i < inner->length(); ++i) { 10611 for (int i = arity + 2; i < inner->length(); ++i) {
10621 inner->SetValueAt(i, undefined); 10612 inner->SetValueAt(i, undefined);
10622 } 10613 }
10623 10614
10624 inner->set_ast_id(BailoutId::FunctionEntry()); 10615 inner->set_ast_id(BailoutId::FunctionEntry());
10625 return inner; 10616 return inner;
10626 } 10617 }
10627 10618
10628 10619
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
10975 if (ShouldProduceTraceOutput()) { 10966 if (ShouldProduceTraceOutput()) {
10976 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10967 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10977 } 10968 }
10978 10969
10979 #ifdef DEBUG 10970 #ifdef DEBUG
10980 graph_->Verify(false); // No full verify. 10971 graph_->Verify(false); // No full verify.
10981 #endif 10972 #endif
10982 } 10973 }
10983 10974
10984 } } // namespace v8::internal 10975 } } // 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