| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 __ BranchLink(&StubCode::Subtype3TestCacheLabel()); | 104 __ BranchLink(&StubCode::Subtype3TestCacheLabel()); |
| 105 } else { | 105 } else { |
| 106 UNREACHABLE(); | 106 UNREACHABLE(); |
| 107 } | 107 } |
| 108 // Result is in V0: null -> not found, otherwise Bool::True or Bool::False. | 108 // Result is in V0: null -> not found, otherwise Bool::True or Bool::False. |
| 109 GenerateBoolToJump(V0, is_instance_lbl, is_not_instance_lbl); | 109 GenerateBoolToJump(V0, is_instance_lbl, is_not_instance_lbl); |
| 110 return type_test_cache.raw(); | 110 return type_test_cache.raw(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 | 113 |
| 114 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if |
| 115 // type test is conclusive, otherwise fallthrough if a type test could not |
| 116 // be completed. |
| 117 // A0: instance being type checked (preserved). |
| 118 // Clobbers T0. |
| 114 RawSubtypeTestCache* | 119 RawSubtypeTestCache* |
| 115 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( | 120 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( |
| 116 intptr_t token_pos, | 121 intptr_t token_pos, |
| 117 const AbstractType& type, | 122 const AbstractType& type, |
| 118 Label* is_instance_lbl, | 123 Label* is_instance_lbl, |
| 119 Label* is_not_instance_lbl) { | 124 Label* is_not_instance_lbl) { |
| 120 UNIMPLEMENTED(); | 125 __ Comment("InstantiatedTypeWithArgumentsTest"); |
| 121 return NULL; | 126 ASSERT(type.IsInstantiated()); |
| 127 const Class& type_class = Class::ZoneHandle(type.type_class()); |
| 128 ASSERT(type_class.HasTypeArguments()); |
| 129 const Register kInstanceReg = A0; |
| 130 // A Smi object cannot be the instance of a parameterized class. |
| 131 __ andi(CMPRES, kInstanceReg, Immediate(kSmiTagMask)); |
| 132 __ beq(CMPRES, ZR, is_not_instance_lbl); |
| 133 const AbstractTypeArguments& type_arguments = |
| 134 AbstractTypeArguments::ZoneHandle(type.arguments()); |
| 135 const bool is_raw_type = type_arguments.IsNull() || |
| 136 type_arguments.IsRaw(type_arguments.Length()); |
| 137 if (is_raw_type) { |
| 138 const Register kClassIdReg = T0; |
| 139 // dynamic type argument, check only classes. |
| 140 __ LoadClassId(kClassIdReg, kInstanceReg); |
| 141 __ BranchEqual(kClassIdReg, type_class.id(), is_instance_lbl); |
| 142 // List is a very common case. |
| 143 if (type_class.IsListClass()) { |
| 144 GenerateListTypeCheck(kClassIdReg, is_instance_lbl); |
| 145 } |
| 146 return GenerateSubtype1TestCacheLookup( |
| 147 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 148 } |
| 149 // If one type argument only, check if type argument is Object or dynamic. |
| 150 if (type_arguments.Length() == 1) { |
| 151 const AbstractType& tp_argument = AbstractType::ZoneHandle( |
| 152 type_arguments.TypeAt(0)); |
| 153 ASSERT(!tp_argument.IsMalformed()); |
| 154 if (tp_argument.IsType()) { |
| 155 ASSERT(tp_argument.HasResolvedTypeClass()); |
| 156 // Check if type argument is dynamic or Object. |
| 157 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 158 if (object_type.IsSubtypeOf(tp_argument, NULL)) { |
| 159 // Instance class test only necessary. |
| 160 return GenerateSubtype1TestCacheLookup( |
| 161 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 162 } |
| 163 } |
| 164 } |
| 165 // Regular subtype test cache involving instance's type arguments. |
| 166 const Register kTypeArgumentsReg = kNoRegister; |
| 167 const Register kTempReg = kNoRegister; |
| 168 // A0: instance (must be preserved). |
| 169 return GenerateCallSubtypeTestStub(kTestTypeTwoArgs, |
| 170 kInstanceReg, |
| 171 kTypeArgumentsReg, |
| 172 kTempReg, |
| 173 is_instance_lbl, |
| 174 is_not_instance_lbl); |
| 122 } | 175 } |
| 123 | 176 |
| 124 | 177 |
| 125 void FlowGraphCompiler::CheckClassIds(Register class_id_reg, | 178 void FlowGraphCompiler::CheckClassIds(Register class_id_reg, |
| 126 const GrowableArray<intptr_t>& class_ids, | 179 const GrowableArray<intptr_t>& class_ids, |
| 127 Label* is_equal_lbl, | 180 Label* is_equal_lbl, |
| 128 Label* is_not_equal_lbl) { | 181 Label* is_not_equal_lbl) { |
| 129 __ TraceSimMsg("CheckClassIds"); | 182 __ TraceSimMsg("CheckClassIds"); |
| 130 for (intptr_t i = 0; i < class_ids.length(); i++) { | 183 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 131 __ BranchEqual(class_id_reg, class_ids[i], is_equal_lbl); | 184 __ BranchEqual(class_id_reg, class_ids[i], is_equal_lbl); |
| (...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 __ AddImmediate(SP, kDoubleSize); | 1462 __ AddImmediate(SP, kDoubleSize); |
| 1410 } | 1463 } |
| 1411 | 1464 |
| 1412 | 1465 |
| 1413 #undef __ | 1466 #undef __ |
| 1414 | 1467 |
| 1415 | 1468 |
| 1416 } // namespace dart | 1469 } // namespace dart |
| 1417 | 1470 |
| 1418 #endif // defined TARGET_ARCH_MIPS | 1471 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |