| 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 16921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16932 peer, | 16932 peer, |
| 16933 callback, | 16933 callback, |
| 16934 external_size); | 16934 external_size); |
| 16935 } | 16935 } |
| 16936 | 16936 |
| 16937 | 16937 |
| 16938 RawString* String::MakeExternal(void* array, | 16938 RawString* String::MakeExternal(void* array, |
| 16939 intptr_t length, | 16939 intptr_t length, |
| 16940 void* peer, | 16940 void* peer, |
| 16941 Dart_PeerFinalizer cback) const { | 16941 Dart_PeerFinalizer cback) const { |
| 16942 NoGCScope no_gc; | 16942 String& result = String::Handle(); |
| 16943 ASSERT(array != NULL); | 16943 void* external_data; |
| 16944 intptr_t str_length = this->Length(); | 16944 Dart_WeakPersistentHandleFinalizer finalizer; |
| 16945 ASSERT(length >= (str_length * this->CharSize())); | 16945 { |
| 16946 intptr_t class_id = raw()->GetClassId(); | 16946 NoGCScope no_gc; |
| 16947 intptr_t used_size = 0; | 16947 ASSERT(array != NULL); |
| 16948 intptr_t original_size = 0; | 16948 intptr_t str_length = this->Length(); |
| 16949 uword tags = raw_ptr()->tags_; | 16949 ASSERT(length >= (str_length * this->CharSize())); |
| 16950 intptr_t class_id = raw()->GetClassId(); |
| 16951 intptr_t used_size = 0; |
| 16952 intptr_t original_size = 0; |
| 16953 uword tags = raw_ptr()->tags_; |
| 16950 | 16954 |
| 16951 ASSERT(!InVMHeap()); | 16955 ASSERT(!InVMHeap()); |
| 16952 if (class_id == kOneByteStringCid) { | 16956 if (class_id == kOneByteStringCid) { |
| 16953 used_size = ExternalOneByteString::InstanceSize(); | 16957 used_size = ExternalOneByteString::InstanceSize(); |
| 16954 original_size = OneByteString::InstanceSize(str_length); | 16958 original_size = OneByteString::InstanceSize(str_length); |
| 16955 ASSERT(original_size >= used_size); | 16959 ASSERT(original_size >= used_size); |
| 16956 | 16960 |
| 16957 // Copy the data into the external array. | 16961 // Copy the data into the external array. |
| 16958 if (str_length > 0) { | 16962 if (str_length > 0) { |
| 16959 memmove(array, OneByteString::CharAddr(*this, 0), str_length); | 16963 memmove(array, OneByteString::CharAddr(*this, 0), str_length); |
| 16964 } |
| 16965 |
| 16966 // Update the class information of the object. |
| 16967 const intptr_t class_id = kExternalOneByteStringCid; |
| 16968 tags = RawObject::SizeTag::update(used_size, tags); |
| 16969 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 16970 raw_ptr()->tags_ = tags; |
| 16971 result = this->raw(); |
| 16972 ExternalStringData<uint8_t>* ext_data = new ExternalStringData<uint8_t>( |
| 16973 reinterpret_cast<const uint8_t*>(array), peer, cback); |
| 16974 result.SetLength(str_length); |
| 16975 result.SetHash(0); |
| 16976 ExternalOneByteString::SetExternalData(result, ext_data); |
| 16977 external_data = ext_data; |
| 16978 finalizer = ExternalOneByteString::Finalize; |
| 16979 } else { |
| 16980 ASSERT(class_id == kTwoByteStringCid); |
| 16981 used_size = ExternalTwoByteString::InstanceSize(); |
| 16982 original_size = TwoByteString::InstanceSize(str_length); |
| 16983 ASSERT(original_size >= used_size); |
| 16984 |
| 16985 // Copy the data into the external array. |
| 16986 if (str_length > 0) { |
| 16987 memmove(array, |
| 16988 TwoByteString::CharAddr(*this, 0), |
| 16989 (str_length * kTwoByteChar)); |
| 16990 } |
| 16991 |
| 16992 // Update the class information of the object. |
| 16993 const intptr_t class_id = kExternalTwoByteStringCid; |
| 16994 tags = RawObject::SizeTag::update(used_size, tags); |
| 16995 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 16996 raw_ptr()->tags_ = tags; |
| 16997 const String& result = String::Handle(this->raw()); |
| 16998 ExternalStringData<uint16_t>* ext_data = new ExternalStringData<uint16_t>( |
| 16999 reinterpret_cast<const uint16_t*>(array), peer, cback); |
| 17000 result.SetLength(str_length); |
| 17001 result.SetHash(0); |
| 17002 ExternalTwoByteString::SetExternalData(result, ext_data); |
| 17003 external_data = ext_data; |
| 17004 finalizer = ExternalTwoByteString::Finalize; |
| 16960 } | 17005 } |
| 16961 | 17006 |
| 16962 // Update the class information of the object. | 17007 // If there is any left over space fill it with either an Array object or |
| 16963 const intptr_t class_id = kExternalOneByteStringCid; | 17008 // just a plain object (depending on the amount of left over space) so |
| 16964 tags = RawObject::SizeTag::update(used_size, tags); | 17009 // that it can be traversed over successfully during garbage collection. |
| 16965 tags = RawObject::ClassIdTag::update(class_id, tags); | 17010 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); |
| 16966 raw_ptr()->tags_ = tags; | 17011 } // NoGCScope |
| 16967 const String& result = String::Handle(this->raw()); | 17012 AddFinalizer(result, external_data, finalizer); |
| 16968 ExternalStringData<uint8_t>* ext_data = new ExternalStringData<uint8_t>( | |
| 16969 reinterpret_cast<const uint8_t*>(array), peer, cback); | |
| 16970 result.SetLength(str_length); | |
| 16971 result.SetHash(0); | |
| 16972 ExternalOneByteString::SetExternalData(result, ext_data); | |
| 16973 AddFinalizer(result, ext_data, ExternalOneByteString::Finalize); | |
| 16974 } else { | |
| 16975 ASSERT(class_id == kTwoByteStringCid); | |
| 16976 used_size = ExternalTwoByteString::InstanceSize(); | |
| 16977 original_size = TwoByteString::InstanceSize(str_length); | |
| 16978 ASSERT(original_size >= used_size); | |
| 16979 | |
| 16980 // Copy the data into the external array. | |
| 16981 if (str_length > 0) { | |
| 16982 memmove(array, | |
| 16983 TwoByteString::CharAddr(*this, 0), | |
| 16984 (str_length * kTwoByteChar)); | |
| 16985 } | |
| 16986 | |
| 16987 // Update the class information of the object. | |
| 16988 const intptr_t class_id = kExternalTwoByteStringCid; | |
| 16989 tags = RawObject::SizeTag::update(used_size, tags); | |
| 16990 tags = RawObject::ClassIdTag::update(class_id, tags); | |
| 16991 raw_ptr()->tags_ = tags; | |
| 16992 const String& result = String::Handle(this->raw()); | |
| 16993 ExternalStringData<uint16_t>* ext_data = new ExternalStringData<uint16_t>( | |
| 16994 reinterpret_cast<const uint16_t*>(array), peer, cback); | |
| 16995 result.SetLength(str_length); | |
| 16996 result.SetHash(0); | |
| 16997 ExternalTwoByteString::SetExternalData(result, ext_data); | |
| 16998 AddFinalizer(result, ext_data, ExternalTwoByteString::Finalize); | |
| 16999 } | |
| 17000 | |
| 17001 // If there is any left over space fill it with either an Array object or | |
| 17002 // just a plain object (depending on the amount of left over space) so | |
| 17003 // that it can be traversed over successfully during garbage collection. | |
| 17004 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); | |
| 17005 | |
| 17006 return this->raw(); | 17013 return this->raw(); |
| 17007 } | 17014 } |
| 17008 | 17015 |
| 17009 | 17016 |
| 17010 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 17017 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
| 17011 const String& str, | 17018 const String& str, |
| 17012 Heap::Space space) { | 17019 Heap::Space space) { |
| 17013 ASSERT(!str.IsNull()); | 17020 ASSERT(!str.IsNull()); |
| 17014 bool has_mapping = false; | 17021 bool has_mapping = false; |
| 17015 int32_t dst_max = 0; | 17022 int32_t dst_max = 0; |
| (...skipping 2106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19122 return tag_label.ToCString(); | 19129 return tag_label.ToCString(); |
| 19123 } | 19130 } |
| 19124 | 19131 |
| 19125 | 19132 |
| 19126 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19133 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 19127 Instance::PrintJSONImpl(stream, ref); | 19134 Instance::PrintJSONImpl(stream, ref); |
| 19128 } | 19135 } |
| 19129 | 19136 |
| 19130 | 19137 |
| 19131 } // namespace dart | 19138 } // namespace dart |
| OLD | NEW |