| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/hydrogen-osr.h" | 9 #include "src/hydrogen-osr.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 int pc_offset = masm()->pc_offset(); | 756 int pc_offset = masm()->pc_offset(); |
| 757 environment->Register(deoptimization_index, | 757 environment->Register(deoptimization_index, |
| 758 translation.index(), | 758 translation.index(), |
| 759 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 759 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); |
| 760 deoptimizations_.Add(environment, zone()); | 760 deoptimizations_.Add(environment, zone()); |
| 761 } | 761 } |
| 762 } | 762 } |
| 763 | 763 |
| 764 | 764 |
| 765 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, | 765 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, |
| 766 Deoptimizer::DeoptReason deopt_reason, |
| 766 Deoptimizer::BailoutType bailout_type, | 767 Deoptimizer::BailoutType bailout_type, |
| 767 const char* detail, Register src1, | 768 Register src1, const Operand& src2) { |
| 768 const Operand& src2) { | |
| 769 LEnvironment* environment = instr->environment(); | 769 LEnvironment* environment = instr->environment(); |
| 770 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 770 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 771 DCHECK(environment->HasBeenRegistered()); | 771 DCHECK(environment->HasBeenRegistered()); |
| 772 int id = environment->deoptimization_index(); | 772 int id = environment->deoptimization_index(); |
| 773 DCHECK(info()->IsOptimizing() || info()->IsStub()); | 773 DCHECK(info()->IsOptimizing() || info()->IsStub()); |
| 774 Address entry = | 774 Address entry = |
| 775 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 775 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 776 if (entry == NULL) { | 776 if (entry == NULL) { |
| 777 Abort(kBailoutWasNotPrepared); | 777 Abort(kBailoutWasNotPrepared); |
| 778 return; | 778 return; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 800 if (info()->ShouldTrapOnDeopt()) { | 800 if (info()->ShouldTrapOnDeopt()) { |
| 801 Label skip; | 801 Label skip; |
| 802 if (condition != al) { | 802 if (condition != al) { |
| 803 __ Branch(&skip, NegateCondition(condition), src1, src2); | 803 __ Branch(&skip, NegateCondition(condition), src1, src2); |
| 804 } | 804 } |
| 805 __ stop("trap_on_deopt"); | 805 __ stop("trap_on_deopt"); |
| 806 __ bind(&skip); | 806 __ bind(&skip); |
| 807 } | 807 } |
| 808 | 808 |
| 809 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(), | 809 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(), |
| 810 instr->Mnemonic(), detail); | 810 instr->Mnemonic(), deopt_reason); |
| 811 DCHECK(info()->IsStub() || frame_is_built_); | 811 DCHECK(info()->IsStub() || frame_is_built_); |
| 812 // Go through jump table if we need to handle condition, build frame, or | 812 // Go through jump table if we need to handle condition, build frame, or |
| 813 // restore caller doubles. | 813 // restore caller doubles. |
| 814 if (condition == al && frame_is_built_ && | 814 if (condition == al && frame_is_built_ && |
| 815 !info()->saves_caller_doubles()) { | 815 !info()->saves_caller_doubles()) { |
| 816 DeoptComment(reason); | 816 DeoptComment(reason); |
| 817 __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2); | 817 __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2); |
| 818 } else { | 818 } else { |
| 819 Deoptimizer::JumpTableEntry table_entry(entry, reason, bailout_type, | 819 Deoptimizer::JumpTableEntry table_entry(entry, reason, bailout_type, |
| 820 !frame_is_built_); | 820 !frame_is_built_); |
| 821 // We often have several deopts to the same entry, reuse the last | 821 // We often have several deopts to the same entry, reuse the last |
| 822 // jump entry if this is the case. | 822 // jump entry if this is the case. |
| 823 if (jump_table_.is_empty() || | 823 if (jump_table_.is_empty() || |
| 824 !table_entry.IsEquivalentTo(jump_table_.last())) { | 824 !table_entry.IsEquivalentTo(jump_table_.last())) { |
| 825 jump_table_.Add(table_entry, zone()); | 825 jump_table_.Add(table_entry, zone()); |
| 826 } | 826 } |
| 827 __ Branch(&jump_table_.last().label, condition, src1, src2); | 827 __ Branch(&jump_table_.last().label, condition, src1, src2); |
| 828 } | 828 } |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, | 832 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, |
| 833 const char* detail, Register src1, | 833 Deoptimizer::DeoptReason deopt_reason, |
| 834 const Operand& src2) { | 834 Register src1, const Operand& src2) { |
| 835 Deoptimizer::BailoutType bailout_type = info()->IsStub() | 835 Deoptimizer::BailoutType bailout_type = info()->IsStub() |
| 836 ? Deoptimizer::LAZY | 836 ? Deoptimizer::LAZY |
| 837 : Deoptimizer::EAGER; | 837 : Deoptimizer::EAGER; |
| 838 DeoptimizeIf(condition, instr, bailout_type, detail, src1, src2); | 838 DeoptimizeIf(condition, instr, deopt_reason, bailout_type, src1, src2); |
| 839 } | 839 } |
| 840 | 840 |
| 841 | 841 |
| 842 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 842 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 843 int length = deoptimizations_.length(); | 843 int length = deoptimizations_.length(); |
| 844 if (length == 0) return; | 844 if (length == 0) return; |
| 845 Handle<DeoptimizationInputData> data = | 845 Handle<DeoptimizationInputData> data = |
| 846 DeoptimizationInputData::New(isolate(), length, TENURED); | 846 DeoptimizationInputData::New(isolate(), length, TENURED); |
| 847 | 847 |
| 848 Handle<ByteArray> translations = | 848 Handle<ByteArray> translations = |
| (...skipping 2419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3268 } else { | 3268 } else { |
| 3269 __ dsra(at, key, -shift_size); | 3269 __ dsra(at, key, -shift_size); |
| 3270 } | 3270 } |
| 3271 __ Daddu(scratch, scratch, at); | 3271 __ Daddu(scratch, scratch, at); |
| 3272 } | 3272 } |
| 3273 | 3273 |
| 3274 __ ldc1(result, MemOperand(scratch)); | 3274 __ ldc1(result, MemOperand(scratch)); |
| 3275 | 3275 |
| 3276 if (instr->hydrogen()->RequiresHoleCheck()) { | 3276 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3277 __ lwu(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); | 3277 __ lwu(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); |
| 3278 DeoptimizeIf(eq, instr, Deopt::kHole, scratch, Operand(kHoleNanUpper32)); | 3278 DeoptimizeIf(eq, instr, Deoptimizer::kHole, scratch, |
| 3279 Operand(kHoleNanUpper32)); |
| 3279 } | 3280 } |
| 3280 } | 3281 } |
| 3281 | 3282 |
| 3282 | 3283 |
| 3283 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3284 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3284 HLoadKeyed* hinstr = instr->hydrogen(); | 3285 HLoadKeyed* hinstr = instr->hydrogen(); |
| 3285 Register elements = ToRegister(instr->elements()); | 3286 Register elements = ToRegister(instr->elements()); |
| 3286 Register result = ToRegister(instr->result()); | 3287 Register result = ToRegister(instr->result()); |
| 3287 Register scratch = scratch0(); | 3288 Register scratch = scratch0(); |
| 3288 Register store_base = scratch; | 3289 Register store_base = scratch; |
| (...skipping 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5048 __ mov(input_reg, zero_reg); // In delay slot. | 5049 __ mov(input_reg, zero_reg); // In delay slot. |
| 5049 | 5050 |
| 5050 __ bind(&check_bools); | 5051 __ bind(&check_bools); |
| 5051 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 5052 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
| 5052 __ Branch(&check_false, ne, scratch2, Operand(at)); | 5053 __ Branch(&check_false, ne, scratch2, Operand(at)); |
| 5053 __ Branch(USE_DELAY_SLOT, &done); | 5054 __ Branch(USE_DELAY_SLOT, &done); |
| 5054 __ li(input_reg, Operand(1)); // In delay slot. | 5055 __ li(input_reg, Operand(1)); // In delay slot. |
| 5055 | 5056 |
| 5056 __ bind(&check_false); | 5057 __ bind(&check_false); |
| 5057 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 5058 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
| 5058 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefinedTrueFalse, | 5059 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefinedBoolean, |
| 5059 scratch2, Operand(at)); | 5060 scratch2, Operand(at)); |
| 5060 __ Branch(USE_DELAY_SLOT, &done); | 5061 __ Branch(USE_DELAY_SLOT, &done); |
| 5061 __ mov(input_reg, zero_reg); // In delay slot. | 5062 __ mov(input_reg, zero_reg); // In delay slot. |
| 5062 } else { | 5063 } else { |
| 5063 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, scratch1, | 5064 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, scratch1, |
| 5064 Operand(at)); | 5065 Operand(at)); |
| 5065 | 5066 |
| 5066 // Load the double value. | 5067 // Load the double value. |
| 5067 __ ldc1(double_scratch, | 5068 __ ldc1(double_scratch, |
| 5068 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 5069 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5810 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { | 5811 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { |
| 5811 Deoptimizer::BailoutType type = instr->hydrogen()->type(); | 5812 Deoptimizer::BailoutType type = instr->hydrogen()->type(); |
| 5812 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the | 5813 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the |
| 5813 // needed return address), even though the implementation of LAZY and EAGER is | 5814 // needed return address), even though the implementation of LAZY and EAGER is |
| 5814 // now identical. When LAZY is eventually completely folded into EAGER, remove | 5815 // now identical. When LAZY is eventually completely folded into EAGER, remove |
| 5815 // the special case below. | 5816 // the special case below. |
| 5816 if (info()->IsStub() && type == Deoptimizer::EAGER) { | 5817 if (info()->IsStub() && type == Deoptimizer::EAGER) { |
| 5817 type = Deoptimizer::LAZY; | 5818 type = Deoptimizer::LAZY; |
| 5818 } | 5819 } |
| 5819 | 5820 |
| 5820 DeoptimizeIf(al, instr, type, instr->hydrogen()->reason(), zero_reg, | 5821 DeoptimizeIf(al, instr, instr->hydrogen()->reason(), type, zero_reg, |
| 5821 Operand(zero_reg)); | 5822 Operand(zero_reg)); |
| 5822 } | 5823 } |
| 5823 | 5824 |
| 5824 | 5825 |
| 5825 void LCodeGen::DoDummy(LDummy* instr) { | 5826 void LCodeGen::DoDummy(LDummy* instr) { |
| 5826 // Nothing to see here, move on! | 5827 // Nothing to see here, move on! |
| 5827 } | 5828 } |
| 5828 | 5829 |
| 5829 | 5830 |
| 5830 void LCodeGen::DoDummyUse(LDummyUse* instr) { | 5831 void LCodeGen::DoDummyUse(LDummyUse* instr) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6055 __ li(at, scope_info); | 6056 __ li(at, scope_info); |
| 6056 __ Push(at, ToRegister(instr->function())); | 6057 __ Push(at, ToRegister(instr->function())); |
| 6057 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6058 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6058 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6059 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6059 } | 6060 } |
| 6060 | 6061 |
| 6061 | 6062 |
| 6062 #undef __ | 6063 #undef __ |
| 6063 | 6064 |
| 6064 } } // namespace v8::internal | 6065 } } // namespace v8::internal |
| OLD | NEW |