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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 12268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12279 } | 12279 } |
12280 } | 12280 } |
12281 | 12281 |
12282 | 12282 |
12283 #if defined(DEBUG) | 12283 #if defined(DEBUG) |
12284 // Used in asserts to verify that a check is not added twice. | 12284 // Used in asserts to verify that a check is not added twice. |
12285 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 12285 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |
12286 const intptr_t len = NumberOfChecks(); | 12286 const intptr_t len = NumberOfChecks(); |
12287 for (intptr_t i = 0; i < len; i++) { | 12287 for (intptr_t i = 0; i < len; i++) { |
12288 GrowableArray<intptr_t> class_ids; | 12288 GrowableArray<intptr_t> class_ids; |
12289 Function& target = Function::Handle(); | 12289 GetClassIdsAt(i, &class_ids); |
12290 GetCheckAt(i, &class_ids, &target); | |
12291 bool matches = true; | 12290 bool matches = true; |
12292 for (intptr_t k = 0; k < class_ids.length(); k++) { | 12291 for (intptr_t k = 0; k < class_ids.length(); k++) { |
12293 if (class_ids[k] != cids[k]) { | 12292 if (class_ids[k] != cids[k]) { |
12294 matches = false; | 12293 matches = false; |
12295 break; | 12294 break; |
12296 } | 12295 } |
12297 } | 12296 } |
12298 if (matches) { | 12297 if (matches) { |
12299 return true; | 12298 return true; |
12300 } | 12299 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12439 class_ids->Clear(); | 12438 class_ids->Clear(); |
12440 const Array& data = Array::Handle(ic_data()); | 12439 const Array& data = Array::Handle(ic_data()); |
12441 intptr_t data_pos = index * TestEntryLength(); | 12440 intptr_t data_pos = index * TestEntryLength(); |
12442 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 12441 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
12443 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); | 12442 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |
12444 } | 12443 } |
12445 (*target) ^= data.At(data_pos++); | 12444 (*target) ^= data.At(data_pos++); |
12446 } | 12445 } |
12447 | 12446 |
12448 | 12447 |
| 12448 void ICData::GetClassIdsAt(intptr_t index, |
| 12449 GrowableArray<intptr_t>* class_ids) const { |
| 12450 ASSERT(index < NumberOfChecks()); |
| 12451 ASSERT(class_ids != NULL); |
| 12452 class_ids->Clear(); |
| 12453 const Array& data = Array::Handle(ic_data()); |
| 12454 intptr_t data_pos = index * TestEntryLength(); |
| 12455 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
| 12456 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |
| 12457 } |
| 12458 } |
| 12459 |
| 12460 |
12449 void ICData::GetOneClassCheckAt(intptr_t index, | 12461 void ICData::GetOneClassCheckAt(intptr_t index, |
12450 intptr_t* class_id, | 12462 intptr_t* class_id, |
12451 Function* target) const { | 12463 Function* target) const { |
12452 ASSERT(class_id != NULL); | 12464 ASSERT(class_id != NULL); |
12453 ASSERT(target != NULL); | 12465 ASSERT(target != NULL); |
12454 ASSERT(NumArgsTested() == 1); | 12466 ASSERT(NumArgsTested() == 1); |
12455 const Array& data = Array::Handle(ic_data()); | 12467 const Array& data = Array::Handle(ic_data()); |
12456 const intptr_t data_pos = index * TestEntryLength(); | 12468 const intptr_t data_pos = index * TestEntryLength(); |
12457 *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); | 12469 *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); |
12458 *target ^= data.At(data_pos + 1); | 12470 *target ^= data.At(data_pos + 1); |
12459 } | 12471 } |
12460 | 12472 |
12461 | 12473 |
12462 intptr_t ICData::GetCidAt(intptr_t index) const { | 12474 intptr_t ICData::GetCidAt(intptr_t index) const { |
12463 ASSERT(NumArgsTested() == 1); | 12475 ASSERT(NumArgsTested() == 1); |
12464 const Array& data = Array::Handle(ic_data()); | 12476 const Array& data = Array::Handle(ic_data()); |
12465 const intptr_t data_pos = index * TestEntryLength(); | 12477 const intptr_t data_pos = index * TestEntryLength(); |
12466 return Smi::Value(Smi::RawCast(data.At(data_pos))); | 12478 return Smi::Value(Smi::RawCast(data.At(data_pos))); |
12467 } | 12479 } |
12468 | 12480 |
12469 | 12481 |
12470 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { | 12482 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { |
12471 GrowableArray<intptr_t> class_ids; | 12483 GrowableArray<intptr_t> class_ids; |
12472 Function& target = Function::Handle(); | 12484 GetClassIdsAt(index, &class_ids); |
12473 GetCheckAt(index, &class_ids, &target); | |
12474 return class_ids[arg_nr]; | 12485 return class_ids[arg_nr]; |
12475 } | 12486 } |
12476 | 12487 |
12477 | 12488 |
12478 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { | 12489 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { |
12479 ASSERT(index < NumberOfChecks()); | 12490 ASSERT(index < NumberOfChecks()); |
12480 const intptr_t data_pos = index * TestEntryLength(); | 12491 const intptr_t data_pos = index * TestEntryLength(); |
12481 NoSafepointScope no_safepoint; | 12492 NoSafepointScope no_safepoint; |
12482 RawArray* raw_data = ic_data(); | 12493 RawArray* raw_data = ic_data(); |
12483 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); | 12494 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12639 } | 12650 } |
12640 return true; | 12651 return true; |
12641 } | 12652 } |
12642 | 12653 |
12643 | 12654 |
12644 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, | 12655 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, |
12645 GrowableArray<intptr_t>* second) const { | 12656 GrowableArray<intptr_t>* second) const { |
12646 ASSERT(NumArgsTested() == 2); | 12657 ASSERT(NumArgsTested() == 2); |
12647 first->Clear(); | 12658 first->Clear(); |
12648 second->Clear(); | 12659 second->Clear(); |
12649 Function& target = Function::Handle(); | |
12650 GrowableArray<intptr_t> class_ids; | 12660 GrowableArray<intptr_t> class_ids; |
12651 const intptr_t len = NumberOfChecks(); | 12661 const intptr_t len = NumberOfChecks(); |
12652 for (intptr_t i = 0; i < len; i++) { | 12662 for (intptr_t i = 0; i < len; i++) { |
12653 if (GetCountAt(i) > 0) { | 12663 if (GetCountAt(i) > 0) { |
12654 GetCheckAt(i, &class_ids, &target); | 12664 GetClassIdsAt(i, &class_ids); |
12655 ASSERT(class_ids.length() == 2); | 12665 ASSERT(class_ids.length() == 2); |
12656 first->Add(class_ids[0]); | 12666 first->Add(class_ids[0]); |
12657 second->Add(class_ids[1]); | 12667 second->Add(class_ids[1]); |
12658 } | 12668 } |
12659 } | 12669 } |
12660 } | 12670 } |
12661 | 12671 |
12662 | 12672 |
12663 bool ICData::IsUsedAt(intptr_t i) const { | 12673 bool ICData::IsUsedAt(intptr_t i) const { |
12664 if (GetCountAt(i) <= 0) { | 12674 if (GetCountAt(i) <= 0) { |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12887 | 12897 |
12888 bool ICData::HasRangeFeedback() const { | 12898 bool ICData::HasRangeFeedback() const { |
12889 const String& target = String::Handle(target_name()); | 12899 const String& target = String::Handle(target_name()); |
12890 const Token::Kind token_kind = RecognizeArithmeticOp(target); | 12900 const Token::Kind token_kind = RecognizeArithmeticOp(target); |
12891 if (!Token::IsBinaryArithmeticOperator(token_kind) && | 12901 if (!Token::IsBinaryArithmeticOperator(token_kind) && |
12892 !Token::IsUnaryArithmeticOperator(token_kind)) { | 12902 !Token::IsUnaryArithmeticOperator(token_kind)) { |
12893 return false; | 12903 return false; |
12894 } | 12904 } |
12895 | 12905 |
12896 bool initialized = false; | 12906 bool initialized = false; |
12897 Function& t = Function::Handle(); | |
12898 const intptr_t len = NumberOfChecks(); | 12907 const intptr_t len = NumberOfChecks(); |
12899 GrowableArray<intptr_t> class_ids; | 12908 GrowableArray<intptr_t> class_ids; |
12900 for (intptr_t i = 0; i < len; i++) { | 12909 for (intptr_t i = 0; i < len; i++) { |
12901 if (IsUsedAt(i)) { | 12910 if (IsUsedAt(i)) { |
12902 initialized = true; | 12911 initialized = true; |
12903 GetCheckAt(i, &class_ids, &t); | 12912 GetClassIdsAt(i, &class_ids); |
12904 for (intptr_t j = 0; j < class_ids.length(); j++) { | 12913 for (intptr_t j = 0; j < class_ids.length(); j++) { |
12905 const intptr_t cid = class_ids[j]; | 12914 const intptr_t cid = class_ids[j]; |
12906 if ((cid != kSmiCid) && (cid != kMintCid)) { | 12915 if ((cid != kSmiCid) && (cid != kMintCid)) { |
12907 return false; | 12916 return false; |
12908 } | 12917 } |
12909 } | 12918 } |
12910 } | 12919 } |
12911 } | 12920 } |
12912 | 12921 |
12913 return initialized; | 12922 return initialized; |
(...skipping 4378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17292 const int64_t right_value = other.AsInt64Value(); | 17301 const int64_t right_value = other.AsInt64Value(); |
17293 switch (operation) { | 17302 switch (operation) { |
17294 case Token::kADD: { | 17303 case Token::kADD: { |
17295 if (((left_value < 0) != (right_value < 0)) || | 17304 if (((left_value < 0) != (right_value < 0)) || |
17296 ((left_value + right_value) < 0) == (left_value < 0)) { | 17305 ((left_value + right_value) < 0) == (left_value < 0)) { |
17297 return Integer::New(left_value + right_value, space); | 17306 return Integer::New(left_value + right_value, space); |
17298 } | 17307 } |
17299 break; | 17308 break; |
17300 } | 17309 } |
17301 case Token::kSUB: { | 17310 case Token::kSUB: { |
17302 // TODO(srdjan): Investigate why XCode 7 produces wrong code | 17311 // TODO(srdjan): XCode 7 produces different code in -O0 than in -O2 for |
17303 // if the comparison is inlined as in above (Token::kADD). | 17312 // following code when 'left_value - right_value' overflows into a |
| 17313 // positive number (left negative, right positive): |
| 17314 // if (((left_value < 0) == (right_value < 0)) || |
| 17315 // ((left_value - right_value) < 0) == (left_value < 0)) { |
| 17316 // |
| 17317 // Restructuring code using temporary variables is a workaround. |
17304 const bool both_same_sign = (left_value < 0) == (right_value < 0); | 17318 const bool both_same_sign = (left_value < 0) == (right_value < 0); |
17305 const bool result_same_sign_as_left = | 17319 const bool result_same_sign_as_left = |
17306 ((left_value - right_value) < 0) == (left_value < 0); | 17320 ((left_value - right_value) < 0) == (left_value < 0); |
17307 if (both_same_sign || result_same_sign_as_left) { | 17321 if (both_same_sign || result_same_sign_as_left) { |
17308 return Integer::New(left_value - right_value, space); | 17322 return Integer::New(left_value - right_value, space); |
17309 } | 17323 } |
17310 break; | 17324 break; |
17311 } | 17325 } |
17312 case Token::kMUL: { | 17326 case Token::kMUL: { |
17313 if ((Utils::HighestBit(left_value) + | 17327 if ((Utils::HighestBit(left_value) + |
(...skipping 4604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21918 return tag_label.ToCString(); | 21932 return tag_label.ToCString(); |
21919 } | 21933 } |
21920 | 21934 |
21921 | 21935 |
21922 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21936 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
21923 Instance::PrintJSONImpl(stream, ref); | 21937 Instance::PrintJSONImpl(stream, ref); |
21924 } | 21938 } |
21925 | 21939 |
21926 | 21940 |
21927 } // namespace dart | 21941 } // namespace dart |
OLD | NEW |