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

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

Issue 1690903003: Remove support for Javascript warnings in the VM. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: 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_arm.cc ('k') | runtime/vm/intermediate_language_ia32.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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"
(...skipping 2649 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 __ CompareImmediate(temp, threshold); 2660 __ CompareImmediate(temp, threshold);
2661 __ b(slow_path->osr_entry_label(), GE); 2661 __ b(slow_path->osr_entry_label(), GE);
2662 } 2662 }
2663 if (compiler->ForceSlowPathForStackOverflow()) { 2663 if (compiler->ForceSlowPathForStackOverflow()) {
2664 __ b(slow_path->entry_label()); 2664 __ b(slow_path->entry_label());
2665 } 2665 }
2666 __ Bind(slow_path->exit_label()); 2666 __ Bind(slow_path->exit_label());
2667 } 2667 }
2668 2668
2669 2669
2670 static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler,
2671 Range* range,
2672 Label* overflow,
2673 Register result) {
2674 if (!RangeUtils::IsWithin(range, -0x20000000000000LL, 0x20000000000000LL)) {
2675 ASSERT(overflow != NULL);
2676 __ LoadImmediate(TMP, 0x20000000000000LL);
2677 __ add(TMP2, result, Operand(TMP));
2678 __ cmp(TMP2, Operand(TMP, LSL, 1));
2679 __ b(overflow, HI);
2680 }
2681 }
2682
2683
2684 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2670 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2685 BinarySmiOpInstr* shift_left) { 2671 BinarySmiOpInstr* shift_left) {
2686 const LocationSummary& locs = *shift_left->locs(); 2672 const LocationSummary& locs = *shift_left->locs();
2687 const Register left = locs.in(0).reg(); 2673 const Register left = locs.in(0).reg();
2688 const Register result = locs.out(0).reg(); 2674 const Register result = locs.out(0).reg();
2689 Label* deopt = shift_left->CanDeoptimize() ? 2675 Label* deopt = shift_left->CanDeoptimize() ?
2690 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) 2676 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp)
2691 : NULL; 2677 : NULL;
2692 if (locs.in(1).IsConstant()) { 2678 if (locs.in(1).IsConstant()) {
2693 const Object& constant = locs.in(1).constant(); 2679 const Object& constant = locs.in(1).constant();
2694 ASSERT(constant.IsSmi()); 2680 ASSERT(constant.IsSmi());
2695 // Immediate shift operation takes 6 bits for the count. 2681 // Immediate shift operation takes 6 bits for the count.
2696 const intptr_t kCountLimit = 0x3F; 2682 const intptr_t kCountLimit = 0x3F;
2697 const intptr_t value = Smi::Cast(constant).Value(); 2683 const intptr_t value = Smi::Cast(constant).Value();
2698 ASSERT((0 < value) && (value < kCountLimit)); 2684 ASSERT((0 < value) && (value < kCountLimit));
2699 if (shift_left->can_overflow()) { 2685 if (shift_left->can_overflow()) {
2700 // Check for overflow (preserve left). 2686 // Check for overflow (preserve left).
2701 __ LslImmediate(TMP, left, value); 2687 __ LslImmediate(TMP, left, value);
2702 __ cmp(left, Operand(TMP, ASR, value)); 2688 __ cmp(left, Operand(TMP, ASR, value));
2703 __ b(deopt, NE); // Overflow. 2689 __ b(deopt, NE); // Overflow.
2704 } 2690 }
2705 // Shift for result now we know there is no overflow. 2691 // Shift for result now we know there is no overflow.
2706 __ LslImmediate(result, left, value); 2692 __ LslImmediate(result, left, value);
2707 if (FLAG_throw_on_javascript_int_overflow) {
2708 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2709 }
2710 return; 2693 return;
2711 } 2694 }
2712 2695
2713 // Right (locs.in(1)) is not constant. 2696 // Right (locs.in(1)) is not constant.
2714 const Register right = locs.in(1).reg(); 2697 const Register right = locs.in(1).reg();
2715 Range* right_range = shift_left->right()->definition()->range(); 2698 Range* right_range = shift_left->right()->definition()->range();
2716 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { 2699 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
2717 // TODO(srdjan): Implement code below for is_truncating(). 2700 // TODO(srdjan): Implement code below for is_truncating().
2718 // If left is constant, we know the maximal allowed size for right. 2701 // If left is constant, we know the maximal allowed size for right.
2719 const Object& obj = shift_left->left()->BoundConstant(); 2702 const Object& obj = shift_left->left()->BoundConstant();
2720 if (obj.IsSmi()) { 2703 if (obj.IsSmi()) {
2721 const intptr_t left_int = Smi::Cast(obj).Value(); 2704 const intptr_t left_int = Smi::Cast(obj).Value();
2722 if (left_int == 0) { 2705 if (left_int == 0) {
2723 __ CompareRegisters(right, ZR); 2706 __ CompareRegisters(right, ZR);
2724 __ b(deopt, MI); 2707 __ b(deopt, MI);
2725 __ mov(result, ZR); 2708 __ mov(result, ZR);
2726 return; 2709 return;
2727 } 2710 }
2728 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); 2711 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
2729 const bool right_needs_check = 2712 const bool right_needs_check =
2730 !RangeUtils::IsWithin(right_range, 0, max_right - 1); 2713 !RangeUtils::IsWithin(right_range, 0, max_right - 1);
2731 if (right_needs_check) { 2714 if (right_needs_check) {
2732 __ CompareImmediate(right, 2715 __ CompareImmediate(right,
2733 reinterpret_cast<int64_t>(Smi::New(max_right))); 2716 reinterpret_cast<int64_t>(Smi::New(max_right)));
2734 __ b(deopt, CS); 2717 __ b(deopt, CS);
2735 } 2718 }
2736 __ SmiUntag(TMP, right); 2719 __ SmiUntag(TMP, right);
2737 __ lslv(result, left, TMP); 2720 __ lslv(result, left, TMP);
2738 } 2721 }
2739 if (FLAG_throw_on_javascript_int_overflow) {
2740 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2741 }
2742 return; 2722 return;
2743 } 2723 }
2744 2724
2745 const bool right_needs_check = 2725 const bool right_needs_check =
2746 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); 2726 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1));
2747 if (!shift_left->can_overflow()) { 2727 if (!shift_left->can_overflow()) {
2748 if (right_needs_check) { 2728 if (right_needs_check) {
2749 const bool right_may_be_negative = 2729 const bool right_may_be_negative =
2750 (right_range == NULL) || !right_range->IsPositive(); 2730 (right_range == NULL) || !right_range->IsPositive();
2751 if (right_may_be_negative) { 2731 if (right_may_be_negative) {
(...skipping 24 matching lines...) Expand all
2776 __ SmiUntag(TMP, right); 2756 __ SmiUntag(TMP, right);
2777 // Overflow test (preserve left, right, and TMP); 2757 // Overflow test (preserve left, right, and TMP);
2778 const Register temp = locs.temp(0).reg(); 2758 const Register temp = locs.temp(0).reg();
2779 __ lslv(temp, left, TMP); 2759 __ lslv(temp, left, TMP);
2780 __ asrv(TMP2, temp, TMP); 2760 __ asrv(TMP2, temp, TMP);
2781 __ CompareRegisters(left, TMP2); 2761 __ CompareRegisters(left, TMP2);
2782 __ b(deopt, NE); // Overflow. 2762 __ b(deopt, NE); // Overflow.
2783 // Shift for result now we know there is no overflow. 2763 // Shift for result now we know there is no overflow.
2784 __ lslv(result, left, TMP); 2764 __ lslv(result, left, TMP);
2785 } 2765 }
2786 if (FLAG_throw_on_javascript_int_overflow) {
2787 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
2788 }
2789 } 2766 }
2790 2767
2791 2768
2792 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, 2769 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
2793 bool opt) const { 2770 bool opt) const {
2794 const intptr_t kNumInputs = 2; 2771 const intptr_t kNumInputs = 2;
2795 const intptr_t kNumTemps = 2772 const intptr_t kNumTemps =
2796 (((op_kind() == Token::kSHL) && can_overflow()) || 2773 (((op_kind() == Token::kSHL) && can_overflow()) ||
2797 (op_kind() == Token::kSHR)) ? 1 : 0; 2774 (op_kind() == Token::kSHR)) ? 1 : 0;
2798 LocationSummary* summary = new(zone) LocationSummary( 2775 LocationSummary* summary = new(zone) LocationSummary(
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 intptr_t value = Smi::Cast(constant).Value(); 2891 intptr_t value = Smi::Cast(constant).Value();
2915 __ AsrImmediate( 2892 __ AsrImmediate(
2916 result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit)); 2893 result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit));
2917 __ SmiTag(result); 2894 __ SmiTag(result);
2918 break; 2895 break;
2919 } 2896 }
2920 default: 2897 default:
2921 UNREACHABLE(); 2898 UNREACHABLE();
2922 break; 2899 break;
2923 } 2900 }
2924 if (FLAG_throw_on_javascript_int_overflow) {
2925 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
2926 }
2927 return; 2901 return;
2928 } 2902 }
2929 2903
2930 const Register right = locs()->in(1).reg(); 2904 const Register right = locs()->in(1).reg();
2931 Range* right_range = this->right()->definition()->range(); 2905 Range* right_range = this->right()->definition()->range();
2932 switch (op_kind()) { 2906 switch (op_kind()) {
2933 case Token::kADD: { 2907 case Token::kADD: {
2934 if (deopt == NULL) { 2908 if (deopt == NULL) {
2935 __ add(result, left, Operand(right)); 2909 __ add(result, left, Operand(right));
2936 } else { 2910 } else {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3059 case Token::kAND: { 3033 case Token::kAND: {
3060 // Flow graph builder has dissected this operation to guarantee correct 3034 // Flow graph builder has dissected this operation to guarantee correct
3061 // behavior (short-circuit evaluation). 3035 // behavior (short-circuit evaluation).
3062 UNREACHABLE(); 3036 UNREACHABLE();
3063 break; 3037 break;
3064 } 3038 }
3065 default: 3039 default:
3066 UNREACHABLE(); 3040 UNREACHABLE();
3067 break; 3041 break;
3068 } 3042 }
3069 if (FLAG_throw_on_javascript_int_overflow) {
3070 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
3071 }
3072 } 3043 }
3073 3044
3074 3045
3075 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone, 3046 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone,
3076 bool opt) const { 3047 bool opt) const {
3077 intptr_t left_cid = left()->Type()->ToCid(); 3048 intptr_t left_cid = left()->Type()->ToCid();
3078 intptr_t right_cid = right()->Type()->ToCid(); 3049 intptr_t right_cid = right()->Type()->ToCid();
3079 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 3050 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
3080 const intptr_t kNumInputs = 2; 3051 const intptr_t kNumInputs = 2;
3081 const intptr_t kNumTemps = 0; 3052 const intptr_t kNumTemps = 0;
(...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after
4520 4491
4521 4492
4522 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4493 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4523 const Register value = locs()->in(0).reg(); 4494 const Register value = locs()->in(0).reg();
4524 const Register result = locs()->out(0).reg(); 4495 const Register result = locs()->out(0).reg();
4525 switch (op_kind()) { 4496 switch (op_kind()) {
4526 case Token::kNEGATE: { 4497 case Token::kNEGATE: {
4527 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); 4498 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
4528 __ subs(result, ZR, Operand(value)); 4499 __ subs(result, ZR, Operand(value));
4529 __ b(deopt, VS); 4500 __ b(deopt, VS);
4530 if (FLAG_throw_on_javascript_int_overflow) {
4531 EmitJavascriptOverflowCheck(compiler, range(), deopt, value);
4532 }
4533 break; 4501 break;
4534 } 4502 }
4535 case Token::kBIT_NOT: 4503 case Token::kBIT_NOT:
4536 __ mvn(result, value); 4504 __ mvn(result, value);
4537 // Remove inverted smi-tag. 4505 // Remove inverted smi-tag.
4538 __ andi(result, result, Immediate(~kSmiTagMask)); 4506 __ andi(result, result, Immediate(~kSmiTagMask));
4539 break; 4507 break;
4540 default: 4508 default:
4541 UNREACHABLE(); 4509 UNREACHABLE();
4542 } 4510 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4638 __ fcmpd(VTMP, VTMP); 4606 __ fcmpd(VTMP, VTMP);
4639 __ b(&do_call, VS); 4607 __ b(&do_call, VS);
4640 4608
4641 __ fcvtzds(result, VTMP); 4609 __ fcvtzds(result, VTMP);
4642 // Overflow is signaled with minint. 4610 // Overflow is signaled with minint.
4643 4611
4644 // Check for overflow and that it fits into Smi. 4612 // Check for overflow and that it fits into Smi.
4645 __ CompareImmediate(result, 0xC000000000000000); 4613 __ CompareImmediate(result, 0xC000000000000000);
4646 __ b(&do_call, MI); 4614 __ b(&do_call, MI);
4647 __ SmiTag(result); 4615 __ SmiTag(result);
4648 if (FLAG_throw_on_javascript_int_overflow) {
4649 EmitJavascriptOverflowCheck(compiler, range(), &do_call, result);
4650 }
4651 __ b(&done); 4616 __ b(&done);
4652 __ Bind(&do_call); 4617 __ Bind(&do_call);
4653 __ Push(value_obj); 4618 __ Push(value_obj);
4654 ASSERT(instance_call()->HasICData()); 4619 ASSERT(instance_call()->HasICData());
4655 const ICData& ic_data = *instance_call()->ic_data(); 4620 const ICData& ic_data = *instance_call()->ic_data();
4656 ASSERT((ic_data.NumberOfChecks() == 1)); 4621 ASSERT((ic_data.NumberOfChecks() == 1));
4657 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 4622 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
4658 4623
4659 const intptr_t kNumberOfArguments = 1; 4624 const intptr_t kNumberOfArguments = 1;
4660 compiler->GenerateStaticCall(deopt_id(), 4625 compiler->GenerateStaticCall(deopt_id(),
(...skipping 27 matching lines...) Expand all
4688 // on ARM64 because fcvtzds gives 0 for NaN. 4653 // on ARM64 because fcvtzds gives 0 for NaN.
4689 // TODO(zra): Check spec that this is true. 4654 // TODO(zra): Check spec that this is true.
4690 __ fcmpd(value, value); 4655 __ fcmpd(value, value);
4691 __ b(deopt, VS); 4656 __ b(deopt, VS);
4692 4657
4693 __ fcvtzds(result, value); 4658 __ fcvtzds(result, value);
4694 // Check for overflow and that it fits into Smi. 4659 // Check for overflow and that it fits into Smi.
4695 __ CompareImmediate(result, 0xC000000000000000); 4660 __ CompareImmediate(result, 0xC000000000000000);
4696 __ b(deopt, MI); 4661 __ b(deopt, MI);
4697 __ SmiTag(result); 4662 __ SmiTag(result);
4698 if (FLAG_throw_on_javascript_int_overflow) {
4699 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
4700 }
4701 } 4663 }
4702 4664
4703 4665
4704 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone, 4666 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
4705 bool opt) const { 4667 bool opt) const {
4706 UNIMPLEMENTED(); 4668 UNIMPLEMENTED();
4707 return NULL; 4669 return NULL;
4708 } 4670 }
4709 4671
4710 4672
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
5004 // } 4966 // }
5005 Label done; 4967 Label done;
5006 __ CompareRegisters(result_mod, ZR);; 4968 __ CompareRegisters(result_mod, ZR);;
5007 __ b(&done, GE); 4969 __ b(&done, GE);
5008 // Result is negative, adjust it. 4970 // Result is negative, adjust it.
5009 __ CompareRegisters(right, ZR); 4971 __ CompareRegisters(right, ZR);
5010 __ sub(TMP2, result_mod, Operand(right)); 4972 __ sub(TMP2, result_mod, Operand(right));
5011 __ add(TMP, result_mod, Operand(right)); 4973 __ add(TMP, result_mod, Operand(right));
5012 __ csel(result_mod, TMP, TMP2, GE); 4974 __ csel(result_mod, TMP, TMP2, GE);
5013 __ Bind(&done); 4975 __ Bind(&done);
5014 // FLAG_throw_on_javascript_int_overflow: not needed.
5015 // Note that the result of an integer division/modulo of two
5016 // in-range arguments, cannot create out-of-range result.
5017 return; 4976 return;
5018 } 4977 }
5019 if (kind() == MergedMathInstr::kSinCos) { 4978 if (kind() == MergedMathInstr::kSinCos) {
5020 UNIMPLEMENTED(); 4979 UNIMPLEMENTED();
5021 } 4980 }
5022 UNIMPLEMENTED(); 4981 UNIMPLEMENTED();
5023 } 4982 }
5024 4983
5025 4984
5026 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 4985 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
5623 1, 5582 1,
5624 locs()); 5583 locs());
5625 __ Drop(1); 5584 __ Drop(1);
5626 __ Pop(result); 5585 __ Pop(result);
5627 } 5586 }
5628 5587
5629 5588
5630 } // namespace dart 5589 } // namespace dart
5631 5590
5632 #endif // defined TARGET_ARCH_ARM64 5591 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698