| Index: runtime/vm/stub_code_arm64.cc
|
| diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
|
| index 93b92179224593fc99a0dc2e4d3a7134d06b1d6e..23fb1b20b2ec80ccdf65192ab555793c241ca959 100644
|
| --- a/runtime/vm/stub_code_arm64.cc
|
| +++ b/runtime/vm/stub_code_arm64.cc
|
| @@ -1799,55 +1799,56 @@ void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
|
| // Used to check class and type arguments. Arguments passed in registers:
|
| // LR: return address.
|
| // R0: instance (must be preserved).
|
| -// R1: instantiator type arguments or NULL.
|
| -// R2: cache array.
|
| +// R1: instantiator type arguments (only if n == 4, can be raw_null).
|
| +// R2: function type arguments (only if n == 4, can be raw_null).
|
| +// R3: SubtypeTestCache.
|
| // Result in R1: null -> not found, otherwise result (true or false).
|
| static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
|
| - ASSERT((1 <= n) && (n <= 3));
|
| + ASSERT((n == 1) || (n == 2) || (n == 4));
|
| if (n > 1) {
|
| - // Get instance type arguments.
|
| - __ LoadClass(R3, R0);
|
| + __ LoadClass(R6, R0);
|
| // Compute instance type arguments into R4.
|
| Label has_no_type_arguments;
|
| __ LoadObject(R4, Object::null_object());
|
| __ LoadFieldFromOffset(
|
| - R5, R3, Class::type_arguments_field_offset_in_words_offset(), kWord);
|
| + R5, R6, Class::type_arguments_field_offset_in_words_offset(), kWord);
|
| __ CompareImmediate(R5, Class::kNoTypeArguments);
|
| __ b(&has_no_type_arguments, EQ);
|
| __ add(R5, R0, Operand(R5, LSL, 3));
|
| __ LoadFieldFromOffset(R4, R5, 0);
|
| __ Bind(&has_no_type_arguments);
|
| }
|
| - __ LoadClassId(R3, R0);
|
| + __ LoadClassId(R6, R0);
|
| // R0: instance.
|
| - // R1: instantiator type arguments or NULL.
|
| - // R2: SubtypeTestCache.
|
| - // R3: instance class id.
|
| + // R1: instantiator type arguments (only if n == 4, can be raw_null).
|
| + // R2: function type arguments (only if n == 4, can be raw_null).
|
| + // R3: SubtypeTestCache.
|
| + // R6: instance class id.
|
| // R4: instance type arguments (null if none), used only if n > 1.
|
| - __ LoadFieldFromOffset(R2, R2, SubtypeTestCache::cache_offset());
|
| - __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag);
|
| + __ LoadFieldFromOffset(R3, R3, SubtypeTestCache::cache_offset());
|
| + __ AddImmediate(R3, R3, Array::data_offset() - kHeapObjectTag);
|
|
|
| Label loop, found, not_found, next_iteration;
|
| - // R2: entry start.
|
| - // R3: instance class id.
|
| + // R3: entry start.
|
| + // R6: instance class id.
|
| // R4: instance type arguments (still null if closure).
|
| - __ SmiTag(R3);
|
| - __ CompareImmediate(R3, Smi::RawValue(kClosureCid));
|
| + __ SmiTag(R6);
|
| + __ CompareImmediate(R6, Smi::RawValue(kClosureCid));
|
| __ b(&loop, NE);
|
| __ LoadFieldFromOffset(R4, R0, Closure::instantiator_offset());
|
| - __ LoadFieldFromOffset(R3, R0, Closure::function_offset());
|
| - // R3: instance class id as Smi or function.
|
| + __ LoadFieldFromOffset(R6, R0, Closure::function_offset());
|
| + // R6: instance class id as Smi or function.
|
| __ Bind(&loop);
|
| - __ LoadFromOffset(R5, R2,
|
| + __ LoadFromOffset(R5, R3,
|
| kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction);
|
| __ CompareObject(R5, Object::null_object());
|
| __ b(¬_found, EQ);
|
| - __ CompareRegisters(R5, R3);
|
| + __ CompareRegisters(R5, R6);
|
| if (n == 1) {
|
| __ b(&found, EQ);
|
| } else {
|
| __ b(&next_iteration, NE);
|
| - __ LoadFromOffset(R5, R2,
|
| + __ LoadFromOffset(R5, R3,
|
| kWordSize * SubtypeTestCache::kInstanceTypeArguments);
|
| __ CompareRegisters(R5, R4);
|
| if (n == 2) {
|
| @@ -1855,13 +1856,17 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
|
| } else {
|
| __ b(&next_iteration, NE);
|
| __ LoadFromOffset(
|
| - R5, R2, kWordSize * SubtypeTestCache::kInstantiatorTypeArguments);
|
| + R5, R3, kWordSize * SubtypeTestCache::kInstantiatorTypeArguments);
|
| __ CompareRegisters(R5, R1);
|
| + __ b(&next_iteration, NE);
|
| + __ LoadFromOffset(R5, R3,
|
| + kWordSize * SubtypeTestCache::kFunctionTypeArguments);
|
| + __ CompareRegisters(R5, R2);
|
| __ b(&found, EQ);
|
| }
|
| }
|
| __ Bind(&next_iteration);
|
| - __ AddImmediate(R2, R2, kWordSize * SubtypeTestCache::kTestEntryLength);
|
| + __ AddImmediate(R3, R3, kWordSize * SubtypeTestCache::kTestEntryLength);
|
| __ b(&loop);
|
| // Fall through to not found.
|
| __ Bind(¬_found);
|
| @@ -1869,17 +1874,18 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
|
| __ ret();
|
|
|
| __ Bind(&found);
|
| - __ LoadFromOffset(R1, R2, kWordSize * SubtypeTestCache::kTestResult);
|
| + __ LoadFromOffset(R1, R3, kWordSize * SubtypeTestCache::kTestResult);
|
| __ ret();
|
| }
|
|
|
|
|
| // Used to check class and type arguments. Arguments passed on stack:
|
| -// TOS + 0: return address.
|
| -// TOS + 1: instantiator type arguments or NULL.
|
| -// TOS + 2: instance.
|
| -// TOS + 3: cache array.
|
| -// Result in RCX: null -> not found, otherwise result (true or false).
|
| +// LR: return address.
|
| +// R0: instance (must be preserved).
|
| +// R1: unused.
|
| +// R2: unused.
|
| +// R3: SubtypeTestCache.
|
| +// Result in R1: null -> not found, otherwise result (true or false).
|
| void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
|
| GenerateSubtypeNTestCacheStub(assembler, 1);
|
| }
|
| @@ -1888,8 +1894,9 @@ void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
|
| // Used to check class and type arguments. Arguments passed in registers:
|
| // LR: return address.
|
| // R0: instance (must be preserved).
|
| -// R1: instantiator type arguments or NULL.
|
| -// R2: cache array.
|
| +// R1: unused.
|
| +// R2: unused.
|
| +// R3: SubtypeTestCache.
|
| // Result in R1: null -> not found, otherwise result (true or false).
|
| void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
|
| GenerateSubtypeNTestCacheStub(assembler, 2);
|
| @@ -1897,13 +1904,14 @@ void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
|
|
|
|
|
| // Used to check class and type arguments. Arguments passed on stack:
|
| -// TOS + 0: return address.
|
| -// TOS + 1: instantiator type arguments.
|
| -// TOS + 2: instance.
|
| -// TOS + 3: cache array.
|
| -// Result in RCX: null -> not found, otherwise result (true or false).
|
| -void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
|
| - GenerateSubtypeNTestCacheStub(assembler, 3);
|
| +// LR: return address.
|
| +// R0: instance (must be preserved).
|
| +// R1: instantiator type arguments (can be raw_null).
|
| +// R2: function type arguments (can be raw_null).
|
| +// R3: SubtypeTestCache.
|
| +// Result in R1: null -> not found, otherwise result (true or false).
|
| +void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) {
|
| + GenerateSubtypeNTestCacheStub(assembler, 4);
|
| }
|
|
|
|
|
|
|