[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();