From bf9906cf51bbb308efda1cd175f331f79da67244 Mon Sep 17 00:00:00 2001 From: "asiva@google.com" Date: Thu, 14 Aug 2014 22:06:54 +0000 Subject: [PATCH] Revert r39246 which reverted r39101 R=koda@google.com Review URL: https://codereview.chromium.org//474073002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@39272 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/vm/object.cc | 83 ++++++++++++++++++++++---- runtime/vm/object.h | 4 ++ runtime/vm/raw_object.h | 1 + tests/standalone/issue14236_test.dart | Bin 9842 -> 9817 bytes 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 2211b5455a5..208769deac2 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -1890,18 +1890,62 @@ bool Class::HasInstanceFields() const { } +class FunctionName { + public: + FunctionName(const String& name, String* tmp_string) + : name_(name), tmp_string_(tmp_string) {} + bool Matches(const Function& function) const { + if (name_.IsSymbol()) { + return name_.raw() == function.name(); + } else { + *tmp_string_ = function.name(); + return name_.Equals(*tmp_string_); + } + } + intptr_t Hash() const { return name_.Hash(); } + private: + const String& name_; + String* tmp_string_; +}; + + +// Traits for looking up Functions by name. +class ClassFunctionsTraits { + public: + // Called when growing the table. + static bool IsMatch(const Object& a, const Object& b) { + ASSERT(a.IsFunction() && b.IsFunction()); + // Function objects are always canonical. + return a.raw() == b.raw(); + } + static bool IsMatch(const FunctionName& name, const Object& obj) { + return name.Matches(Function::Cast(obj)); + } + static uword Hash(const Object& key) { + return String::HashRawSymbol(Function::Cast(key).name()); + } + static uword Hash(const FunctionName& name) { + return name.Hash(); + } +}; +typedef UnorderedHashSet ClassFunctionsSet; + + void Class::SetFunctions(const Array& value) const { ASSERT(!value.IsNull()); -#if defined(DEBUG) - // Verify that all the functions in the array have this class as owner. - Function& func = Function::Handle(); - intptr_t len = value.Length(); - for (intptr_t i = 0; i < len; i++) { - func ^= value.At(i); - ASSERT(func.Owner() == raw()); - } -#endif StorePointer(&raw_ptr()->functions_, value.raw()); + const intptr_t len = value.Length(); + ClassFunctionsSet set(HashTables::New(len)); + if (len >= kFunctionLookupHashTreshold) { + Function& func = Function::Handle(); + for (intptr_t i = 0; i < len; ++i) { + func ^= value.At(i); + // Verify that all the functions in the array have this class as owner. + ASSERT(func.Owner() == raw()); + set.Insert(func); + } + } + StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); } @@ -1909,7 +1953,17 @@ void Class::AddFunction(const Function& function) const { const Array& arr = Array::Handle(functions()); const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); new_arr.SetAt(arr.Length(), function); - SetFunctions(new_arr); + StorePointer(&raw_ptr()->functions_, new_arr.raw()); + // Add to hash table, if any. + const intptr_t new_len = new_arr.Length(); + if (new_len == kFunctionLookupHashTreshold) { + // Transition to using hash table. + SetFunctions(new_arr); + } else if (new_len > kFunctionLookupHashTreshold) { + ClassFunctionsSet set(raw_ptr()->functions_hash_table_); + set.Insert(function); + StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); + } } @@ -3831,6 +3885,15 @@ RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { ASSERT(!funcs.IsNull()); const intptr_t len = funcs.Length(); Function& function = isolate->FunctionHandle(); + if (len >= kFunctionLookupHashTreshold) { + ClassFunctionsSet set(raw_ptr()->functions_hash_table_); + REUSABLE_STRING_HANDLESCOPE(isolate); + function ^= set.GetOrNull(FunctionName(name, &(isolate->StringHandle()))); + // No mutations. + ASSERT(set.Release().raw() == raw_ptr()->functions_hash_table_); + return function.IsNull() ? Function::null() + : CheckFunctionType(function, kind); + } if (name.IsSymbol()) { // Quick Symbol compare. NoGCScope no_gc; diff --git a/runtime/vm/object.h b/runtime/vm/object.h index a41e01ddada..cede5f6bb91 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -949,6 +949,7 @@ class Class : public Object { // Returns true if non-static fields are defined. bool HasInstanceFields() const; + // TODO(koda): Unite w/ hash table. RawArray* functions() const { return raw_ptr()->functions_; } void SetFunctions(const Array& value) const; void AddFunction(const Function& function) const; @@ -1211,6 +1212,9 @@ class Class : public Object { void CalculateFieldOffsets() const; + // functions_hash_table is in use iff there are at least this many functions. + static const intptr_t kFunctionLookupHashTreshold = 16; + // Initial value for the cached number of type arguments. static const intptr_t kUnknownNumTypeArguments = -1; diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 8b49789be97..09f58e936bb 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -499,6 +499,7 @@ class RawClass : public RawObject { RawString* name_; RawString* user_name_; RawArray* functions_; + RawArray* functions_hash_table_; RawArray* fields_; RawArray* offset_in_words_to_field_; RawGrowableObjectArray* closure_functions_; // Local functions and literals. diff --git a/tests/standalone/issue14236_test.dart b/tests/standalone/issue14236_test.dart index f720a6528601cf67e7b0c6a9647d8315230afd5b..7e248f332491800d1ba835c1ecb1673afe01e56a 100644 GIT binary patch delta 2243 zcmb7FZ%k8H6zBC1@c1JXinXmspt6bL&OPUM z&pr2?cYpUu+fQxMXU`ry=$w$gRbAyfY~6m4Ju=|18}xeph|8&WP`x&XzMrD{9d`Xu z>bPA$NcGwDM@EJm6g3EBMCF8+Ot0O#eOt}8>iUV#E4(mqIpw#%86U&srX8-EXP88q zKPx1vt?~rjc9%ObmAfYF_s!4GGk4^_?wIYIO^o?i^oFM(oPvq-xd<=$-Q|NIq9wRBC$E7q)r($#(J)Ta}FE66OIfkV1|5^Mpr%oMb$9yS|VF!z|zf(fg zSc3yD*N7dYiDrRD{7tqbvZu0C6l^&;Z0~ggM%)b6OVV|_m`qftl~NUPT`W0=ioxI) zCLi|N9!WkSk_9F%$$?8cD%!zoqSX8*7Ft*<*Ns;XLx!1|nK{5A-47EvzN|4$+|NPS zDOhs2ZmclSCI~4wm|7#T2BzS(&r-88GY105+v=jWVaHyb4G!_Em1$9IkU<#UueDJEE(yP9?oKqH?OWE54 zYmU=5UowgRj>PboC@BNPgVsY(5f1rLy(95x~&Yzv}vU zIA@>FO*!mN+fc9F&_rR^lKG~21rpnzyQK~7fX{gBCg@hQlbKk2NkD!Otp{%*u~U zizZ&07tJ75eVxbwP+h-P5y7<%9NTJCEqr2g;3d=%HON@M3#Hz+zTaSsB$xZe*+RUt zP;St44%zuLWbf1H%-Fp|PLh+$uq^fiqP~yOWpsc))~m=K-meX5L2jXnu!4%h$~19+ zVF(WgdJ2^X%$%8btFX8UM=J><=O8k}XqLXob4`=%j{L zB7lX$&8QZC7AiAV!-Cum&FMT9)<*I{=Z5Bu_0cz1RYxJzMW;|8KOYGF!P;n;1k)Ql zq$`q`S~q&t6#+JhysiMB(Gc`T5JV~Hi8CpdfWQ>h*zyQs27bPeS)pKXs>n#(x;9s| zlOXL;1lh?z9gr4pK}Wo%`0b6Z$lmCQ8zwGU>R4)qx7gombEEH4BaYz`;{*6raf3J~ zrUmzkcM=MqEKw6hpsvIqu83KHv&4Y5Jz287uo2_=59EGTYr|ceYjmi$!;Q#!Q+bu? zf_58W0d?BlDkG=Ieb5S-3nfR4^_SQPCbUYSS{*3x_uBje7pSNus$jo`bBQlgo-oV> z4;tsQ44lI|UF$pcCWTr!OH{f_p$O2<dau$$Z+Tc~kmwV6?MOok;Ags(U^W(aS zgsV$BX^HZDjJxbt#FITj$ZUTFk6gawtg+=~c_c)MK1PYUP@g2h zrHvlZ4|O11>Q?ADQ+#Hoy}N`CTTpJWWu@B`4zk+yZtU>G zo*02!i|9Kd#Y%|34M?oAkenmuvISK+Suk0?YONGh*(?=lz$$-nNZRg-YopK$4`5Rm znxmO%mvBv8JMLPK(JLoEH delta 2104 zcmZ`)eM}o=81MBcrIZ1s&;q6Fm5+5B&~B8$pg`FtQ9vAIYbMOvbsaK3Dr;GXIO~yY z$%r!{uO_;G)WrRvjxE`&%Y+Np(z`<8S~bpSTq7>V#KgZAX4r>`S9tUK3A>DWb&MKnogO=2dYx4Dr$CB zRqU-Azg~JQaZR++LeoK-&XkJhX*wYdB}GMBjnl%oO9#?nY~1tkiho8m7R(nc3Rf!8HAGiyOK45Eb~_+)Rd;z|rF2cJr`z$6*OjzhHlAWQW! zZDAkdVBl^-lx)f+03FjWfJ8ov= zbRG^-YPJZpE55@Hfa0tduud?LrNf-yy{vGmayIdS=&3TIjDRj>zDCEtN@u0WE~BEe zh3Us0G?WpgU|gv#G4p=;tep3k+$g!x$sm0fw%2y+XU@7D9`}F^a7wqLgO6;QZQ`ws zv4PfXHC)t{y}i7b=X?=gWPO#Ny1KmWEL_In^bR@tYKb}@A2Sje0pDadi{*1bnqw5J z=RkGN9;^uT=hR^)@I_8}S@qo79BJW9x2v7qL0H$Bq=n>`nylbyM^B%}*feKgK!!@A zY+HAyh10`|Ff?ih!Q2XL1T5ut>E!e4`;5L~seC!oP*_IP zDG~V;pU3BcJI}2#^RI?^!$xfQ)nRXTm^fhtkMm5b<_$iYt-WxZCQcZQ#tzVs-&)zt z54FwPHbQ=EuPkqaLt#iNygLaGAJRGB$y@up9ZctcjTyi>O|{CjfGWtI*=5b2Ip^p@ zS(z8iU`DeKZckFsjoCnd!B)%;-Yv+p_AVg*k?TjUuWc!feeJEICqrd~!NR6h_lq}_*foCBAe^eqM%3A9^_mUQim?9>? zHy%H$WI>}gHyQOSd=A*PD%qxERJ#*OKcUTgj{8>Iz&E$%1p`oRZ76BxHfN$t97S2U z06MVzEbu`!anTa+=2l;doJ$09hi}P&z9gq|HwzEWETx76s67HsTom=fgNLqG#5{m$ zUlT3Aw9!$)0iE^sC0#ux8{(k9k){rS1)>bIfXBqaZF0`e4c@UaYqBN9l2iTq&|!xc zeeKE^QWYH%r@jW)#j3%_`bJouMZE@o<}3PI+!C{cn!;LG5pQ7?-1V1*8u-CQ3M*k< zRton!I+$jps#VBP5EXWdzwr*Z1+-ywqlAZplF()sbH<#U1ius4@LG zd*}}I58pa;=PtbDTnDPA|AbIMC#t4nqndK0)n-+Pkt0O8V|l20Axg<<5eUORESu5` zFmEDfqJERzCqTudlxsy03Y-y4YPp9u!IfNyiBg@M#vjj!kHoC;9>lPeG~OJS#|LBl z08MyE05;}=0Ay2GoOgA{6bR5%j$pKc(FtH3C2>C_=a)PEq>=M&27g IBp}Jeztzm?761SM