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

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

Issue 2988493002: Reapply "Improve hashCode for closure objects" with fixes. (Closed)
Patch Set: 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/precompiler.cc » ('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 6871 matching lines...) Expand 10 before | Expand all | Expand 10 after
6882 if (!HasInstantiatedSignature(kCurrentClass)) { 6882 if (!HasInstantiatedSignature(kCurrentClass)) {
6883 instantiator_type_arguments = receiver.GetTypeArguments(); 6883 instantiator_type_arguments = receiver.GetTypeArguments();
6884 } 6884 }
6885 if (!HasInstantiatedSignature(kFunctions)) { 6885 if (!HasInstantiatedSignature(kFunctions)) {
6886 function_type_arguments = Object::empty_type_arguments().raw(); 6886 function_type_arguments = Object::empty_type_arguments().raw();
6887 } 6887 }
6888 return Closure::New(instantiator_type_arguments, function_type_arguments, 6888 return Closure::New(instantiator_type_arguments, function_type_arguments,
6889 *this, context); 6889 *this, context);
6890 } 6890 }
6891 6891
6892 RawSmi* Function::GetClosureHashCode() const { 6892 intptr_t Function::ComputeClosureHash() const {
6893 ASSERT(IsClosureFunction()); 6893 ASSERT(IsClosureFunction());
6894 const Object& obj = Object::Handle(raw_ptr()->data_);
6895 ASSERT(!obj.IsNull());
6896 if (ClosureData::Cast(obj).hash() != Object::null()) {
6897 return Smi::RawCast(ClosureData::Cast(obj).hash());
6898 }
6899 // Hash not yet computed. Compute and cache it.
6900 const Class& cls = Class::Handle(Owner()); 6894 const Class& cls = Class::Handle(Owner());
6901 intptr_t result = String::Handle(name()).Hash(); 6895 intptr_t result = String::Handle(name()).Hash();
6902 result += String::Handle(Signature()).Hash(); 6896 result += String::Handle(Signature()).Hash();
6903 result += String::Handle(cls.Name()).Hash(); 6897 result += String::Handle(cls.Name()).Hash();
6904 // Finalize hash value like for strings so that it fits into a smi. 6898 return result;
6905 result += result << 3;
6906 result ^= result >> 11;
6907 result += result << 15;
6908 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1);
6909 ClosureData::Cast(obj).set_hash(result);
6910 return Smi::New(result);
6911 } 6899 }
6912 6900
6913 RawString* Function::BuildSignature(NameVisibility name_visibility) const { 6901 RawString* Function::BuildSignature(NameVisibility name_visibility) const {
6914 Thread* thread = Thread::Current(); 6902 Thread* thread = Thread::Current();
6915 Zone* zone = thread->zone(); 6903 Zone* zone = thread->zone();
6916 GrowableHandlePtrArray<const String> pieces(zone, 4); 6904 GrowableHandlePtrArray<const String> pieces(zone, 4);
6917 String& name = String::Handle(zone); 6905 String& name = String::Handle(zone);
6918 if (FLAG_reify_generic_functions) { 6906 if (FLAG_reify_generic_functions) {
6919 const TypeArguments& type_params = 6907 const TypeArguments& type_params =
6920 TypeArguments::Handle(zone, type_parameters()); 6908 TypeArguments::Handle(zone, type_parameters());
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
7320 void ClosureData::set_context_scope(const ContextScope& value) const { 7308 void ClosureData::set_context_scope(const ContextScope& value) const {
7321 StorePointer(&raw_ptr()->context_scope_, value.raw()); 7309 StorePointer(&raw_ptr()->context_scope_, value.raw());
7322 } 7310 }
7323 7311
7324 void ClosureData::set_implicit_static_closure(const Instance& closure) const { 7312 void ClosureData::set_implicit_static_closure(const Instance& closure) const {
7325 ASSERT(!closure.IsNull()); 7313 ASSERT(!closure.IsNull());
7326 ASSERT(raw_ptr()->closure_ == Instance::null()); 7314 ASSERT(raw_ptr()->closure_ == Instance::null());
7327 StorePointer(&raw_ptr()->closure_, closure.raw()); 7315 StorePointer(&raw_ptr()->closure_, closure.raw());
7328 } 7316 }
7329 7317
7330 void ClosureData::set_hash(intptr_t value) const {
7331 StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value)));
7332 }
7333
7334 void ClosureData::set_parent_function(const Function& value) const { 7318 void ClosureData::set_parent_function(const Function& value) const {
7335 StorePointer(&raw_ptr()->parent_function_, value.raw()); 7319 StorePointer(&raw_ptr()->parent_function_, value.raw());
7336 } 7320 }
7337 7321
7338 void ClosureData::set_signature_type(const Type& value) const { 7322 void ClosureData::set_signature_type(const Type& value) const {
7339 StorePointer(&raw_ptr()->signature_type_, value.raw()); 7323 StorePointer(&raw_ptr()->signature_type_, value.raw());
7340 } 7324 }
7341 7325
7342 RawClosureData* ClosureData::New() { 7326 RawClosureData* ClosureData::New() {
7343 ASSERT(Object::closure_data_class() != Class::null()); 7327 ASSERT(Object::closure_data_class() != Class::null());
(...skipping 7529 matching lines...) Expand 10 before | Expand all | Expand 10 after
14873 } 14857 }
14874 return DartEntry::InvokeFunction(eval_func, args); 14858 return DartEntry::InvokeFunction(eval_func, args);
14875 } 14859 }
14876 14860
14877 RawObject* Instance::HashCode() const { 14861 RawObject* Instance::HashCode() const {
14878 // TODO(koda): Optimize for all builtin classes and all classes 14862 // TODO(koda): Optimize for all builtin classes and all classes
14879 // that do not override hashCode. 14863 // that do not override hashCode.
14880 return DartLibraryCalls::HashCode(*this); 14864 return DartLibraryCalls::HashCode(*this);
14881 } 14865 }
14882 14866
14867 RawObject* Instance::IdentityHashCode() const {
14868 return DartLibraryCalls::IdentityHashCode(*this);
14869 }
14870
14883 bool Instance::CanonicalizeEquals(const Instance& other) const { 14871 bool Instance::CanonicalizeEquals(const Instance& other) const {
14884 if (this->raw() == other.raw()) { 14872 if (this->raw() == other.raw()) {
14885 return true; // "===". 14873 return true; // "===".
14886 } 14874 }
14887 14875
14888 if (other.IsNull() || (this->clazz() != other.clazz())) { 14876 if (other.IsNull() || (this->clazz() != other.clazz())) {
14889 return false; 14877 return false;
14890 } 14878 }
14891 14879
14892 { 14880 {
(...skipping 6769 matching lines...) Expand 10 before | Expand all | Expand 10 after
21662 const char* Closure::ToCString() const { 21650 const char* Closure::ToCString() const {
21663 const Function& fun = Function::Handle(function()); 21651 const Function& fun = Function::Handle(function());
21664 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); 21652 const bool is_implicit_closure = fun.IsImplicitClosureFunction();
21665 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); 21653 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString();
21666 const char* from = is_implicit_closure ? " from " : ""; 21654 const char* from = is_implicit_closure ? " from " : "";
21667 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; 21655 const char* fun_desc = is_implicit_closure ? fun.ToCString() : "";
21668 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, 21656 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig,
21669 from, fun_desc); 21657 from, fun_desc);
21670 } 21658 }
21671 21659
21660 int64_t Closure::ComputeHash() const {
21661 Zone* zone = Thread::Current()->zone();
21662 const Function& func = Function::Handle(zone, function());
21663 uint32_t result = 0;
21664 if (func.IsImplicitInstanceClosureFunction()) {
21665 // Implicit instance closures are not unqiue, so combine function's hash
21666 // code with identityHashCode of cached receiver.
21667 result = static_cast<uint32_t>(func.ComputeClosureHash());
21668 const Context& context = Context::Handle(zone, this->context());
21669 const Object& receiver = Object::Handle(zone, context.At(0));
21670 const Object& receiverHash =
21671 Object::Handle(zone, Instance::Cast(receiver).IdentityHashCode());
21672 if (receiverHash.IsError()) {
21673 Exceptions::PropagateError(Error::Cast(receiverHash));
21674 UNREACHABLE();
21675 }
21676 result = CombineHashes(
21677 result, Integer::Cast(receiverHash).AsTruncatedUint32Value());
21678 } else {
21679 // Explicit closures and implicit static closures are unique,
21680 // so identityHashCode of closure object is good enough.
21681 const Object& identityHash = Object::Handle(zone, this->IdentityHashCode());
21682 if (identityHash.IsError()) {
21683 Exceptions::PropagateError(Error::Cast(identityHash));
21684 UNREACHABLE();
21685 }
21686 result = Integer::Cast(identityHash).AsTruncatedUint32Value();
21687 }
21688 return FinalizeHash(result, String::kHashBits);
21689 }
21690
21672 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, 21691 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
21673 const TypeArguments& function_type_arguments, 21692 const TypeArguments& function_type_arguments,
21674 const Function& function, 21693 const Function& function,
21675 const Context& context, 21694 const Context& context,
21676 Heap::Space space) { 21695 Heap::Space space) {
21677 Closure& result = Closure::Handle(); 21696 Closure& result = Closure::Handle();
21678 { 21697 {
21679 RawObject* raw = 21698 RawObject* raw =
21680 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); 21699 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
21681 NoSafepointScope no_safepoint; 21700 NoSafepointScope no_safepoint;
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
22247 } 22266 }
22248 return UserTag::null(); 22267 return UserTag::null();
22249 } 22268 }
22250 22269
22251 const char* UserTag::ToCString() const { 22270 const char* UserTag::ToCString() const {
22252 const String& tag_label = String::Handle(label()); 22271 const String& tag_label = String::Handle(label());
22253 return tag_label.ToCString(); 22272 return tag_label.ToCString();
22254 } 22273 }
22255 22274
22256 } // namespace dart 22275 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698