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

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

Issue 2983823002: Improve hashCode for closures (Closed)
Patch Set: Error handling Created 3 years, 5 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/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/become.h" 10 #include "vm/become.h"
(...skipping 6884 matching lines...) Expand 10 before | Expand all | Expand 10 after
6895 if (!HasInstantiatedSignature(kCurrentClass)) { 6895 if (!HasInstantiatedSignature(kCurrentClass)) {
6896 instantiator_type_arguments = receiver.GetTypeArguments(); 6896 instantiator_type_arguments = receiver.GetTypeArguments();
6897 } 6897 }
6898 if (!HasInstantiatedSignature(kFunctions)) { 6898 if (!HasInstantiatedSignature(kFunctions)) {
6899 function_type_arguments = Object::empty_type_arguments().raw(); 6899 function_type_arguments = Object::empty_type_arguments().raw();
6900 } 6900 }
6901 return Closure::New(instantiator_type_arguments, function_type_arguments, 6901 return Closure::New(instantiator_type_arguments, function_type_arguments,
6902 *this, context); 6902 *this, context);
6903 } 6903 }
6904 6904
6905 RawSmi* Function::GetClosureHashCode() const { 6905 intptr_t Function::ComputeClosureHash() const {
6906 ASSERT(IsClosureFunction()); 6906 ASSERT(IsClosureFunction());
6907 const Object& obj = Object::Handle(raw_ptr()->data_);
6908 ASSERT(!obj.IsNull());
6909 if (ClosureData::Cast(obj).hash() != Object::null()) {
6910 return Smi::RawCast(ClosureData::Cast(obj).hash());
6911 }
6912 // Hash not yet computed. Compute and cache it.
6913 const Class& cls = Class::Handle(Owner()); 6907 const Class& cls = Class::Handle(Owner());
6914 intptr_t result = String::Handle(name()).Hash(); 6908 intptr_t result = String::Handle(name()).Hash();
6915 result += String::Handle(Signature()).Hash(); 6909 result += String::Handle(Signature()).Hash();
6916 result += String::Handle(cls.Name()).Hash(); 6910 result += String::Handle(cls.Name()).Hash();
6917 // Finalize hash value like for strings so that it fits into a smi. 6911 return result;
6918 result += result << 3;
6919 result ^= result >> 11;
6920 result += result << 15;
6921 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1);
6922 ClosureData::Cast(obj).set_hash(result);
6923 return Smi::New(result);
6924 } 6912 }
6925 6913
6926 RawString* Function::BuildSignature(NameVisibility name_visibility) const { 6914 RawString* Function::BuildSignature(NameVisibility name_visibility) const {
6927 Thread* thread = Thread::Current(); 6915 Thread* thread = Thread::Current();
6928 Zone* zone = thread->zone(); 6916 Zone* zone = thread->zone();
6929 GrowableHandlePtrArray<const String> pieces(zone, 4); 6917 GrowableHandlePtrArray<const String> pieces(zone, 4);
6930 String& name = String::Handle(zone); 6918 String& name = String::Handle(zone);
6931 if (FLAG_reify_generic_functions) { 6919 if (FLAG_reify_generic_functions) {
6932 const TypeArguments& type_params = 6920 const TypeArguments& type_params =
6933 TypeArguments::Handle(zone, type_parameters()); 6921 TypeArguments::Handle(zone, type_parameters());
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
7323 void ClosureData::set_context_scope(const ContextScope& value) const { 7311 void ClosureData::set_context_scope(const ContextScope& value) const {
7324 StorePointer(&raw_ptr()->context_scope_, value.raw()); 7312 StorePointer(&raw_ptr()->context_scope_, value.raw());
7325 } 7313 }
7326 7314
7327 void ClosureData::set_implicit_static_closure(const Instance& closure) const { 7315 void ClosureData::set_implicit_static_closure(const Instance& closure) const {
7328 ASSERT(!closure.IsNull()); 7316 ASSERT(!closure.IsNull());
7329 ASSERT(raw_ptr()->closure_ == Instance::null()); 7317 ASSERT(raw_ptr()->closure_ == Instance::null());
7330 StorePointer(&raw_ptr()->closure_, closure.raw()); 7318 StorePointer(&raw_ptr()->closure_, closure.raw());
7331 } 7319 }
7332 7320
7333 void ClosureData::set_hash(intptr_t value) const {
7334 StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value)));
7335 }
7336
7337 void ClosureData::set_parent_function(const Function& value) const { 7321 void ClosureData::set_parent_function(const Function& value) const {
7338 StorePointer(&raw_ptr()->parent_function_, value.raw()); 7322 StorePointer(&raw_ptr()->parent_function_, value.raw());
7339 } 7323 }
7340 7324
7341 void ClosureData::set_signature_type(const Type& value) const { 7325 void ClosureData::set_signature_type(const Type& value) const {
7342 StorePointer(&raw_ptr()->signature_type_, value.raw()); 7326 StorePointer(&raw_ptr()->signature_type_, value.raw());
7343 } 7327 }
7344 7328
7345 RawClosureData* ClosureData::New() { 7329 RawClosureData* ClosureData::New() {
7346 ASSERT(Object::closure_data_class() != Class::null()); 7330 ASSERT(Object::closure_data_class() != Class::null());
(...skipping 7528 matching lines...) Expand 10 before | Expand all | Expand 10 after
14875 } 14859 }
14876 return DartEntry::InvokeFunction(eval_func, args); 14860 return DartEntry::InvokeFunction(eval_func, args);
14877 } 14861 }
14878 14862
14879 RawObject* Instance::HashCode() const { 14863 RawObject* Instance::HashCode() const {
14880 // TODO(koda): Optimize for all builtin classes and all classes 14864 // TODO(koda): Optimize for all builtin classes and all classes
14881 // that do not override hashCode. 14865 // that do not override hashCode.
14882 return DartLibraryCalls::HashCode(*this); 14866 return DartLibraryCalls::HashCode(*this);
14883 } 14867 }
14884 14868
14869 RawObject* Instance::IdentityHashCode() const {
14870 return DartLibraryCalls::IdentityHashCode(*this);
14871 }
14872
14885 bool Instance::CanonicalizeEquals(const Instance& other) const { 14873 bool Instance::CanonicalizeEquals(const Instance& other) const {
14886 if (this->raw() == other.raw()) { 14874 if (this->raw() == other.raw()) {
14887 return true; // "===". 14875 return true; // "===".
14888 } 14876 }
14889 14877
14890 if (other.IsNull() || (this->clazz() != other.clazz())) { 14878 if (other.IsNull() || (this->clazz() != other.clazz())) {
14891 return false; 14879 return false;
14892 } 14880 }
14893 14881
14894 { 14882 {
(...skipping 6752 matching lines...) Expand 10 before | Expand all | Expand 10 after
21647 const char* Closure::ToCString() const { 21635 const char* Closure::ToCString() const {
21648 const Function& fun = Function::Handle(function()); 21636 const Function& fun = Function::Handle(function());
21649 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); 21637 const bool is_implicit_closure = fun.IsImplicitClosureFunction();
21650 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); 21638 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString();
21651 const char* from = is_implicit_closure ? " from " : ""; 21639 const char* from = is_implicit_closure ? " from " : "";
21652 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; 21640 const char* fun_desc = is_implicit_closure ? fun.ToCString() : "";
21653 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, 21641 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig,
21654 from, fun_desc); 21642 from, fun_desc);
21655 } 21643 }
21656 21644
21645 int64_t Closure::ComputeHash() const {
siva 2017/07/19 21:59:47 Maybe declare zone here Zone* zone = Thread::Curr
alexmarkov 2017/07/20 21:47:18 Done (see the new review).
21646 const Function& func = Function::Handle(function());
21647 uint32_t result = 0;
21648 if (func.IsImplicitInstanceClosureFunction()) {
21649 // Implicit instance closures are not unqiue, so combine function's hash
21650 // code with identityHashCode of cached receiver.
21651 result = static_cast<uint32_t>(func.ComputeClosureHash());
21652 const Context& context = Context::Handle(this->context());
21653 const Object& receiver = Object::Handle(context.At(0));
21654 const Object& receiverHash =
21655 Object::Handle(Instance::Cast(receiver).IdentityHashCode());
21656 if (receiverHash.IsError()) {
21657 Exceptions::PropagateError(Error::Cast(receiverHash));
21658 UNREACHABLE();
21659 }
21660 result = CombineHashes(
21661 result, Integer::Cast(receiverHash).AsTruncatedUint32Value());
21662 } else {
21663 // Explicit closures and implicit static closures are unique,
21664 // so identityHashCode of closure object is good enough.
21665 const Object& identityHash = Object::Handle(this->IdentityHashCode());
21666 if (identityHash.IsError()) {
21667 Exceptions::PropagateError(Error::Cast(identityHash));
21668 UNREACHABLE();
21669 }
21670 result = Integer::Cast(identityHash).AsTruncatedUint32Value();
21671 }
21672 return FinalizeHash(result, String::kHashBits);
21673 }
21674
21657 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, 21675 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
21658 const TypeArguments& function_type_arguments, 21676 const TypeArguments& function_type_arguments,
21659 const Function& function, 21677 const Function& function,
21660 const Context& context, 21678 const Context& context,
21661 Heap::Space space) { 21679 Heap::Space space) {
21662 Closure& result = Closure::Handle(); 21680 Closure& result = Closure::Handle();
21663 { 21681 {
21664 RawObject* raw = 21682 RawObject* raw =
21665 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); 21683 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
21666 NoSafepointScope no_safepoint; 21684 NoSafepointScope no_safepoint;
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
22232 } 22250 }
22233 return UserTag::null(); 22251 return UserTag::null();
22234 } 22252 }
22235 22253
22236 const char* UserTag::ToCString() const { 22254 const char* UserTag::ToCString() const {
22237 const String& tag_label = String::Handle(label()); 22255 const String& tag_label = String::Handle(label());
22238 return tag_label.ToCString(); 22256 return tag_label.ToCString();
22239 } 22257 }
22240 22258
22241 } // namespace dart 22259 } // 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