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

Unified Diff: runtime/vm/object.cc

Issue 8372041: Canonicalize types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 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/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 1042)
+++ runtime/vm/object.cc (working copy)
@@ -614,8 +614,7 @@
// Set up empty classes in the object store, these will get
// initialized correctly when we read from the snapshot.
- // This is done do allow bootstrapping of reading classes from
- // the snapshot.
+ // This is done to allow bootstrapping of reading classes from the snapshot.
cls = Class::New<Array>();
object_store->set_array_class(cls);
@@ -774,6 +773,7 @@
result.raw_ptr()->class_state_ = RawClass::kPreFinalized;
result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
result.raw_ptr()->num_constants_ = 0;
+ result.raw_ptr()->num_canonical_types_ = 0;
result.raw_ptr()->num_native_fields_ = 0;
result.InitEmptyFields();
return result.raw();
@@ -793,6 +793,7 @@
Array::Handle(Array::New(FunctionsCache::kNumEntries * 32, Heap::kOld));
StorePointer(&raw_ptr()->functions_cache_, fcache.raw());
StorePointer(&raw_ptr()->constants_, empty_array.raw());
+ StorePointer(&raw_ptr()->canonical_types_, empty_array.raw());
StorePointer(&raw_ptr()->functions_, empty_array.raw());
StorePointer(&raw_ptr()->fields_, empty_array.raw());
}
@@ -1010,6 +1011,7 @@
result.raw_ptr()->class_state_ = RawClass::kAllocated;
result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
result.raw_ptr()->num_constants_ = 0;
+ result.raw_ptr()->num_canonical_types_ = 0;
result.raw_ptr()->num_native_fields_ = 0;
result.InitEmptyFields();
return result.raw();
@@ -1210,6 +1212,26 @@
}
+RawArray* Class::canonical_types() const {
+ return raw_ptr()->canonical_types_;
+}
+
+void Class::set_canonical_types(const Array& value) const {
+ ASSERT(!value.IsNull());
+ StorePointer(&raw_ptr()->canonical_types_, value.raw());
+}
+
+
+intptr_t Class::num_canonical_types() const {
+ return raw_ptr()->num_canonical_types_;
+}
+
+
+void Class::set_num_canonical_types(intptr_t value) const {
+ raw_ptr()->num_canonical_types_ = value;
+}
+
+
void Class::set_allocation_stub(const Code& value) const {
ASSERT(!value.IsNull());
ASSERT(raw_ptr()->allocation_stub_ == Code::null());
@@ -1654,6 +1676,13 @@
}
+bool Type::Equals(const Type& other) const {
+ // Type is an abstract class.
+ UNREACHABLE();
+ return false;
+}
+
+
RawType* Type::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
intptr_t offset) const {
@@ -1663,6 +1692,13 @@
}
+RawType* Type::Canonicalize() const {
+ // Type is an abstract class.
+ UNREACHABLE();
+ return Type::null();
+}
+
+
RawString* Type::Name() const {
// If the type is still being finalized, we may be reporting an error about
// an illformed type, so proceed with caution.
@@ -1891,6 +1927,7 @@
type ^= ParameterizedType::New(
Object::Handle(type_class.raw()), no_type_arguments);
type.set_is_finalized();
+ type ^= type.Canonicalize();
return type.raw();
}
@@ -1997,6 +2034,62 @@
}
+bool ParameterizedType::Equals(const Type& other) const {
+ ASSERT(IsFinalized() && other.IsFinalized());
+ if (raw() == other.raw()) {
+ return true;
+ }
+ if (!other.IsParameterizedType()) {
+ return false;
+ }
+ ParameterizedType& other_parameterized_type = ParameterizedType::Handle();
+ other_parameterized_type ^= other.raw();
+ if (type_class() != other_parameterized_type.type_class()) {
+ return false;
+ }
+ return TypeArguments::AreEqual(TypeArguments::Handle(arguments()),
+ TypeArguments::Handle(other.arguments()));
+}
+
+
+RawType* ParameterizedType::Canonicalize() const {
+ const Class& cls = Class::Handle(type_class());
+ Array& canonical_types = Array::Handle(cls.canonical_types());
+ if (canonical_types.IsNull()) {
+ // Types defined in the VM isolate are canonicalized via the object store.
+ // TODO(regis): Should we add null_class_, void_class_, dynamic_class_ to
+ // the object store, remove all types from the object store, and replace
+ // the test above by an assert?
+ return this->raw();
+ }
+ const intptr_t num_canonical_types = cls.num_canonical_types();
+ ASSERT(canonical_types.Length() >= num_canonical_types);
+ // Linear search to see whether this type is already present in the
+ // list of canonicalized types.
+ Type& type = Type::Handle();
+ for (int i = 0; i < num_canonical_types; i++) {
+ type ^= canonical_types.At(i);
+ ASSERT(!type.IsNull());
+ if (this->Equals(type)) {
+ return type.raw();
+ }
+ }
+ // The type needs to be added to the list. Grow the list if it is full.
+ if (canonical_types.Length() == num_canonical_types) {
+ const intptr_t kLengthIncrement = 2; // Raw and parameterized.
+ const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
+ const Array& new_canonical_types =
+ Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld));
+ cls.set_canonical_types(new_canonical_types);
+ new_canonical_types.SetAt(num_canonical_types, *this);
+ } else {
+ canonical_types.SetAt(num_canonical_types, *this);
+ }
+ cls.set_num_canonical_types(num_canonical_types + 1);
+ return this->raw();
+}
+
+
void ParameterizedType::set_type_class(const Object& value) const {
ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass()));
StorePointer(&raw_ptr()->type_class_, value.raw());
@@ -2042,6 +2135,19 @@
}
+bool TypeParameter::Equals(const Type& other) const {
+ if (raw() == other.raw()) {
+ return true;
+ }
+ if (!other.IsTypeParameter()) {
+ return false;
+ }
+ TypeParameter& other_type_parameter = TypeParameter::Handle();
+ other_type_parameter ^= other.raw();
+ return Index() == other_type_parameter.Index();
+}
+
+
void TypeParameter::set_index(intptr_t value) const {
ASSERT(value >= 0);
raw_ptr()->index_ = value;
@@ -2177,6 +2283,28 @@
}
+bool TypeArguments::Equals(const TypeArguments& other) const {
+ // TypeArguments is an abstract class.
+ UNREACHABLE();
+ return false;
+}
+
+
+bool TypeArguments::AreEqual(const TypeArguments& arguments,
+ const TypeArguments& other_arguments) {
+ if (arguments.raw() == other_arguments.raw()) {
+ return true;
+ }
+ if (arguments.IsNull()) {
+ return other_arguments.IsDynamicTypes(other_arguments.Length());
+ }
+ if (other_arguments.IsNull()) {
+ return arguments.IsDynamicTypes(arguments.Length());
+ }
+ return arguments.Equals(other_arguments);
+}
+
+
RawTypeArguments* TypeArguments::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
intptr_t offset) const {
@@ -2303,6 +2431,24 @@
}
+bool TypeArray::Equals(const TypeArguments& other) const {
+ intptr_t num_types = Length();
+ if (num_types != other.Length()) {
+ return false;
+ }
+ Type& type = Type::Handle();
+ Type& other_type = Type::Handle();
+ for (intptr_t i = 0; i < num_types; i++) {
+ type = TypeAt(i);
+ other_type = other.TypeAt(i);
+ if (!type.Equals(other_type)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
RawTypeArguments* TypeArray::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
intptr_t offset) const {
@@ -6421,8 +6567,10 @@
return false;
}
- // Must have the same type.
- if (GetTypeArguments() != other.GetTypeArguments()) {
+ // Must have the same type arguments.
+ if (!TypeArguments::AreEqual(
+ TypeArguments::Handle(GetTypeArguments()),
+ TypeArguments::Handle(other.GetTypeArguments()))) {
return false;
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698