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

Unified Diff: runtime/vm/object.cc

Issue 2160953002: Add a verification step which iterates over the heap and verifies that all canonical objects are co… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address code review comments. Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 7bf95a0dbd29193a2ecf3dd639ef4eb369029d49..9744fb8c5cb6fb49c9e258d446a06cf29a88fb09 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15307,6 +15307,19 @@ RawInstance* Instance::CheckAndCanonicalize(Thread* thread,
}
+#if defined(DEBUG)
+bool Instance::CheckIsCanonical(Thread* thread) const {
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
+ Instance& result = Instance::Handle(zone);
+ const Class& cls = Class::Handle(zone, this->clazz());
+ SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
+ result ^= cls.LookupCanonicalInstance(zone, *this);
+ return (result.raw() == this->raw());
+}
+#endif // DEBUG
+
+
RawAbstractType* Instance::GetType() const {
if (IsNull()) {
return Type::NullType();
@@ -17115,6 +17128,38 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
}
+#if defined(DEBUG)
+bool Type::CheckIsCanonical(Thread* thread) const {
+ if (IsMalformed()) {
+ return true;
+ }
+ if (type_class() == Object::dynamic_class()) {
+ return (raw() == Object::dynamic_type().raw());
+ }
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
+ AbstractType& type = Type::Handle(zone);
+ const Class& cls = Class::Handle(zone, type_class());
+
+ // Fast canonical lookup/registry for simple types.
+ if (!cls.IsGeneric() && !cls.IsClosureClass() && !cls.IsTypedefClass()) {
+ ASSERT(!IsFunctionType());
+ type = cls.CanonicalType();
+ return (raw() == type.raw());
+ }
+
+ ObjectStore* object_store = isolate->object_store();
+ {
+ SafepointMutexLocker ml(isolate->type_canonicalization_mutex());
+ CanonicalTypeSet table(zone, object_store->canonical_types());
+ type ^= table.GetOrNull(CanonicalTypeKey(*this));
+ object_store->set_canonical_types(table.Release());
+ }
+ return (raw() == type.raw());
+}
+#endif // DEBUG
+
+
RawString* Type::EnumerateURIs() const {
if (IsDynamicType() || IsVoidType()) {
return Symbols::Empty().raw();
@@ -17377,6 +17422,14 @@ RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const {
}
+#if defined(DEBUG)
+bool TypeRef::CheckIsCanonical(Thread* thread) const {
+ AbstractType& ref_type = AbstractType::Handle(type());
+ return ref_type.CheckIsCanonical(thread);
+}
+#endif // DEBUG
+
+
RawString* TypeRef::EnumerateURIs() const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -18040,11 +18093,11 @@ RawInstance* Number::CheckAndCanonicalize(Thread* thread,
case kDoubleCid:
return Double::NewCanonical(Double::Cast(*this).value());
case kBigintCid: {
+ if (this->IsCanonical()) {
+ return this->raw();
+ }
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
- if (!CheckAndCanonicalizeFields(thread, error_str)) {
- return Instance::null();
- }
Bigint& result = Bigint::Handle(zone);
const Class& cls = Class::Handle(zone, this->clazz());
intptr_t index = 0;
@@ -18084,6 +18137,38 @@ RawInstance* Number::CheckAndCanonicalize(Thread* thread,
}
+#if defined(DEBUG)
+bool Number::CheckIsCanonical(Thread* thread) const {
+ intptr_t cid = GetClassId();
+ intptr_t idx = 0;
+ Zone* zone = thread->zone();
+ const Class& cls = Class::Handle(zone, this->clazz());
+ switch (cid) {
+ case kSmiCid:
+ return true;
+ case kMintCid: {
+ Mint& result = Mint::Handle(zone);
+ result ^= cls.LookupCanonicalMint(zone, Mint::Cast(*this).value(), &idx);
+ return (result.raw() == this->raw());
+ }
+ case kDoubleCid: {
+ Double& dbl = Double::Handle(zone);
+ dbl ^= cls.LookupCanonicalDouble(zone, Double::Cast(*this).value(), &idx);
+ return (dbl.raw() == this->raw());
+ }
+ case kBigintCid: {
+ Bigint& result = Bigint::Handle(zone);
+ result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx);
+ return (result.raw() == this->raw());
+ }
+ default:
+ UNREACHABLE();
+ }
+ return false;
+}
+#endif // DEBUG
+
+
const char* Number::ToCString() const {
// Number is an interface. No instances of Number should exist.
UNREACHABLE();
@@ -19784,6 +19869,15 @@ RawInstance* String::CheckAndCanonicalize(Thread* thread,
}
+#if defined(DEBUG)
+bool String::CheckIsCanonical(Thread* thread) const {
+ Zone* zone = thread->zone();
+ const String& str = String::Handle(zone, Symbols::Lookup(thread, *this));
+ return (str.raw() == this->raw());
+}
+#endif // DEBUG
+
+
RawString* String::New(const char* cstr, Heap::Space space) {
ASSERT(cstr != NULL);
intptr_t array_len = strlen(cstr);
@@ -21304,6 +21398,7 @@ RawArray* Array::Slice(intptr_t start,
void Array::MakeImmutable() const {
if (IsImmutable()) return;
+ ASSERT(!IsCanonical());
NoSafepointScope no_safepoint;
uword tags = raw_ptr()->tags_;
uword old_tags;
« 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