| OLD | NEW |
| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4938 | 4938 |
| 4939 | 4939 |
| 4940 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4940 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4941 comparison()->EmitBranchCode(compiler, this); | 4941 comparison()->EmitBranchCode(compiler, this); |
| 4942 } | 4942 } |
| 4943 | 4943 |
| 4944 | 4944 |
| 4945 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, | 4945 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, |
| 4946 bool opt) const { | 4946 bool opt) const { |
| 4947 const intptr_t kNumInputs = 1; | 4947 const intptr_t kNumInputs = 1; |
| 4948 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 4948 const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; |
| 4949 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | |
| 4950 LocationSummary* summary = new(isolate) LocationSummary( | 4949 LocationSummary* summary = new(isolate) LocationSummary( |
| 4951 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4950 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4952 summary->set_in(0, Location::RequiresRegister()); | 4951 summary->set_in(0, Location::RequiresRegister()); |
| 4953 if (!IsNullCheck()) { | 4952 if (!IsNullCheck()) { |
| 4954 summary->set_temp(0, Location::RequiresRegister()); | 4953 summary->set_temp(0, Location::RequiresRegister()); |
| 4955 if (need_mask_temp) { | |
| 4956 summary->set_temp(1, Location::RequiresRegister()); | |
| 4957 } | |
| 4958 } | 4954 } |
| 4959 return summary; | 4955 return summary; |
| 4960 } | 4956 } |
| 4961 | 4957 |
| 4962 | 4958 |
| 4963 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4959 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4964 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 4960 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 4965 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 4961 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 4966 if (IsNullCheck()) { | 4962 if (IsNullCheck()) { |
| 4967 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 4963 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4979 intptr_t cix = 0; | 4975 intptr_t cix = 0; |
| 4980 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 4976 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 4981 __ tsti(value, kSmiTagMask); | 4977 __ tsti(value, kSmiTagMask); |
| 4982 __ b(&is_ok, EQ); | 4978 __ b(&is_ok, EQ); |
| 4983 cix++; // Skip first check. | 4979 cix++; // Skip first check. |
| 4984 } else { | 4980 } else { |
| 4985 __ tsti(value, kSmiTagMask); | 4981 __ tsti(value, kSmiTagMask); |
| 4986 __ b(deopt, EQ); | 4982 __ b(deopt, EQ); |
| 4987 } | 4983 } |
| 4988 __ LoadClassId(temp, value, PP); | 4984 __ LoadClassId(temp, value, PP); |
| 4989 | 4985 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 4990 if (IsDenseSwitch()) { | 4986 for (intptr_t i = cix; i < num_checks; i++) { |
| 4991 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 4987 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| 4992 __ AddImmediate(temp, temp, -cids_[0], PP); | 4988 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i), PP); |
| 4993 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0], PP); | 4989 if (i == (num_checks - 1)) { |
| 4994 __ b(deopt, HI); | 4990 __ b(deopt, NE); |
| 4995 | 4991 } else { |
| 4996 intptr_t mask = ComputeCidMask(); | 4992 __ b(&is_ok, EQ); |
| 4997 if (!IsDenseMask(mask)) { | |
| 4998 // Only need mask if there are missing numbers in the range. | |
| 4999 ASSERT(cids_.length() > 2); | |
| 5000 Register mask_reg = locs()->temp(1).reg(); | |
| 5001 __ LoadImmediate(mask_reg, 1, PP); | |
| 5002 __ Lsl(mask_reg, mask_reg, temp); | |
| 5003 __ TestImmediate(mask_reg, mask, PP); | |
| 5004 __ b(deopt, EQ); | |
| 5005 } | |
| 5006 | |
| 5007 } else { | |
| 5008 const intptr_t num_checks = unary_checks().NumberOfChecks(); | |
| 5009 for (intptr_t i = cix; i < num_checks; i++) { | |
| 5010 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | |
| 5011 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i), PP); | |
| 5012 if (i == (num_checks - 1)) { | |
| 5013 __ b(deopt, NE); | |
| 5014 } else { | |
| 5015 __ b(&is_ok, EQ); | |
| 5016 } | |
| 5017 } | 4993 } |
| 5018 } | 4994 } |
| 5019 __ Bind(&is_ok); | 4995 __ Bind(&is_ok); |
| 5020 } | 4996 } |
| 5021 | 4997 |
| 5022 | 4998 |
| 5023 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, | |
| 5024 bool opt) const { | |
| 5025 const intptr_t kNumInputs = 2; | |
| 5026 const intptr_t kNumTemps = 0; | |
| 5027 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5028 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5029 summary->set_in(0, Location::RequiresRegister()); | |
| 5030 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | |
| 5031 return summary; | |
| 5032 } | |
| 5033 | |
| 5034 | |
| 5035 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5036 Register left = locs()->in(0).reg(); | |
| 5037 Location right = locs()->in(1); | |
| 5038 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | |
| 5039 if (right.IsRegister()) { | |
| 5040 __ cmp(left, Operand(right.reg())); | |
| 5041 } else { | |
| 5042 ASSERT(right.IsConstant()); | |
| 5043 const Object& right_const = Smi::Cast(right.constant()); | |
| 5044 __ CompareImmediate(left, reinterpret_cast<int64_t>(right_const.raw()), PP); | |
| 5045 } | |
| 5046 __ b(deopt, NE); | |
| 5047 } | |
| 5048 | |
| 5049 | |
| 5050 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 4999 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5051 bool opt) const { | 5000 bool opt) const { |
| 5052 const intptr_t kNumInputs = 1; | 5001 const intptr_t kNumInputs = 1; |
| 5053 const intptr_t kNumTemps = 0; | 5002 const intptr_t kNumTemps = 0; |
| 5054 LocationSummary* summary = new(isolate) LocationSummary( | 5003 LocationSummary* summary = new(isolate) LocationSummary( |
| 5055 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5004 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5056 summary->set_in(0, Location::RequiresRegister()); | 5005 summary->set_in(0, Location::RequiresRegister()); |
| 5057 return summary; | 5006 return summary; |
| 5058 } | 5007 } |
| 5059 | 5008 |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5423 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 5372 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 5424 #if defined(DEBUG) | 5373 #if defined(DEBUG) |
| 5425 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); | 5374 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); |
| 5426 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); | 5375 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); |
| 5427 #endif | 5376 #endif |
| 5428 } | 5377 } |
| 5429 | 5378 |
| 5430 } // namespace dart | 5379 } // namespace dart |
| 5431 | 5380 |
| 5432 #endif // defined TARGET_ARCH_ARM64 | 5381 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |