[VM] Add missing 6-type-test to subtypecache search in simdbc (it has it in 2 places)
Also this CL ports x64 changes to StubCode::GenerateSlowTypeTestStub() to arm/arm64.
Change-Id: I1e6bb3ae51724e97dac28c7d75ac9d0f4f2db01b
Reviewed-on: https://dart-review.googlesource.com/68885
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index b06321f..f64ebd8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -695,7 +695,7 @@
return;
}
- if (FLAG_precompiled_mode) {
+ if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
GenerateAssertAssignableViaTypeTestingStub(token_pos, deopt_id, dst_type,
dst_name, locs);
} else {
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index c5d2269..243622a 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -2909,13 +2909,15 @@
RawTypeArguments* instance_type_arguments =
static_cast<RawTypeArguments*>(null_value);
RawObject* instance_cid_or_function;
+ RawTypeArguments* parent_function_type_arguments;
+ RawTypeArguments* delayed_function_type_arguments;
if (cid == kClosureCid) {
RawClosure* closure = static_cast<RawClosure*>(instance);
- if (closure->ptr()->function_type_arguments_ != TypeArguments::null()) {
- // Cache cannot be used for generic closures.
- goto InstanceOfCallRuntime;
- }
instance_type_arguments = closure->ptr()->instantiator_type_arguments_;
+ parent_function_type_arguments =
+ closure->ptr()->function_type_arguments_;
+ delayed_function_type_arguments =
+ closure->ptr()->delayed_type_arguments_;
instance_cid_or_function = closure->ptr()->function_;
} else {
instance_cid_or_function = Smi::New(cid);
@@ -2928,6 +2930,10 @@
instance->ptr())[instance_class->ptr()
->type_arguments_field_offset_in_words_];
}
+ parent_function_type_arguments =
+ static_cast<RawTypeArguments*>(null_value);
+ delayed_function_type_arguments =
+ static_cast<RawTypeArguments*>(null_value);
}
for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
@@ -2940,7 +2946,11 @@
(entries[SubtypeTestCache::kInstantiatorTypeArguments] ==
instantiator_type_arguments) &&
(entries[SubtypeTestCache::kFunctionTypeArguments] ==
- function_type_arguments)) {
+ function_type_arguments) &&
+ (entries[SubtypeTestCache::kInstanceParentFunctionTypeArguments] ==
+ parent_function_type_arguments) &&
+ (entries[SubtypeTestCache::kInstanceDelayedFunctionTypeArguments] ==
+ delayed_function_type_arguments)) {
SP[-4] = entries[SubtypeTestCache::kTestResult];
goto InstanceOfOk;
}
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 6158b18..6a0a2ed 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -2202,22 +2202,28 @@
const Register kTmp = NOTFP;
// If this is not a [Type] object, we'll go to the runtime.
- Label is_simple, is_instantiated, is_uninstantiated;
+ Label is_simple_case, is_complex_case;
__ LoadClassId(kTmp, kDstTypeReg);
__ cmp(kTmp, Operand(kTypeCid));
- __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
// Check whether this [Type] is instantiated/uninstantiated.
__ ldrb(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()));
__ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
- __ BranchIf(NOT_EQUAL, &is_uninstantiated);
- // Fall through to &is_instantiated
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+ // Check whether this [Type] is a function type.
+ __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::signature_offset()));
+ __ CompareObject(kTmp, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+ // Fall through to &is_simple_case
const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
(1 << kDstTypeReg) |
(1 << kFunctionTypeArgumentsReg);
- __ Bind(&is_instantiated);
+ __ Bind(&is_simple_case);
{
__ PushList(kRegsToSave);
__ BranchLink(*StubCode::Subtype2TestCache_entry());
@@ -2227,10 +2233,10 @@
__ Jump(&call_runtime);
}
- __ Bind(&is_uninstantiated);
+ __ Bind(&is_complex_case);
{
__ PushList(kRegsToSave);
- __ BranchLink(*StubCode::Subtype4TestCache_entry());
+ __ BranchLink(*StubCode::Subtype6TestCache_entry());
__ CompareObject(R1, Bool::True());
__ PopList(kRegsToSave);
__ BranchIf(EQUAL, &done); // Cache said: yes.
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 41c1e28..81d1bb8 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -2449,18 +2449,24 @@
const Register kTmp = R9;
// If this is not a [Type] object, we'll go to the runtime.
- Label is_simple, is_instantiated, is_uninstantiated;
+ Label is_simple_case, is_complex_case;
__ LoadClassId(kTmp, kDstTypeReg);
__ cmp(kTmp, Operand(kTypeCid));
- __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
// Check whether this [Type] is instantiated/uninstantiated.
__ ldr(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()), kByte);
__ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
- __ BranchIf(NOT_EQUAL, &is_uninstantiated);
- // Fall through to &is_instantiated
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
- __ Bind(&is_instantiated);
+ // Check whether this [Type] is a function type.
+ __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::signature_offset()));
+ __ CompareObject(kTmp, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+ // Fall through to &is_simple_case
+
+ __ Bind(&is_simple_case);
{
__ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
__ BranchLink(*StubCode::Subtype2TestCache_entry());
@@ -2470,10 +2476,10 @@
__ Jump(&call_runtime);
}
- __ Bind(&is_uninstantiated);
+ __ Bind(&is_complex_case);
{
__ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
- __ BranchLink(*StubCode::Subtype4TestCache_entry());
+ __ BranchLink(*StubCode::Subtype6TestCache_entry());
__ CompareObject(R1, Bool::True());
__ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
__ BranchIf(EQUAL, &done); // Cache said: yes.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 22ec171..131baac 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -69,7 +69,6 @@
function_propagation_test: RuntimeError
function_subtype_inline2_test: RuntimeError
generic_function_bounds_test: RuntimeError
-generic_function_dcall_test: RuntimeError
generic_instanceof2_test: RuntimeError
generic_is_check_test: RuntimeError
generic_no_such_method_dispatcher_simple_test: CompileTimeError