OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 2694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 __ testl(value, Immediate(kSmiTagMask)); | 2705 __ testl(value, Immediate(kSmiTagMask)); |
2706 __ j(NOT_ZERO, deopt); | 2706 __ j(NOT_ZERO, deopt); |
2707 } | 2707 } |
2708 | 2708 |
2709 | 2709 |
2710 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 2710 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { |
2711 const intptr_t kNumInputs = 2; | 2711 const intptr_t kNumInputs = 2; |
2712 const intptr_t kNumTemps = 0; | 2712 const intptr_t kNumTemps = 0; |
2713 LocationSummary* locs = | 2713 LocationSummary* locs = |
2714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2715 locs->set_in(0, Location::RegisterOrSmiConstant(array())); | 2715 locs->set_in(0, Location::RegisterOrSmiConstant(length())); |
2716 locs->set_in(1, Location::RegisterOrSmiConstant(index())); | 2716 locs->set_in(1, Location::RegisterOrSmiConstant(index())); |
2717 return locs; | 2717 return locs; |
2718 } | 2718 } |
2719 | 2719 |
2720 | 2720 |
2721 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2721 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2722 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2722 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
2723 kDeoptCheckArrayBound); | 2723 kDeoptCheckArrayBound); |
2724 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) { | 2724 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) { |
2725 // Unconditionally deoptimize for constant bounds checks because they | 2725 // Unconditionally deoptimize for constant bounds checks because they |
2726 // only occur only when index is out-of-bounds. | 2726 // only occur only when index is out-of-bounds. |
2727 __ jmp(deopt); | 2727 __ jmp(deopt); |
2728 return; | 2728 return; |
2729 } | 2729 } |
2730 | 2730 |
2731 intptr_t length_offset = LengthOffsetFor(array_type()); | |
2732 if (locs()->in(1).IsConstant()) { | 2731 if (locs()->in(1).IsConstant()) { |
2733 Register receiver = locs()->in(0).reg(); | 2732 Register length = locs()->in(0).reg(); |
2734 const Object& constant = locs()->in(1).constant(); | 2733 const Object& constant = locs()->in(1).constant(); |
2735 ASSERT(constant.IsSmi()); | 2734 ASSERT(constant.IsSmi()); |
2736 const int32_t imm = | 2735 const int32_t imm = |
2737 reinterpret_cast<int32_t>(constant.raw()); | 2736 reinterpret_cast<int32_t>(constant.raw()); |
2738 __ cmpl(FieldAddress(receiver, length_offset), Immediate(imm)); | 2737 __ cmpl(length, Immediate(imm)); |
2739 __ j(BELOW_EQUAL, deopt); | 2738 __ j(BELOW_EQUAL, deopt); |
2740 } else if (locs()->in(0).IsConstant()) { | 2739 } else if (locs()->in(0).IsConstant()) { |
2741 ASSERT(locs()->in(0).constant().IsArray() || | 2740 ASSERT(locs()->in(0).constant().IsSmi()); |
2742 locs()->in(0).constant().IsString()); | 2741 const Smi& smi_const = Smi::Cast(locs()->in(0).constant()); |
2743 intptr_t length = locs()->in(0).constant().IsArray() | |
2744 ? Array::Cast(locs()->in(0).constant()).Length() | |
2745 : String::Cast(locs()->in(0).constant()).Length(); | |
2746 Register index = locs()->in(1).reg(); | 2742 Register index = locs()->in(1).reg(); |
2747 __ cmpl(index, | 2743 __ cmpl(index, Immediate(reinterpret_cast<int32_t>(smi_const.raw()))); |
2748 Immediate(reinterpret_cast<int32_t>(Smi::New(length)))); | |
2749 __ j(ABOVE_EQUAL, deopt); | 2744 __ j(ABOVE_EQUAL, deopt); |
2750 } else { | 2745 } else { |
2751 Register receiver = locs()->in(0).reg(); | 2746 Register length = locs()->in(0).reg(); |
2752 Register index = locs()->in(1).reg(); | 2747 Register index = locs()->in(1).reg(); |
2753 __ cmpl(index, FieldAddress(receiver, length_offset)); | 2748 __ cmpl(index, length); |
2754 __ j(ABOVE_EQUAL, deopt); | 2749 __ j(ABOVE_EQUAL, deopt); |
2755 } | 2750 } |
2756 } | 2751 } |
2757 | 2752 |
2758 | 2753 |
2759 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 2754 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { |
2760 const intptr_t kNumInputs = 1; | 2755 const intptr_t kNumInputs = 1; |
2761 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; | 2756 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; |
2762 LocationSummary* summary = | 2757 LocationSummary* summary = |
2763 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3366 PcDescriptors::kOther, | 3361 PcDescriptors::kOther, |
3367 locs()); | 3362 locs()); |
3368 __ Drop(2); // Discard type arguments and receiver. | 3363 __ Drop(2); // Discard type arguments and receiver. |
3369 } | 3364 } |
3370 | 3365 |
3371 } // namespace dart | 3366 } // namespace dart |
3372 | 3367 |
3373 #undef __ | 3368 #undef __ |
3374 | 3369 |
3375 #endif // defined TARGET_ARCH_IA32 | 3370 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |