From 34f17b29735d5f8a9d3f6be7571edec379327a9f Mon Sep 17 00:00:00 2001 From: Martin Kustermann Date: Wed, 8 Aug 2018 15:45:02 +0000 Subject: [PATCH] [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 Reviewed-by: Vyacheslav Egorov --- .../backend/flow_graph_compiler_arm.cc | 2 +- runtime/vm/simulator_dbc.cc | 20 ++++++++++++++----- runtime/vm/stub_code_arm.cc | 20 ++++++++++++------- runtime/vm/stub_code_arm64.cc | 20 ++++++++++++------- tests/language_2/language_2_kernel.status | 1 - 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc index b06321f3ee1..f64ebd89520 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 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos, 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 c5d22697a0f..243622ab94c 100644 --- a/runtime/vm/simulator_dbc.cc +++ b/runtime/vm/simulator_dbc.cc @@ -2909,13 +2909,15 @@ RawObject* Simulator::Call(const Code& code, RawTypeArguments* instance_type_arguments = static_cast(null_value); RawObject* instance_cid_or_function; + RawTypeArguments* parent_function_type_arguments; + RawTypeArguments* delayed_function_type_arguments; if (cid == kClosureCid) { RawClosure* closure = static_cast(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 @@ RawObject* Simulator::Call(const Code& code, instance->ptr())[instance_class->ptr() ->type_arguments_field_offset_in_words_]; } + parent_function_type_arguments = + static_cast(null_value); + delayed_function_type_arguments = + static_cast(null_value); } for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); @@ -2940,7 +2946,11 @@ RawObject* Simulator::Call(const Code& code, (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 6158b18d73c..6a0a2ede736 100644 --- a/runtime/vm/stub_code_arm.cc +++ b/runtime/vm/stub_code_arm.cc @@ -2202,22 +2202,28 @@ void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) { 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 @@ void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) { __ 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 41c1e28967c..81d1bb8b388 100644 --- a/runtime/vm/stub_code_arm64.cc +++ b/runtime/vm/stub_code_arm64.cc @@ -2449,18 +2449,24 @@ void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) { 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 @@ void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) { __ 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 22ec1716698..131baac93fe 100644 --- a/tests/language_2/language_2_kernel.status +++ b/tests/language_2/language_2_kernel.status @@ -69,7 +69,6 @@ flatten_test/12: MissingRuntimeError 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