| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 7374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7385 const Array& data = Array::Handle(ic_data()); | 7385 const Array& data = Array::Handle(ic_data()); |
| 7386 for (intptr_t i = 1; i <= TestEntryLength(); i++) { | 7386 for (intptr_t i = 1; i <= TestEntryLength(); i++) { |
| 7387 data.SetAt(data.Length() - i, sentinel_value); | 7387 data.SetAt(data.Length() - i, sentinel_value); |
| 7388 } | 7388 } |
| 7389 } | 7389 } |
| 7390 | 7390 |
| 7391 | 7391 |
| 7392 #if defined(DEBUG) | 7392 #if defined(DEBUG) |
| 7393 // Used in asserts to verify that a check is not added twice. | 7393 // Used in asserts to verify that a check is not added twice. |
| 7394 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 7394 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |
| 7395 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 7395 const intptr_t len = NumberOfChecks(); |
| 7396 for (intptr_t i = 0; i < len; i++) { |
| 7396 GrowableArray<intptr_t> class_ids; | 7397 GrowableArray<intptr_t> class_ids; |
| 7397 Function& target = Function::Handle(); | 7398 Function& target = Function::Handle(); |
| 7398 GetCheckAt(i, &class_ids, &target); | 7399 GetCheckAt(i, &class_ids, &target); |
| 7399 bool matches = true; | 7400 bool matches = true; |
| 7400 for (intptr_t k = 0; k < class_ids.length(); k++) { | 7401 for (intptr_t k = 0; k < class_ids.length(); k++) { |
| 7401 if (class_ids[k] != cids[k]) { | 7402 if (class_ids[k] != cids[k]) { |
| 7402 matches = false; | 7403 matches = false; |
| 7403 break; | 7404 break; |
| 7404 } | 7405 } |
| 7405 } | 7406 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7515 const intptr_t data_pos = index * TestEntryLength(); | 7516 const intptr_t data_pos = index * TestEntryLength(); |
| 7516 Smi& smi = Smi::Handle(); | 7517 Smi& smi = Smi::Handle(); |
| 7517 smi ^= data.At(data_pos); | 7518 smi ^= data.At(data_pos); |
| 7518 return smi.Value(); | 7519 return smi.Value(); |
| 7519 } | 7520 } |
| 7520 | 7521 |
| 7521 | 7522 |
| 7522 RawFunction* ICData::GetTargetAt(intptr_t index) const { | 7523 RawFunction* ICData::GetTargetAt(intptr_t index) const { |
| 7523 const Array& data = Array::Handle(ic_data()); | 7524 const Array& data = Array::Handle(ic_data()); |
| 7524 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); | 7525 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); |
| 7525 Function& target = Function::Handle(); | 7526 ASSERT(Object::Handle(data.At(data_pos)).IsFunction()); |
| 7526 target ^= data.At(data_pos); | 7527 return reinterpret_cast<RawFunction*>(data.At(data_pos)); |
| 7527 return target.raw(); | |
| 7528 } | 7528 } |
| 7529 | 7529 |
| 7530 | 7530 |
| 7531 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const { | 7531 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const { |
| 7532 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 7532 const intptr_t len = NumberOfChecks(); |
| 7533 for (intptr_t i = 0; i < len; i++) { |
| 7533 if (GetReceiverClassIdAt(i) == class_id) { | 7534 if (GetReceiverClassIdAt(i) == class_id) { |
| 7534 return GetTargetAt(i); | 7535 return GetTargetAt(i); |
| 7535 } | 7536 } |
| 7536 } | 7537 } |
| 7537 return Function::null(); | 7538 return Function::null(); |
| 7538 } | 7539 } |
| 7539 | 7540 |
| 7540 | 7541 |
| 7541 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { | 7542 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { |
| 7542 ASSERT(!IsNull()); | 7543 ASSERT(!IsNull()); |
| 7543 ASSERT(num_args_tested() > arg_nr); | 7544 ASSERT(num_args_tested() > arg_nr); |
| 7544 if ((arg_nr == 0) && (num_args_tested() == 1)) { | 7545 if ((arg_nr == 0) && (num_args_tested() == 1)) { |
| 7545 // Frequent case. | 7546 // Frequent case. |
| 7546 return raw(); | 7547 return raw(); |
| 7547 } | 7548 } |
| 7548 const intptr_t kNumArgsTested = 1; | 7549 const intptr_t kNumArgsTested = 1; |
| 7549 ICData& result = ICData::Handle(ICData::New( | 7550 ICData& result = ICData::Handle(ICData::New( |
| 7550 Function::Handle(function()), | 7551 Function::Handle(function()), |
| 7551 String::Handle(target_name()), | 7552 String::Handle(target_name()), |
| 7552 deopt_id(), | 7553 deopt_id(), |
| 7553 kNumArgsTested)); | 7554 kNumArgsTested)); |
| 7554 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 7555 const intptr_t len = NumberOfChecks(); |
| 7556 for (intptr_t i = 0; i < len; i++) { |
| 7555 const intptr_t class_id = GetClassIdAt(i, arg_nr); | 7557 const intptr_t class_id = GetClassIdAt(i, arg_nr); |
| 7556 intptr_t duplicate_class_id = -1; | 7558 intptr_t duplicate_class_id = -1; |
| 7557 for (intptr_t k = 0; k < result.NumberOfChecks(); k++) { | 7559 const intptr_t result_len = result.NumberOfChecks(); |
| 7560 for (intptr_t k = 0; k < result_len; k++) { |
| 7558 if (class_id == result.GetReceiverClassIdAt(k)) { | 7561 if (class_id == result.GetReceiverClassIdAt(k)) { |
| 7559 duplicate_class_id = k; | 7562 duplicate_class_id = k; |
| 7560 break; | 7563 break; |
| 7561 } | 7564 } |
| 7562 } | 7565 } |
| 7563 if (duplicate_class_id >= 0) { | 7566 if (duplicate_class_id >= 0) { |
| 7564 // This check is valid only when checking the receiver. | 7567 // This check is valid only when checking the receiver. |
| 7565 ASSERT((arg_nr != 0) || | 7568 ASSERT((arg_nr != 0) || |
| 7566 (result.GetTargetAt(duplicate_class_id) == GetTargetAt(i))); | 7569 (result.GetTargetAt(duplicate_class_id) == GetTargetAt(i))); |
| 7567 } else { | 7570 } else { |
| 7568 // This will make sure that Smi is first if it exists. | 7571 // This will make sure that Smi is first if it exists. |
| 7569 result.AddReceiverCheck(class_id, | 7572 result.AddReceiverCheck(class_id, |
| 7570 Function::Handle(GetTargetAt(i))); | 7573 Function::Handle(GetTargetAt(i))); |
| 7571 } | 7574 } |
| 7572 } | 7575 } |
| 7573 return result.raw(); | 7576 return result.raw(); |
| 7574 } | 7577 } |
| 7575 | 7578 |
| 7576 | 7579 |
| 7577 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { | 7580 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { |
| 7578 if (NumberOfChecks() == 0) return false; | 7581 if (NumberOfChecks() == 0) return false; |
| 7579 Class& cls = Class::Handle(); | 7582 Class& cls = Class::Handle(); |
| 7580 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 7583 const intptr_t len = NumberOfChecks(); |
| 7584 for (intptr_t i = 0; i < len; i++) { |
| 7581 cls = Function::Handle(GetTargetAt(i)).Owner(); | 7585 cls = Function::Handle(GetTargetAt(i)).Owner(); |
| 7582 if (cls.id() != owner_cid) { | 7586 if (cls.id() != owner_cid) { |
| 7583 return false; | 7587 return false; |
| 7584 } | 7588 } |
| 7585 } | 7589 } |
| 7586 return true; | 7590 return true; |
| 7587 } | 7591 } |
| 7588 | 7592 |
| 7589 | 7593 |
| 7590 bool ICData::AllReceiversAreNumbers() const { | 7594 bool ICData::AllReceiversAreNumbers() const { |
| 7591 if (NumberOfChecks() == 0) return false; | 7595 if (NumberOfChecks() == 0) return false; |
| 7592 Class& cls = Class::Handle(); | 7596 Class& cls = Class::Handle(); |
| 7593 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 7597 const intptr_t len = NumberOfChecks(); |
| 7598 for (intptr_t i = 0; i < len; i++) { |
| 7594 cls = Function::Handle(GetTargetAt(i)).Owner(); | 7599 cls = Function::Handle(GetTargetAt(i)).Owner(); |
| 7595 const intptr_t cid = cls.id(); | 7600 const intptr_t cid = cls.id(); |
| 7596 if ((cid != kSmiCid) && | 7601 if ((cid != kSmiCid) && |
| 7597 (cid != kMintCid) && | 7602 (cid != kMintCid) && |
| 7598 (cid != kBigintCid) && | 7603 (cid != kBigintCid) && |
| 7599 (cid != kDoubleCid)) { | 7604 (cid != kDoubleCid)) { |
| 7600 return false; | 7605 return false; |
| 7601 } | 7606 } |
| 7602 } | 7607 } |
| 7603 return true; | 7608 return true; |
| 7604 } | 7609 } |
| 7605 | 7610 |
| 7606 | 7611 |
| 7607 // Returns true if all targets are the same. | 7612 // Returns true if all targets are the same. |
| 7608 // TODO(srdjan): if targets are native use their C_function to compare. | 7613 // TODO(srdjan): if targets are native use their C_function to compare. |
| 7609 bool ICData::HasOneTarget() const { | 7614 bool ICData::HasOneTarget() const { |
| 7610 ASSERT(NumberOfChecks() > 0); | 7615 ASSERT(NumberOfChecks() > 0); |
| 7611 const Function& first_target = Function::Handle(GetTargetAt(0)); | 7616 const Function& first_target = Function::Handle(GetTargetAt(0)); |
| 7612 Function& test_target = Function::Handle(); | 7617 const intptr_t len = NumberOfChecks(); |
| 7613 for (intptr_t i = 1; i < NumberOfChecks(); i++) { | 7618 for (intptr_t i = 1; i < len; i++) { |
| 7614 test_target = GetTargetAt(i); | 7619 if (GetTargetAt(i) != first_target.raw()) { |
| 7615 if (first_target.raw() != test_target.raw()) { | |
| 7616 return false; | 7620 return false; |
| 7617 } | 7621 } |
| 7618 } | 7622 } |
| 7619 return true; | 7623 return true; |
| 7620 } | 7624 } |
| 7621 | 7625 |
| 7622 | 7626 |
| 7623 RawICData* ICData::New(const Function& function, | 7627 RawICData* ICData::New(const Function& function, |
| 7624 const String& target_name, | 7628 const String& target_name, |
| 7625 intptr_t deopt_id, | 7629 intptr_t deopt_id, |
| (...skipping 4263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11889 } | 11893 } |
| 11890 return result.raw(); | 11894 return result.raw(); |
| 11891 } | 11895 } |
| 11892 | 11896 |
| 11893 | 11897 |
| 11894 const char* WeakProperty::ToCString() const { | 11898 const char* WeakProperty::ToCString() const { |
| 11895 return "_WeakProperty"; | 11899 return "_WeakProperty"; |
| 11896 } | 11900 } |
| 11897 | 11901 |
| 11898 } // namespace dart | 11902 } // namespace dart |
| OLD | NEW |