[VM runtime] Explicitly specify length of parent type argument vector in native
call Internal_prependTypeArguments to protect against vector reuse optimization.
This is indirectly related to issue #33040.

Change-Id: Ic03805135b1c68b59234336e145f5578cf178c74
Reviewed-on: https://dart-review.googlesource.com/53692
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index dc6b038..fb640c3 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -93,11 +93,12 @@
   }
 }
 
-// Prepend the parent type arguments (maybe null) to the function type
-// arguments (may be null). The result is null if both input vectors are null
-// or is a newly allocated and canonicalized vector of length 'len'.
-_prependTypeArguments(functionTypeArguments, parentTypeArguments, len)
-    native "Internal_prependTypeArguments";
+// Prepend the parent type arguments (maybe null) of length 'parentLen' to the
+// function type arguments (may be null). The result is null if both input
+// vectors are null or is a newly allocated and canonicalized vector of length
+// 'totalLen'.
+_prependTypeArguments(functionTypeArguments, parentTypeArguments, parentLen,
+    totalLen) native "Internal_prependTypeArguments";
 
 // Called by IRRegExpMacroAssembler::GrowStack.
 Int32List _growRegExpStack(Int32List stack) {
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index d586dc0..f47a80a 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -457,7 +457,7 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 3) {
+DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 4) {
   const TypeArguments& function_type_arguments =
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
   const TypeArguments& parent_type_arguments =
@@ -465,23 +465,22 @@
   if (function_type_arguments.IsNull() && parent_type_arguments.IsNull()) {
     return TypeArguments::null();
   }
-  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_len, arguments->NativeArgAt(2));
-  const intptr_t len = smi_len.Value();
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_parent_len, arguments->NativeArgAt(2));
+  const intptr_t parent_len = smi_parent_len.Value();
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_total_len, arguments->NativeArgAt(3));
+  const intptr_t total_len = smi_total_len.Value();
   const TypeArguments& result =
-      TypeArguments::Handle(zone, TypeArguments::New(len, Heap::kNew));
+      TypeArguments::Handle(zone, TypeArguments::New(total_len, Heap::kNew));
   AbstractType& type = AbstractType::Handle(zone);
-  const intptr_t split = parent_type_arguments.IsNull()
-                             ? len - function_type_arguments.Length()
-                             : parent_type_arguments.Length();
-  for (intptr_t i = 0; i < split; i++) {
+  for (intptr_t i = 0; i < parent_len; i++) {
     type = parent_type_arguments.IsNull() ? Type::DynamicType()
                                           : parent_type_arguments.TypeAt(i);
     result.SetTypeAt(i, type);
   }
-  for (intptr_t i = split; i < len; i++) {
+  for (intptr_t i = parent_len; i < total_len; i++) {
     type = function_type_arguments.IsNull()
                ? Type::DynamicType()
-               : function_type_arguments.TypeAt(i - split);
+               : function_type_arguments.TypeAt(i - parent_len);
     result.SetTypeAt(i, type);
   }
   return result.Canonicalize();
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 753fbd4..b292388 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -315,7 +315,7 @@
   V(Internal_makeFixedListUnmodifiable, 1)                                     \
   V(Internal_inquireIs64Bit, 0)                                                \
   V(Internal_extractTypeArguments, 2)                                          \
-  V(Internal_prependTypeArguments, 3)                                          \
+  V(Internal_prependTypeArguments, 4)                                          \
   V(InvocationMirror_unpackTypeArguments, 1)                                   \
   V(NoSuchMethodError_existingMethodSignature, 3)                              \
   V(LinkedHashMap_getIndex, 1)                                                 \
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 5c82158..c26f4a6 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -3797,15 +3797,18 @@
         ASSERT(parent_type_args_var->owner() != scope);
         // Call the runtime to concatenate both vectors.
         ZoneGrowableArray<PushArgumentInstr*>* arguments =
-            new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
+            new (Z) ZoneGrowableArray<PushArgumentInstr*>(4);
         arguments->Add(PushArgument(type_args_val));
         Value* parent_type_args_val =
             Bind(BuildLoadLocal(*parent_type_args_var, node->token_pos()));
         arguments->Add(PushArgument(parent_type_args_val));
-        Value* len_const = Bind(new (Z) ConstantInstr(
+        Value* parent_len = Bind(new (Z) ConstantInstr(
+            Smi::ZoneHandle(Z, Smi::New(function.NumParentTypeParameters()))));
+        arguments->Add(PushArgument(parent_len));
+        Value* total_len = Bind(new (Z) ConstantInstr(
             Smi::ZoneHandle(Z, Smi::New(function.NumTypeParameters() +
                                         function.NumParentTypeParameters()))));
-        arguments->Add(PushArgument(len_const));
+        arguments->Add(PushArgument(total_len));
         const Library& dart_internal =
             Library::Handle(Z, Library::InternalLibrary());
         const Function& prepend_function =
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index c9044d3..d7a97ee 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -5574,6 +5574,8 @@
       body += LoadLocal(closure);
       body += LoadField(Closure::function_type_arguments_offset());
       body += PushArgument();
+      body += IntConstant(dart_function.NumParentTypeParameters());
+      body += PushArgument();
       body += IntConstant(dart_function.NumTypeParameters() +
                           dart_function.NumParentTypeParameters());
       body += PushArgument();