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

Unified Diff: runtime/vm/object.cc

Issue 8773026: Canonicalize TypeArguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 2094)
+++ runtime/vm/object.cc (working copy)
@@ -391,6 +391,10 @@
array.SetAt(kInitialSymbolTableSize, Smi::Handle(Smi::New(0)));
object_store->set_symbol_table(array);
+ // canonical_type_arguments_ are NULL terminated.
+ array = Array::New(4);
+ object_store->set_canonical_type_arguments(array);
+
// Pre-allocate the OneByteString class needed by the symbol table.
cls = Class::New<OneByteString>();
object_store->set_one_byte_string_class(cls);
@@ -2312,7 +2316,7 @@
RawAbstractTypeArguments* InstantiatedType::arguments() const {
- return AbstractTypeArguments::NewInstantiatedTypeArguments(
+ return InstantiatedTypeArguments::New(
AbstractTypeArguments::Handle(AbstractType::Handle(
uninstantiated_type()).arguments()),
AbstractTypeArguments::Handle(instantiator_type_arguments()));
@@ -2400,9 +2404,23 @@
bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const {
- // AbstractTypeArguments is an abstract class.
- UNREACHABLE();
- return false;
+ if (this->raw() == other.raw()) {
+ return true;
+ }
+ intptr_t num_types = Length();
+ if (num_types != other.Length()) {
+ return false;
+ }
+ AbstractType& type = AbstractType::Handle();
+ AbstractType& other_type = AbstractType::Handle();
+ for (intptr_t i = 0; i < num_types; i++) {
+ type = TypeAt(i);
+ other_type = other.TypeAt(i);
+ if (!type.IsNull() && !type.Equals(other_type)) {
regis 2011/12/05 23:16:35 What if type.IsNull() && !other_type.IsNull()?
srdjan 2011/12/06 17:24:15 Type can't be NULL, removed test (see comment belo
+ return false;
+ }
+ }
+ return true;
}
@@ -2472,14 +2490,6 @@
}
-RawAbstractTypeArguments* AbstractTypeArguments::NewInstantiatedTypeArguments(
- const AbstractTypeArguments& uninstantiated_type_arguments,
- const AbstractTypeArguments& instantiator_type_arguments) {
- return InstantiatedTypeArguments::New(uninstantiated_type_arguments,
- instantiator_type_arguments);
-}
-
-
const char* AbstractTypeArguments::ToCString() const {
// AbstractTypeArguments is an abstract class.
UNREACHABLE();
@@ -2522,7 +2532,8 @@
intptr_t num_types = Length();
for (intptr_t i = 0; i < num_types; i++) {
type = TypeAt(i);
- if (!type.IsInstantiated()) {
+ // type.IsNull() means it is Dynamic type.
regis 2011/12/05 23:16:35 We should not encounter a Null type in a non-null
srdjan 2011/12/06 17:24:15 Removed isNull case (reverting the lines here). It
+ if (!type.IsNull() && !type.IsInstantiated()) {
return false;
}
}
@@ -2544,24 +2555,6 @@
}
-bool TypeArguments::Equals(const AbstractTypeArguments& other) const {
- intptr_t num_types = Length();
- if (num_types != other.Length()) {
- return false;
- }
- AbstractType& type = AbstractType::Handle();
- AbstractType& other_type = AbstractType::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;
-}
-
-
RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
const AbstractTypeArguments& instantiator_type_arguments,
intptr_t offset) const {
@@ -2603,15 +2596,18 @@
Heap::kOld);
NoGCScope no_gc;
result ^= raw;
+ // Length must be set before we start storing into the array.
result.SetLength(len);
for (intptr_t i = 0; i < len; i++) {
*result.TypeAddr(i) = Type::null();
}
}
+ result.set_is_canonical(false);
return result.raw();
}
+
RawAbstractType** TypeArguments::TypeAddr(intptr_t index) const {
// TODO(iposva): Determine if we should throw an exception here.
ASSERT((index >= 0) && (index < Length()));
@@ -2626,6 +2622,44 @@
}
+RawAbstractTypeArguments* TypeArguments::Canonicalize() const {
regis 2011/12/05 23:16:35 I would add a comment that Canonicalize for a non-
srdjan 2011/12/06 17:24:15 Expanded the existing comment in header file.
+ if (IsNull() || is_canonical() || !IsInstantiated()) {
+ return this->raw();
+ }
+ ObjectStore* object_store = Isolate::Current()->object_store();
+ // 'table' must be null terminated.
+ Array& table = Array::Handle(object_store->canonical_type_arguments());
+ ASSERT(table.Length() > 0);
+ intptr_t ix = 0;
regis 2011/12/05 23:16:35 index?
srdjan 2011/12/06 17:24:15 Done.
+ TypeArguments& other = TypeArguments::Handle();
+ other ^= table.At(ix);
+ while (!other.IsNull()) {
+ if (this->Equals(other)) {
+ return other.raw();
+ }
+ other ^= table.At(++ix);
+ }
+ // Not found. Add 'this' to table.
+ if (ix == table.Length() - 1) {
+ table = Array::Grow(table, table.Length() + 4, Heap::kOld);
+ object_store->set_canonical_type_arguments(table);
+ }
+ table.SetAt(ix, *this);
+ this->set_is_canonical(true);
+ return this->raw();
+}
+
+
+bool TypeArguments::is_canonical() const {
+ return raw_ptr()->is_canonical_ == Bool::True();
+}
+
+
+void TypeArguments::set_is_canonical(bool value) const {
+ raw_ptr()->is_canonical_ = value ? Bool::True() : Bool::False();
regis 2011/12/05 23:16:35 Why do you store a dart value? Other flags in clas
srdjan 2011/12/06 17:24:15 I am moving it to above the length of RawTypeArgum
+}
+
+
const char* TypeArguments::ToCString() const {
if (IsNull()) {
return "NULL TypeArguments";
@@ -2633,7 +2667,8 @@
const char* format = "%s [%s]";
const char* prev_cstr = "TypeArguments:";
for (int i = 0; i < Length(); i++) {
- const char* type_cstr = AbstractType::Handle(TypeAt(i)).ToCString();
+ const AbstractType& type_at = AbstractType::Handle(TypeAt(i));
+ const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString();
intptr_t len = OS::SNPrint(NULL, 0, format, prev_cstr, type_cstr) + 1;
char* chars = reinterpret_cast<char*>(
Isolate::Current()->current_zone()->Allocate(len));
@@ -2712,7 +2747,7 @@
if (IsNull()) {
return "NULL InstantiatedTypeArguments";
}
- const char* format = "InstantiatedTypeArguments: [%s] instantiator: [%s]\n";
+ const char* format = "InstantiatedTypeArguments: [%s] instantiator: [%s]";
const char* arg_cstr =
AbstractTypeArguments::Handle(
uninstantiated_type_arguments()).ToCString();
@@ -5037,7 +5072,7 @@
const Class& cls = Class::Handle(clazz());
intptr_t field_offset = cls.type_arguments_instance_field_offset();
ASSERT(field_offset != Class::kNoTypeArguments);
- *FieldAddrAtOffset(field_offset) = value.raw();
+ *FieldAddrAtOffset(field_offset) = value.Canonicalize();
regis 2011/12/05 23:16:35 Same comment: What about inline assembly?
srdjan 2011/12/06 17:24:15 Discussed, not an issue.
}

Powered by Google App Engine
This is Rietveld 408576698