Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 1683363002: Remove support for Javascript warnings in the VM. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intrinsifier.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph.h" 12 #include "vm/flow_graph.h"
13 #include "vm/flow_graph_compiler.h" 13 #include "vm/flow_graph_compiler.h"
14 #include "vm/flow_graph_range_analysis.h" 14 #include "vm/flow_graph_range_analysis.h"
15 #include "vm/locations.h" 15 #include "vm/locations.h"
16 #include "vm/object_store.h" 16 #include "vm/object_store.h"
17 #include "vm/parser.h" 17 #include "vm/parser.h"
18 #include "vm/stack_frame.h" 18 #include "vm/stack_frame.h"
19 #include "vm/stub_code.h" 19 #include "vm/stub_code.h"
20 #include "vm/symbols.h" 20 #include "vm/symbols.h"
21 21
22 #define __ compiler->assembler()-> 22 #define __ compiler->assembler()->
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DECLARE_FLAG(bool, allow_absolute_addresses); 26 DECLARE_FLAG(bool, allow_absolute_addresses);
27 DECLARE_FLAG(bool, emit_edge_counters); 27 DECLARE_FLAG(bool, emit_edge_counters);
28 DECLARE_FLAG(int, optimization_counter_threshold); 28 DECLARE_FLAG(int, optimization_counter_threshold);
29 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
30 DECLARE_FLAG(bool, use_osr); 29 DECLARE_FLAG(bool, use_osr);
31 DECLARE_FLAG(bool, precompilation); 30 DECLARE_FLAG(bool, precompilation);
32 31
33 // Generic summary for call instructions that have all arguments pushed 32 // Generic summary for call instructions that have all arguments pushed
34 // on the stack and return the result in a fixed register RAX. 33 // on the stack and return the result in a fixed register RAX.
35 LocationSummary* Instruction::MakeCallSummary(Zone* zone) { 34 LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
36 LocationSummary* result = new(zone) LocationSummary( 35 LocationSummary* result = new(zone) LocationSummary(
37 zone, 0, 0, LocationSummary::kCall); 36 zone, 0, 0, LocationSummary::kCall);
38 result->set_out(0, Location::RegisterLocation(RAX)); 37 result->set_out(0, Location::RegisterLocation(RAX));
39 return result; 38 return result;
(...skipping 2640 matching lines...) Expand 10 before | Expand all | Expand 10 after
2680 Immediate(threshold)); 2679 Immediate(threshold));
2681 __ j(GREATER_EQUAL, slow_path->osr_entry_label()); 2680 __ j(GREATER_EQUAL, slow_path->osr_entry_label());
2682 } 2681 }
2683 if (compiler->ForceSlowPathForStackOverflow()) { 2682 if (compiler->ForceSlowPathForStackOverflow()) {
2684 __ jmp(slow_path->entry_label()); 2683 __ jmp(slow_path->entry_label());
2685 } 2684 }
2686 __ Bind(slow_path->exit_label()); 2685 __ Bind(slow_path->exit_label());
2687 } 2686 }
2688 2687
2689 2688
2690 static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler,
2691 Range* range,
2692 Label* overflow,
2693 Register result) {
2694 if (!RangeUtils::IsWithin(range, -0x20000000000000LL, 0x20000000000000LL)) {
2695 ASSERT(overflow != NULL);
2696 // TODO(zra): This can be tightened to one compare/branch using:
2697 // overflow = (result + 2^52) > 2^53 with an unsigned comparison.
2698 __ CompareImmediate(result, Immediate(-0x20000000000000LL));
2699 __ j(LESS, overflow);
2700 __ CompareImmediate(result, Immediate(0x20000000000000LL));
2701 __ j(GREATER, overflow);
2702 }
2703 }
2704
2705
2706 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2689 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2707 BinarySmiOpInstr* shift_left) { 2690 BinarySmiOpInstr* shift_left) {
2708 const LocationSummary& locs = *shift_left->locs(); 2691 const LocationSummary& locs = *shift_left->locs();
2709 Register left = locs.in(0).reg(); 2692 Register left = locs.in(0).reg();
2710 Register result = locs.out(0).reg(); 2693 Register result = locs.out(0).reg();
2711 ASSERT(left == result); 2694 ASSERT(left == result);
2712 Label* deopt = shift_left->CanDeoptimize() ? 2695 Label* deopt = shift_left->CanDeoptimize() ?
2713 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) 2696 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp)
2714 : NULL; 2697 : NULL;
2715 if (locs.in(1).IsConstant()) { 2698 if (locs.in(1).IsConstant()) {
2716 const Object& constant = locs.in(1).constant(); 2699 const Object& constant = locs.in(1).constant();
2717 ASSERT(constant.IsSmi()); 2700 ASSERT(constant.IsSmi());
2718 // shlq operation masks the count to 6 bits. 2701 // shlq operation masks the count to 6 bits.
2719 const intptr_t kCountLimit = 0x3F; 2702 const intptr_t kCountLimit = 0x3F;
2720 const intptr_t value = Smi::Cast(constant).Value(); 2703 const intptr_t value = Smi::Cast(constant).Value();
2721 ASSERT((0 < value) && (value < kCountLimit)); 2704 ASSERT((0 < value) && (value < kCountLimit));
2722 if (shift_left->can_overflow()) { 2705 if (shift_left->can_overflow()) {
2723 // Check for overflow. 2706 // Check for overflow.
2724 Register temp = locs.temp(0).reg(); 2707 Register temp = locs.temp(0).reg();
2725 __ movq(temp, left); 2708 __ movq(temp, left);
2726 __ shlq(left, Immediate(value)); 2709 __ shlq(left, Immediate(value));
2727 __ sarq(left, Immediate(value)); 2710 __ sarq(left, Immediate(value));
2728 __ cmpq(left, temp); 2711 __ cmpq(left, temp);
2729 __ j(NOT_EQUAL, deopt); // Overflow. 2712 __ j(NOT_EQUAL, deopt); // Overflow.
2730 } 2713 }
2731 // Shift for result now we know there is no overflow. 2714 // Shift for result now we know there is no overflow.
2732 __ shlq(left, Immediate(value)); 2715 __ shlq(left, Immediate(value));
2733 if (FLAG_throw_on_javascript_int_overflow) {
2734 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2735 }
2736 return; 2716 return;
2737 } 2717 }
2738 2718
2739 // Right (locs.in(1)) is not constant. 2719 // Right (locs.in(1)) is not constant.
2740 Register right = locs.in(1).reg(); 2720 Register right = locs.in(1).reg();
2741 Range* right_range = shift_left->right()->definition()->range(); 2721 Range* right_range = shift_left->right()->definition()->range();
2742 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { 2722 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
2743 // TODO(srdjan): Implement code below for is_truncating(). 2723 // TODO(srdjan): Implement code below for is_truncating().
2744 // If left is constant, we know the maximal allowed size for right. 2724 // If left is constant, we know the maximal allowed size for right.
2745 const Object& obj = shift_left->left()->BoundConstant(); 2725 const Object& obj = shift_left->left()->BoundConstant();
2746 if (obj.IsSmi()) { 2726 if (obj.IsSmi()) {
2747 const intptr_t left_int = Smi::Cast(obj).Value(); 2727 const intptr_t left_int = Smi::Cast(obj).Value();
2748 if (left_int == 0) { 2728 if (left_int == 0) {
2749 __ CompareImmediate(right, Immediate(0)); 2729 __ CompareImmediate(right, Immediate(0));
2750 __ j(NEGATIVE, deopt); 2730 __ j(NEGATIVE, deopt);
2751 return; 2731 return;
2752 } 2732 }
2753 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); 2733 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
2754 const bool right_needs_check = 2734 const bool right_needs_check =
2755 !RangeUtils::IsWithin(right_range, 0, max_right - 1); 2735 !RangeUtils::IsWithin(right_range, 0, max_right - 1);
2756 if (right_needs_check) { 2736 if (right_needs_check) {
2757 __ CompareImmediate(right, 2737 __ CompareImmediate(right,
2758 Immediate(reinterpret_cast<int64_t>(Smi::New(max_right)))); 2738 Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
2759 __ j(ABOVE_EQUAL, deopt); 2739 __ j(ABOVE_EQUAL, deopt);
2760 } 2740 }
2761 __ SmiUntag(right); 2741 __ SmiUntag(right);
2762 __ shlq(left, right); 2742 __ shlq(left, right);
2763 } 2743 }
2764 if (FLAG_throw_on_javascript_int_overflow) {
2765 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2766 }
2767 return; 2744 return;
2768 } 2745 }
2769 2746
2770 const bool right_needs_check = 2747 const bool right_needs_check =
2771 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); 2748 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1));
2772 ASSERT(right == RCX); // Count must be in RCX 2749 ASSERT(right == RCX); // Count must be in RCX
2773 if (!shift_left->can_overflow()) { 2750 if (!shift_left->can_overflow()) {
2774 if (right_needs_check) { 2751 if (right_needs_check) {
2775 const bool right_may_be_negative = 2752 const bool right_may_be_negative =
2776 (right_range == NULL) || !right_range->IsPositive(); 2753 (right_range == NULL) || !right_range->IsPositive();
(...skipping 29 matching lines...) Expand all
2806 __ movq(temp, left); 2783 __ movq(temp, left);
2807 __ SmiUntag(right); 2784 __ SmiUntag(right);
2808 // Overflow test (preserve temp and right); 2785 // Overflow test (preserve temp and right);
2809 __ shlq(left, right); 2786 __ shlq(left, right);
2810 __ sarq(left, right); 2787 __ sarq(left, right);
2811 __ cmpq(left, temp); 2788 __ cmpq(left, temp);
2812 __ j(NOT_EQUAL, deopt); // Overflow. 2789 __ j(NOT_EQUAL, deopt); // Overflow.
2813 // Shift for result now we know there is no overflow. 2790 // Shift for result now we know there is no overflow.
2814 __ shlq(left, right); 2791 __ shlq(left, right);
2815 } 2792 }
2816 if (FLAG_throw_on_javascript_int_overflow) {
2817 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2818 }
2819 } 2793 }
2820 2794
2821 2795
2822 static bool CanBeImmediate(const Object& constant) { 2796 static bool CanBeImmediate(const Object& constant) {
2823 return constant.IsSmi() && 2797 return constant.IsSmi() &&
2824 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); 2798 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32();
2825 } 2799 }
2826 2800
2827 2801
2828 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, 2802 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2989 __ sarq(left, Immediate( 2963 __ sarq(left, Immediate(
2990 Utils::Minimum(value + kSmiTagSize, kCountLimit))); 2964 Utils::Minimum(value + kSmiTagSize, kCountLimit)));
2991 __ SmiTag(left); 2965 __ SmiTag(left);
2992 break; 2966 break;
2993 } 2967 }
2994 2968
2995 default: 2969 default:
2996 UNREACHABLE(); 2970 UNREACHABLE();
2997 break; 2971 break;
2998 } 2972 }
2999 if (FLAG_throw_on_javascript_int_overflow) {
3000 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
3001 }
3002 return; 2973 return;
3003 } // locs()->in(1).IsConstant(). 2974 } // locs()->in(1).IsConstant().
3004 2975
3005 2976
3006 if (locs()->in(1).IsStackSlot()) { 2977 if (locs()->in(1).IsStackSlot()) {
3007 const Address& right = locs()->in(1).ToStackSlotAddress(); 2978 const Address& right = locs()->in(1).ToStackSlotAddress();
3008 switch (op_kind()) { 2979 switch (op_kind()) {
3009 case Token::kADD: { 2980 case Token::kADD: {
3010 __ addq(left, right); 2981 __ addq(left, right);
3011 if (deopt != NULL) __ j(OVERFLOW, deopt); 2982 if (deopt != NULL) __ j(OVERFLOW, deopt);
(...skipping 22 matching lines...) Expand all
3034 } 3005 }
3035 case Token::kBIT_XOR: { 3006 case Token::kBIT_XOR: {
3036 // No overflow check. 3007 // No overflow check.
3037 __ xorq(left, right); 3008 __ xorq(left, right);
3038 break; 3009 break;
3039 } 3010 }
3040 default: 3011 default:
3041 UNREACHABLE(); 3012 UNREACHABLE();
3042 break; 3013 break;
3043 } 3014 }
3044 if (FLAG_throw_on_javascript_int_overflow) {
3045 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
3046 }
3047 return; 3015 return;
3048 } // locs()->in(1).IsStackSlot(). 3016 } // locs()->in(1).IsStackSlot().
3049 3017
3050 // if locs()->in(1).IsRegister. 3018 // if locs()->in(1).IsRegister.
3051 Register right = locs()->in(1).reg(); 3019 Register right = locs()->in(1).reg();
3052 Range* right_range = this->right()->definition()->range(); 3020 Range* right_range = this->right()->definition()->range();
3053 switch (op_kind()) { 3021 switch (op_kind()) {
3054 case Token::kADD: { 3022 case Token::kADD: {
3055 __ addq(left, right); 3023 __ addq(left, right);
3056 if (deopt != NULL) __ j(OVERFLOW, deopt); 3024 if (deopt != NULL) __ j(OVERFLOW, deopt);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
3233 case Token::kAND: { 3201 case Token::kAND: {
3234 // Flow graph builder has dissected this operation to guarantee correct 3202 // Flow graph builder has dissected this operation to guarantee correct
3235 // behavior (short-circuit evaluation). 3203 // behavior (short-circuit evaluation).
3236 UNREACHABLE(); 3204 UNREACHABLE();
3237 break; 3205 break;
3238 } 3206 }
3239 default: 3207 default:
3240 UNREACHABLE(); 3208 UNREACHABLE();
3241 break; 3209 break;
3242 } 3210 }
3243 if (FLAG_throw_on_javascript_int_overflow) {
3244 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
3245 }
3246 } 3211 }
3247 3212
3248 3213
3249 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone, 3214 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone,
3250 bool opt) const { 3215 bool opt) const {
3251 intptr_t left_cid = left()->Type()->ToCid(); 3216 intptr_t left_cid = left()->Type()->ToCid();
3252 intptr_t right_cid = right()->Type()->ToCid(); 3217 intptr_t right_cid = right()->Type()->ToCid();
3253 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 3218 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
3254 const intptr_t kNumInputs = 2; 3219 const intptr_t kNumInputs = 2;
3255 const bool need_temp = (left()->definition() != right()->definition()) 3220 const bool need_temp = (left()->definition() != right()->definition())
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
4725 4690
4726 4691
4727 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4692 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4728 Register value = locs()->in(0).reg(); 4693 Register value = locs()->in(0).reg();
4729 ASSERT(value == locs()->out(0).reg()); 4694 ASSERT(value == locs()->out(0).reg());
4730 switch (op_kind()) { 4695 switch (op_kind()) {
4731 case Token::kNEGATE: { 4696 case Token::kNEGATE: {
4732 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); 4697 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
4733 __ negq(value); 4698 __ negq(value);
4734 __ j(OVERFLOW, deopt); 4699 __ j(OVERFLOW, deopt);
4735 if (FLAG_throw_on_javascript_int_overflow) {
4736 EmitJavascriptOverflowCheck(compiler, range(), deopt, value);
4737 }
4738 break; 4700 break;
4739 } 4701 }
4740 case Token::kBIT_NOT: 4702 case Token::kBIT_NOT:
4741 __ notq(value); 4703 __ notq(value);
4742 // Remove inverted smi-tag. 4704 // Remove inverted smi-tag.
4743 __ AndImmediate(value, Immediate(~kSmiTagMask)); 4705 __ AndImmediate(value, Immediate(~kSmiTagMask));
4744 break; 4706 break;
4745 default: 4707 default:
4746 UNREACHABLE(); 4708 UNREACHABLE();
4747 } 4709 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
4931 ASSERT(result != temp); 4893 ASSERT(result != temp);
4932 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset())); 4894 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset()));
4933 __ cvttsd2siq(result, value_double); 4895 __ cvttsd2siq(result, value_double);
4934 // Overflow is signalled with minint. 4896 // Overflow is signalled with minint.
4935 Label do_call, done; 4897 Label do_call, done;
4936 // Check for overflow and that it fits into Smi. 4898 // Check for overflow and that it fits into Smi.
4937 __ movq(temp, result); 4899 __ movq(temp, result);
4938 __ shlq(temp, Immediate(1)); 4900 __ shlq(temp, Immediate(1));
4939 __ j(OVERFLOW, &do_call, Assembler::kNearJump); 4901 __ j(OVERFLOW, &do_call, Assembler::kNearJump);
4940 __ SmiTag(result); 4902 __ SmiTag(result);
4941 if (FLAG_throw_on_javascript_int_overflow) {
4942 EmitJavascriptOverflowCheck(compiler, range(), &do_call, result);
4943 }
4944 __ jmp(&done); 4903 __ jmp(&done);
4945 __ Bind(&do_call); 4904 __ Bind(&do_call);
4946 ASSERT(instance_call()->HasICData()); 4905 ASSERT(instance_call()->HasICData());
4947 const ICData& ic_data = *instance_call()->ic_data(); 4906 const ICData& ic_data = *instance_call()->ic_data();
4948 ASSERT((ic_data.NumberOfChecks() == 1)); 4907 ASSERT((ic_data.NumberOfChecks() == 1));
4949 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 4908 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
4950 4909
4951 const intptr_t kNumberOfArguments = 1; 4910 const intptr_t kNumberOfArguments = 1;
4952 __ pushq(value_obj); 4911 __ pushq(value_obj);
4953 compiler->GenerateStaticCall(deopt_id(), 4912 compiler->GenerateStaticCall(deopt_id(),
(...skipping 27 matching lines...) Expand all
4981 Register temp = locs()->temp(0).reg(); 4940 Register temp = locs()->temp(0).reg();
4982 4941
4983 __ cvttsd2siq(result, value); 4942 __ cvttsd2siq(result, value);
4984 // Overflow is signalled with minint. 4943 // Overflow is signalled with minint.
4985 Label do_call, done; 4944 Label do_call, done;
4986 // Check for overflow and that it fits into Smi. 4945 // Check for overflow and that it fits into Smi.
4987 __ movq(temp, result); 4946 __ movq(temp, result);
4988 __ shlq(temp, Immediate(1)); 4947 __ shlq(temp, Immediate(1));
4989 __ j(OVERFLOW, deopt); 4948 __ j(OVERFLOW, deopt);
4990 __ SmiTag(result); 4949 __ SmiTag(result);
4991 if (FLAG_throw_on_javascript_int_overflow) {
4992 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
4993 }
4994 } 4950 }
4995 4951
4996 4952
4997 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone, 4953 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
4998 bool opt) const { 4954 bool opt) const {
4999 const intptr_t kNumInputs = 1; 4955 const intptr_t kNumInputs = 1;
5000 const intptr_t kNumTemps = 0; 4956 const intptr_t kNumTemps = 0;
5001 LocationSummary* result = new(zone) LocationSummary( 4957 LocationSummary* result = new(zone) LocationSummary(
5002 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4958 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5003 result->set_in(0, Location::RequiresFpuRegister()); 4959 result->set_in(0, Location::RequiresFpuRegister());
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
5416 // Right is positive. 5372 // Right is positive.
5417 __ addq(RDX, right); 5373 __ addq(RDX, right);
5418 } else { 5374 } else {
5419 // Right is negative. 5375 // Right is negative.
5420 __ subq(RDX, right); 5376 __ subq(RDX, right);
5421 } 5377 }
5422 __ Bind(&all_done); 5378 __ Bind(&all_done);
5423 5379
5424 __ SmiTag(RAX); 5380 __ SmiTag(RAX);
5425 __ SmiTag(RDX); 5381 __ SmiTag(RDX);
5426 // FLAG_throw_on_javascript_int_overflow: not needed.
5427 // Note that the result of an integer division/modulo of two 5382 // Note that the result of an integer division/modulo of two
5428 // in-range arguments, cannot create out-of-range result. 5383 // in-range arguments, cannot create out-of-range result.
5429 return; 5384 return;
5430 } 5385 }
5431 if (kind() == MergedMathInstr::kSinCos) { 5386 if (kind() == MergedMathInstr::kSinCos) {
5432 ASSERT(locs()->out(0).IsPairLocation()); 5387 ASSERT(locs()->out(0).IsPairLocation());
5433 PairLocation* pair = locs()->out(0).AsPairLocation(); 5388 PairLocation* pair = locs()->out(0).AsPairLocation();
5434 XmmRegister out1 = pair->At(0).fpu_reg(); 5389 XmmRegister out1 = pair->At(0).fpu_reg();
5435 XmmRegister out2 = pair->At(1).fpu_reg(); 5390 XmmRegister out2 = pair->At(1).fpu_reg();
5436 5391
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
5721 const Register out = locs()->out(0).reg(); 5676 const Register out = locs()->out(0).reg();
5722 5677
5723 ASSERT(out == left); 5678 ASSERT(out == left);
5724 5679
5725 Label* deopt = NULL; 5680 Label* deopt = NULL;
5726 if (CanDeoptimize()) { 5681 if (CanDeoptimize()) {
5727 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); 5682 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5728 } 5683 }
5729 5684
5730 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt); 5685 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt);
5731
5732 if (FLAG_throw_on_javascript_int_overflow) {
5733 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5734 }
5735 } 5686 }
5736 5687
5737 5688
5738 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, 5689 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone,
5739 bool opt) const { 5690 bool opt) const {
5740 const intptr_t kNumInputs = 1; 5691 const intptr_t kNumInputs = 1;
5741 const intptr_t kNumTemps = 0; 5692 const intptr_t kNumTemps = 0;
5742 LocationSummary* summary = new(zone) LocationSummary( 5693 LocationSummary* summary = new(zone) LocationSummary(
5743 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5694 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5744 summary->set_in(0, Location::RequiresRegister()); 5695 summary->set_in(0, Location::RequiresRegister());
5745 summary->set_out(0, Location::SameAsFirstInput()); 5696 summary->set_out(0, Location::SameAsFirstInput());
5746 return summary; 5697 return summary;
5747 } 5698 }
5748 5699
5749 5700
5750 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5701 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5751 ASSERT(op_kind() == Token::kBIT_NOT); 5702 ASSERT(op_kind() == Token::kBIT_NOT);
5752 const Register left = locs()->in(0).reg(); 5703 const Register left = locs()->in(0).reg();
5753 const Register out = locs()->out(0).reg(); 5704 const Register out = locs()->out(0).reg();
5754 ASSERT(out == left); 5705 ASSERT(out == left);
5755
5756 Label* deopt = NULL;
5757 if (FLAG_throw_on_javascript_int_overflow) {
5758 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5759 }
5760
5761 __ notq(left); 5706 __ notq(left);
5762
5763 if (FLAG_throw_on_javascript_int_overflow) {
5764 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5765 }
5766 } 5707 }
5767 5708
5768 5709
5769 static const intptr_t kMintShiftCountLimit = 63; 5710 static const intptr_t kMintShiftCountLimit = 63;
5770 5711
5771 bool ShiftMintOpInstr::has_shift_count_check() const { 5712 bool ShiftMintOpInstr::has_shift_count_check() const {
5772 return !RangeUtils::IsWithin( 5713 return !RangeUtils::IsWithin(
5773 right()->definition()->range(), 0, kMintShiftCountLimit); 5714 right()->definition()->range(), 0, kMintShiftCountLimit);
5774 } 5715 }
5775 5716
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
5852 __ j(NOT_EQUAL, deopt); // Overflow. 5793 __ j(NOT_EQUAL, deopt); // Overflow.
5853 } 5794 }
5854 // Shift for result now we know there is no overflow. 5795 // Shift for result now we know there is no overflow.
5855 __ shlq(left, RCX); 5796 __ shlq(left, RCX);
5856 break; 5797 break;
5857 } 5798 }
5858 default: 5799 default:
5859 UNREACHABLE(); 5800 UNREACHABLE();
5860 } 5801 }
5861 } 5802 }
5862 if (FLAG_throw_on_javascript_int_overflow) {
5863 EmitJavascriptOverflowCheck(compiler, range(), deopt, out);
5864 }
5865 } 5803 }
5866 5804
5867 5805
5868 CompileType BinaryUint32OpInstr::ComputeType() const { 5806 CompileType BinaryUint32OpInstr::ComputeType() const {
5869 return CompileType::FromCid(kSmiCid); 5807 return CompileType::FromCid(kSmiCid);
5870 } 5808 }
5871 5809
5872 5810
5873 CompileType ShiftUint32OpInstr::ComputeType() const { 5811 CompileType ShiftUint32OpInstr::ComputeType() const {
5874 return CompileType::FromCid(kSmiCid); 5812 return CompileType::FromCid(kSmiCid);
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
6459 __ Drop(1); 6397 __ Drop(1);
6460 __ popq(result); 6398 __ popq(result);
6461 } 6399 }
6462 6400
6463 6401
6464 } // namespace dart 6402 } // namespace dart
6465 6403
6466 #undef __ 6404 #undef __
6467 6405
6468 #endif // defined TARGET_ARCH_X64 6406 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intrinsifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698