Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1365)

Unified Diff: runtime/vm/flow_graph_compiler_arm64.cc

Issue 2799373002: Pass a second type argument vector to all type instantiation calls in the VM. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_compiler_arm64.cc
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 6f02236c483f9568f99b6bb6f4168a35dad99857..611029834b9db09f462e1ee647fa15a658f5ffa4 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -202,29 +202,32 @@ void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
// R0: instance (must be preserved).
// R1: instantiator type arguments (if used).
+// R2: function type arguments (if used).
RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
- Register type_arguments_reg,
+ Register instantiator_type_arguments_reg,
+ Register function_type_arguments_reg,
Register temp_reg,
Label* is_instance_lbl,
Label* is_not_instance_lbl) {
ASSERT(instance_reg == R0);
- ASSERT(temp_reg == kNoRegister); // Unused on ARM.
+ ASSERT(temp_reg == kNoRegister); // Unused on ARM64.
const SubtypeTestCache& type_test_cache =
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
- __ LoadUniqueObject(R2, type_test_cache);
+ __ LoadUniqueObject(R3, type_test_cache);
if (test_kind == kTestTypeOneArg) {
- ASSERT(type_arguments_reg == kNoRegister);
- __ LoadObject(R1, Object::null_object());
+ ASSERT(instantiator_type_arguments_reg == kNoRegister);
+ ASSERT(function_type_arguments_reg == kNoRegister);
__ BranchLink(*StubCode::Subtype1TestCache_entry());
} else if (test_kind == kTestTypeTwoArgs) {
- ASSERT(type_arguments_reg == kNoRegister);
- __ LoadObject(R1, Object::null_object());
+ ASSERT(instantiator_type_arguments_reg == kNoRegister);
+ ASSERT(function_type_arguments_reg == kNoRegister);
__ BranchLink(*StubCode::Subtype2TestCache_entry());
- } else if (test_kind == kTestTypeThreeArgs) {
- ASSERT(type_arguments_reg == R1);
- __ BranchLink(*StubCode::Subtype3TestCache_entry());
+ } else if (test_kind == kTestTypeFourArgs) {
+ ASSERT(instantiator_type_arguments_reg == R1);
+ ASSERT(function_type_arguments_reg == R2);
+ __ BranchLink(*StubCode::Subtype4TestCache_entry());
} else {
UNREACHABLE();
}
@@ -238,7 +241,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
// type test is conclusive, otherwise fallthrough if a type test could not
// be completed.
// R0: instance being type checked (preserved).
-// Clobbers R2.
+// Clobbers R1, R2.
RawSubtypeTestCache*
FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
@@ -302,11 +305,13 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
}
}
// Regular subtype test cache involving instance's type arguments.
- const Register kTypeArgumentsReg = kNoRegister;
+ const Register kInstantiatorTypeArgumentsReg = kNoRegister;
+ const Register kFunctionTypeArgumentsReg = kNoRegister;
const Register kTempReg = kNoRegister;
// R0: instance (must be preserved).
return GenerateCallSubtypeTestStub(kTestTypeTwoArgs, kInstanceReg,
- kTypeArgumentsReg, kTempReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kTempReg,
is_instance_lbl, is_not_instance_lbl);
}
@@ -413,10 +418,12 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
__ CompareImmediate(R2, Smi::RawValue(type_class.id()));
__ b(is_instance_lbl, EQ);
- const Register kTypeArgumentsReg = kNoRegister;
+ const Register kInstantiatorTypeArgumentsReg = kNoRegister;
+ const Register kFunctionTypeArgumentsReg = kNoRegister;
const Register kTempReg = kNoRegister;
return GenerateCallSubtypeTestStub(kTestTypeOneArg, kInstanceReg,
- kTypeArgumentsReg, kTempReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kTempReg,
is_instance_lbl, is_not_instance_lbl);
}
@@ -433,28 +440,32 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
// Skip check if destination is a dynamic type.
if (type.IsTypeParameter()) {
const TypeParameter& type_param = TypeParameter::Cast(type);
- // Load instantiator type arguments on stack.
- __ ldr(R1, Address(SP)); // Get instantiator type arguments.
+ __ ldr(R1, Address(SP, 1 * kWordSize)); // Get instantiator type args.
zra 2017/04/07 17:36:30 ldp to load a pair.
regis 2017/04/11 04:23:07 Done.
+ __ ldr(R2, Address(SP, 0 * kWordSize)); // Get function type args.
// R1: instantiator type arguments.
+ // R2: function type arguments.
+ const Register kTypeArgumentsReg =
+ type_param.IsClassTypeParameter() ? R1 : R2;
// Check if type arguments are null, i.e. equivalent to vector of dynamic.
- __ CompareObject(R1, Object::null_object());
+ __ CompareObject(kTypeArgumentsReg, Object::null_object());
__ b(is_instance_lbl, EQ);
- __ LoadFieldFromOffset(R2, R1,
+ __ LoadFieldFromOffset(R3, kTypeArgumentsReg,
TypeArguments::type_at_offset(type_param.index()));
- // R2: concrete type of type.
+ // R3: concrete type of type.
// Check if type argument is dynamic.
- __ CompareObject(R2, Object::dynamic_type());
+ __ CompareObject(R3, Object::dynamic_type());
__ b(is_instance_lbl, EQ);
- __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
+ __ CompareObject(R3, Type::ZoneHandle(zone(), Type::ObjectType()));
__ b(is_instance_lbl, EQ);
+ // TODO(regis): Optimize void type as well once allowed as type argument.
// For Smi check quickly against int and num interfaces.
Label not_smi;
__ tsti(R0, Immediate(kSmiTagMask)); // Value is Smi?
__ b(&not_smi, NE);
- __ CompareObject(R2, Type::ZoneHandle(zone(), Type::IntType()));
+ __ CompareObject(R3, Type::ZoneHandle(zone(), Type::IntType()));
__ b(is_instance_lbl, EQ);
- __ CompareObject(R2, Type::ZoneHandle(zone(), Type::Number()));
+ __ CompareObject(R3, Type::ZoneHandle(zone(), Type::Number()));
__ b(is_instance_lbl, EQ);
// Smi must be handled in runtime.
Label fall_through;
@@ -462,28 +473,34 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
__ Bind(&not_smi);
// R1: instantiator type arguments.
+ // R2: function type arguments.
// R0: instance.
const Register kInstanceReg = R0;
- const Register kTypeArgumentsReg = R1;
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
const Register kTempReg = kNoRegister;
const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
zone(), GenerateCallSubtypeTestStub(
- kTestTypeThreeArgs, kInstanceReg, kTypeArgumentsReg,
+ kTestTypeFourArgs, kInstanceReg,
+ kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg,
kTempReg, is_instance_lbl, is_not_instance_lbl));
__ Bind(&fall_through);
return type_test_cache.raw();
}
if (type.IsType()) {
const Register kInstanceReg = R0;
- const Register kTypeArgumentsReg = R1;
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
__ tsti(kInstanceReg, Immediate(kSmiTagMask)); // Is instance Smi?
__ b(is_not_instance_lbl, EQ);
- __ ldr(kTypeArgumentsReg, Address(SP)); // Instantiator type args.
+ __ ldr(kInstantiatorTypeArgumentsReg, Address(SP, 1 * kWordSize));
zra 2017/04/07 17:36:30 ditto
regis 2017/04/11 04:23:08 Done.
+ __ ldr(kFunctionTypeArgumentsReg, Address(SP, 0 * kWordSize));
// Uninstantiated type class is known at compile time, but the type
// arguments are determined at runtime by the instantiator.
const Register kTempReg = kNoRegister;
- return GenerateCallSubtypeTestStub(kTestTypeThreeArgs, kInstanceReg,
- kTypeArgumentsReg, kTempReg,
+ return GenerateCallSubtypeTestStub(kTestTypeFourArgs, kInstanceReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kTempReg,
is_instance_lbl, is_not_instance_lbl);
}
return SubtypeTestCache::null();
@@ -493,9 +510,11 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
// Inputs:
// - R0: instance being type checked (preserved).
// - R1: optional instantiator type arguments (preserved).
-// Clobbers R2, R3.
+// - R2: optional function type arguments (preserved).
+// Clobbers R3, R4, R8, R9.
// Returns:
-// - preserved instance in R0 and optional instantiator type arguments in R1.
+// - preserved instance in R0, optional instantiator type arguments in R1, and
+// optional function type arguments in R2.
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
@@ -544,6 +563,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
// Inputs:
// - R0: object.
// - R1: instantiator type arguments or raw_null.
+// - R2: function type arguments or raw_null.
// Returns:
// - true or false in R0.
void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
@@ -553,8 +573,8 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
ASSERT(!type.IsObjectType() && !type.IsDynamicType());
- // Preserve instantiator type arguments (R1).
- __ Push(R1);
+ __ Push(R1); // Store instantiator type arguments.
zra 2017/04/07 17:36:30 PushPair
regis 2017/04/11 04:23:08 Done. However, the argument names 'first' and 'se
+ __ Push(R2); // Store function type arguments.
Label is_instance, is_not_instance;
// If type is instantiated and non-parameterized, we can inline code
@@ -581,17 +601,19 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
if (!test_cache.IsNull()) {
// Generate runtime call.
// Load instantiator (R2) and its type arguments (R1).
- __ ldr(R1, Address(SP, 0 * kWordSize));
- __ PushObject(Object::null_object()); // Make room for the result.
- __ Push(R0); // Push the instance.
- __ PushObject(type); // Push the type.
- __ Push(R1); // Push instantiator type arguments (R1).
+ __ ldr(R1, Address(SP, 1 * kWordSize)); // Get instantiator type args.
zra 2017/04/07 17:36:30 ldp
regis 2017/04/11 04:23:08 Done.
+ __ ldr(R2, Address(SP, 0 * kWordSize)); // Get function type args.
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ Push(R0); // Push the instance.
+ __ PushObject(type); // Push the type.
+ __ Push(R1); // Instantiator type arguments.
zra 2017/04/07 17:36:30 PushPair
regis 2017/04/11 04:23:08 Done.
+ __ Push(R2); // Function type arguments.
__ LoadUniqueObject(R0, test_cache);
__ Push(R0);
- GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 4, locs);
+ GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// instanceof runtime call will be left as the result of the operation.
- __ Drop(4);
+ __ Drop(5);
__ Pop(R0);
__ b(&done);
}
@@ -602,8 +624,8 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
__ Bind(&is_instance);
__ LoadObject(R0, Bool::Get(true));
__ Bind(&done);
- // Remove instantiator type arguments (R1).
- __ Drop(1);
+ // Remove instantiator type arguments and function type arguments.
+ __ Drop(2);
}
@@ -614,6 +636,7 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
// Inputs:
// - R0: instance being type checked.
// - R1: instantiator type arguments or raw_null.
+// - R2: function type arguments or raw_null.
// Returns:
// - object in R0 for successful assignable check (or throws TypeError).
// Performance notes: positive checks must be quick, negative checks can be slow
@@ -629,8 +652,8 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
// Assignable check is skipped in FlowGraphBuilder, not here.
ASSERT(dst_type.IsMalformedOrMalbounded() ||
(!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
- // Preserve instantiator type arguments (R1).
- __ Push(R1);
+ __ Push(R1); // Store instantiator type arguments.
zra 2017/04/07 17:36:30 PushPair
regis 2017/04/11 04:23:08 Done.
+ __ Push(R2); // Store function type arguments.
// A null object is always assignable and is returned as result.
Label is_assignable, runtime_call;
__ CompareObject(R0, Object::null_object());
@@ -648,8 +671,8 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
__ brk(0);
__ Bind(&is_assignable); // For a null object.
- // Restore instantiator type arguments (R1).
- __ Pop(R1);
+ __ Pop(R2); // Remove pushed function type arguments.
zra 2017/04/07 17:36:30 PopPair
regis 2017/04/11 04:23:08 Done.
+ __ Pop(R1); // Remove pushed instantiator type arguments.
return;
}
@@ -659,23 +682,25 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
&runtime_call);
__ Bind(&runtime_call);
- __ ldr(R1, Address(SP)); // Load instantiator type arguments (R1).
- __ PushObject(Object::null_object()); // Make room for the result.
- __ Push(R0); // Push the source object.
- __ PushObject(dst_type); // Push the type of the destination.
- __ Push(R1); // Push instantiator type arguments (R1).
- __ PushObject(dst_name); // Push the name of the destination.
+ __ ldr(R1, Address(SP, 1 * kWordSize)); // Get instantiator type args.
zra 2017/04/07 17:36:30 ldp
regis 2017/04/11 04:23:07 Done.
+ __ ldr(R2, Address(SP, 0 * kWordSize)); // Get function type args.
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ Push(R0); // Push the source object.
+ __ PushObject(dst_type); // Push the type of the destination.
+ __ Push(R1); // Instantiator type arguments.
zra 2017/04/07 17:36:30 PushPair
regis 2017/04/11 04:23:07 Done.
+ __ Push(R2); // Function type arguments.
+ __ PushObject(dst_name); // Push the name of the destination.
__ LoadUniqueObject(R0, test_cache);
__ Push(R0);
- GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
+ GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// type check runtime call is the checked value.
- __ Drop(5);
+ __ Drop(6);
__ Pop(R0);
__ Bind(&is_assignable);
- // Restore instantiator type arguments (R1).
- __ Pop(R1);
+ __ Pop(R2); // Remove pushed function type arguments.
zra 2017/04/07 17:36:30 PopPair
regis 2017/04/11 04:23:08 Done.
+ __ Pop(R1); // Remove pushed instantiator type arguments.
}

Powered by Google App Engine
This is Rietveld 408576698