Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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( | |
| 7671 int receiver_index, | |
| 7672 Handle<JSFunction> function) { | |
| 7673 // TODO(dcarney): Fix deserializer to be able to hookup the global receiver | |
| 7674 // and object during deserialization and embed the global receiver here | |
| 7675 // directly. | |
| 7676 // Install global receiver on stack. | |
| 7677 HValue* function_constant = Add<HConstant>(function); | |
| 7678 HValue* context = Add<HLoadNamedField>( | |
| 7679 function_constant, | |
| 7680 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); | |
| 7681 HValue* global_object = Add<HLoadNamedField>( | |
| 7682 context, | |
| 7683 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | |
| 7684 HValue* global_receiver = Add<HLoadNamedField>( | |
| 7685 global_object, | |
| 7686 HObjectAccess::ForJSObjectOffset(GlobalObject::kGlobalReceiverOffset)); | |
| 7687 environment()->SetExpressionStackAt(receiver_index, global_receiver); | |
| 7688 } | |
| 7689 | |
| 7690 | |
| 7691 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 7672 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| 7692 ASSERT(!HasStackOverflow()); | 7673 ASSERT(!HasStackOverflow()); |
| 7693 ASSERT(current_block() != NULL); | 7674 ASSERT(current_block() != NULL); |
| 7694 ASSERT(current_block()->HasPredecessor()); | 7675 ASSERT(current_block()->HasPredecessor()); |
| 7695 Expression* callee = expr->expression(); | 7676 Expression* callee = expr->expression(); |
| 7696 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 7677 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 7697 HInstruction* call = NULL; | 7678 HInstruction* call = NULL; |
| 7698 | 7679 |
| 7699 Property* prop = callee->AsProperty(); | 7680 Property* prop = callee->AsProperty(); |
| 7700 if (prop != NULL) { | 7681 if (prop != NULL) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7795 if (type == kUseCell && | 7776 if (type == kUseCell && |
| 7796 !current_info()->global_object()->IsAccessCheckNeeded()) { | 7777 !current_info()->global_object()->IsAccessCheckNeeded()) { |
| 7797 Handle<GlobalObject> global(current_info()->global_object()); | 7778 Handle<GlobalObject> global(current_info()->global_object()); |
| 7798 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 7779 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
| 7799 } | 7780 } |
| 7800 if (known_global_function) { | 7781 if (known_global_function) { |
| 7801 // Push the global object instead of the global receiver because | 7782 // Push the global object instead of the global receiver because |
| 7802 // code generated by the full code generator expects it. | 7783 // code generated by the full code generator expects it. |
| 7803 HGlobalObject* global_object = Add<HGlobalObject>(); | 7784 HGlobalObject* global_object = Add<HGlobalObject>(); |
| 7804 Push(global_object); | 7785 Push(global_object); |
| 7786 | |
| 7805 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7787 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 7806 | 7788 |
| 7807 CHECK_ALIVE(VisitForValue(expr->expression())); | 7789 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 7808 HValue* function = Pop(); | 7790 HValue* function = Pop(); |
| 7809 Add<HCheckValue>(function, expr->target()); | 7791 Add<HCheckValue>(function, expr->target()); |
| 7810 | 7792 |
| 7811 // Install global receiver on stack. | 7793 // Patch the global object on the stack by the expected receiver. |
| 7794 Handle<JSFunction> target = expr->target(); | |
| 7795 SharedFunctionInfo* shared = target->shared(); | |
| 7796 HValue* receiver; | |
| 7812 const int receiver_index = argument_count - 1; | 7797 const int receiver_index = argument_count - 1; |
| 7813 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 7798 if (shared->is_classic_mode() && !shared->native()) { |
|
dcarney
2014/01/13 18:35:03
not really for this patch maybe, but:
is_classic_
| |
| 7814 IsGlobalObject()); | 7799 HValue* context = Add<HLoadNamedField>( |
| 7815 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); | 7800 function, |
| 7801 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); | |
| 7802 HValue* global_object = Add<HLoadNamedField>( | |
| 7803 context, | |
| 7804 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | |
| 7805 receiver = Add<HLoadNamedField>( | |
| 7806 global_object, | |
| 7807 HObjectAccess::ForJSObjectOffset( | |
| 7808 GlobalObject::kGlobalReceiverOffset)); | |
| 7809 } else { | |
| 7810 receiver = graph()->GetConstantUndefined(); | |
| 7811 } | |
| 7812 environment()->SetExpressionStackAt(receiver_index, receiver); | |
| 7816 | 7813 |
| 7817 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 7814 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
| 7818 if (FLAG_trace_inlining) { | 7815 if (FLAG_trace_inlining) { |
| 7819 PrintF("Inlining builtin "); | 7816 PrintF("Inlining builtin "); |
| 7820 expr->target()->ShortPrint(); | 7817 expr->target()->ShortPrint(); |
| 7821 PrintF("\n"); | 7818 PrintF("\n"); |
| 7822 } | 7819 } |
| 7823 return; | 7820 return; |
| 7824 } | 7821 } |
| 7825 if (TryInlineCall(expr)) return; | 7822 if (TryInlineCall(expr)) return; |
| 7826 | 7823 |
| 7827 if (expr->target().is_identical_to(current_info()->closure())) { | 7824 if (expr->target().is_identical_to(current_info()->closure())) { |
| 7828 graph()->MarkRecursive(); | 7825 graph()->MarkRecursive(); |
| 7829 } | 7826 } |
| 7830 | 7827 |
| 7831 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7828 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
| 7832 // We're about to install a contextual IC, which expects the global | 7829 // We're about to install a contextual IC, which expects the global |
| 7833 // object as receiver rather than the global proxy. | 7830 // object as receiver rather than the global proxy. |
| 7831 HGlobalObject* global_object = Add<HGlobalObject>(); | |
| 7832 const int receiver_index = argument_count - 1; | |
| 7834 environment()->SetExpressionStackAt(receiver_index, global_object); | 7833 environment()->SetExpressionStackAt(receiver_index, global_object); |
| 7835 // When the target has a custom call IC generator, use the IC, | 7834 // When the target has a custom call IC generator, use the IC, |
| 7836 // because it is likely to generate better code. | 7835 // because it is likely to generate better code. |
| 7837 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count)); | 7836 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count)); |
| 7838 } else { | 7837 } else { |
| 7839 call = PreProcessCall(New<HCallKnownGlobal>( | 7838 call = PreProcessCall(New<HCallKnownGlobal>( |
| 7840 expr->target(), argument_count)); | 7839 expr->target(), argument_count)); |
| 7841 } | 7840 } |
| 7842 } else { | 7841 } else { |
| 7843 HGlobalObject* receiver = Add<HGlobalObject>(); | 7842 HGlobalObject* receiver = Add<HGlobalObject>(); |
| 7844 Push(Add<HPushArgument>(receiver)); | 7843 Push(Add<HPushArgument>(receiver)); |
| 7845 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7844 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7846 | 7845 |
| 7847 call = New<HCallGlobal>(var->name(), argument_count); | 7846 call = New<HCallGlobal>(var->name(), argument_count); |
| 7848 Drop(argument_count); | 7847 Drop(argument_count); |
| 7849 } | 7848 } |
| 7850 | 7849 |
| 7851 } else if (expr->IsMonomorphic()) { | 7850 } else if (expr->IsMonomorphic()) { |
| 7852 // The function is on the stack in the unoptimized code during | 7851 // The function is on the stack in the unoptimized code during |
| 7853 // evaluation of the arguments. | 7852 // evaluation of the arguments. |
| 7854 CHECK_ALIVE(VisitForValue(expr->expression())); | 7853 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 7855 HValue* function = Top(); | 7854 HValue* function = Top(); |
| 7856 HGlobalObject* global = Add<HGlobalObject>(); | 7855 |
| 7857 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global); | |
| 7858 Push(receiver); | |
| 7859 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
| 7860 Add<HCheckValue>(function, expr->target()); | 7856 Add<HCheckValue>(function, expr->target()); |
| 7861 | 7857 |
| 7862 // Install global receiver on stack. | 7858 Handle<JSFunction> target = expr->target(); |
| 7863 const int receiver_index = argument_count - 1; | 7859 SharedFunctionInfo* shared = target->shared(); |
| 7864 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 7860 if (shared->is_classic_mode() && !shared->native()) { |
|
dcarney
2014/01/13 18:35:03
this block is identical to the above except for th
| |
| 7865 IsGlobalReceiver()); | 7861 HValue* context = Add<HLoadNamedField>( |
| 7866 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); | 7862 function, |
| 7863 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); | |
| 7864 HValue* global_object = Add<HLoadNamedField>( | |
| 7865 context, | |
| 7866 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | |
| 7867 HValue* global_receiver = Add<HLoadNamedField>( | |
| 7868 global_object, | |
| 7869 HObjectAccess::ForJSObjectOffset( | |
| 7870 GlobalObject::kGlobalReceiverOffset)); | |
| 7871 Push(global_receiver); | |
| 7872 } else { | |
| 7873 Push(graph()->GetConstantUndefined()); | |
| 7874 } | |
| 7875 | |
| 7876 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
| 7867 | 7877 |
| 7868 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 7878 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
| 7869 if (FLAG_trace_inlining) { | 7879 if (FLAG_trace_inlining) { |
| 7870 PrintF("Inlining builtin "); | 7880 PrintF("Inlining builtin "); |
| 7871 expr->target()->ShortPrint(); | 7881 expr->target()->ShortPrint(); |
| 7872 PrintF("\n"); | 7882 PrintF("\n"); |
| 7873 } | 7883 } |
| 7874 return; | 7884 return; |
| 7875 } | 7885 } |
| 7876 | 7886 |
| 7877 if (TryInlineCall(expr, true)) { // Drop function from environment. | 7887 if (TryInlineCall(expr, true)) { // Drop function from environment. |
| 7878 return; | 7888 return; |
| 7879 } else { | 7889 } else { |
| 7880 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), | 7890 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), |
| 7881 argument_count)); | 7891 argument_count)); |
| 7882 Drop(1); // The function. | 7892 Drop(1); // The function. |
| 7883 } | 7893 } |
| 7884 | 7894 |
| 7885 } else { | 7895 } else { |
| 7886 CHECK_ALIVE(VisitForValue(expr->expression())); | 7896 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 7887 HValue* function = Top(); | 7897 HValue* function = Top(); |
| 7888 HValue* receiver = graph()->GetConstantHole(); | 7898 HValue* receiver = graph()->GetConstantUndefined(); |
| 7889 Push(Add<HPushArgument>(receiver)); | 7899 Push(Add<HPushArgument>(receiver)); |
| 7890 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7900 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7891 call = New<HCallFunction>( | 7901 call = New<HCallFunction>( |
| 7892 function, argument_count, NORMAL_CONTEXTUAL_CALL); | 7902 function, argument_count, NORMAL_CONTEXTUAL_CALL); |
| 7893 Drop(argument_count + 1); | 7903 Drop(argument_count + 1); |
| 7894 } | 7904 } |
| 7895 } | 7905 } |
| 7896 | 7906 |
| 7897 return ast_context()->ReturnInstruction(call, expr->id()); | 7907 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7898 } | 7908 } |
| (...skipping 2665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10564 new_env->ClearHistory(); | 10574 new_env->ClearHistory(); |
| 10565 return new_env; | 10575 return new_env; |
| 10566 } | 10576 } |
| 10567 | 10577 |
| 10568 | 10578 |
| 10569 HEnvironment* HEnvironment::CopyForInlining( | 10579 HEnvironment* HEnvironment::CopyForInlining( |
| 10570 Handle<JSFunction> target, | 10580 Handle<JSFunction> target, |
| 10571 int arguments, | 10581 int arguments, |
| 10572 FunctionLiteral* function, | 10582 FunctionLiteral* function, |
| 10573 HConstant* undefined, | 10583 HConstant* undefined, |
| 10574 InliningKind inlining_kind, | 10584 InliningKind inlining_kind) const { |
| 10575 bool undefined_receiver) const { | |
| 10576 ASSERT(frame_type() == JS_FUNCTION); | 10585 ASSERT(frame_type() == JS_FUNCTION); |
| 10577 | 10586 |
| 10578 // Outer environment is a copy of this one without the arguments. | 10587 // Outer environment is a copy of this one without the arguments. |
| 10579 int arity = function->scope()->num_parameters(); | 10588 int arity = function->scope()->num_parameters(); |
| 10580 | 10589 |
| 10581 HEnvironment* outer = Copy(); | 10590 HEnvironment* outer = Copy(); |
| 10582 outer->Drop(arguments + 1); // Including receiver. | 10591 outer->Drop(arguments + 1); // Including receiver. |
| 10583 outer->ClearHistory(); | 10592 outer->ClearHistory(); |
| 10584 | 10593 |
| 10585 if (inlining_kind == CONSTRUCT_CALL_RETURN) { | 10594 if (inlining_kind == CONSTRUCT_CALL_RETURN) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 10603 } | 10612 } |
| 10604 | 10613 |
| 10605 HEnvironment* inner = | 10614 HEnvironment* inner = |
| 10606 new(zone()) HEnvironment(outer, function->scope(), target, zone()); | 10615 new(zone()) HEnvironment(outer, function->scope(), target, zone()); |
| 10607 // Get the argument values from the original environment. | 10616 // Get the argument values from the original environment. |
| 10608 for (int i = 0; i <= arity; ++i) { // Include receiver. | 10617 for (int i = 0; i <= arity; ++i) { // Include receiver. |
| 10609 HValue* push = (i <= arguments) ? | 10618 HValue* push = (i <= arguments) ? |
| 10610 ExpressionStackAt(arguments - i) : undefined; | 10619 ExpressionStackAt(arguments - i) : undefined; |
| 10611 inner->SetValueAt(i, push); | 10620 inner->SetValueAt(i, push); |
| 10612 } | 10621 } |
| 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()); | 10622 inner->SetValueAt(arity + 1, context()); |
| 10620 for (int i = arity + 2; i < inner->length(); ++i) { | 10623 for (int i = arity + 2; i < inner->length(); ++i) { |
| 10621 inner->SetValueAt(i, undefined); | 10624 inner->SetValueAt(i, undefined); |
| 10622 } | 10625 } |
| 10623 | 10626 |
| 10624 inner->set_ast_id(BailoutId::FunctionEntry()); | 10627 inner->set_ast_id(BailoutId::FunctionEntry()); |
| 10625 return inner; | 10628 return inner; |
| 10626 } | 10629 } |
| 10627 | 10630 |
| 10628 | 10631 |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10975 if (ShouldProduceTraceOutput()) { | 10978 if (ShouldProduceTraceOutput()) { |
| 10976 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10979 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10977 } | 10980 } |
| 10978 | 10981 |
| 10979 #ifdef DEBUG | 10982 #ifdef DEBUG |
| 10980 graph_->Verify(false); // No full verify. | 10983 graph_->Verify(false); // No full verify. |
| 10981 #endif | 10984 #endif |
| 10982 } | 10985 } |
| 10983 | 10986 |
| 10984 } } // namespace v8::internal | 10987 } } // namespace v8::internal |
| OLD | NEW |