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

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

Issue 471843003: Revert revision 39101 "Avoid linear search for function lookup." (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.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 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after
1883 for (intptr_t i = 0; i < field_array.Length(); ++i) { 1883 for (intptr_t i = 0; i < field_array.Length(); ++i) {
1884 field ^= field_array.At(i); 1884 field ^= field_array.At(i);
1885 if (!field.is_static()) { 1885 if (!field.is_static()) {
1886 return true; 1886 return true;
1887 } 1887 }
1888 } 1888 }
1889 return false; 1889 return false;
1890 } 1890 }
1891 1891
1892 1892
1893 class FunctionName {
1894 public:
1895 FunctionName(const String& name, String* tmp_string)
1896 : name_(name), tmp_string_(tmp_string) {}
1897 bool Matches(const Function& function) const {
1898 if (name_.IsSymbol()) {
1899 return name_.raw() == function.name();
1900 } else {
1901 *tmp_string_ = function.name();
1902 return name_.Equals(*tmp_string_);
1903 }
1904 }
1905 intptr_t Hash() const { return name_.Hash(); }
1906 private:
1907 const String& name_;
1908 String* tmp_string_;
1909 };
1910
1911
1912 // Traits for looking up Functions by name.
1913 class ClassFunctionsTraits {
1914 public:
1915 // Called when growing the table.
1916 static bool IsMatch(const Object& a, const Object& b) {
1917 ASSERT(a.IsFunction() && b.IsFunction());
1918 // Function objects are always canonical.
1919 return a.raw() == b.raw();
1920 }
1921 static bool IsMatch(const FunctionName& name, const Object& obj) {
1922 return name.Matches(Function::Cast(obj));
1923 }
1924 static uword Hash(const Object& key) {
1925 return String::HashRawSymbol(Function::Cast(key).name());
1926 }
1927 static uword Hash(const FunctionName& name) {
1928 return name.Hash();
1929 }
1930 };
1931 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet;
1932
1933
1934 void Class::SetFunctions(const Array& value) const { 1893 void Class::SetFunctions(const Array& value) const {
1935 ASSERT(!value.IsNull()); 1894 ASSERT(!value.IsNull());
1895 #if defined(DEBUG)
1896 // Verify that all the functions in the array have this class as owner.
1897 Function& func = Function::Handle();
1898 intptr_t len = value.Length();
1899 for (intptr_t i = 0; i < len; i++) {
1900 func ^= value.At(i);
1901 ASSERT(func.Owner() == raw());
1902 }
1903 #endif
1936 StorePointer(&raw_ptr()->functions_, value.raw()); 1904 StorePointer(&raw_ptr()->functions_, value.raw());
1937 const intptr_t len = value.Length();
1938 ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len));
1939 if (len >= kFunctionLookupHashTreshold) {
1940 Function& func = Function::Handle();
1941 for (intptr_t i = 0; i < len; ++i) {
1942 func ^= value.At(i);
1943 // Verify that all the functions in the array have this class as owner.
1944 ASSERT(func.Owner() == raw());
1945 set.Insert(func);
1946 }
1947 }
1948 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
1949 } 1905 }
1950 1906
1951 1907
1952 void Class::AddFunction(const Function& function) const { 1908 void Class::AddFunction(const Function& function) const {
1953 const Array& arr = Array::Handle(functions()); 1909 const Array& arr = Array::Handle(functions());
1954 const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); 1910 const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1));
1955 new_arr.SetAt(arr.Length(), function); 1911 new_arr.SetAt(arr.Length(), function);
1956 StorePointer(&raw_ptr()->functions_, new_arr.raw()); 1912 SetFunctions(new_arr);
1957 // Add to hash table, if any.
1958 const intptr_t new_len = new_arr.Length();
1959 if (new_len == kFunctionLookupHashTreshold) {
1960 // Transition to using hash table.
1961 SetFunctions(new_arr);
1962 } else if (new_len > kFunctionLookupHashTreshold) {
1963 ClassFunctionsSet set(raw_ptr()->functions_hash_table_);
1964 set.Insert(function);
1965 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
1966 }
1967 } 1913 }
1968 1914
1969 1915
1970 intptr_t Class::FindFunctionIndex(const Function& needle) const { 1916 intptr_t Class::FindFunctionIndex(const Function& needle) const {
1971 Isolate* isolate = Isolate::Current(); 1917 Isolate* isolate = Isolate::Current();
1972 if (EnsureIsFinalized(isolate) != Error::null()) { 1918 if (EnsureIsFinalized(isolate) != Error::null()) {
1973 return -1; 1919 return -1;
1974 } 1920 }
1975 REUSABLE_ARRAY_HANDLESCOPE(isolate); 1921 REUSABLE_ARRAY_HANDLESCOPE(isolate);
1976 REUSABLE_FUNCTION_HANDLESCOPE(isolate); 1922 REUSABLE_FUNCTION_HANDLESCOPE(isolate);
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 if (EnsureIsFinalized(isolate) != Error::null()) { 3824 if (EnsureIsFinalized(isolate) != Error::null()) {
3879 return Function::null(); 3825 return Function::null();
3880 } 3826 }
3881 REUSABLE_ARRAY_HANDLESCOPE(isolate); 3827 REUSABLE_ARRAY_HANDLESCOPE(isolate);
3882 REUSABLE_FUNCTION_HANDLESCOPE(isolate); 3828 REUSABLE_FUNCTION_HANDLESCOPE(isolate);
3883 Array& funcs = isolate->ArrayHandle(); 3829 Array& funcs = isolate->ArrayHandle();
3884 funcs ^= functions(); 3830 funcs ^= functions();
3885 ASSERT(!funcs.IsNull()); 3831 ASSERT(!funcs.IsNull());
3886 const intptr_t len = funcs.Length(); 3832 const intptr_t len = funcs.Length();
3887 Function& function = isolate->FunctionHandle(); 3833 Function& function = isolate->FunctionHandle();
3888 if (len >= kFunctionLookupHashTreshold) {
3889 ClassFunctionsSet set(raw_ptr()->functions_hash_table_);
3890 REUSABLE_STRING_HANDLESCOPE(isolate);
3891 function ^= set.GetOrNull(FunctionName(name, &(isolate->StringHandle())));
3892 // No mutations.
3893 ASSERT(set.Release().raw() == raw_ptr()->functions_hash_table_);
3894 return function.IsNull() ? Function::null()
3895 : CheckFunctionType(function, kind);
3896 }
3897 if (name.IsSymbol()) { 3834 if (name.IsSymbol()) {
3898 // Quick Symbol compare. 3835 // Quick Symbol compare.
3899 NoGCScope no_gc; 3836 NoGCScope no_gc;
3900 for (intptr_t i = 0; i < len; i++) { 3837 for (intptr_t i = 0; i < len; i++) {
3901 function ^= funcs.At(i); 3838 function ^= funcs.At(i);
3902 if (function.name() == name.raw()) { 3839 if (function.name() == name.raw()) {
3903 return CheckFunctionType(function, kind); 3840 return CheckFunctionType(function, kind);
3904 } 3841 }
3905 } 3842 }
3906 } else { 3843 } else {
(...skipping 15572 matching lines...) Expand 10 before | Expand all | Expand 10 after
19479 return tag_label.ToCString(); 19416 return tag_label.ToCString();
19480 } 19417 }
19481 19418
19482 19419
19483 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19420 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19484 Instance::PrintJSONImpl(stream, ref); 19421 Instance::PrintJSONImpl(stream, ref);
19485 } 19422 }
19486 19423
19487 19424
19488 } // namespace dart 19425 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698