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 11454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11465 } | 11465 } |
11466 // Warning issued in ic miss handler. | 11466 // Warning issued in ic miss handler. |
11467 // No decoding necessary, so allow optimization if warning already issued. | 11467 // No decoding necessary, so allow optimization if warning already issued. |
11468 if (name.Equals(Symbols::toString()) && !IssuedJSWarning()) { | 11468 if (name.Equals(Symbols::toString()) && !IssuedJSWarning()) { |
11469 return true; | 11469 return true; |
11470 } | 11470 } |
11471 return false; | 11471 return false; |
11472 } | 11472 } |
11473 | 11473 |
11474 | 11474 |
| 11475 void ICData::set_range_feedback(uint32_t feedback) { |
| 11476 StoreNonPointer(&raw_ptr()->range_feedback_, feedback); |
| 11477 } |
| 11478 |
| 11479 |
11475 void ICData::set_state_bits(uint32_t bits) const { | 11480 void ICData::set_state_bits(uint32_t bits) const { |
11476 StoreNonPointer(&raw_ptr()->state_bits_, bits); | 11481 StoreNonPointer(&raw_ptr()->state_bits_, bits); |
11477 } | 11482 } |
11478 | 11483 |
11479 | 11484 |
11480 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { | 11485 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { |
11481 return num_args + 1 /* target function*/ + 1 /* frequency */; | 11486 return num_args + 1 /* target function*/ + 1 /* frequency */; |
11482 } | 11487 } |
11483 | 11488 |
11484 | 11489 |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11920 ICData::InstanceSize(), | 11925 ICData::InstanceSize(), |
11921 Heap::kOld); | 11926 Heap::kOld); |
11922 NoGCScope no_gc; | 11927 NoGCScope no_gc; |
11923 result ^= raw; | 11928 result ^= raw; |
11924 } | 11929 } |
11925 result.set_owner(owner); | 11930 result.set_owner(owner); |
11926 result.set_target_name(target_name); | 11931 result.set_target_name(target_name); |
11927 result.set_arguments_descriptor(arguments_descriptor); | 11932 result.set_arguments_descriptor(arguments_descriptor); |
11928 result.set_deopt_id(deopt_id); | 11933 result.set_deopt_id(deopt_id); |
11929 result.set_state_bits(0); | 11934 result.set_state_bits(0); |
| 11935 result.set_range_feedback(0); |
11930 result.SetNumArgsTested(num_args_tested); | 11936 result.SetNumArgsTested(num_args_tested); |
11931 // Number of array elements in one test entry. | 11937 // Number of array elements in one test entry. |
11932 intptr_t len = result.TestEntryLength(); | 11938 intptr_t len = result.TestEntryLength(); |
11933 // IC data array must be null terminated (sentinel entry). | 11939 // IC data array must be null terminated (sentinel entry). |
11934 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 11940 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
11935 result.set_ic_data(ic_data); | 11941 result.set_ic_data(ic_data); |
11936 result.WriteSentinel(ic_data); | 11942 result.WriteSentinel(ic_data); |
11937 return result.raw(); | 11943 return result.raw(); |
11938 } | 11944 } |
11939 | 11945 |
11940 | 11946 |
11941 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const { | 11947 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
11942 Object::PrintJSONImpl(stream, ref); | 11948 Object::PrintJSONImpl(stream, ref); |
11943 } | 11949 } |
11944 | 11950 |
11945 | 11951 |
| 11952 static Token::Kind RecognizeArithmeticOp(const String& name) { |
| 11953 ASSERT(name.IsSymbol()); |
| 11954 if (name.raw() == Symbols::Plus().raw()) { |
| 11955 return Token::kADD; |
| 11956 } else if (name.raw() == Symbols::Minus().raw()) { |
| 11957 return Token::kSUB; |
| 11958 } else if (name.raw() == Symbols::Star().raw()) { |
| 11959 return Token::kMUL; |
| 11960 } else if (name.raw() == Symbols::Slash().raw()) { |
| 11961 return Token::kDIV; |
| 11962 } else if (name.raw() == Symbols::TruncDivOperator().raw()) { |
| 11963 return Token::kTRUNCDIV; |
| 11964 } else if (name.raw() == Symbols::Percent().raw()) { |
| 11965 return Token::kMOD; |
| 11966 } else if (name.raw() == Symbols::BitOr().raw()) { |
| 11967 return Token::kBIT_OR; |
| 11968 } else if (name.raw() == Symbols::Ampersand().raw()) { |
| 11969 return Token::kBIT_AND; |
| 11970 } else if (name.raw() == Symbols::Caret().raw()) { |
| 11971 return Token::kBIT_XOR; |
| 11972 } else if (name.raw() == Symbols::LeftShiftOperator().raw()) { |
| 11973 return Token::kSHL; |
| 11974 } else if (name.raw() == Symbols::RightShiftOperator().raw()) { |
| 11975 return Token::kSHR; |
| 11976 } else if (name.raw() == Symbols::Tilde().raw()) { |
| 11977 return Token::kBIT_NOT; |
| 11978 } else if (name.raw() == Symbols::UnaryMinus().raw()) { |
| 11979 return Token::kNEGATE; |
| 11980 } |
| 11981 return Token::kILLEGAL; |
| 11982 } |
| 11983 |
| 11984 |
| 11985 bool ICData::HasRangeFeedback() const { |
| 11986 const String& target = String::Handle(target_name()); |
| 11987 const Token::Kind token_kind = RecognizeArithmeticOp(target); |
| 11988 if (!Token::IsBinaryArithmeticOperator(token_kind) && |
| 11989 !Token::IsUnaryArithmeticOperator(token_kind)) { |
| 11990 return false; |
| 11991 } |
| 11992 |
| 11993 bool initialized = false; |
| 11994 Function& t = Function::Handle(); |
| 11995 const intptr_t len = NumberOfChecks(); |
| 11996 GrowableArray<intptr_t> class_ids; |
| 11997 for (intptr_t i = 0; i < len; i++) { |
| 11998 if (IsUsedAt(i)) { |
| 11999 initialized = true; |
| 12000 GetCheckAt(i, &class_ids, &t); |
| 12001 for (intptr_t j = 0; j < class_ids.length(); j++) { |
| 12002 const intptr_t cid = class_ids[j]; |
| 12003 if ((cid != kSmiCid) && (cid != kMintCid)) { |
| 12004 return false; |
| 12005 } |
| 12006 } |
| 12007 } |
| 12008 } |
| 12009 |
| 12010 return initialized; |
| 12011 } |
| 12012 |
| 12013 |
| 12014 ICData::RangeFeedback ICData::DecodeRangeFeedbackAt(intptr_t idx) const { |
| 12015 ASSERT((0 <= idx) && (idx < 3)); |
| 12016 const uint32_t feedback = |
| 12017 (range_feedback() >> (idx * kBitsPerRangeFeedback)) & kRangeFeedbackMask; |
| 12018 if ((feedback & kInt64RangeBit) != 0) { |
| 12019 return kInt64Range; |
| 12020 } |
| 12021 |
| 12022 if ((feedback & kUint32RangeBit) != 0) { |
| 12023 if ((feedback & kSignedRangeBit) == 0) { |
| 12024 return kUint32Range; |
| 12025 } |
| 12026 |
| 12027 // Check if Smi is large enough to accomodate Int33: a mixture of Uint32 |
| 12028 // and negative Int32 values. |
| 12029 return (kSmiBits < 33) ? kInt64Range : kSmiRange; |
| 12030 } |
| 12031 |
| 12032 if ((feedback & kInt32RangeBit) != 0) { |
| 12033 return kInt32Range; |
| 12034 } |
| 12035 |
| 12036 return kSmiRange; |
| 12037 } |
| 12038 |
| 12039 |
11946 Code::Comments& Code::Comments::New(intptr_t count) { | 12040 Code::Comments& Code::Comments::New(intptr_t count) { |
11947 Comments* comments; | 12041 Comments* comments; |
11948 if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { | 12042 if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { |
11949 // This should be caught before we reach here. | 12043 // This should be caught before we reach here. |
11950 FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", | 12044 FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", |
11951 count); | 12045 count); |
11952 } | 12046 } |
11953 if (count == 0) { | 12047 if (count == 0) { |
11954 comments = new Comments(Object::empty_array()); | 12048 comments = new Comments(Object::empty_array()); |
11955 } else { | 12049 } else { |
(...skipping 8534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20490 return tag_label.ToCString(); | 20584 return tag_label.ToCString(); |
20491 } | 20585 } |
20492 | 20586 |
20493 | 20587 |
20494 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 20588 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
20495 Instance::PrintJSONImpl(stream, ref); | 20589 Instance::PrintJSONImpl(stream, ref); |
20496 } | 20590 } |
20497 | 20591 |
20498 | 20592 |
20499 } // namespace dart | 20593 } // namespace dart |
OLD | NEW |