| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/constant_propagator.h" | 10 #include "vm/constant_propagator.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 126 |
| 127 | 127 |
| 128 CheckClassInstr::CheckClassInstr(Value* value, | 128 CheckClassInstr::CheckClassInstr(Value* value, |
| 129 intptr_t deopt_id, | 129 intptr_t deopt_id, |
| 130 const ICData& unary_checks, | 130 const ICData& unary_checks, |
| 131 TokenPosition token_pos) | 131 TokenPosition token_pos) |
| 132 : TemplateInstruction(deopt_id), | 132 : TemplateInstruction(deopt_id), |
| 133 unary_checks_(unary_checks), | 133 unary_checks_(unary_checks), |
| 134 cids_(unary_checks.NumberOfChecks()), | 134 cids_(unary_checks.NumberOfChecks()), |
| 135 licm_hoisted_(false), | 135 licm_hoisted_(false), |
| 136 is_dense_switch_(IsDenseCidRange(unary_checks)), |
| 136 token_pos_(token_pos) { | 137 token_pos_(token_pos) { |
| 137 ASSERT(unary_checks.IsZoneHandle()); | 138 ASSERT(unary_checks.IsZoneHandle()); |
| 138 // Expected useful check data. | 139 // Expected useful check data. |
| 139 ASSERT(!unary_checks_.IsNull()); | 140 ASSERT(!unary_checks_.IsNull()); |
| 140 ASSERT(unary_checks_.NumberOfChecks() > 0); | 141 ASSERT(unary_checks_.NumberOfChecks() > 0); |
| 141 ASSERT(unary_checks_.NumArgsTested() == 1); | 142 ASSERT(unary_checks_.NumArgsTested() == 1); |
| 142 SetInputAt(0, value); | 143 SetInputAt(0, value); |
| 143 // Otherwise use CheckSmiInstr. | 144 // Otherwise use CheckSmiInstr. |
| 144 ASSERT((unary_checks_.NumberOfChecks() != 1) || | 145 ASSERT((unary_checks_.NumberOfChecks() != 1) || |
| 145 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); | 146 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 // we can check against null instance instead. | 225 // we can check against null instance instead. |
| 225 bool CheckClassInstr::DeoptIfNotNull() const { | 226 bool CheckClassInstr::DeoptIfNotNull() const { |
| 226 if (unary_checks().NumberOfChecks() != 1) { | 227 if (unary_checks().NumberOfChecks() != 1) { |
| 227 return false; | 228 return false; |
| 228 } | 229 } |
| 229 const intptr_t cid = unary_checks().GetCidAt(0); | 230 const intptr_t cid = unary_checks().GetCidAt(0); |
| 230 return cid == kNullCid; | 231 return cid == kNullCid; |
| 231 } | 232 } |
| 232 | 233 |
| 233 | 234 |
| 234 | 235 bool CheckClassInstr::IsDenseCidRange(const ICData& unary_checks) { |
| 235 bool CheckClassInstr::IsDenseSwitch() const { | 236 ASSERT(unary_checks.NumArgsTested() == 1); |
| 236 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) return false; | 237 // TODO(fschneider): Support smis in dense cid checks. |
| 237 if (cids_.length() > 2 && | 238 if (unary_checks.GetReceiverClassIdAt(0) == kSmiCid) return false; |
| 238 cids_[cids_.length() - 1] - cids_[0] < kBitsPerWord) { | 239 if (unary_checks.NumberOfChecks() <= 2) return false; |
| 239 return true; | 240 intptr_t max = 0; |
| 241 intptr_t min = kIntptrMax; |
| 242 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { |
| 243 intptr_t cid = unary_checks.GetCidAt(i); |
| 244 if (cid < min) min = cid; |
| 245 if (cid > max) max = cid; |
| 240 } | 246 } |
| 241 return false; | 247 return (max - min) < kBitsPerWord; |
| 242 } | 248 } |
| 243 | 249 |
| 244 | 250 |
| 251 bool CheckClassInstr::IsDenseSwitch() const { |
| 252 return is_dense_switch_; |
| 253 } |
| 254 |
| 255 |
| 245 intptr_t CheckClassInstr::ComputeCidMask() const { | 256 intptr_t CheckClassInstr::ComputeCidMask() const { |
| 246 ASSERT(IsDenseSwitch()); | 257 ASSERT(IsDenseSwitch()); |
| 247 intptr_t mask = 0; | 258 intptr_t mask = 0; |
| 248 for (intptr_t i = 0; i < cids_.length(); ++i) { | 259 for (intptr_t i = 0; i < cids_.length(); ++i) { |
| 249 mask |= static_cast<intptr_t>(1) << (cids_[i] - cids_[0]); | 260 mask |= static_cast<intptr_t>(1) << (cids_[i] - cids_[0]); |
| 250 } | 261 } |
| 251 return mask; | 262 return mask; |
| 252 } | 263 } |
| 253 | 264 |
| 254 | 265 |
| (...skipping 3485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3740 set_native_c_function(native_function); | 3751 set_native_c_function(native_function); |
| 3741 function().SetIsNativeAutoSetupScope(auto_setup_scope); | 3752 function().SetIsNativeAutoSetupScope(auto_setup_scope); |
| 3742 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 3753 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 3743 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 3754 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 3744 set_is_bootstrap_native(is_bootstrap_native); | 3755 set_is_bootstrap_native(is_bootstrap_native); |
| 3745 } | 3756 } |
| 3746 | 3757 |
| 3747 #undef __ | 3758 #undef __ |
| 3748 | 3759 |
| 3749 } // namespace dart | 3760 } // namespace dart |
| OLD | NEW |