| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 HInstruction* hinstr, | 689 HInstruction* hinstr, |
| 690 CanDeoptimize can_deoptimize) { | 690 CanDeoptimize can_deoptimize) { |
| 691 info()->MarkAsNonDeferredCalling(); | 691 info()->MarkAsNonDeferredCalling(); |
| 692 | 692 |
| 693 #ifdef DEBUG | 693 #ifdef DEBUG |
| 694 instr->VerifyCall(); | 694 instr->VerifyCall(); |
| 695 #endif | 695 #endif |
| 696 instr->MarkAsCall(); | 696 instr->MarkAsCall(); |
| 697 instr = AssignPointerMap(instr); | 697 instr = AssignPointerMap(instr); |
| 698 | 698 |
| 699 if (hinstr->HasObservableSideEffects()) { | |
| 700 ASSERT(hinstr->next()->IsSimulate()); | |
| 701 HSimulate* sim = HSimulate::cast(hinstr->next()); | |
| 702 ASSERT(instruction_pending_deoptimization_environment_ == NULL); | |
| 703 ASSERT(pending_deoptimization_ast_id_.IsNone()); | |
| 704 instruction_pending_deoptimization_environment_ = instr; | |
| 705 pending_deoptimization_ast_id_ = sim->ast_id(); | |
| 706 } | |
| 707 | |
| 708 // If instruction does not have side-effects lazy deoptimization | 699 // If instruction does not have side-effects lazy deoptimization |
| 709 // after the call will try to deoptimize to the point before the call. | 700 // after the call will try to deoptimize to the point before the call. |
| 710 // Thus we still need to attach environment to this call even if | 701 // Thus we still need to attach environment to this call even if |
| 711 // call sequence can not deoptimize eagerly. | 702 // call sequence can not deoptimize eagerly. |
| 712 bool needs_environment = | 703 bool needs_environment = |
| 713 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || | 704 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || |
| 714 !hinstr->HasObservableSideEffects(); | 705 !hinstr->HasObservableSideEffects(); |
| 715 if (needs_environment && !instr->HasEnvironment()) { | 706 if (needs_environment && !instr->HasEnvironment()) { |
| 716 instr = AssignEnvironment(instr); | 707 instr = AssignEnvironment(instr); |
| 717 } | 708 } |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 LGoto::cast(instr)->jumps_to_join()) { | 979 LGoto::cast(instr)->jumps_to_join()) { |
| 989 // TODO(olivf) Since phis of spilled values are joined as registers | 980 // TODO(olivf) Since phis of spilled values are joined as registers |
| 990 // (not in the stack slot), we need to allow the goto gaps to keep one | 981 // (not in the stack slot), we need to allow the goto gaps to keep one |
| 991 // x87 register alive. To ensure all other values are still spilled, we | 982 // x87 register alive. To ensure all other values are still spilled, we |
| 992 // insert a fpu register barrier right before. | 983 // insert a fpu register barrier right before. |
| 993 LClobberDoubles* clobber = new(zone()) LClobberDoubles(); | 984 LClobberDoubles* clobber = new(zone()) LClobberDoubles(); |
| 994 clobber->set_hydrogen_value(current); | 985 clobber->set_hydrogen_value(current); |
| 995 chunk_->AddInstruction(clobber, current_block_); | 986 chunk_->AddInstruction(clobber, current_block_); |
| 996 } | 987 } |
| 997 chunk_->AddInstruction(instr, current_block_); | 988 chunk_->AddInstruction(instr, current_block_); |
| 989 |
| 990 if (instr->IsCall()) { |
| 991 HValue* hydrogen_value_for_lazy_bailout = current; |
| 992 LInstruction* instruction_needing_environment = NULL; |
| 993 if (current->HasObservableSideEffects()) { |
| 994 HSimulate* sim = HSimulate::cast(current->next()); |
| 995 instruction_needing_environment = instr; |
| 996 sim->ReplayEnvironment(current_block_->last_environment()); |
| 997 hydrogen_value_for_lazy_bailout = sim; |
| 998 } |
| 999 LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout()); |
| 1000 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); |
| 1001 chunk_->AddInstruction(bailout, current_block_); |
| 1002 if (instruction_needing_environment != NULL) { |
| 1003 // Store the lazy deopt environment with the instruction if needed. |
| 1004 // Right now it is only used for LInstanceOfKnownGlobal. |
| 1005 instruction_needing_environment-> |
| 1006 SetDeferredLazyDeoptimizationEnvironment(bailout->environment()); |
| 1007 } |
| 1008 } |
| 998 } | 1009 } |
| 999 current_instruction_ = old_current; | 1010 current_instruction_ = old_current; |
| 1000 } | 1011 } |
| 1001 | 1012 |
| 1002 | 1013 |
| 1003 LEnvironment* LChunkBuilder::CreateEnvironment( | 1014 LEnvironment* LChunkBuilder::CreateEnvironment( |
| 1004 HEnvironment* hydrogen_env, | 1015 HEnvironment* hydrogen_env, |
| 1005 int* argument_index_accumulator, | 1016 int* argument_index_accumulator, |
| 1006 ZoneList<HValue*>* objects_to_materialize) { | 1017 ZoneList<HValue*>* objects_to_materialize) { |
| 1007 if (hydrogen_env == NULL) return NULL; | 1018 if (hydrogen_env == NULL) return NULL; |
| (...skipping 1677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2685 | 2696 |
| 2686 | 2697 |
| 2687 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2698 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| 2688 HIsConstructCallAndBranch* instr) { | 2699 HIsConstructCallAndBranch* instr) { |
| 2689 return new(zone()) LIsConstructCallAndBranch(TempRegister()); | 2700 return new(zone()) LIsConstructCallAndBranch(TempRegister()); |
| 2690 } | 2701 } |
| 2691 | 2702 |
| 2692 | 2703 |
| 2693 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2704 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 2694 instr->ReplayEnvironment(current_block_->last_environment()); | 2705 instr->ReplayEnvironment(current_block_->last_environment()); |
| 2695 | |
| 2696 // If there is an instruction pending deoptimization environment create a | |
| 2697 // lazy bailout instruction to capture the environment. | |
| 2698 if (!pending_deoptimization_ast_id_.IsNone()) { | |
| 2699 ASSERT(pending_deoptimization_ast_id_ == instr->ast_id()); | |
| 2700 LLazyBailout* lazy_bailout = new(zone()) LLazyBailout; | |
| 2701 LInstruction* result = AssignEnvironment(lazy_bailout); | |
| 2702 // Store the lazy deopt environment with the instruction if needed. Right | |
| 2703 // now it is only used for LInstanceOfKnownGlobal. | |
| 2704 instruction_pending_deoptimization_environment_-> | |
| 2705 SetDeferredLazyDeoptimizationEnvironment(result->environment()); | |
| 2706 instruction_pending_deoptimization_environment_ = NULL; | |
| 2707 pending_deoptimization_ast_id_ = BailoutId::None(); | |
| 2708 return result; | |
| 2709 } | |
| 2710 | |
| 2711 return NULL; | 2706 return NULL; |
| 2712 } | 2707 } |
| 2713 | 2708 |
| 2714 | 2709 |
| 2715 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2710 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2716 info()->MarkAsDeferredCalling(); | 2711 info()->MarkAsDeferredCalling(); |
| 2717 if (instr->is_function_entry()) { | 2712 if (instr->is_function_entry()) { |
| 2718 LOperand* context = UseFixed(instr->context(), esi); | 2713 LOperand* context = UseFixed(instr->context(), esi); |
| 2719 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2714 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2720 } else { | 2715 } else { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2784 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2790 LOperand* object = UseRegister(instr->object()); | 2785 LOperand* object = UseRegister(instr->object()); |
| 2791 LOperand* index = UseTempRegister(instr->index()); | 2786 LOperand* index = UseTempRegister(instr->index()); |
| 2792 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2787 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2793 } | 2788 } |
| 2794 | 2789 |
| 2795 | 2790 |
| 2796 } } // namespace v8::internal | 2791 } } // namespace v8::internal |
| 2797 | 2792 |
| 2798 #endif // V8_TARGET_ARCH_IA32 | 2793 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |