| 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 8846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8857 const intptr_t num_checks = NumberOfChecks(); | 8857 const intptr_t num_checks = NumberOfChecks(); |
| 8858 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(), | 8858 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(), |
| 8859 num_args, num_checks) + 1; | 8859 num_args, num_checks) + 1; |
| 8860 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 8860 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 8861 OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks); | 8861 OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks); |
| 8862 return chars; | 8862 return chars; |
| 8863 } | 8863 } |
| 8864 | 8864 |
| 8865 | 8865 |
| 8866 void ICData::set_function(const Function& value) const { | 8866 void ICData::set_function(const Function& value) const { |
| 8867 ASSERT(!value.IsNull()); |
| 8867 StorePointer(&raw_ptr()->function_, value.raw()); | 8868 StorePointer(&raw_ptr()->function_, value.raw()); |
| 8868 } | 8869 } |
| 8869 | 8870 |
| 8870 | 8871 |
| 8871 void ICData::set_target_name(const String& value) const { | 8872 void ICData::set_target_name(const String& value) const { |
| 8873 ASSERT(!value.IsNull()); |
| 8872 StorePointer(&raw_ptr()->target_name_, value.raw()); | 8874 StorePointer(&raw_ptr()->target_name_, value.raw()); |
| 8873 } | 8875 } |
| 8874 | 8876 |
| 8875 | 8877 |
| 8876 void ICData::set_arguments_descriptor(const Array& value) const { | 8878 void ICData::set_arguments_descriptor(const Array& value) const { |
| 8879 ASSERT(!value.IsNull()); |
| 8877 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 8880 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |
| 8878 } | 8881 } |
| 8879 | 8882 |
| 8880 void ICData::set_deopt_id(intptr_t value) const { | 8883 void ICData::set_deopt_id(intptr_t value) const { |
| 8881 raw_ptr()->deopt_id_ = value; | 8884 raw_ptr()->deopt_id_ = value; |
| 8882 } | 8885 } |
| 8883 | 8886 |
| 8884 | 8887 |
| 8885 void ICData::set_num_args_tested(intptr_t value) const { | 8888 void ICData::set_num_args_tested(intptr_t value) const { |
| 8886 raw_ptr()->num_args_tested_ = value; | 8889 raw_ptr()->num_args_tested_ = value; |
| 8887 } | 8890 } |
| 8888 | 8891 |
| 8889 | 8892 |
| 8890 void ICData::set_ic_data(const Array& value) const { | 8893 void ICData::set_ic_data(const Array& value) const { |
| 8894 ASSERT(!value.IsNull()); |
| 8891 StorePointer(&raw_ptr()->ic_data_, value.raw()); | 8895 StorePointer(&raw_ptr()->ic_data_, value.raw()); |
| 8892 } | 8896 } |
| 8893 | 8897 |
| 8894 | 8898 |
| 8895 void ICData::set_deopt_reason(intptr_t deopt_reason) const { | 8899 void ICData::set_deopt_reason(intptr_t deopt_reason) const { |
| 8896 raw_ptr()->deopt_reason_ = deopt_reason; | 8900 raw_ptr()->deopt_reason_ = deopt_reason; |
| 8897 } | 8901 } |
| 8898 | 8902 |
| 8899 void ICData::set_is_closure_call(bool value) const { | 8903 void ICData::set_is_closure_call(bool value) const { |
| 8900 raw_ptr()->is_closure_call_ = value ? 1 : 0; | 8904 raw_ptr()->is_closure_call_ = value ? 1 : 0; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8911 } | 8915 } |
| 8912 | 8916 |
| 8913 | 8917 |
| 8914 intptr_t ICData::NumberOfChecks() const { | 8918 intptr_t ICData::NumberOfChecks() const { |
| 8915 // Do not count the sentinel; | 8919 // Do not count the sentinel; |
| 8916 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; | 8920 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; |
| 8917 } | 8921 } |
| 8918 | 8922 |
| 8919 | 8923 |
| 8920 void ICData::WriteSentinel(const Array& data) const { | 8924 void ICData::WriteSentinel(const Array& data) const { |
| 8925 ASSERT(!data.IsNull()); |
| 8921 for (intptr_t i = 1; i <= TestEntryLength(); i++) { | 8926 for (intptr_t i = 1; i <= TestEntryLength(); i++) { |
| 8922 data.SetAt(data.Length() - i, smi_illegal_cid()); | 8927 data.SetAt(data.Length() - i, smi_illegal_cid()); |
| 8923 } | 8928 } |
| 8924 } | 8929 } |
| 8925 | 8930 |
| 8926 | 8931 |
| 8927 #if defined(DEBUG) | 8932 #if defined(DEBUG) |
| 8928 // Used in asserts to verify that a check is not added twice. | 8933 // Used in asserts to verify that a check is not added twice. |
| 8929 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 8934 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |
| 8930 const intptr_t len = NumberOfChecks(); | 8935 const intptr_t len = NumberOfChecks(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8943 return true; | 8948 return true; |
| 8944 } | 8949 } |
| 8945 } | 8950 } |
| 8946 return false; | 8951 return false; |
| 8947 } | 8952 } |
| 8948 #endif // DEBUG | 8953 #endif // DEBUG |
| 8949 | 8954 |
| 8950 | 8955 |
| 8951 // Used for unoptimized static calls when no class-ids are checked. | 8956 // Used for unoptimized static calls when no class-ids are checked. |
| 8952 void ICData::AddTarget(const Function& target) const { | 8957 void ICData::AddTarget(const Function& target) const { |
| 8958 ASSERT(!target.IsNull()); |
| 8953 if (num_args_tested() > 0) { | 8959 if (num_args_tested() > 0) { |
| 8954 // Create a fake cid entry, so that we can store the target. | 8960 // Create a fake cid entry, so that we can store the target. |
| 8955 GrowableArray<intptr_t> class_ids(num_args_tested()); | 8961 GrowableArray<intptr_t> class_ids(num_args_tested()); |
| 8956 for (intptr_t i = 0; i < num_args_tested(); i++) { | 8962 for (intptr_t i = 0; i < num_args_tested(); i++) { |
| 8957 class_ids.Add(kObjectCid); | 8963 class_ids.Add(kObjectCid); |
| 8958 } | 8964 } |
| 8959 AddCheck(class_ids, target); | 8965 AddCheck(class_ids, target); |
| 8960 return; | 8966 return; |
| 8961 } | 8967 } |
| 8962 ASSERT(num_args_tested() >= 0); | 8968 ASSERT(num_args_tested() >= 0); |
| 8963 // Can add only once. | 8969 // Can add only once. |
| 8964 const intptr_t old_num = NumberOfChecks(); | 8970 const intptr_t old_num = NumberOfChecks(); |
| 8965 ASSERT(old_num == 0); | 8971 ASSERT(old_num == 0); |
| 8966 Array& data = Array::Handle(ic_data()); | 8972 Array& data = Array::Handle(ic_data()); |
| 8967 const intptr_t new_len = data.Length() + TestEntryLength(); | 8973 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 8968 data = Array::Grow(data, new_len, Heap::kOld); | 8974 data = Array::Grow(data, new_len, Heap::kOld); |
| 8969 set_ic_data(data); | 8975 set_ic_data(data); |
| 8970 WriteSentinel(data); | 8976 WriteSentinel(data); |
| 8971 intptr_t data_pos = old_num * TestEntryLength(); | 8977 intptr_t data_pos = old_num * TestEntryLength(); |
| 8972 ASSERT(!target.IsNull()); | 8978 ASSERT(!target.IsNull()); |
| 8973 data.SetAt(data_pos++, target); | 8979 data.SetAt(data_pos++, target); |
| 8974 const Smi& value = Smi::Handle(Smi::New(0)); | 8980 const Smi& value = Smi::Handle(Smi::New(0)); |
| 8975 data.SetAt(data_pos, value); | 8981 data.SetAt(data_pos, value); |
| 8976 } | 8982 } |
| 8977 | 8983 |
| 8978 | 8984 |
| 8979 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, | 8985 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
| 8980 const Function& target) const { | 8986 const Function& target) const { |
| 8987 ASSERT(!target.IsNull()); |
| 8981 DEBUG_ASSERT(!HasCheck(class_ids)); | 8988 DEBUG_ASSERT(!HasCheck(class_ids)); |
| 8982 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. | 8989 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. |
| 8983 ASSERT(class_ids.length() == num_args_tested()); | 8990 ASSERT(class_ids.length() == num_args_tested()); |
| 8984 const intptr_t old_num = NumberOfChecks(); | 8991 const intptr_t old_num = NumberOfChecks(); |
| 8985 Array& data = Array::Handle(ic_data()); | 8992 Array& data = Array::Handle(ic_data()); |
| 8986 // ICData of static calls with num_args_tested() > 0 have initially a | 8993 // ICData of static calls with num_args_tested() > 0 have initially a |
| 8987 // dummy set of cids entered (see ICData::AddTarget). That entry is | 8994 // dummy set of cids entered (see ICData::AddTarget). That entry is |
| 8988 // overwritten by first real type feedback data. | 8995 // overwritten by first real type feedback data. |
| 8989 if (old_num == 1) { | 8996 if (old_num == 1) { |
| 8990 bool has_dummy_entry = true; | 8997 bool has_dummy_entry = true; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9026 | 9033 |
| 9027 | 9034 |
| 9028 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 9035 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| 9029 const Function& target, | 9036 const Function& target, |
| 9030 intptr_t count) const { | 9037 intptr_t count) const { |
| 9031 #if defined(DEBUG) | 9038 #if defined(DEBUG) |
| 9032 GrowableArray<intptr_t> class_ids(1); | 9039 GrowableArray<intptr_t> class_ids(1); |
| 9033 class_ids.Add(receiver_class_id); | 9040 class_ids.Add(receiver_class_id); |
| 9034 ASSERT(!HasCheck(class_ids)); | 9041 ASSERT(!HasCheck(class_ids)); |
| 9035 #endif // DEBUG | 9042 #endif // DEBUG |
| 9043 ASSERT(!target.IsNull()); |
| 9036 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. | 9044 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. |
| 9037 ASSERT(receiver_class_id != kIllegalCid); | 9045 ASSERT(receiver_class_id != kIllegalCid); |
| 9038 | 9046 |
| 9039 const intptr_t old_num = NumberOfChecks(); | 9047 const intptr_t old_num = NumberOfChecks(); |
| 9040 Array& data = Array::Handle(ic_data()); | 9048 Array& data = Array::Handle(ic_data()); |
| 9041 const intptr_t new_len = data.Length() + TestEntryLength(); | 9049 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 9042 data = Array::Grow(data, new_len, Heap::kOld); | 9050 data = Array::Grow(data, new_len, Heap::kOld); |
| 9043 set_ic_data(data); | 9051 set_ic_data(data); |
| 9044 WriteSentinel(data); | 9052 WriteSentinel(data); |
| 9045 intptr_t data_pos = old_num * TestEntryLength(); | 9053 intptr_t data_pos = old_num * TestEntryLength(); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9262 } | 9270 } |
| 9263 return true; | 9271 return true; |
| 9264 } | 9272 } |
| 9265 | 9273 |
| 9266 | 9274 |
| 9267 RawICData* ICData::New(const Function& function, | 9275 RawICData* ICData::New(const Function& function, |
| 9268 const String& target_name, | 9276 const String& target_name, |
| 9269 const Array& arguments_descriptor, | 9277 const Array& arguments_descriptor, |
| 9270 intptr_t deopt_id, | 9278 intptr_t deopt_id, |
| 9271 intptr_t num_args_tested) { | 9279 intptr_t num_args_tested) { |
| 9280 ASSERT(!function.IsNull()); |
| 9281 ASSERT(!target_name.IsNull()); |
| 9282 ASSERT(!arguments_descriptor.IsNull()); |
| 9272 ASSERT(Object::icdata_class() != Class::null()); | 9283 ASSERT(Object::icdata_class() != Class::null()); |
| 9273 ASSERT(num_args_tested >= 0); | 9284 ASSERT(num_args_tested >= 0); |
| 9274 ICData& result = ICData::Handle(); | 9285 ICData& result = ICData::Handle(); |
| 9275 { | 9286 { |
| 9276 // IC data objects are long living objects, allocate them in old generation. | 9287 // IC data objects are long living objects, allocate them in old generation. |
| 9277 RawObject* raw = Object::Allocate(ICData::kClassId, | 9288 RawObject* raw = Object::Allocate(ICData::kClassId, |
| 9278 ICData::InstanceSize(), | 9289 ICData::InstanceSize(), |
| 9279 Heap::kOld); | 9290 Heap::kOld); |
| 9280 NoGCScope no_gc; | 9291 NoGCScope no_gc; |
| 9281 result ^= raw; | 9292 result ^= raw; |
| (...skipping 5086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14368 } | 14379 } |
| 14369 | 14380 |
| 14370 | 14381 |
| 14371 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 14382 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 14372 stream->OpenObject(); | 14383 stream->OpenObject(); |
| 14373 stream->CloseObject(); | 14384 stream->CloseObject(); |
| 14374 } | 14385 } |
| 14375 | 14386 |
| 14376 | 14387 |
| 14377 } // namespace dart | 14388 } // namespace dart |
| OLD | NEW |