Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: runtime/vm/object.cc

Issue 342503002: Heap::AllocateExternal may trigger GC, so fix String::MakeExternal. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/heap.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/heap.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698