OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |