[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>
This commit is contained in:
Martin Kustermann 2018-08-08 15:45:02 +00:00 committed by commit-bot@chromium.org
parent 19a90c2c8b
commit 34f17b2973
5 changed files with 42 additions and 21 deletions

View file

@ -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 {

View file

@ -2909,13 +2909,15 @@ RawObject* Simulator::Call(const Code& code,
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 @@ RawObject* Simulator::Call(const Code& code,
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 @@ 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;
}

View file

@ -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.

View file

@ -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.

View file

@ -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