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 7535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7546 HInvokeFunction* call = New<HInvokeFunction>(function, | 7546 HInvokeFunction* call = New<HInvokeFunction>(function, |
7547 known_function, | 7547 known_function, |
7548 arguments_count); | 7548 arguments_count); |
7549 Drop(arguments_count); | 7549 Drop(arguments_count); |
7550 ast_context()->ReturnInstruction(call, expr->id()); | 7550 ast_context()->ReturnInstruction(call, expr->id()); |
7551 return true; | 7551 return true; |
7552 } | 7552 } |
7553 } | 7553 } |
7554 | 7554 |
7555 | 7555 |
| 7556 void HOptimizedGraphBuilder::InstallGlobalReceiverInExpressionStack( |
| 7557 int receiver_index, |
| 7558 Handle<JSFunction> function) { |
| 7559 // TODO(dcarney): Fix deserializer to be able to hookup the global receiver |
| 7560 // and object during deserialization and embed the global receiver here |
| 7561 // directly. |
| 7562 // Install global receiver on stack. |
| 7563 HValue* function_constant = Add<HConstant>(function); |
| 7564 HValue* context = Add<HLoadNamedField>( |
| 7565 function_constant, |
| 7566 HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); |
| 7567 HValue* global_object = Add<HLoadNamedField>( |
| 7568 context, |
| 7569 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 7570 HValue* global_receiver = Add<HLoadNamedField>( |
| 7571 global_object, |
| 7572 HObjectAccess::ForJSObjectOffset(GlobalObject::kGlobalReceiverOffset)); |
| 7573 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
| 7574 } |
| 7575 |
| 7576 |
7556 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 7577 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
7557 ASSERT(!HasStackOverflow()); | 7578 ASSERT(!HasStackOverflow()); |
7558 ASSERT(current_block() != NULL); | 7579 ASSERT(current_block() != NULL); |
7559 ASSERT(current_block()->HasPredecessor()); | 7580 ASSERT(current_block()->HasPredecessor()); |
7560 Expression* callee = expr->expression(); | 7581 Expression* callee = expr->expression(); |
7561 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 7582 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
7562 HInstruction* call = NULL; | 7583 HInstruction* call = NULL; |
7563 | 7584 |
7564 Property* prop = callee->AsProperty(); | 7585 Property* prop = callee->AsProperty(); |
7565 if (prop != NULL) { | 7586 if (prop != NULL) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7666 // Push the global object instead of the global receiver because | 7687 // Push the global object instead of the global receiver because |
7667 // code generated by the full code generator expects it. | 7688 // code generated by the full code generator expects it. |
7668 HGlobalObject* global_object = Add<HGlobalObject>(); | 7689 HGlobalObject* global_object = Add<HGlobalObject>(); |
7669 Push(global_object); | 7690 Push(global_object); |
7670 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7691 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
7671 | 7692 |
7672 CHECK_ALIVE(VisitForValue(expr->expression())); | 7693 CHECK_ALIVE(VisitForValue(expr->expression())); |
7673 HValue* function = Pop(); | 7694 HValue* function = Pop(); |
7674 Add<HCheckValue>(function, expr->target()); | 7695 Add<HCheckValue>(function, expr->target()); |
7675 | 7696 |
7676 // Replace the global object with the global receiver. | 7697 // Install global receiver on stack. |
7677 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); | |
7678 // Index of the receiver from the top of the expression stack. | |
7679 const int receiver_index = argument_count - 1; | 7698 const int receiver_index = argument_count - 1; |
7680 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 7699 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
7681 IsGlobalObject()); | 7700 IsGlobalObject()); |
7682 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 7701 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); |
7683 | 7702 |
7684 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 7703 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
7685 if (FLAG_trace_inlining) { | 7704 if (FLAG_trace_inlining) { |
7686 PrintF("Inlining builtin "); | 7705 PrintF("Inlining builtin "); |
7687 expr->target()->ShortPrint(); | 7706 expr->target()->ShortPrint(); |
7688 PrintF("\n"); | 7707 PrintF("\n"); |
7689 } | 7708 } |
7690 return; | 7709 return; |
7691 } | 7710 } |
7692 if (TryInlineCall(expr)) return; | 7711 if (TryInlineCall(expr)) return; |
7693 | 7712 |
7694 if (expr->target().is_identical_to(current_info()->closure())) { | 7713 if (expr->target().is_identical_to(current_info()->closure())) { |
7695 graph()->MarkRecursive(); | 7714 graph()->MarkRecursive(); |
7696 } | 7715 } |
7697 | 7716 |
7698 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7717 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
| 7718 // We're about to install a contextual IC, which expects the global |
| 7719 // object as receiver rather than the global proxy. |
| 7720 environment()->SetExpressionStackAt(receiver_index, global_object); |
7699 // When the target has a custom call IC generator, use the IC, | 7721 // When the target has a custom call IC generator, use the IC, |
7700 // because it is likely to generate better code. | 7722 // because it is likely to generate better code. |
7701 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); | 7723 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count)); |
7702 } else { | 7724 } else { |
7703 call = PreProcessCall(New<HCallKnownGlobal>( | 7725 call = PreProcessCall(New<HCallKnownGlobal>( |
7704 expr->target(), argument_count)); | 7726 expr->target(), argument_count)); |
7705 } | 7727 } |
7706 } else { | 7728 } else { |
7707 HGlobalObject* receiver = Add<HGlobalObject>(); | 7729 HGlobalObject* receiver = Add<HGlobalObject>(); |
7708 Push(Add<HPushArgument>(receiver)); | 7730 Push(Add<HPushArgument>(receiver)); |
7709 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7731 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
7710 | 7732 |
7711 call = New<HCallGlobal>(var->name(), argument_count); | 7733 call = New<HCallGlobal>(var->name(), argument_count); |
7712 Drop(argument_count); | 7734 Drop(argument_count); |
7713 } | 7735 } |
7714 | 7736 |
7715 } else if (expr->IsMonomorphic()) { | 7737 } else if (expr->IsMonomorphic()) { |
7716 // The function is on the stack in the unoptimized code during | 7738 // The function is on the stack in the unoptimized code during |
7717 // evaluation of the arguments. | 7739 // evaluation of the arguments. |
7718 CHECK_ALIVE(VisitForValue(expr->expression())); | 7740 CHECK_ALIVE(VisitForValue(expr->expression())); |
7719 HValue* function = Top(); | 7741 HValue* function = Top(); |
7720 HGlobalObject* global = Add<HGlobalObject>(); | 7742 HGlobalObject* global = Add<HGlobalObject>(); |
7721 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global); | 7743 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global); |
7722 Push(receiver); | 7744 Push(receiver); |
7723 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7745 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
7724 Add<HCheckValue>(function, expr->target()); | 7746 Add<HCheckValue>(function, expr->target()); |
7725 | 7747 |
| 7748 // Install global receiver on stack. |
| 7749 const int receiver_index = argument_count - 1; |
| 7750 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
| 7751 IsGlobalReceiver()); |
| 7752 InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); |
| 7753 |
7726 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 7754 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
7727 if (FLAG_trace_inlining) { | 7755 if (FLAG_trace_inlining) { |
7728 PrintF("Inlining builtin "); | 7756 PrintF("Inlining builtin "); |
7729 expr->target()->ShortPrint(); | 7757 expr->target()->ShortPrint(); |
7730 PrintF("\n"); | 7758 PrintF("\n"); |
7731 } | 7759 } |
7732 return; | 7760 return; |
7733 } | 7761 } |
7734 | 7762 |
7735 if (TryInlineCall(expr, true)) { // Drop function from environment. | 7763 if (TryInlineCall(expr, true)) { // Drop function from environment. |
7736 return; | 7764 return; |
7737 } else { | 7765 } else { |
7738 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), | 7766 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), |
7739 argument_count)); | 7767 argument_count)); |
7740 Drop(1); // The function. | 7768 Drop(1); // The function. |
7741 } | 7769 } |
7742 | 7770 |
7743 } else { | 7771 } else { |
7744 CHECK_ALIVE(VisitForValue(expr->expression())); | 7772 CHECK_ALIVE(VisitForValue(expr->expression())); |
7745 HValue* function = Top(); | 7773 HValue* function = Top(); |
7746 HGlobalObject* global_object = Add<HGlobalObject>(); | 7774 HValue* receiver = graph()->GetConstantHole(); |
7747 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); | |
7748 Push(Add<HPushArgument>(receiver)); | 7775 Push(Add<HPushArgument>(receiver)); |
7749 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7776 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
7750 | 7777 call = New<HCallFunction>( |
7751 call = New<HCallFunction>(function, argument_count); | 7778 function, argument_count, NORMAL_CONTEXTUAL_CALL); |
7752 Drop(argument_count + 1); | 7779 Drop(argument_count + 1); |
7753 } | 7780 } |
7754 } | 7781 } |
7755 | 7782 |
7756 return ast_context()->ReturnInstruction(call, expr->id()); | 7783 return ast_context()->ReturnInstruction(call, expr->id()); |
7757 } | 7784 } |
7758 | 7785 |
7759 | 7786 |
7760 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) { | 7787 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) { |
7761 NoObservableSideEffectsScope no_effects(this); | 7788 NoObservableSideEffectsScope no_effects(this); |
(...skipping 3015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10777 if (ShouldProduceTraceOutput()) { | 10804 if (ShouldProduceTraceOutput()) { |
10778 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10805 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10779 } | 10806 } |
10780 | 10807 |
10781 #ifdef DEBUG | 10808 #ifdef DEBUG |
10782 graph_->Verify(false); // No full verify. | 10809 graph_->Verify(false); // No full verify. |
10783 #endif | 10810 #endif |
10784 } | 10811 } |
10785 | 10812 |
10786 } } // namespace v8::internal | 10813 } } // namespace v8::internal |
OLD | NEW |