Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index c85afa2c21058d56586eadf69c79333f1ccf39b7..d9f3125cf6ea0d4872fe058f6f33473965a52f09 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -1737,6 +1737,17 @@ RawError* Object::Init(Isolate* isolate) { |
} |
+#if defined(DEBUG) |
+bool Object:: InVMHeap() const { |
+ if (FLAG_verify_handles && raw()->IsVMHeapObject()) { |
+ Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); |
+ ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw()))); |
+ } |
+ return raw()->IsVMHeapObject(); |
+} |
+#endif // DEBUG |
+ |
+ |
void Object::Print() const { |
THR_Print("%s\n", ToCString()); |
} |
@@ -2110,6 +2121,7 @@ typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; |
void Class::SetFunctions(const Array& value) const { |
+ ASSERT(Thread::Current()->IsMutatorThread()); |
ASSERT(!value.IsNull()); |
StorePointer(&raw_ptr()->functions_, value.raw()); |
const intptr_t len = value.Length(); |
@@ -2130,6 +2142,7 @@ void Class::SetFunctions(const Array& value) const { |
void Class::AddFunction(const Function& function) const { |
+ ASSERT(Thread::Current()->IsMutatorThread()); |
const Array& arr = Array::Handle(functions()); |
const Array& new_arr = |
Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); |
@@ -2149,6 +2162,7 @@ void Class::AddFunction(const Function& function) const { |
void Class::RemoveFunction(const Function& function) const { |
+ ASSERT(Thread::Current()->IsMutatorThread()); |
const Array& arr = Array::Handle(functions()); |
StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |
StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); |
@@ -3935,13 +3949,18 @@ RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { |
const intptr_t len = funcs.Length(); |
Function& function = thread->FunctionHandle(); |
if (len >= kFunctionLookupHashTreshold) { |
- ClassFunctionsSet set(raw_ptr()->functions_hash_table_); |
- REUSABLE_STRING_HANDLESCOPE(thread); |
- function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle()))); |
- // No mutations. |
- ASSERT(set.Release().raw() == raw_ptr()->functions_hash_table_); |
- return function.IsNull() ? Function::null() |
- : CheckFunctionType(function, kind); |
+ // Cache functions hash table to allow multi threaded access. |
+ const Array& hash_table = Array::Handle(thread->zone(), |
+ raw_ptr()->functions_hash_table_); |
+ if (!hash_table.IsNull()) { |
+ ClassFunctionsSet set(hash_table.raw()); |
+ REUSABLE_STRING_HANDLESCOPE(thread); |
+ function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle()))); |
+ // No mutations. |
+ ASSERT(set.Release().raw() == hash_table.raw()); |
+ return function.IsNull() ? Function::null() |
+ : CheckFunctionType(function, kind); |
+ } |
} |
if (name.IsSymbol()) { |
// Quick Symbol compare. |