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/become.h" | 10 #include "vm/become.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 DEFINE_FLAG(bool, | 78 DEFINE_FLAG(bool, |
79 remove_script_timestamps_for_test, | 79 remove_script_timestamps_for_test, |
80 false, | 80 false, |
81 "Remove script timestamps to allow for deterministic testing."); | 81 "Remove script timestamps to allow for deterministic testing."); |
82 | 82 |
83 DECLARE_FLAG(bool, show_invisible_frames); | 83 DECLARE_FLAG(bool, show_invisible_frames); |
84 DECLARE_FLAG(bool, trace_deoptimization); | 84 DECLARE_FLAG(bool, trace_deoptimization); |
85 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 85 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
86 DECLARE_FLAG(bool, trace_reload); | 86 DECLARE_FLAG(bool, trace_reload); |
87 DECLARE_FLAG(bool, write_protect_code); | 87 DECLARE_FLAG(bool, write_protect_code); |
88 DECLARE_FLAG(bool, support_externalizable_strings); | |
89 | 88 |
90 static const char* const kGetterPrefix = "get:"; | 89 static const char* const kGetterPrefix = "get:"; |
91 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 90 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
92 static const char* const kSetterPrefix = "set:"; | 91 static const char* const kSetterPrefix = "set:"; |
93 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 92 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
94 | 93 |
95 // A cache of VM heap allocated preinitialized empty ic data entry arrays. | 94 // A cache of VM heap allocated preinitialized empty ic data entry arrays. |
96 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; | 95 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; |
97 | 96 |
98 cpp_vtable Object::handle_vtable_ = 0; | 97 cpp_vtable Object::handle_vtable_ = 0; |
(...skipping 8093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8192 return Thread::Current()->zone()->PrintToString( | 8191 return Thread::Current()->zone()->PrintToString( |
8193 "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), | 8192 "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), |
8194 guarded_list_length_in_object_offset()); | 8193 guarded_list_length_in_object_offset()); |
8195 } | 8194 } |
8196 } | 8195 } |
8197 | 8196 |
8198 return Thread::Current()->zone()->PrintToString( | 8197 return Thread::Current()->zone()->PrintToString( |
8199 "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); | 8198 "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); |
8200 } | 8199 } |
8201 | 8200 |
8202 bool Field::IsExternalizableCid(intptr_t cid) { | |
8203 if (FLAG_support_externalizable_strings) { | |
8204 return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid); | |
8205 } else { | |
8206 return false; | |
8207 } | |
8208 } | |
8209 | |
8210 void Field::InitializeGuardedListLengthInObjectOffset() const { | 8201 void Field::InitializeGuardedListLengthInObjectOffset() const { |
8211 ASSERT(IsOriginal()); | 8202 ASSERT(IsOriginal()); |
8212 if (needs_length_check() && | 8203 if (needs_length_check() && |
8213 (guarded_list_length() != Field::kUnknownFixedLength)) { | 8204 (guarded_list_length() != Field::kUnknownFixedLength)) { |
8214 const intptr_t offset = GetListLengthOffset(guarded_cid()); | 8205 const intptr_t offset = GetListLengthOffset(guarded_cid()); |
8215 set_guarded_list_length_in_object_offset(offset); | 8206 set_guarded_list_length_in_object_offset(offset); |
8216 ASSERT(offset != Field::kUnknownLengthOffset); | 8207 ASSERT(offset != Field::kUnknownLengthOffset); |
8217 } else { | 8208 } else { |
8218 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 8209 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |
8219 } | 8210 } |
(...skipping 12065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20285 const Object& referent, | 20276 const Object& referent, |
20286 void* peer, | 20277 void* peer, |
20287 Dart_WeakPersistentHandleFinalizer callback, | 20278 Dart_WeakPersistentHandleFinalizer callback, |
20288 intptr_t external_size) { | 20279 intptr_t external_size) { |
20289 ASSERT((callback != NULL && peer != NULL) || | 20280 ASSERT((callback != NULL && peer != NULL) || |
20290 (callback == NULL && peer == NULL)); | 20281 (callback == NULL && peer == NULL)); |
20291 return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, | 20282 return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, |
20292 callback, external_size); | 20283 callback, external_size); |
20293 } | 20284 } |
20294 | 20285 |
20295 RawString* String::MakeExternal(void* array, | |
20296 intptr_t external_size, | |
20297 void* peer, | |
20298 Dart_PeerFinalizer cback) const { | |
20299 ASSERT(FLAG_support_externalizable_strings); | |
20300 String& result = String::Handle(); | |
20301 void* external_data; | |
20302 Dart_WeakPersistentHandleFinalizer finalizer; | |
20303 { | |
20304 NoSafepointScope no_safepoint; | |
20305 ASSERT(array != NULL); | |
20306 intptr_t str_length = this->Length(); | |
20307 ASSERT(external_size >= (str_length * this->CharSize())); | |
20308 intptr_t class_id = raw()->GetClassId(); | |
20309 | |
20310 ASSERT(!InVMHeap()); | |
20311 if (class_id == kOneByteStringCid) { | |
20312 intptr_t used_size = ExternalOneByteString::InstanceSize(); | |
20313 intptr_t original_size = OneByteString::InstanceSize(str_length); | |
20314 ASSERT(original_size >= used_size); | |
20315 | |
20316 // Copy the data into the external array. | |
20317 if (str_length > 0) { | |
20318 memmove(array, OneByteString::CharAddr(*this, 0), str_length); | |
20319 } | |
20320 | |
20321 // If there is any left over space fill it with either an Array object or | |
20322 // just a plain object (depending on the amount of left over space) so | |
20323 // that it can be traversed over successfully during garbage collection. | |
20324 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); | |
20325 | |
20326 // Update the class information of the object. | |
20327 const intptr_t class_id = kExternalOneByteStringCid; | |
20328 uint32_t tags = raw_ptr()->tags_; | |
20329 uint32_t old_tags; | |
20330 do { | |
20331 old_tags = tags; | |
20332 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags); | |
20333 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); | |
20334 tags = CompareAndSwapTags(old_tags, new_tags); | |
20335 } while (tags != old_tags); | |
20336 result = this->raw(); | |
20337 const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array); | |
20338 ExternalStringData<uint8_t>* ext_data = | |
20339 new ExternalStringData<uint8_t>(ext_array, peer, cback); | |
20340 ASSERT(result.Length() == str_length); | |
20341 ASSERT(!result.HasHash() || | |
20342 (result.Hash() == String::Hash(ext_array, str_length))); | |
20343 ExternalOneByteString::SetExternalData(result, ext_data); | |
20344 external_data = ext_data; | |
20345 finalizer = ExternalOneByteString::Finalize; | |
20346 } else { | |
20347 ASSERT(class_id == kTwoByteStringCid); | |
20348 intptr_t used_size = ExternalTwoByteString::InstanceSize(); | |
20349 intptr_t original_size = TwoByteString::InstanceSize(str_length); | |
20350 ASSERT(original_size >= used_size); | |
20351 | |
20352 // Copy the data into the external array. | |
20353 if (str_length > 0) { | |
20354 memmove(array, TwoByteString::CharAddr(*this, 0), | |
20355 (str_length * kTwoByteChar)); | |
20356 } | |
20357 | |
20358 // If there is any left over space fill it with either an Array object or | |
20359 // just a plain object (depending on the amount of left over space) so | |
20360 // that it can be traversed over successfully during garbage collection. | |
20361 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); | |
20362 | |
20363 // Update the class information of the object. | |
20364 const intptr_t class_id = kExternalTwoByteStringCid; | |
20365 uint32_t tags = raw_ptr()->tags_; | |
20366 uint32_t old_tags; | |
20367 do { | |
20368 old_tags = tags; | |
20369 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags); | |
20370 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); | |
20371 tags = CompareAndSwapTags(old_tags, new_tags); | |
20372 } while (tags != old_tags); | |
20373 result = this->raw(); | |
20374 const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array); | |
20375 ExternalStringData<uint16_t>* ext_data = | |
20376 new ExternalStringData<uint16_t>(ext_array, peer, cback); | |
20377 ASSERT(result.Length() == str_length); | |
20378 ASSERT(!result.HasHash() || | |
20379 (result.Hash() == String::Hash(ext_array, str_length))); | |
20380 ExternalTwoByteString::SetExternalData(result, ext_data); | |
20381 external_data = ext_data; | |
20382 finalizer = ExternalTwoByteString::Finalize; | |
20383 } | |
20384 } // NoSafepointScope | |
20385 AddFinalizer(result, external_data, finalizer, external_size); | |
20386 return this->raw(); | |
20387 } | |
20388 | |
20389 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 20286 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
20390 const String& str, | 20287 const String& str, |
20391 Heap::Space space) { | 20288 Heap::Space space) { |
20392 ASSERT(!str.IsNull()); | 20289 ASSERT(!str.IsNull()); |
20393 bool has_mapping = false; | 20290 bool has_mapping = false; |
20394 int32_t dst_max = 0; | 20291 int32_t dst_max = 0; |
20395 CodePointIterator it(str); | 20292 CodePointIterator it(str); |
20396 while (it.Next()) { | 20293 while (it.Next()) { |
20397 int32_t src = it.Current(); | 20294 int32_t src = it.Current(); |
20398 int32_t dst = mapping(src); | 20295 int32_t dst = mapping(src); |
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22539 } | 22436 } |
22540 return UserTag::null(); | 22437 return UserTag::null(); |
22541 } | 22438 } |
22542 | 22439 |
22543 const char* UserTag::ToCString() const { | 22440 const char* UserTag::ToCString() const { |
22544 const String& tag_label = String::Handle(label()); | 22441 const String& tag_label = String::Handle(label()); |
22545 return tag_label.ToCString(); | 22442 return tag_label.ToCString(); |
22546 } | 22443 } |
22547 | 22444 |
22548 } // namespace dart | 22445 } // namespace dart |
OLD | NEW |