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

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

Issue 2953753002: Revert "Inline instance object hash code into object header on 64 bit." (Closed)
Patch Set: Created 3 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/profiler.cc » ('j') | 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/become.h" 10 #include "vm/become.h"
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 ASSERT(!speculative_inlining_error_->IsSmi()); 985 ASSERT(!speculative_inlining_error_->IsSmi());
986 ASSERT(speculative_inlining_error_->IsLanguageError()); 986 ASSERT(speculative_inlining_error_->IsLanguageError());
987 ASSERT(!background_compilation_error_->IsSmi()); 987 ASSERT(!background_compilation_error_->IsSmi());
988 ASSERT(background_compilation_error_->IsLanguageError()); 988 ASSERT(background_compilation_error_->IsLanguageError());
989 ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); 989 ASSERT(!vm_isolate_snapshot_object_table_->IsSmi());
990 ASSERT(vm_isolate_snapshot_object_table_->IsArray()); 990 ASSERT(vm_isolate_snapshot_object_table_->IsArray());
991 } 991 }
992 992
993 993
994 // An object visitor which will mark all visited objects. This is used to 994 // An object visitor which will mark all visited objects. This is used to
995 // premark all objects in the vm_isolate_ heap. Also precalculates hash 995 // premark all objects in the vm_isolate_ heap.
996 // codes so that we can get the identity hash code of objects in the read- 996 class PremarkingVisitor : public ObjectVisitor {
997 // only VM isolate.
998 class FinalizeVMIsolateVisitor : public ObjectVisitor {
999 public: 997 public:
1000 FinalizeVMIsolateVisitor() 998 PremarkingVisitor() {}
1001 #if defined(HASH_IN_OBJECT_HEADER)
1002 : counter_(1337)
1003 #endif
1004 {
1005 }
1006 999
1007 void VisitObject(RawObject* obj) { 1000 void VisitObject(RawObject* obj) {
1008 // Free list elements should never be marked. 1001 // Free list elements should never be marked.
1009 ASSERT(!obj->IsMarked()); 1002 ASSERT(!obj->IsMarked());
1010 // No forwarding corpses in the VM isolate. 1003 // No forwarding corpses in the VM isolate.
1011 ASSERT(!obj->IsForwardingCorpse()); 1004 ASSERT(!obj->IsForwardingCorpse());
1012 if (!obj->IsFreeListElement()) { 1005 if (!obj->IsFreeListElement()) {
1013 ASSERT(obj->IsVMHeapObject()); 1006 ASSERT(obj->IsVMHeapObject());
1014 obj->SetMarkBitUnsynchronized(); 1007 obj->SetMarkBitUnsynchronized();
1015 if (obj->IsStringInstance()) {
1016 RawString* str = reinterpret_cast<RawString*>(obj);
1017 intptr_t hash = String::Hash(str);
1018 String::SetCachedHash(str, hash);
1019 }
1020 #if defined(HASH_IN_OBJECT_HEADER)
1021 // These objects end up in the read-only VM isolate which is shared
1022 // between isolates, so we have to prepopulate them with identity hash
1023 // codes, since we can't add hash codes later.
1024 if (Object::GetCachedHash(obj) == 0) {
1025 // Some classes have identity hash codes that depend on their contents,
1026 // not per object.
1027 ASSERT(!obj->IsStringInstance());
1028 if (!obj->IsMint() && !obj->IsDouble() && !obj->IsBigint() &&
1029 !obj->IsRawNull() && !obj->IsBool()) {
1030 counter_ += 2011; // The year Dart was announced and a prime.
1031 counter_ &= 0x3fffffff;
1032 if (counter_ == 0) counter_++;
1033 Object::SetCachedHash(obj, counter_);
1034 }
1035 }
1036 #endif
1037 } 1008 }
1038 } 1009 }
1039
1040 private:
1041 #if defined(HASH_IN_OBJECT_HEADER)
1042 int counter_;
1043 #endif
1044 }; 1010 };
1045 1011
1046 1012
1047 #define SET_CLASS_NAME(class_name, name) \ 1013 #define SET_CLASS_NAME(class_name, name) \
1048 cls = class_name##_class(); \ 1014 cls = class_name##_class(); \
1049 cls.set_name(Symbols::name()); 1015 cls.set_name(Symbols::name());
1050 1016
1051 void Object::FinalizeVMIsolate(Isolate* isolate) { 1017 void Object::FinalizeVMIsolate(Isolate* isolate) {
1052 // Should only be run by the vm isolate. 1018 // Should only be run by the vm isolate.
1053 ASSERT(isolate == Dart::vm_isolate()); 1019 ASSERT(isolate == Dart::vm_isolate());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 // Set up names for the pseudo-classes for free list elements and forwarding 1079 // Set up names for the pseudo-classes for free list elements and forwarding
1114 // corpses. Mainly this makes VM debugging easier. 1080 // corpses. Mainly this makes VM debugging easier.
1115 cls = isolate->class_table()->At(kFreeListElement); 1081 cls = isolate->class_table()->At(kFreeListElement);
1116 cls.set_name(Symbols::FreeListElement()); 1082 cls.set_name(Symbols::FreeListElement());
1117 cls = isolate->class_table()->At(kForwardingCorpse); 1083 cls = isolate->class_table()->At(kForwardingCorpse);
1118 cls.set_name(Symbols::ForwardingCorpse()); 1084 cls.set_name(Symbols::ForwardingCorpse());
1119 1085
1120 { 1086 {
1121 ASSERT(isolate == Dart::vm_isolate()); 1087 ASSERT(isolate == Dart::vm_isolate());
1122 WritableVMIsolateScope scope(Thread::Current()); 1088 WritableVMIsolateScope scope(Thread::Current());
1123 FinalizeVMIsolateVisitor premarker; 1089 PremarkingVisitor premarker;
1124 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); 1090 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0);
1125 isolate->heap()->IterateOldObjectsNoImagePages(&premarker); 1091 isolate->heap()->IterateOldObjectsNoImagePages(&premarker);
1126 // Make the VM isolate read-only again after setting all objects as marked. 1092 // Make the VM isolate read-only again after setting all objects as marked.
1127 // Note objects in image pages are already pre-marked. 1093 // Note objects in image pages are already pre-marked.
1128 } 1094 }
1129 } 1095 }
1130 1096
1131 1097
1132 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { 1098 void Object::set_vm_isolate_snapshot_object_table(const Array& table) {
1133 ASSERT(Isolate::Current() == Dart::vm_isolate()); 1099 ASSERT(Isolate::Current() == Dart::vm_isolate());
(...skipping 14 matching lines...) Expand all
1148 if (original_size > used_size) { 1114 if (original_size > used_size) {
1149 intptr_t leftover_size = original_size - used_size; 1115 intptr_t leftover_size = original_size - used_size;
1150 1116
1151 uword addr = RawObject::ToAddr(obj.raw()) + used_size; 1117 uword addr = RawObject::ToAddr(obj.raw()) + used_size;
1152 if (leftover_size >= TypedData::InstanceSize(0)) { 1118 if (leftover_size >= TypedData::InstanceSize(0)) {
1153 // Update the leftover space as a TypedDataInt8Array object. 1119 // Update the leftover space as a TypedDataInt8Array object.
1154 RawTypedData* raw = 1120 RawTypedData* raw =
1155 reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr)); 1121 reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
1156 uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0); 1122 uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
1157 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); 1123 new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
1158 uint32_t tags = raw->ptr()->tags_; 1124 uword tags = raw->ptr()->tags_;
1159 uint32_t old_tags; 1125 uword old_tags;
1160 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. 1126 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
1161 do { 1127 do {
1162 old_tags = tags; 1128 old_tags = tags;
1163 // We can't use obj.CompareAndSwapTags here because we don't have a 1129 tags = AtomicOperations::CompareAndSwapWord(&raw->ptr()->tags_,
1164 // handle for the new object. 1130 old_tags, new_tags);
1165 tags = AtomicOperations::CompareAndSwapUint32(&raw->ptr()->tags_,
1166 old_tags, new_tags);
1167 } while (tags != old_tags); 1131 } while (tags != old_tags);
1168 1132
1169 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0)); 1133 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
1170 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size); 1134 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
1171 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len)); 1135 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
1172 } else { 1136 } else {
1173 // Update the leftover space as a basic object. 1137 // Update the leftover space as a basic object.
1174 ASSERT(leftover_size == Object::InstanceSize()); 1138 ASSERT(leftover_size == Object::InstanceSize());
1175 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); 1139 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
1176 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0); 1140 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0);
1177 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); 1141 new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
1178 uint32_t tags = raw->ptr()->tags_; 1142 uword tags = raw->ptr()->tags_;
1179 uint32_t old_tags; 1143 uword old_tags;
1180 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. 1144 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
1181 do { 1145 do {
1182 old_tags = tags; 1146 old_tags = tags;
1183 tags = obj.CompareAndSwapTags(old_tags, new_tags); 1147 tags = AtomicOperations::CompareAndSwapWord(&raw->ptr()->tags_,
1148 old_tags, new_tags);
1184 } while (tags != old_tags); 1149 } while (tags != old_tags);
1185 } 1150 }
1186 } 1151 }
1187 } 1152 }
1188 1153
1189 1154
1190 void Object::VerifyBuiltinVtables() { 1155 void Object::VerifyBuiltinVtables() {
1191 #if defined(DEBUG) 1156 #if defined(DEBUG)
1192 Thread* thread = Thread::Current(); 1157 Thread* thread = Thread::Current();
1193 Isolate* isolate = thread->isolate(); 1158 Isolate* isolate = thread->isolate();
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 bool is_vm_object) { 1860 bool is_vm_object) {
1896 uword initial_value = (class_id == kInstructionsCid) 1861 uword initial_value = (class_id == kInstructionsCid)
1897 ? Assembler::GetBreakInstructionFiller() 1862 ? Assembler::GetBreakInstructionFiller()
1898 : reinterpret_cast<uword>(null_); 1863 : reinterpret_cast<uword>(null_);
1899 uword cur = address; 1864 uword cur = address;
1900 uword end = address + size; 1865 uword end = address + size;
1901 while (cur < end) { 1866 while (cur < end) {
1902 *reinterpret_cast<uword*>(cur) = initial_value; 1867 *reinterpret_cast<uword*>(cur) = initial_value;
1903 cur += kWordSize; 1868 cur += kWordSize;
1904 } 1869 }
1905 uint32_t tags = 0; 1870 uword tags = 0;
1906 ASSERT(class_id != kIllegalCid); 1871 ASSERT(class_id != kIllegalCid);
1907 tags = RawObject::ClassIdTag::update(class_id, tags); 1872 tags = RawObject::ClassIdTag::update(class_id, tags);
1908 tags = RawObject::SizeTag::update(size, tags); 1873 tags = RawObject::SizeTag::update(size, tags);
1909 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); 1874 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags);
1910 reinterpret_cast<RawObject*>(address)->tags_ = tags; 1875 reinterpret_cast<RawObject*>(address)->tags_ = tags;
1911 #if defined(HASH_IN_OBJECT_HEADER)
1912 reinterpret_cast<RawObject*>(address)->hash_ = 0;
1913 #endif
1914 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); 1876 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags));
1915 } 1877 }
1916 1878
1917 1879
1918 void Object::CheckHandle() const { 1880 void Object::CheckHandle() const {
1919 #if defined(DEBUG) 1881 #if defined(DEBUG)
1920 if (raw_ != Object::null()) { 1882 if (raw_ != Object::null()) {
1921 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { 1883 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) {
1922 ASSERT(vtable() == Smi::handle_vtable_); 1884 ASSERT(vtable() == Smi::handle_vtable_);
1923 return; 1885 return;
(...skipping 18434 matching lines...) Expand 10 before | Expand all | Expand 10 after
20358 static intptr_t HashImpl(const T* characters, intptr_t len) { 20320 static intptr_t HashImpl(const T* characters, intptr_t len) {
20359 ASSERT(len >= 0); 20321 ASSERT(len >= 0);
20360 StringHasher hasher; 20322 StringHasher hasher;
20361 for (intptr_t i = 0; i < len; i++) { 20323 for (intptr_t i = 0; i < len; i++) {
20362 hasher.Add(characters[i]); 20324 hasher.Add(characters[i]);
20363 } 20325 }
20364 return hasher.Finalize(String::kHashBits); 20326 return hasher.Finalize(String::kHashBits);
20365 } 20327 }
20366 20328
20367 20329
20368 intptr_t String::Hash(RawString* raw) {
20369 StringHasher hasher;
20370 uword length = Smi::Value(raw->ptr()->length_);
20371 if (raw->IsOneByteString() || raw->IsExternalOneByteString()) {
20372 const uint8_t* data;
20373 if (raw->IsOneByteString()) {
20374 data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data();
20375 } else {
20376 ASSERT(raw->IsExternalOneByteString());
20377 RawExternalOneByteString* str =
20378 reinterpret_cast<RawExternalOneByteString*>(raw);
20379 data = str->ptr()->external_data_->data();
20380 }
20381 return String::Hash(data, length);
20382 } else {
20383 const uint16_t* data;
20384 if (raw->IsTwoByteString()) {
20385 data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data();
20386 } else {
20387 ASSERT(raw->IsExternalTwoByteString());
20388 RawExternalTwoByteString* str =
20389 reinterpret_cast<RawExternalTwoByteString*>(raw);
20390 data = str->ptr()->external_data_->data();
20391 }
20392 return String::Hash(data, length);
20393 }
20394 }
20395
20396
20397 intptr_t String::Hash(const char* characters, intptr_t len) { 20330 intptr_t String::Hash(const char* characters, intptr_t len) {
20398 return HashImpl(characters, len); 20331 return HashImpl(characters, len);
20399 } 20332 }
20400 20333
20401 20334
20402 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { 20335 intptr_t String::Hash(const uint8_t* characters, intptr_t len) {
20403 return HashImpl(characters, len); 20336 return HashImpl(characters, len);
20404 } 20337 }
20405 20338
20406 20339
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
21207 memmove(array, OneByteString::CharAddr(*this, 0), str_length); 21140 memmove(array, OneByteString::CharAddr(*this, 0), str_length);
21208 } 21141 }
21209 21142
21210 // If there is any left over space fill it with either an Array object or 21143 // If there is any left over space fill it with either an Array object or
21211 // just a plain object (depending on the amount of left over space) so 21144 // just a plain object (depending on the amount of left over space) so
21212 // that it can be traversed over successfully during garbage collection. 21145 // that it can be traversed over successfully during garbage collection.
21213 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); 21146 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
21214 21147
21215 // Update the class information of the object. 21148 // Update the class information of the object.
21216 const intptr_t class_id = kExternalOneByteStringCid; 21149 const intptr_t class_id = kExternalOneByteStringCid;
21217 uint32_t tags = raw_ptr()->tags_; 21150 uword tags = raw_ptr()->tags_;
21218 uint32_t old_tags; 21151 uword old_tags;
21219 do { 21152 do {
21220 old_tags = tags; 21153 old_tags = tags;
21221 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags); 21154 uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
21222 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); 21155 new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
21223 tags = CompareAndSwapTags(old_tags, new_tags); 21156 tags = CompareAndSwapTags(old_tags, new_tags);
21224 } while (tags != old_tags); 21157 } while (tags != old_tags);
21225 result = this->raw(); 21158 result = this->raw();
21226 const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array); 21159 const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array);
21227 ExternalStringData<uint8_t>* ext_data = 21160 ExternalStringData<uint8_t>* ext_data =
21228 new ExternalStringData<uint8_t>(ext_array, peer, cback); 21161 new ExternalStringData<uint8_t>(ext_array, peer, cback);
21229 ASSERT(result.Length() == str_length); 21162 ASSERT(result.Length() == str_length);
21230 ASSERT(!result.HasHash() || 21163 ASSERT(!result.HasHash() ||
21231 (result.Hash() == String::Hash(ext_array, str_length))); 21164 (result.Hash() == String::Hash(ext_array, str_length)));
(...skipping 12 matching lines...) Expand all
21244 (str_length * kTwoByteChar)); 21177 (str_length * kTwoByteChar));
21245 } 21178 }
21246 21179
21247 // If there is any left over space fill it with either an Array object or 21180 // If there is any left over space fill it with either an Array object or
21248 // just a plain object (depending on the amount of left over space) so 21181 // just a plain object (depending on the amount of left over space) so
21249 // that it can be traversed over successfully during garbage collection. 21182 // that it can be traversed over successfully during garbage collection.
21250 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); 21183 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
21251 21184
21252 // Update the class information of the object. 21185 // Update the class information of the object.
21253 const intptr_t class_id = kExternalTwoByteStringCid; 21186 const intptr_t class_id = kExternalTwoByteStringCid;
21254 uint32_t tags = raw_ptr()->tags_; 21187 uword tags = raw_ptr()->tags_;
21255 uint32_t old_tags; 21188 uword old_tags;
21256 do { 21189 do {
21257 old_tags = tags; 21190 old_tags = tags;
21258 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags); 21191 uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
21259 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); 21192 new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
21260 tags = CompareAndSwapTags(old_tags, new_tags); 21193 tags = CompareAndSwapTags(old_tags, new_tags);
21261 } while (tags != old_tags); 21194 } while (tags != old_tags);
21262 result = this->raw(); 21195 result = this->raw();
21263 const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array); 21196 const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array);
21264 ExternalStringData<uint16_t>* ext_data = 21197 ExternalStringData<uint16_t>* ext_data =
21265 new ExternalStringData<uint16_t>(ext_array, peer, cback); 21198 new ExternalStringData<uint16_t>(ext_array, peer, cback);
21266 ASSERT(result.Length() == str_length); 21199 ASSERT(result.Length() == str_length);
21267 ASSERT(!result.HasHash() || 21200 ASSERT(!result.HasHash() ||
21268 (result.Hash() == String::Hash(ext_array, str_length))); 21201 (result.Hash() == String::Hash(ext_array, str_length)));
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
22136 } 22069 }
22137 22070
22138 return dest.raw(); 22071 return dest.raw();
22139 } 22072 }
22140 22073
22141 22074
22142 void Array::MakeImmutable() const { 22075 void Array::MakeImmutable() const {
22143 if (IsImmutable()) return; 22076 if (IsImmutable()) return;
22144 ASSERT(!IsCanonical()); 22077 ASSERT(!IsCanonical());
22145 NoSafepointScope no_safepoint; 22078 NoSafepointScope no_safepoint;
22146 uint32_t tags = raw_ptr()->tags_; 22079 uword tags = raw_ptr()->tags_;
22147 uint32_t old_tags; 22080 uword old_tags;
22148 do { 22081 do {
22149 old_tags = tags; 22082 old_tags = tags;
22150 uint32_t new_tags = 22083 uword new_tags =
22151 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); 22084 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags);
22152 tags = CompareAndSwapTags(old_tags, new_tags); 22085 tags = CompareAndSwapTags(old_tags, new_tags);
22153 } while (tags != old_tags); 22086 } while (tags != old_tags);
22154 } 22087 }
22155 22088
22156 22089
22157 const char* Array::ToCString() const { 22090 const char* Array::ToCString() const {
22158 if (IsNull()) { 22091 if (IsNull()) {
22159 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; 22092 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL";
22160 } 22093 }
(...skipping 21 matching lines...) Expand all
22182 for (int i = 0; i < len; i++) { 22115 for (int i = 0; i < len; i++) {
22183 obj = source.At(i); 22116 obj = source.At(i);
22184 result.SetAt(i, obj); 22117 result.SetAt(i, obj);
22185 } 22118 }
22186 return result.raw(); 22119 return result.raw();
22187 } 22120 }
22188 22121
22189 22122
22190 RawArray* Array::MakeArray(const GrowableObjectArray& growable_array) { 22123 RawArray* Array::MakeArray(const GrowableObjectArray& growable_array) {
22191 ASSERT(!growable_array.IsNull()); 22124 ASSERT(!growable_array.IsNull());
22192 ASSERT(growable_array.IsGrowableObjectArray());
22193 intptr_t used_len = growable_array.Length(); 22125 intptr_t used_len = growable_array.Length();
22194 // Get the type arguments and prepare to copy them. 22126 // Get the type arguments and prepare to copy them.
22195 const TypeArguments& type_arguments = 22127 const TypeArguments& type_arguments =
22196 TypeArguments::Handle(growable_array.GetTypeArguments()); 22128 TypeArguments::Handle(growable_array.GetTypeArguments());
22197 if ((used_len == 0) && (type_arguments.IsNull())) { 22129 if ((used_len == 0) && (type_arguments.IsNull())) {
22198 // This is a raw List (as in no type arguments), so we can return the 22130 // This is a raw List (as in no type arguments), so we can return the
22199 // simple empty array. 22131 // simple empty array.
22200 return Object::empty_array().raw(); 22132 return Object::empty_array().raw();
22201 } 22133 }
22202 intptr_t capacity_len = growable_array.Capacity(); 22134 intptr_t capacity_len = growable_array.Capacity();
22203 Zone* zone = Thread::Current()->zone(); 22135 Zone* zone = Thread::Current()->zone();
22204 const Array& array = Array::Handle(zone, growable_array.data()); 22136 const Array& array = Array::Handle(zone, growable_array.data());
22205 ASSERT(array.IsArray());
22206 array.SetTypeArguments(type_arguments); 22137 array.SetTypeArguments(type_arguments);
22207 intptr_t capacity_size = Array::InstanceSize(capacity_len); 22138 intptr_t capacity_size = Array::InstanceSize(capacity_len);
22208 intptr_t used_size = Array::InstanceSize(used_len); 22139 intptr_t used_size = Array::InstanceSize(used_len);
22209 NoSafepointScope no_safepoint; 22140 NoSafepointScope no_safepoint;
22210 22141
22211 // If there is any left over space fill it with either an Array object or 22142 // If there is any left over space fill it with either an Array object or
22212 // just a plain object (depending on the amount of left over space) so 22143 // just a plain object (depending on the amount of left over space) so
22213 // that it can be traversed over successfully during garbage collection. 22144 // that it can be traversed over successfully during garbage collection.
22214 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size); 22145 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size);
22215 22146
22216 // Update the size in the header field and length of the array object. 22147 // Update the size in the header field and length of the array object.
22217 uword tags = array.raw_ptr()->tags_; 22148 uword tags = array.raw_ptr()->tags_;
22218 ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags)); 22149 ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags));
22219 uint32_t old_tags; 22150 uword old_tags;
22220 do { 22151 do {
22221 old_tags = tags; 22152 old_tags = tags;
22222 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags); 22153 uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
22223 tags = array.CompareAndSwapTags(old_tags, new_tags); 22154 tags = array.CompareAndSwapTags(old_tags, new_tags);
22224 } while (tags != old_tags); 22155 } while (tags != old_tags);
22225 // TODO(22501): For the heap to remain walkable by the sweeper, it must 22156 // TODO(22501): For the heap to remain walkable by the sweeper, it must
22226 // observe the creation of the filler object no later than the new length 22157 // observe the creation of the filler object no later than the new length
22227 // of the array. This assumption holds on ia32/x64 or if the CAS above is a 22158 // of the array. This assumption holds on ia32/x64 or if the CAS above is a
22228 // full memory barrier. 22159 // full memory barrier.
22229 // 22160 //
22230 // Also, between the CAS of the header above and the SetLength below, 22161 // Also, between the CAS of the header above and the SetLength below,
22231 // the array is temporarily in an inconsistent state. The header is considered 22162 // the array is temporarily in an inconsistent state. The header is considered
22232 // the overriding source of object size by RawObject::Size, but the ASSERTs 22163 // the overriding source of object size by RawObject::Size, but the ASSERTs
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after
23546 return UserTag::null(); 23477 return UserTag::null();
23547 } 23478 }
23548 23479
23549 23480
23550 const char* UserTag::ToCString() const { 23481 const char* UserTag::ToCString() const {
23551 const String& tag_label = String::Handle(label()); 23482 const String& tag_label = String::Handle(label());
23552 return tag_label.ToCString(); 23483 return tag_label.ToCString();
23553 } 23484 }
23554 23485
23555 } // namespace dart 23486 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698