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

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

Issue 1709273003: Make function lookup in classes thread-safe: (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: d Created 4 years, 10 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/resolver.h » ('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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 const Context& context = Context::Handle(zone, 1730 const Context& context = Context::Handle(zone,
1731 Context::New(0, Heap::kOld)); 1731 Context::New(0, Heap::kOld));
1732 object_store->set_empty_context(context); 1732 object_store->set_empty_context(context);
1733 1733
1734 #endif // defined(DART_NO_SNAPSHOT). 1734 #endif // defined(DART_NO_SNAPSHOT).
1735 1735
1736 return Error::null(); 1736 return Error::null();
1737 } 1737 }
1738 1738
1739 1739
1740 #if defined(DEBUG)
1741 bool Object:: InVMHeap() const {
1742 if (FLAG_verify_handles && raw()->IsVMHeapObject()) {
1743 Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
1744 ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw())));
1745 }
1746 return raw()->IsVMHeapObject();
1747 }
1748 #endif // DEBUG
1749
1750
1740 void Object::Print() const { 1751 void Object::Print() const {
1741 THR_Print("%s\n", ToCString()); 1752 THR_Print("%s\n", ToCString());
1742 } 1753 }
1743 1754
1744 1755
1745 RawString* Object::DictionaryName() const { 1756 RawString* Object::DictionaryName() const {
1746 return String::null(); 1757 return String::null();
1747 } 1758 }
1748 1759
1749 1760
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 return String::HashRawSymbol(Function::Cast(key).name()); 2114 return String::HashRawSymbol(Function::Cast(key).name());
2104 } 2115 }
2105 static uword Hash(const FunctionName& name) { 2116 static uword Hash(const FunctionName& name) {
2106 return name.Hash(); 2117 return name.Hash();
2107 } 2118 }
2108 }; 2119 };
2109 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; 2120 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet;
2110 2121
2111 2122
2112 void Class::SetFunctions(const Array& value) const { 2123 void Class::SetFunctions(const Array& value) const {
2124 ASSERT(Thread::Current()->IsMutatorThread());
2113 ASSERT(!value.IsNull()); 2125 ASSERT(!value.IsNull());
2114 StorePointer(&raw_ptr()->functions_, value.raw()); 2126 StorePointer(&raw_ptr()->functions_, value.raw());
2115 const intptr_t len = value.Length(); 2127 const intptr_t len = value.Length();
2116 if (len >= kFunctionLookupHashTreshold) { 2128 if (len >= kFunctionLookupHashTreshold) {
2117 ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld)); 2129 ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld));
2118 Function& func = Function::Handle(); 2130 Function& func = Function::Handle();
2119 for (intptr_t i = 0; i < len; ++i) { 2131 for (intptr_t i = 0; i < len; ++i) {
2120 func ^= value.At(i); 2132 func ^= value.At(i);
2121 // Verify that all the functions in the array have this class as owner. 2133 // Verify that all the functions in the array have this class as owner.
2122 ASSERT(func.Owner() == raw()); 2134 ASSERT(func.Owner() == raw());
2123 set.Insert(func); 2135 set.Insert(func);
2124 } 2136 }
2125 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); 2137 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
2126 } else { 2138 } else {
2127 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); 2139 StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
2128 } 2140 }
2129 } 2141 }
2130 2142
2131 2143
2132 void Class::AddFunction(const Function& function) const { 2144 void Class::AddFunction(const Function& function) const {
2145 ASSERT(Thread::Current()->IsMutatorThread());
2133 const Array& arr = Array::Handle(functions()); 2146 const Array& arr = Array::Handle(functions());
2134 const Array& new_arr = 2147 const Array& new_arr =
2135 Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); 2148 Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld));
2136 new_arr.SetAt(arr.Length(), function); 2149 new_arr.SetAt(arr.Length(), function);
2137 StorePointer(&raw_ptr()->functions_, new_arr.raw()); 2150 StorePointer(&raw_ptr()->functions_, new_arr.raw());
2138 // Add to hash table, if any. 2151 // Add to hash table, if any.
2139 const intptr_t new_len = new_arr.Length(); 2152 const intptr_t new_len = new_arr.Length();
2140 if (new_len == kFunctionLookupHashTreshold) { 2153 if (new_len == kFunctionLookupHashTreshold) {
2141 // Transition to using hash table. 2154 // Transition to using hash table.
2142 SetFunctions(new_arr); 2155 SetFunctions(new_arr);
2143 } else if (new_len > kFunctionLookupHashTreshold) { 2156 } else if (new_len > kFunctionLookupHashTreshold) {
2144 ClassFunctionsSet set(raw_ptr()->functions_hash_table_); 2157 ClassFunctionsSet set(raw_ptr()->functions_hash_table_);
2145 set.Insert(function); 2158 set.Insert(function);
2146 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); 2159 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
2147 } 2160 }
2148 } 2161 }
2149 2162
2150 2163
2151 void Class::RemoveFunction(const Function& function) const { 2164 void Class::RemoveFunction(const Function& function) const {
2165 ASSERT(Thread::Current()->IsMutatorThread());
2152 const Array& arr = Array::Handle(functions()); 2166 const Array& arr = Array::Handle(functions());
2153 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); 2167 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
2154 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); 2168 StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
2155 Function& entry = Function::Handle(); 2169 Function& entry = Function::Handle();
2156 for (intptr_t i = 0; i < arr.Length(); i++) { 2170 for (intptr_t i = 0; i < arr.Length(); i++) {
2157 entry ^= arr.At(i); 2171 entry ^= arr.At(i);
2158 if (function.raw() != entry.raw()) { 2172 if (function.raw() != entry.raw()) {
2159 AddFunction(entry); 2173 AddFunction(entry);
2160 } 2174 }
2161 } 2175 }
(...skipping 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after
3928 return Function::null(); 3942 return Function::null();
3929 } 3943 }
3930 REUSABLE_ARRAY_HANDLESCOPE(thread); 3944 REUSABLE_ARRAY_HANDLESCOPE(thread);
3931 REUSABLE_FUNCTION_HANDLESCOPE(thread); 3945 REUSABLE_FUNCTION_HANDLESCOPE(thread);
3932 Array& funcs = thread->ArrayHandle(); 3946 Array& funcs = thread->ArrayHandle();
3933 funcs ^= functions(); 3947 funcs ^= functions();
3934 ASSERT(!funcs.IsNull()); 3948 ASSERT(!funcs.IsNull());
3935 const intptr_t len = funcs.Length(); 3949 const intptr_t len = funcs.Length();
3936 Function& function = thread->FunctionHandle(); 3950 Function& function = thread->FunctionHandle();
3937 if (len >= kFunctionLookupHashTreshold) { 3951 if (len >= kFunctionLookupHashTreshold) {
3938 ClassFunctionsSet set(raw_ptr()->functions_hash_table_); 3952 // Cache functions hash table to allow multi threaded access.
3939 REUSABLE_STRING_HANDLESCOPE(thread); 3953 const Array& hash_table = Array::Handle(thread->zone(),
3940 function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle()))); 3954 raw_ptr()->functions_hash_table_);
3941 // No mutations. 3955 if (!hash_table.IsNull()) {
3942 ASSERT(set.Release().raw() == raw_ptr()->functions_hash_table_); 3956 ClassFunctionsSet set(hash_table.raw());
3943 return function.IsNull() ? Function::null() 3957 REUSABLE_STRING_HANDLESCOPE(thread);
3944 : CheckFunctionType(function, kind); 3958 function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle())));
3959 // No mutations.
3960 ASSERT(set.Release().raw() == hash_table.raw());
3961 return function.IsNull() ? Function::null()
3962 : CheckFunctionType(function, kind);
3963 }
3945 } 3964 }
3946 if (name.IsSymbol()) { 3965 if (name.IsSymbol()) {
3947 // Quick Symbol compare. 3966 // Quick Symbol compare.
3948 NoSafepointScope no_safepoint; 3967 NoSafepointScope no_safepoint;
3949 for (intptr_t i = 0; i < len; i++) { 3968 for (intptr_t i = 0; i < len; i++) {
3950 function ^= funcs.At(i); 3969 function ^= funcs.At(i);
3951 if (function.name() == name.raw()) { 3970 if (function.name() == name.raw()) {
3952 return CheckFunctionType(function, kind); 3971 return CheckFunctionType(function, kind);
3953 } 3972 }
3954 } 3973 }
(...skipping 17477 matching lines...) Expand 10 before | Expand all | Expand 10 after
21432 return UserTag::null(); 21451 return UserTag::null();
21433 } 21452 }
21434 21453
21435 21454
21436 const char* UserTag::ToCString() const { 21455 const char* UserTag::ToCString() const {
21437 const String& tag_label = String::Handle(label()); 21456 const String& tag_label = String::Handle(label());
21438 return tag_label.ToCString(); 21457 return tag_label.ToCString();
21439 } 21458 }
21440 21459
21441 } // namespace dart 21460 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/resolver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698