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

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

Issue 274333002: Instance equality (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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
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 12690 matching lines...) Expand 10 before | Expand all | Expand 10 after
12701 param = param_values.At(i); 12701 param = param_values.At(i);
12702 args.SetAt(i + 1, param); 12702 args.SetAt(i + 1, param);
12703 } 12703 }
12704 const Object& result = 12704 const Object& result =
12705 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); 12705 Object::Handle(DartEntry::InvokeFunction(eval_func, args));
12706 return result.raw(); 12706 return result.raw();
12707 } 12707 }
12708 12708
12709 12709
12710 12710
12711 bool Instance::Equals(const Instance& other) const { 12711 bool Instance::CanonicalizeEquals(const Instance& other) const {
12712 if (this->raw() == other.raw()) { 12712 if (this->raw() == other.raw()) {
12713 return true; // "===". 12713 return true; // "===".
12714 } 12714 }
12715 12715
12716 if (other.IsNull() || (this->clazz() != other.clazz())) { 12716 if (other.IsNull() || (this->clazz() != other.clazz())) {
12717 return false; 12717 return false;
12718 } 12718 }
12719 12719
12720 { 12720 {
12721 NoGCScope no_gc; 12721 NoGCScope no_gc;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
12812 Array& constants = Array::Handle(cls.constants()); 12812 Array& constants = Array::Handle(cls.constants());
12813 const intptr_t constants_len = constants.Length(); 12813 const intptr_t constants_len = constants.Length();
12814 // Linear search to see whether this value is already present in the 12814 // Linear search to see whether this value is already present in the
12815 // list of canonicalized constants. 12815 // list of canonicalized constants.
12816 intptr_t index = 0; 12816 intptr_t index = 0;
12817 while (index < constants_len) { 12817 while (index < constants_len) {
12818 result ^= constants.At(index); 12818 result ^= constants.At(index);
12819 if (result.IsNull()) { 12819 if (result.IsNull()) {
12820 break; 12820 break;
12821 } 12821 }
12822 if (this->Equals(result)) { 12822 if (this->CanonicalizeEquals(result)) {
12823 return result.raw(); 12823 return result.raw();
12824 } 12824 }
12825 index++; 12825 index++;
12826 } 12826 }
12827 // The value needs to be added to the list. Grow the list if 12827 // The value needs to be added to the list. Grow the list if
12828 // it is full. 12828 // it is full.
12829 result ^= this->raw(); 12829 result ^= this->raw();
12830 if (result.IsNew()) { 12830 if (result.IsNew()) {
12831 // Create a canonical object in old space. 12831 // Create a canonical object in old space.
12832 result ^= Object::Clone(result, Heap::kOld); 12832 result ^= Object::Clone(result, Heap::kOld);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
12918 other_type_arguments = instantiated_other.arguments(); 12918 other_type_arguments = instantiated_other.arguments();
12919 } else { 12919 } else {
12920 other_class = other.type_class(); 12920 other_class = other.type_class();
12921 other_type_arguments = other.arguments(); 12921 other_type_arguments = other.arguments();
12922 } 12922 }
12923 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, 12923 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
12924 bound_error); 12924 bound_error);
12925 } 12925 }
12926 12926
12927 12927
12928 bool Instance::OperatorEquals(const Instance& other) const {
12929 // TODO(koda): Optimize for all builtin classes and all classes
12930 // that do not override operator==.
12931 const Object& result =
12932 Object::Handle(DartLibraryCalls::Equals(*this, other));
12933 return result.raw() == Object::bool_true().raw();
12934 }
12935
12936
12928 bool Instance::IsIdenticalTo(const Instance& other) const { 12937 bool Instance::IsIdenticalTo(const Instance& other) const {
12929 if (raw() == other.raw()) return true; 12938 if (raw() == other.raw()) return true;
12930 if (IsInteger() && other.IsInteger()) { 12939 if (IsInteger() && other.IsInteger()) {
12931 return Equals(other); 12940 return Integer::Cast(*this).Equals(other);
12932 } 12941 }
12933 if (IsDouble() && other.IsDouble()) { 12942 if (IsDouble() && other.IsDouble()) {
12934 if (Equals(other)) return true; 12943 if (Double::Cast(*this).CanonicalizeEquals(other)) return true;
12935 // Check for NaN. 12944 // Check for NaN.
12936 const Double& a_double = Double::Cast(*this); 12945 const Double& a_double = Double::Cast(*this);
12937 const Double& b_double = Double::Cast(other); 12946 const Double& b_double = Double::Cast(other);
12938 if (isnan(a_double.value()) && isnan(b_double.value())) { 12947 if (isnan(a_double.value()) && isnan(b_double.value())) {
12939 return true; 12948 return true;
12940 } 12949 }
12941 } 12950 }
12942 return false; 12951 return false;
12943 } 12952 }
12944 12953
(...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after
15450 void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const { 15459 void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const {
15451 Number::PrintJSONImpl(stream, ref); 15460 Number::PrintJSONImpl(stream, ref);
15452 } 15461 }
15453 15462
15454 15463
15455 void Double::set_value(double value) const { 15464 void Double::set_value(double value) const {
15456 raw_ptr()->value_ = value; 15465 raw_ptr()->value_ = value;
15457 } 15466 }
15458 15467
15459 15468
15460 bool Double::EqualsToDouble(double value) const { 15469 bool Double::BitwiseEqualsToDouble(double value) const {
15461 intptr_t value_offset = Double::value_offset(); 15470 intptr_t value_offset = Double::value_offset();
15462 void* this_addr = reinterpret_cast<void*>( 15471 void* this_addr = reinterpret_cast<void*>(
15463 reinterpret_cast<uword>(this->raw_ptr()) + value_offset); 15472 reinterpret_cast<uword>(this->raw_ptr()) + value_offset);
15464 void* other_addr = reinterpret_cast<void*>(&value); 15473 void* other_addr = reinterpret_cast<void*>(&value);
15465 return (memcmp(this_addr, other_addr, sizeof(value)) == 0); 15474 return (memcmp(this_addr, other_addr, sizeof(value)) == 0);
15466 } 15475 }
15467 15476
15468 15477
15469 bool Double::Equals(const Instance& other) const { 15478 bool Double::OperatorEquals(const Instance& other) const {
15479 if (this->IsNull() || other.IsNull()) {
15480 return (this->IsNull() && other.IsNull());
15481 }
15482 if (!other.IsDouble()) {
15483 return false;
15484 }
15485 return this->value() == Double::Cast(other).value();
15486 }
15487
15488
15489 bool Double::CanonicalizeEquals(const Instance& other) const {
15470 if (this->raw() == other.raw()) { 15490 if (this->raw() == other.raw()) {
15471 return true; // "===". 15491 return true; // "===".
15472 } 15492 }
15473 if (other.IsNull() || !other.IsDouble()) { 15493 if (other.IsNull() || !other.IsDouble()) {
15474 return false; 15494 return false;
15475 } 15495 }
15476 return EqualsToDouble(Double::Cast(other).value()); 15496 return BitwiseEqualsToDouble(Double::Cast(other).value());
15477 } 15497 }
15478 15498
15479 15499
15480 RawDouble* Double::New(double d, Heap::Space space) { 15500 RawDouble* Double::New(double d, Heap::Space space) {
15481 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); 15501 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null());
15482 Double& result = Double::Handle(); 15502 Double& result = Double::Handle();
15483 { 15503 {
15484 RawObject* raw = Object::Allocate(Double::kClassId, 15504 RawObject* raw = Object::Allocate(Double::kClassId,
15485 Double::InstanceSize(), 15505 Double::InstanceSize(),
15486 space); 15506 space);
(...skipping 21 matching lines...) Expand all
15508 const intptr_t constants_len = constants.Length(); 15528 const intptr_t constants_len = constants.Length();
15509 // Linear search to see whether this value is already present in the 15529 // Linear search to see whether this value is already present in the
15510 // list of canonicalized constants. 15530 // list of canonicalized constants.
15511 Double& canonical_value = Double::Handle(); 15531 Double& canonical_value = Double::Handle();
15512 intptr_t index = 0; 15532 intptr_t index = 0;
15513 while (index < constants_len) { 15533 while (index < constants_len) {
15514 canonical_value ^= constants.At(index); 15534 canonical_value ^= constants.At(index);
15515 if (canonical_value.IsNull()) { 15535 if (canonical_value.IsNull()) {
15516 break; 15536 break;
15517 } 15537 }
15518 if (canonical_value.EqualsToDouble(value)) { 15538 if (canonical_value.BitwiseEqualsToDouble(value)) {
15519 return canonical_value.raw(); 15539 return canonical_value.raw();
15520 } 15540 }
15521 index++; 15541 index++;
15522 } 15542 }
15523 // The value needs to be added to the constants list. Grow the list if 15543 // The value needs to be added to the constants list. Grow the list if
15524 // it is full. 15544 // it is full.
15525 canonical_value = Double::New(value, Heap::kOld); 15545 canonical_value = Double::New(value, Heap::kOld);
15526 cls.InsertCanonicalConstant(index, canonical_value); 15546 cls.InsertCanonicalConstant(index, canonical_value);
15527 canonical_value.SetCanonical(); 15547 canonical_value.SetCanonical();
15528 return canonical_value.raw(); 15548 return canonical_value.raw();
(...skipping 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after
17409 const char* str = ToCString(); 17429 const char* str = ToCString();
17410 JSONObject jsobj(stream); 17430 JSONObject jsobj(stream);
17411 jsobj.AddProperty("type", JSONType(ref)); 17431 jsobj.AddProperty("type", JSONType(ref));
17412 jsobj.AddPropertyF("id", "objects/bool-%s", str); 17432 jsobj.AddPropertyF("id", "objects/bool-%s", str);
17413 class Class& cls = Class::Handle(this->clazz()); 17433 class Class& cls = Class::Handle(this->clazz());
17414 jsobj.AddProperty("class", cls); 17434 jsobj.AddProperty("class", cls);
17415 jsobj.AddPropertyF("valueAsString", "%s", str); 17435 jsobj.AddPropertyF("valueAsString", "%s", str);
17416 } 17436 }
17417 17437
17418 17438
17419 bool Array::Equals(const Instance& other) const { 17439 bool Array::CanonicalizeEquals(const Instance& other) const {
17420 if (this->raw() == other.raw()) { 17440 if (this->raw() == other.raw()) {
17421 // Both handles point to the same raw instance. 17441 // Both handles point to the same raw instance.
17422 return true; 17442 return true;
17423 } 17443 }
17424 17444
17425 // An Array may be compared to an ImmutableArray. 17445 // An Array may be compared to an ImmutableArray.
17426 if (!other.IsArray() || other.IsNull()) { 17446 if (!other.IsArray() || other.IsNull()) {
17427 return false; 17447 return false;
17428 } 17448 }
17429 17449
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
17649 ASSERT(Length() > 0); 17669 ASSERT(Length() > 0);
17650 intptr_t index = Length() - 1; 17670 intptr_t index = Length() - 1;
17651 const Array& contents = Array::Handle(data()); 17671 const Array& contents = Array::Handle(data());
17652 const Object& obj = Object::Handle(contents.At(index)); 17672 const Object& obj = Object::Handle(contents.At(index));
17653 contents.SetAt(index, Object::null_object()); 17673 contents.SetAt(index, Object::null_object());
17654 SetLength(index); 17674 SetLength(index);
17655 return obj.raw(); 17675 return obj.raw();
17656 } 17676 }
17657 17677
17658 17678
17659 bool GrowableObjectArray::Equals(const Instance& other) const { 17679 bool GrowableObjectArray::CanonicalizeEquals(const Instance& other) const {
17660 // If both handles point to the same raw instance they are equal. 17680 // If both handles point to the same raw instance they are equal.
17661 if (this->raw() == other.raw()) { 17681 if (this->raw() == other.raw()) {
17662 return true; 17682 return true;
17663 } 17683 }
17664 17684
17665 // Other instance must be non null and a GrowableObjectArray. 17685 // Other instance must be non null and a GrowableObjectArray.
17666 if (!other.IsGrowableObjectArray() || other.IsNull()) { 17686 if (!other.IsGrowableObjectArray() || other.IsNull()) {
17667 return false; 17687 return false;
17668 } 17688 }
17669 17689
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
18559 case kGlobal | kMultiLine : 18579 case kGlobal | kMultiLine :
18560 case kMultiLine: 18580 case kMultiLine:
18561 return "m"; 18581 return "m";
18562 default: 18582 default:
18563 break; 18583 break;
18564 } 18584 }
18565 return ""; 18585 return "";
18566 } 18586 }
18567 18587
18568 18588
18569 bool JSRegExp::Equals(const Instance& other) const { 18589 bool JSRegExp::CanonicalizeEquals(const Instance& other) const {
18570 if (this->raw() == other.raw()) { 18590 if (this->raw() == other.raw()) {
18571 return true; // "===". 18591 return true; // "===".
18572 } 18592 }
18573 if (other.IsNull() || !other.IsJSRegExp()) { 18593 if (other.IsNull() || !other.IsJSRegExp()) {
18574 return false; 18594 return false;
18575 } 18595 }
18576 const JSRegExp& other_js = JSRegExp::Cast(other); 18596 const JSRegExp& other_js = JSRegExp::Cast(other);
18577 // Match the pattern. 18597 // Match the pattern.
18578 const String& str1 = String::Handle(pattern()); 18598 const String& str1 = String::Handle(pattern());
18579 const String& str2 = String::Handle(other_js.pattern()); 18599 const String& str2 = String::Handle(other_js.pattern());
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
18813 return tag_label.ToCString(); 18833 return tag_label.ToCString();
18814 } 18834 }
18815 18835
18816 18836
18817 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 18837 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
18818 Instance::PrintJSONImpl(stream, ref); 18838 Instance::PrintJSONImpl(stream, ref);
18819 } 18839 }
18820 18840
18821 18841
18822 } // namespace dart 18842 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698