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

Unified Diff: runtime/vm/code_generator.cc

Issue 9939003: Use null type argument vector instead of vector of Dynamic for a generic raw (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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
Index: runtime/vm/code_generator.cc
===================================================================
--- runtime/vm/code_generator.cc (revision 6066)
+++ runtime/vm/code_generator.cc (working copy)
@@ -114,51 +114,29 @@
// Allocation of a fixed length array of given element type.
+// TODO(regis): This runtime entry is never called for allocating a List of a
+// generic type, which does not seem correct. Verify that generic user Lists are
+// properly supported.
// Arg0: array length.
// Arg1: array element type.
-// Arg2: type arguments of the instantiator.
// Return value: newly allocated array of length arg0.
-DEFINE_RUNTIME_ENTRY(AllocateArray, 3) {
+DEFINE_RUNTIME_ENTRY(AllocateArray, 2) {
ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count());
const Smi& length = Smi::CheckedHandle(arguments.At(0));
const Array& array = Array::Handle(Array::New(length.Value()));
arguments.SetReturn(array);
AbstractTypeArguments& element_type =
AbstractTypeArguments::CheckedHandle(arguments.At(1));
- if (element_type.IsNull()) {
- // No instantiator required for a raw type.
- ASSERT(AbstractTypeArguments::CheckedHandle(arguments.At(2)).IsNull());
- return;
- }
- // An Array takes only one type argument.
- ASSERT(element_type.Length() == 1);
- const AbstractTypeArguments& instantiator =
- AbstractTypeArguments::CheckedHandle(arguments.At(2));
- if (instantiator.IsNull()) {
- // Either the type element is instantiated (use it), or the instantiator is
- // of a raw type and we cannot instantiate the element type (leave as null).
- if (element_type.IsInstantiated()) {
- array.SetTypeArguments(element_type);
- }
- return;
- }
- ASSERT(!element_type.IsInstantiated());
- // If possible, use the instantiator as the type argument vector.
- if (element_type.IsUninstantiatedIdentity() && (instantiator.Length() == 1)) {
- // No need to check that the instantiator is a TypeArguments, since the
- // virtual call to Length() handles other cases that are harder to inline.
- element_type = instantiator.raw();
- } else {
- element_type = InstantiatedTypeArguments::New(element_type, instantiator);
- }
- array.SetTypeArguments(element_type);
+ // An Array is raw or takes only one type argument.
+ ASSERT(element_type.IsNull() || (element_type.Length() == 1));
+ array.SetTypeArguments(element_type); // May be null.
}
// Allocate a new object.
// Arg0: class of the object that needs to be allocated.
// Arg1: type arguments of the object that needs to be allocated.
-// Arg2: type arguments of the instantiator.
+// Arg2: type arguments of the instantiator or kNoInstantiator.
// Return value: newly allocated object.
DEFINE_RUNTIME_ENTRY(AllocateObject, 3) {
ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count());
@@ -172,26 +150,23 @@
}
AbstractTypeArguments& type_arguments =
AbstractTypeArguments::CheckedHandle(arguments.At(1));
- if (type_arguments.IsNull()) {
- // No instantiator is required for a raw type.
- ASSERT(Instance::CheckedHandle(arguments.At(2)).IsNull());
+ ASSERT(type_arguments.IsNull() ||
+ (type_arguments.Length() == cls.NumTypeArguments()));
+ // If no instantiator is provided, set the type arguments and return.
+ if (Object::Handle(arguments.At(2)).IsSmi()) {
+ ASSERT(Smi::CheckedHandle(arguments.At(2)).Value() ==
+ StubCode::kNoInstantiator);
+ instance.SetTypeArguments(type_arguments); // May be null.
return;
}
- ASSERT(type_arguments.Length() == cls.NumTypeArguments());
+ ASSERT(!type_arguments.IsInstantiated());
const AbstractTypeArguments& instantiator =
AbstractTypeArguments::CheckedHandle(arguments.At(2));
+ ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
if (instantiator.IsNull()) {
- // Either the type argument vector is instantiated (use it), or the
- // instantiator is of a raw type and we cannot instantiate the type argument
- // vector (leave it as null).
- if (type_arguments.IsInstantiated()) {
- instance.SetTypeArguments(type_arguments);
- }
- return;
- }
- ASSERT(!type_arguments.IsInstantiated());
- // If possible, use the instantiator as the type argument vector.
- if (instantiator.IsTypeArguments()) {
+ type_arguments =
+ InstantiatedTypeArguments::New(type_arguments, instantiator);
+ } else if (instantiator.IsTypeArguments()) {
// Code inlined in the caller should have optimized the case where the
// instantiator is a TypeArguments and can be used as type argument vector.
ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
@@ -199,6 +174,7 @@
type_arguments =
InstantiatedTypeArguments::New(type_arguments, instantiator);
} else {
+ // If possible, use the instantiator as the type argument vector.
if (type_arguments.IsUninstantiatedIdentity() &&
(instantiator.Length() == type_arguments.Length())) {
type_arguments = instantiator.raw();
@@ -207,6 +183,7 @@
InstantiatedTypeArguments::New(type_arguments, instantiator);
}
}
+ ASSERT(type_arguments.IsInstantiated());
instance.SetTypeArguments(type_arguments);
}
@@ -222,22 +199,27 @@
AbstractTypeArguments::CheckedHandle(arguments.At(0));
const AbstractTypeArguments& instantiator =
AbstractTypeArguments::CheckedHandle(arguments.At(1));
- ASSERT(!type_arguments.IsNull() &&
- !type_arguments.IsInstantiated() &&
- !instantiator.IsNull());
+ ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated());
+ ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
// Code inlined in the caller should have optimized the case where the
// instantiator can be used as type argument vector.
- ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
+ ASSERT(instantiator.IsNull() ||
+ !type_arguments.IsUninstantiatedIdentity() ||
!instantiator.IsTypeArguments() ||
(instantiator.Length() != type_arguments.Length()));
type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator);
+ ASSERT(type_arguments.IsInstantiated());
arguments.SetReturn(type_arguments);
}
// Allocate a new closure.
+// The type argument vector of a closure is always the vector of type parameters
+// of its signature class, i.e. an uninstantiated identity vector. Therefore,
+// the instantiator type arguments can be used as the instantiated closure type
+// arguments and is passed here as the type arguments.
// Arg0: local function.
-// Arg1: type arguments of the closure.
+// Arg1: type arguments of the closure (i.e. instantiator).
// Return value: newly allocated closure.
DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) {
ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count());
@@ -418,6 +400,7 @@
if (FLAG_trace_type_checks) {
const Type& src_type = Type::Handle(src_instance.GetType());
+ ASSERT(src_type.IsInstantiated());
if (dst_type.IsInstantiated()) {
OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s'.\n",
String::Handle(src_type.Name()).ToCString(),

Powered by Google App Engine
This is Rietveld 408576698