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

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

Issue 1747073002: Make type canonicalization thread safe (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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/isolate.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 4116 matching lines...) Expand 10 before | Expand all | Expand 10 after
4127 } 4127 }
4128 return LibraryPrefix::null(); 4128 return LibraryPrefix::null();
4129 } 4129 }
4130 4130
4131 4131
4132 // Canonicalizing the type arguments may have changed the index, may have 4132 // Canonicalizing the type arguments may have changed the index, may have
4133 // grown the table, or may even have canonicalized this type. Therefore 4133 // grown the table, or may even have canonicalized this type. Therefore
4134 // conrtinue search for canonical type at the last index visited. 4134 // conrtinue search for canonical type at the last index visited.
4135 RawAbstractType* Class::LookupOrAddCanonicalType( 4135 RawAbstractType* Class::LookupOrAddCanonicalType(
4136 const AbstractType& lookup_type, intptr_t start_index) const { 4136 const AbstractType& lookup_type, intptr_t start_index) const {
4137 intptr_t index = start_index; 4137 Thread* thread = Thread::Current();
4138 Zone* zone = Thread::Current()->zone(); 4138 Zone* zone = thread->zone();
4139 Isolate* isolate = thread->isolate();
4139 AbstractType& type = Type::Handle(zone); 4140 AbstractType& type = Type::Handle(zone);
4140 Array& canonical_types = Array::Handle(zone); 4141 Array& canonical_types = Array::Handle(zone);
4141 canonical_types ^= this->canonical_types(); 4142 canonical_types ^= this->canonical_types();
4142 if (canonical_types.IsNull()) { 4143 if (canonical_types.IsNull()) {
4143 canonical_types = empty_array().raw(); 4144 canonical_types = empty_array().raw();
4144 } 4145 }
4145 ASSERT(canonical_types.IsArray()); 4146 ASSERT(canonical_types.IsArray());
4146 const intptr_t length = canonical_types.Length(); 4147 intptr_t length = canonical_types.Length();
4148 intptr_t index = start_index;
4147 while (index < length) { 4149 while (index < length) {
4148 type ^= canonical_types.At(index); 4150 type ^= canonical_types.At(index);
4149 if (type.IsNull()) { 4151 if (type.IsNull()) {
4150 break; 4152 break;
4151 } 4153 }
4152 ASSERT(type.IsFinalized()); 4154 ASSERT(type.IsFinalized());
4153 if (lookup_type.Equals(type)) { 4155 if (lookup_type.Equals(type)) {
4154 ASSERT(type.IsCanonical()); 4156 ASSERT(type.IsCanonical());
4155 return type.raw(); 4157 return type.raw();
4156 } 4158 }
4157 index++; 4159 index++;
4158 } 4160 }
siva 2016/03/01 16:57:40 Should we hoist the while loop as a helper method
srdjan 2016/03/01 19:28:13 Done.
4159 4161
4160 lookup_type.SetCanonical(); 4162 {
4163 SafepointMutexLocker ml(isolate->type_canonicalization_mutex());
4164 // Lookup again, in case the canonicalization array changed.
4165 canonical_types ^= this->canonical_types();
4166 if (canonical_types.IsNull()) {
4167 canonical_types = empty_array().raw();
4168 }
4169 length = canonical_types.Length();
4170 while (index < length) {
4171 type ^= canonical_types.At(index);
4172 if (type.IsNull()) {
4173 break;
4174 }
4175 ASSERT(type.IsFinalized());
4176 if (lookup_type.Equals(type)) {
4177 ASSERT(type.IsCanonical());
4178 return type.raw();
4179 }
4180 index++;
4181 }
4161 4182
4162 // The type needs to be added to the list. Grow the list if it is full. 4183 lookup_type.SetCanonical();
4163 if (index >= length) { 4184
4164 ASSERT((index == length) || ((index == 1) && (length == 0))); 4185 // The type needs to be added to the list. Grow the list if it is full.
4165 const intptr_t new_length = (length > 64) ? 4186 if (index >= length) {
4166 (length + 64) : 4187 ASSERT((index == length) || ((index == 1) && (length == 0)));
4167 ((length == 0) ? 2 : (length * 2)); 4188 const intptr_t new_length = (length > 64) ?
4168 const Array& new_canonical_types = Array::Handle( 4189 (length + 64) :
4169 zone, Array::Grow(canonical_types, new_length, Heap::kOld)); 4190 ((length == 0) ? 2 : (length * 2));
4170 new_canonical_types.SetAt(index, lookup_type); 4191 const Array& new_canonical_types = Array::Handle(
4171 this->set_canonical_types(new_canonical_types); 4192 zone, Array::Grow(canonical_types, new_length, Heap::kOld));
4172 } else { 4193 new_canonical_types.SetAt(index, lookup_type);
4173 canonical_types.SetAt(index, lookup_type); 4194 this->set_canonical_types(new_canonical_types);
4195 } else {
4196 canonical_types.SetAt(index, lookup_type);
4197 }
4174 } 4198 }
4175 return lookup_type.raw(); 4199 return lookup_type.raw();
4176 } 4200 }
4177 4201
4178 4202
4179 const char* Class::ToCString() const { 4203 const char* Class::ToCString() const {
4180 const Library& lib = Library::Handle(library()); 4204 const Library& lib = Library::Handle(library());
4181 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); 4205 const char* library_name = lib.IsNull() ? "" : lib.ToCString();
4182 const char* patch_prefix = is_patch() ? "Patch " : ""; 4206 const char* patch_prefix = is_patch() ? "Patch " : "";
4183 const char* class_name = String::Handle(Name()).ToCString(); 4207 const char* class_name = String::Handle(Name()).ToCString();
(...skipping 11602 matching lines...) Expand 10 before | Expand all | Expand 10 after
15786 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); 15810 TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
15787 type_args = type_args.Canonicalize(trail); 15811 type_args = type_args.Canonicalize(trail);
15788 if (IsCanonical()) { 15812 if (IsCanonical()) {
15789 // Canonicalizing type_args canonicalized this type. 15813 // Canonicalizing type_args canonicalized this type.
15790 ASSERT(IsRecursive()); 15814 ASSERT(IsRecursive());
15791 return this->raw(); 15815 return this->raw();
15792 } 15816 }
15793 set_arguments(type_args); 15817 set_arguments(type_args);
15794 type = cls.CanonicalType(); // May be set while canonicalizing type args. 15818 type = cls.CanonicalType(); // May be set while canonicalizing type args.
15795 if (type.IsNull()) { 15819 if (type.IsNull()) {
15796 cls.set_canonical_types(*this); 15820 MutexLocker ml(isolate->type_canonicalization_mutex());
15797 SetCanonical(); 15821 // Recheck if type exists.
15798 return this->raw(); 15822 type = cls.CanonicalType();
15823 if (type.IsNull()) {
15824 SetCanonical();
15825 cls.set_canonical_types(*this);
15826 return this->raw();
15827 }
15799 } 15828 }
15800 } 15829 }
15801 ASSERT(this->Equals(type)); 15830 ASSERT(this->Equals(type));
15802 ASSERT(type.IsCanonical()); 15831 ASSERT(type.IsCanonical());
15803 return type.raw(); 15832 return type.raw();
15804 } 15833 }
15805 15834
15806 Array& canonical_types = Array::Handle(zone); 15835 Array& canonical_types = Array::Handle(zone);
15807 canonical_types ^= cls.canonical_types(); 15836 canonical_types ^= cls.canonical_types();
15808 if (canonical_types.IsNull()) { 15837 if (canonical_types.IsNull()) {
(...skipping 5850 matching lines...) Expand 10 before | Expand all | Expand 10 after
21659 return UserTag::null(); 21688 return UserTag::null();
21660 } 21689 }
21661 21690
21662 21691
21663 const char* UserTag::ToCString() const { 21692 const char* UserTag::ToCString() const {
21664 const String& tag_label = String::Handle(label()); 21693 const String& tag_label = String::Handle(label());
21665 return tag_label.ToCString(); 21694 return tag_label.ToCString();
21666 } 21695 }
21667 21696
21668 } // namespace dart 21697 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698