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

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

Issue 2965723002: VM: Reland Inline instance object hash code into object header on 64bit. (Closed)
Patch Set: Fix snapshot incompatibility that sank Flutter Gallery Created 3 years, 5 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
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. 995 // premark all objects in the vm_isolate_ heap. Also precalculates hash
996 class PremarkingVisitor : public ObjectVisitor { 996 // codes so that we can get the identity hash code of objects in the read-
997 // only VM isolate.
998 class FinalizeVMIsolateVisitor : public ObjectVisitor {
997 public: 999 public:
998 PremarkingVisitor() {} 1000 FinalizeVMIsolateVisitor()
1001 #if defined(HASH_IN_OBJECT_HEADER)
1002 : counter_(1337)
1003 #endif
1004 {
1005 }
999 1006
1000 void VisitObject(RawObject* obj) { 1007 void VisitObject(RawObject* obj) {
1001 // Free list elements should never be marked. 1008 // Free list elements should never be marked.
1002 ASSERT(!obj->IsMarked()); 1009 ASSERT(!obj->IsMarked());
1003 // No forwarding corpses in the VM isolate. 1010 // No forwarding corpses in the VM isolate.
1004 ASSERT(!obj->IsForwardingCorpse()); 1011 ASSERT(!obj->IsForwardingCorpse());
1005 if (!obj->IsFreeListElement()) { 1012 if (!obj->IsFreeListElement()) {
1006 ASSERT(obj->IsVMHeapObject()); 1013 ASSERT(obj->IsVMHeapObject());
1007 obj->SetMarkBitUnsynchronized(); 1014 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
1008 } 1037 }
1009 } 1038 }
1039
1040 private:
1041 #if defined(HASH_IN_OBJECT_HEADER)
1042 int32_t counter_;
1043 #endif
1010 }; 1044 };
1011 1045
1012 1046
1013 #define SET_CLASS_NAME(class_name, name) \ 1047 #define SET_CLASS_NAME(class_name, name) \
1014 cls = class_name##_class(); \ 1048 cls = class_name##_class(); \
1015 cls.set_name(Symbols::name()); 1049 cls.set_name(Symbols::name());
1016 1050
1017 void Object::FinalizeVMIsolate(Isolate* isolate) { 1051 void Object::FinalizeVMIsolate(Isolate* isolate) {
1018 // Should only be run by the vm isolate. 1052 // Should only be run by the vm isolate.
1019 ASSERT(isolate == Dart::vm_isolate()); 1053 ASSERT(isolate == Dart::vm_isolate());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 // Set up names for the pseudo-classes for free list elements and forwarding 1113 // Set up names for the pseudo-classes for free list elements and forwarding
1080 // corpses. Mainly this makes VM debugging easier. 1114 // corpses. Mainly this makes VM debugging easier.
1081 cls = isolate->class_table()->At(kFreeListElement); 1115 cls = isolate->class_table()->At(kFreeListElement);
1082 cls.set_name(Symbols::FreeListElement()); 1116 cls.set_name(Symbols::FreeListElement());
1083 cls = isolate->class_table()->At(kForwardingCorpse); 1117 cls = isolate->class_table()->At(kForwardingCorpse);
1084 cls.set_name(Symbols::ForwardingCorpse()); 1118 cls.set_name(Symbols::ForwardingCorpse());
1085 1119
1086 { 1120 {
1087 ASSERT(isolate == Dart::vm_isolate()); 1121 ASSERT(isolate == Dart::vm_isolate());
1088 WritableVMIsolateScope scope(Thread::Current()); 1122 WritableVMIsolateScope scope(Thread::Current());
1089 PremarkingVisitor premarker; 1123 FinalizeVMIsolateVisitor premarker;
1090 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); 1124 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0);
1091 isolate->heap()->IterateOldObjectsNoImagePages(&premarker); 1125 isolate->heap()->IterateOldObjectsNoImagePages(&premarker);
1092 // Make the VM isolate read-only again after setting all objects as marked. 1126 // Make the VM isolate read-only again after setting all objects as marked.
1093 // Note objects in image pages are already pre-marked. 1127 // Note objects in image pages are already pre-marked.
1094 } 1128 }
1095 } 1129 }
1096 1130
1097 1131
1098 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { 1132 void Object::set_vm_isolate_snapshot_object_table(const Array& table) {
1099 ASSERT(Isolate::Current() == Dart::vm_isolate()); 1133 ASSERT(Isolate::Current() == Dart::vm_isolate());
(...skipping 14 matching lines...) Expand all
1114 if (original_size > used_size) { 1148 if (original_size > used_size) {
1115 intptr_t leftover_size = original_size - used_size; 1149 intptr_t leftover_size = original_size - used_size;
1116 1150
1117 uword addr = RawObject::ToAddr(obj.raw()) + used_size; 1151 uword addr = RawObject::ToAddr(obj.raw()) + used_size;
1118 if (leftover_size >= TypedData::InstanceSize(0)) { 1152 if (leftover_size >= TypedData::InstanceSize(0)) {
1119 // Update the leftover space as a TypedDataInt8Array object. 1153 // Update the leftover space as a TypedDataInt8Array object.
1120 RawTypedData* raw = 1154 RawTypedData* raw =
1121 reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr)); 1155 reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
1122 uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0); 1156 uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
1123 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); 1157 new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
1124 uword tags = raw->ptr()->tags_; 1158 uint32_t tags = raw->ptr()->tags_;
1125 uword old_tags; 1159 uint32_t old_tags;
1126 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. 1160 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
1127 do { 1161 do {
1128 old_tags = tags; 1162 old_tags = tags;
1129 tags = AtomicOperations::CompareAndSwapWord(&raw->ptr()->tags_, 1163 // We can't use obj.CompareAndSwapTags here because we don't have a
1130 old_tags, new_tags); 1164 // handle for the new object.
1165 tags = AtomicOperations::CompareAndSwapUint32(&raw->ptr()->tags_,
1166 old_tags, new_tags);
1131 } while (tags != old_tags); 1167 } while (tags != old_tags);
1132 1168
1133 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0)); 1169 intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
1134 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size); 1170 ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
1135 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len)); 1171 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
1136 } else { 1172 } else {
1137 // Update the leftover space as a basic object. 1173 // Update the leftover space as a basic object.
1138 ASSERT(leftover_size == Object::InstanceSize()); 1174 ASSERT(leftover_size == Object::InstanceSize());
1139 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); 1175 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
1140 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0); 1176 uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0);
1141 new_tags = RawObject::SizeTag::update(leftover_size, new_tags); 1177 new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
1142 uword tags = raw->ptr()->tags_; 1178 uint32_t tags = raw->ptr()->tags_;
1143 uword old_tags; 1179 uint32_t old_tags;
1144 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. 1180 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
1145 do { 1181 do {
1146 old_tags = tags; 1182 old_tags = tags;
1147 tags = AtomicOperations::CompareAndSwapWord(&raw->ptr()->tags_, 1183 tags = obj.CompareAndSwapTags(old_tags, new_tags);
1148 old_tags, new_tags);
1149 } while (tags != old_tags); 1184 } while (tags != old_tags);
1150 } 1185 }
1151 } 1186 }
1152 } 1187 }
1153 1188
1154 1189
1155 void Object::VerifyBuiltinVtables() { 1190 void Object::VerifyBuiltinVtables() {
1156 #if defined(DEBUG) 1191 #if defined(DEBUG)
1157 Thread* thread = Thread::Current(); 1192 Thread* thread = Thread::Current();
1158 Isolate* isolate = thread->isolate(); 1193 Isolate* isolate = thread->isolate();
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 bool is_vm_object) { 1895 bool is_vm_object) {
1861 uword initial_value = (class_id == kInstructionsCid) 1896 uword initial_value = (class_id == kInstructionsCid)
1862 ? Assembler::GetBreakInstructionFiller() 1897 ? Assembler::GetBreakInstructionFiller()
1863 : reinterpret_cast<uword>(null_); 1898 : reinterpret_cast<uword>(null_);
1864 uword cur = address; 1899 uword cur = address;
1865 uword end = address + size; 1900 uword end = address + size;
1866 while (cur < end) { 1901 while (cur < end) {
1867 *reinterpret_cast<uword*>(cur) = initial_value; 1902 *reinterpret_cast<uword*>(cur) = initial_value;
1868 cur += kWordSize; 1903 cur += kWordSize;
1869 } 1904 }
1870 uword tags = 0; 1905 uint32_t tags = 0;
1871 ASSERT(class_id != kIllegalCid); 1906 ASSERT(class_id != kIllegalCid);
1872 tags = RawObject::ClassIdTag::update(class_id, tags); 1907 tags = RawObject::ClassIdTag::update(class_id, tags);
1873 tags = RawObject::SizeTag::update(size, tags); 1908 tags = RawObject::SizeTag::update(size, tags);
1874 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); 1909 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags);
1875 reinterpret_cast<RawObject*>(address)->tags_ = tags; 1910 reinterpret_cast<RawObject*>(address)->tags_ = tags;
1911 #if defined(HASH_IN_OBJECT_HEADER)
1912 reinterpret_cast<RawObject*>(address)->hash_ = 0;
1913 #endif
1876 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); 1914 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags));
1877 } 1915 }
1878 1916
1879 1917
1880 void Object::CheckHandle() const { 1918 void Object::CheckHandle() const {
1881 #if defined(DEBUG) 1919 #if defined(DEBUG)
1882 if (raw_ != Object::null()) { 1920 if (raw_ != Object::null()) {
1883 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { 1921 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) {
1884 ASSERT(vtable() == Smi::handle_vtable_); 1922 ASSERT(vtable() == Smi::handle_vtable_);
1885 return; 1923 return;
(...skipping 18446 matching lines...) Expand 10 before | Expand all | Expand 10 after
20332 static intptr_t HashImpl(const T* characters, intptr_t len) { 20370 static intptr_t HashImpl(const T* characters, intptr_t len) {
20333 ASSERT(len >= 0); 20371 ASSERT(len >= 0);
20334 StringHasher hasher; 20372 StringHasher hasher;
20335 for (intptr_t i = 0; i < len; i++) { 20373 for (intptr_t i = 0; i < len; i++) {
20336 hasher.Add(characters[i]); 20374 hasher.Add(characters[i]);
20337 } 20375 }
20338 return hasher.Finalize(String::kHashBits); 20376 return hasher.Finalize(String::kHashBits);
20339 } 20377 }
20340 20378
20341 20379
20380 intptr_t String::Hash(RawString* raw) {
20381 StringHasher hasher;
20382 uword length = Smi::Value(raw->ptr()->length_);
20383 if (raw->IsOneByteString() || raw->IsExternalOneByteString()) {
20384 const uint8_t* data;
20385 if (raw->IsOneByteString()) {
20386 data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data();
20387 } else {
20388 ASSERT(raw->IsExternalOneByteString());
20389 RawExternalOneByteString* str =
20390 reinterpret_cast<RawExternalOneByteString*>(raw);
20391 data = str->ptr()->external_data_->data();
20392 }
20393 return String::Hash(data, length);
20394 } else {
20395 const uint16_t* data;
20396 if (raw->IsTwoByteString()) {
20397 data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data();
20398 } else {
20399 ASSERT(raw->IsExternalTwoByteString());
20400 RawExternalTwoByteString* str =
20401 reinterpret_cast<RawExternalTwoByteString*>(raw);
20402 data = str->ptr()->external_data_->data();
20403 }
20404 return String::Hash(data, length);
20405 }
20406 }
20407
20408
20342 intptr_t String::Hash(const char* characters, intptr_t len) { 20409 intptr_t String::Hash(const char* characters, intptr_t len) {
20343 return HashImpl(characters, len); 20410 return HashImpl(characters, len);
20344 } 20411 }
20345 20412
20346 20413
20347 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { 20414 intptr_t String::Hash(const uint8_t* characters, intptr_t len) {
20348 return HashImpl(characters, len); 20415 return HashImpl(characters, len);
20349 } 20416 }
20350 20417
20351 20418
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
21152 memmove(array, OneByteString::CharAddr(*this, 0), str_length); 21219 memmove(array, OneByteString::CharAddr(*this, 0), str_length);
21153 } 21220 }
21154 21221
21155 // If there is any left over space fill it with either an Array object or 21222 // If there is any left over space fill it with either an Array object or
21156 // just a plain object (depending on the amount of left over space) so 21223 // just a plain object (depending on the amount of left over space) so
21157 // that it can be traversed over successfully during garbage collection. 21224 // that it can be traversed over successfully during garbage collection.
21158 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); 21225 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
21159 21226
21160 // Update the class information of the object. 21227 // Update the class information of the object.
21161 const intptr_t class_id = kExternalOneByteStringCid; 21228 const intptr_t class_id = kExternalOneByteStringCid;
21162 uword tags = raw_ptr()->tags_; 21229 uint32_t tags = raw_ptr()->tags_;
21163 uword old_tags; 21230 uint32_t old_tags;
21164 do { 21231 do {
21165 old_tags = tags; 21232 old_tags = tags;
21166 uword new_tags = RawObject::SizeTag::update(used_size, old_tags); 21233 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags);
21167 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); 21234 new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
21168 tags = CompareAndSwapTags(old_tags, new_tags); 21235 tags = CompareAndSwapTags(old_tags, new_tags);
21169 } while (tags != old_tags); 21236 } while (tags != old_tags);
21170 result = this->raw(); 21237 result = this->raw();
21171 const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array); 21238 const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array);
21172 ExternalStringData<uint8_t>* ext_data = 21239 ExternalStringData<uint8_t>* ext_data =
21173 new ExternalStringData<uint8_t>(ext_array, peer, cback); 21240 new ExternalStringData<uint8_t>(ext_array, peer, cback);
21174 ASSERT(result.Length() == str_length); 21241 ASSERT(result.Length() == str_length);
21175 ASSERT(!result.HasHash() || 21242 ASSERT(!result.HasHash() ||
21176 (result.Hash() == String::Hash(ext_array, str_length))); 21243 (result.Hash() == String::Hash(ext_array, str_length)));
(...skipping 12 matching lines...) Expand all
21189 (str_length * kTwoByteChar)); 21256 (str_length * kTwoByteChar));
21190 } 21257 }
21191 21258
21192 // If there is any left over space fill it with either an Array object or 21259 // If there is any left over space fill it with either an Array object or
21193 // just a plain object (depending on the amount of left over space) so 21260 // just a plain object (depending on the amount of left over space) so
21194 // that it can be traversed over successfully during garbage collection. 21261 // that it can be traversed over successfully during garbage collection.
21195 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size); 21262 Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
21196 21263
21197 // Update the class information of the object. 21264 // Update the class information of the object.
21198 const intptr_t class_id = kExternalTwoByteStringCid; 21265 const intptr_t class_id = kExternalTwoByteStringCid;
21199 uword tags = raw_ptr()->tags_; 21266 uint32_t tags = raw_ptr()->tags_;
21200 uword old_tags; 21267 uint32_t old_tags;
21201 do { 21268 do {
21202 old_tags = tags; 21269 old_tags = tags;
21203 uword new_tags = RawObject::SizeTag::update(used_size, old_tags); 21270 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags);
21204 new_tags = RawObject::ClassIdTag::update(class_id, new_tags); 21271 new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
21205 tags = CompareAndSwapTags(old_tags, new_tags); 21272 tags = CompareAndSwapTags(old_tags, new_tags);
21206 } while (tags != old_tags); 21273 } while (tags != old_tags);
21207 result = this->raw(); 21274 result = this->raw();
21208 const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array); 21275 const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array);
21209 ExternalStringData<uint16_t>* ext_data = 21276 ExternalStringData<uint16_t>* ext_data =
21210 new ExternalStringData<uint16_t>(ext_array, peer, cback); 21277 new ExternalStringData<uint16_t>(ext_array, peer, cback);
21211 ASSERT(result.Length() == str_length); 21278 ASSERT(result.Length() == str_length);
21212 ASSERT(!result.HasHash() || 21279 ASSERT(!result.HasHash() ||
21213 (result.Hash() == String::Hash(ext_array, str_length))); 21280 (result.Hash() == String::Hash(ext_array, str_length)));
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
22081 } 22148 }
22082 22149
22083 return dest.raw(); 22150 return dest.raw();
22084 } 22151 }
22085 22152
22086 22153
22087 void Array::MakeImmutable() const { 22154 void Array::MakeImmutable() const {
22088 if (IsImmutable()) return; 22155 if (IsImmutable()) return;
22089 ASSERT(!IsCanonical()); 22156 ASSERT(!IsCanonical());
22090 NoSafepointScope no_safepoint; 22157 NoSafepointScope no_safepoint;
22091 uword tags = raw_ptr()->tags_; 22158 uint32_t tags = raw_ptr()->tags_;
22092 uword old_tags; 22159 uint32_t old_tags;
22093 do { 22160 do {
22094 old_tags = tags; 22161 old_tags = tags;
22095 uword new_tags = 22162 uint32_t new_tags =
22096 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); 22163 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags);
22097 tags = CompareAndSwapTags(old_tags, new_tags); 22164 tags = CompareAndSwapTags(old_tags, new_tags);
22098 } while (tags != old_tags); 22165 } while (tags != old_tags);
22099 } 22166 }
22100 22167
22101 22168
22102 const char* Array::ToCString() const { 22169 const char* Array::ToCString() const {
22103 if (IsNull()) { 22170 if (IsNull()) {
22104 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; 22171 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL";
22105 } 22172 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
22150 22217
22151 // The backing array may be a shared instance, or may not have correct 22218 // The backing array may be a shared instance, or may not have correct
22152 // type parameters. Create a new empty array. 22219 // type parameters. Create a new empty array.
22153 Heap::Space space = thread->IsMutatorThread() ? Heap::kNew : Heap::kOld; 22220 Heap::Space space = thread->IsMutatorThread() ? Heap::kNew : Heap::kOld;
22154 Array& array = Array::Handle(zone, Array::New(0, space)); 22221 Array& array = Array::Handle(zone, Array::New(0, space));
22155 array.SetTypeArguments(type_arguments); 22222 array.SetTypeArguments(type_arguments);
22156 return array.raw(); 22223 return array.raw();
22157 } 22224 }
22158 intptr_t capacity_len = growable_array.Capacity(); 22225 intptr_t capacity_len = growable_array.Capacity();
22159 const Array& array = Array::Handle(zone, growable_array.data()); 22226 const Array& array = Array::Handle(zone, growable_array.data());
22227 ASSERT(array.IsArray());
22160 array.SetTypeArguments(type_arguments); 22228 array.SetTypeArguments(type_arguments);
22161 intptr_t capacity_size = Array::InstanceSize(capacity_len); 22229 intptr_t capacity_size = Array::InstanceSize(capacity_len);
22162 intptr_t used_size = Array::InstanceSize(used_len); 22230 intptr_t used_size = Array::InstanceSize(used_len);
22163 NoSafepointScope no_safepoint; 22231 NoSafepointScope no_safepoint;
22164 22232
22165 // If there is any left over space fill it with either an Array object or 22233 // If there is any left over space fill it with either an Array object or
22166 // just a plain object (depending on the amount of left over space) so 22234 // just a plain object (depending on the amount of left over space) so
22167 // that it can be traversed over successfully during garbage collection. 22235 // that it can be traversed over successfully during garbage collection.
22168 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size); 22236 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size);
22169 22237
22170 // Update the size in the header field and length of the array object. 22238 // Update the size in the header field and length of the array object.
22171 uword tags = array.raw_ptr()->tags_; 22239 uword tags = array.raw_ptr()->tags_;
22172 ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags)); 22240 ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags));
22173 uword old_tags; 22241 uint32_t old_tags;
22174 do { 22242 do {
22175 old_tags = tags; 22243 old_tags = tags;
22176 uword new_tags = RawObject::SizeTag::update(used_size, old_tags); 22244 uint32_t new_tags = RawObject::SizeTag::update(used_size, old_tags);
22177 tags = array.CompareAndSwapTags(old_tags, new_tags); 22245 tags = array.CompareAndSwapTags(old_tags, new_tags);
22178 } while (tags != old_tags); 22246 } while (tags != old_tags);
22179 // TODO(22501): For the heap to remain walkable by the sweeper, it must 22247 // TODO(22501): For the heap to remain walkable by the sweeper, it must
22180 // observe the creation of the filler object no later than the new length 22248 // observe the creation of the filler object no later than the new length
22181 // of the array. This assumption holds on ia32/x64 or if the CAS above is a 22249 // of the array. This assumption holds on ia32/x64 or if the CAS above is a
22182 // full memory barrier. 22250 // full memory barrier.
22183 // 22251 //
22184 // Also, between the CAS of the header above and the SetLength below, 22252 // Also, between the CAS of the header above and the SetLength below,
22185 // the array is temporarily in an inconsistent state. The header is considered 22253 // the array is temporarily in an inconsistent state. The header is considered
22186 // the overriding source of object size by RawObject::Size, but the ASSERTs 22254 // the overriding source of object size by RawObject::Size, but the ASSERTs
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after
23502 return UserTag::null(); 23570 return UserTag::null();
23503 } 23571 }
23504 23572
23505 23573
23506 const char* UserTag::ToCString() const { 23574 const char* UserTag::ToCString() const {
23507 const String& tag_label = String::Handle(label()); 23575 const String& tag_label = String::Handle(label());
23508 return tag_label.ToCString(); 23576 return tag_label.ToCString();
23509 } 23577 }
23510 23578
23511 } // namespace dart 23579 } // namespace dart
OLDNEW
« runtime/vm/intrinsifier.cc ('K') | « runtime/vm/object.h ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698