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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 11280230: Optimize checked mode asserts with uninstantiated types and known constant type-arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // type test is conclusive, otherwise fallthrough if a type test could not 111 // type test is conclusive, otherwise fallthrough if a type test could not
112 // be completed. 112 // be completed.
113 // RAX: instance (must survive). 113 // RAX: instance (must survive).
114 // Clobbers R10. 114 // Clobbers R10.
115 RawSubtypeTestCache* 115 RawSubtypeTestCache*
116 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 116 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
117 intptr_t token_pos, 117 intptr_t token_pos,
118 const AbstractType& type, 118 const AbstractType& type,
119 Label* is_instance_lbl, 119 Label* is_instance_lbl,
120 Label* is_not_instance_lbl) { 120 Label* is_not_instance_lbl) {
121 __ Comment("InstantiatedTypeWithArgumentsTest");
121 ASSERT(type.IsInstantiated()); 122 ASSERT(type.IsInstantiated());
122 const Class& type_class = Class::ZoneHandle(type.type_class()); 123 const Class& type_class = Class::ZoneHandle(type.type_class());
123 ASSERT(type_class.HasTypeArguments()); 124 ASSERT(type_class.HasTypeArguments());
124 const Register kInstanceReg = RAX; 125 const Register kInstanceReg = RAX;
125 // A Smi object cannot be the instance of a parameterized class. 126 // A Smi object cannot be the instance of a parameterized class.
126 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 127 __ testq(kInstanceReg, Immediate(kSmiTagMask));
127 __ j(ZERO, is_not_instance_lbl); 128 __ j(ZERO, is_not_instance_lbl);
128 const AbstractTypeArguments& type_arguments = 129 const AbstractTypeArguments& type_arguments =
129 AbstractTypeArguments::ZoneHandle(type.arguments()); 130 AbstractTypeArguments::ZoneHandle(type.arguments());
130 const bool is_raw_type = type_arguments.IsNull() || 131 const bool is_raw_type = type_arguments.IsNull() ||
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 // Testing against an instantiated type with no arguments, without 188 // Testing against an instantiated type with no arguments, without
188 // SubtypeTestCache. 189 // SubtypeTestCache.
189 // RAX: instance to test against (preserved). 190 // RAX: instance to test against (preserved).
190 // Clobbers R10, R13. 191 // Clobbers R10, R13.
191 // Returns true if there is a fallthrough. 192 // Returns true if there is a fallthrough.
192 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 193 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
193 intptr_t token_pos, 194 intptr_t token_pos,
194 const AbstractType& type, 195 const AbstractType& type,
195 Label* is_instance_lbl, 196 Label* is_instance_lbl,
196 Label* is_not_instance_lbl) { 197 Label* is_not_instance_lbl) {
198 __ Comment("InstantiatedTypeNoArgumentsTest");
197 ASSERT(type.IsInstantiated()); 199 ASSERT(type.IsInstantiated());
198 const Class& type_class = Class::Handle(type.type_class()); 200 const Class& type_class = Class::Handle(type.type_class());
199 ASSERT(!type_class.HasTypeArguments()); 201 ASSERT(!type_class.HasTypeArguments());
200 202
201 const Register kInstanceReg = RAX; 203 const Register kInstanceReg = RAX;
202 Label compare_classes; 204 Label compare_classes;
203 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 205 __ testq(kInstanceReg, Immediate(kSmiTagMask));
204 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); 206 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump);
205 // Instance is Smi, check directly. 207 // Instance is Smi, check directly.
206 const Class& smi_class = Class::Handle(Smi::Class()); 208 const Class& smi_class = Class::Handle(Smi::Class());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // Clobbers R10, R13. 263 // Clobbers R10, R13.
262 // Immediate class test already done. 264 // Immediate class test already done.
263 // TODO(srdjan): Implement a quicker subtype check, as type test 265 // TODO(srdjan): Implement a quicker subtype check, as type test
264 // arrays can grow too high, but they may be useful when optimizing 266 // arrays can grow too high, but they may be useful when optimizing
265 // code (type-feedback). 267 // code (type-feedback).
266 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 268 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
267 intptr_t token_pos, 269 intptr_t token_pos,
268 const Class& type_class, 270 const Class& type_class,
269 Label* is_instance_lbl, 271 Label* is_instance_lbl,
270 Label* is_not_instance_lbl) { 272 Label* is_not_instance_lbl) {
273 __ Comment("Subtype1TestCacheLookup");
271 const Register kInstanceReg = RAX; 274 const Register kInstanceReg = RAX;
272 __ LoadClass(R10, kInstanceReg); 275 __ LoadClass(R10, kInstanceReg);
273 // R10: instance class. 276 // R10: instance class.
274 // Check immediate superclass equality. 277 // Check immediate superclass equality.
275 __ movq(R13, FieldAddress(R10, Class::super_type_offset())); 278 __ movq(R13, FieldAddress(R10, Class::super_type_offset()));
276 __ movq(R13, FieldAddress(R13, Type::type_class_offset())); 279 __ movq(R13, FieldAddress(R13, Type::type_class_offset()));
277 __ CompareObject(R13, type_class); 280 __ CompareObject(R13, type_class);
278 __ j(EQUAL, is_instance_lbl); 281 __ j(EQUAL, is_instance_lbl);
279 282
280 const Register kTypeArgumentsReg = kNoRegister; 283 const Register kTypeArgumentsReg = kNoRegister;
281 const Register kTempReg = R10; 284 const Register kTempReg = R10;
282 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 285 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
283 kInstanceReg, 286 kInstanceReg,
284 kTypeArgumentsReg, 287 kTypeArgumentsReg,
285 kTempReg, 288 kTempReg,
286 is_instance_lbl, 289 is_instance_lbl,
287 is_not_instance_lbl); 290 is_not_instance_lbl);
288 } 291 }
289 292
290 293
291 // Generates inlined check if 'type' is a type parameter or type itsef 294 // Generates inlined check if 'type' is a type parameter or type itsef
292 // RAX: instance (preserved). 295 // RAX: instance (preserved).
293 // Clobbers RDI, RDX, R10. 296 // Clobbers RDI, RDX, R10.
294 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 297 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
295 intptr_t token_pos, 298 intptr_t token_pos,
296 const AbstractType& type, 299 const AbstractType& type,
297 Label* is_instance_lbl, 300 Label* is_instance_lbl,
298 Label* is_not_instance_lbl) { 301 Label* is_not_instance_lbl) {
302 __ Comment("UninstantiatedTypeTest");
299 ASSERT(!type.IsInstantiated()); 303 ASSERT(!type.IsInstantiated());
300 // Skip check if destination is a dynamic type. 304 // Skip check if destination is a dynamic type.
301 const Immediate raw_null = 305 const Immediate raw_null =
302 Immediate(reinterpret_cast<intptr_t>(Object::null())); 306 Immediate(reinterpret_cast<intptr_t>(Object::null()));
303 if (type.IsTypeParameter()) { 307 if (type.IsTypeParameter()) {
304 const TypeParameter& type_param = TypeParameter::Cast(type); 308 const TypeParameter& type_param = TypeParameter::Cast(type);
305 // Load instantiator (or null) and instantiator type arguments on stack. 309 // Load instantiator (or null) and instantiator type arguments on stack.
306 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 310 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
307 // RDX: instantiator type arguments. 311 // RDX: instantiator type arguments.
308 // Check if type argument is dynamic. 312 // Check if type argument is dynamic.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // Returns: 384 // Returns:
381 // - preserved instance in RAX and optional instantiator type arguments in RDX. 385 // - preserved instance in RAX and optional instantiator type arguments in RDX.
382 // Note that this inlined code must be followed by the runtime_call code, as it 386 // Note that this inlined code must be followed by the runtime_call code, as it
383 // may fall through to it. Otherwise, this inline code will jump to the label 387 // may fall through to it. Otherwise, this inline code will jump to the label
384 // is_instance or to the label is_not_instance. 388 // is_instance or to the label is_not_instance.
385 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 389 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
386 intptr_t token_pos, 390 intptr_t token_pos,
387 const AbstractType& type, 391 const AbstractType& type,
388 Label* is_instance_lbl, 392 Label* is_instance_lbl,
389 Label* is_not_instance_lbl) { 393 Label* is_not_instance_lbl) {
394 __ Comment("InlineInstanceof");
390 if (type.IsVoidType()) { 395 if (type.IsVoidType()) {
391 // A non-null value is returned from a void function, which will result in a 396 // A non-null value is returned from a void function, which will result in a
392 // type error. A null value is handled prior to executing this inline code. 397 // type error. A null value is handled prior to executing this inline code.
393 return SubtypeTestCache::null(); 398 return SubtypeTestCache::null();
394 } 399 }
395 if (type.IsInstantiated()) { 400 if (type.IsInstantiated()) {
396 const Class& type_class = Class::ZoneHandle(type.type_class()); 401 const Class& type_class = Class::ZoneHandle(type.type_class());
397 // A Smi object cannot be the instance of a parameterized class. 402 // A Smi object cannot be the instance of a parameterized class.
398 // A class equality check is only applicable with a dst type of a 403 // A class equality check is only applicable with a dst type of a
399 // non-parameterized class or with a raw dst type of a parameterized class. 404 // non-parameterized class or with a raw dst type of a parameterized class.
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1382 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1378 __ Exchange(mem1, mem2); 1383 __ Exchange(mem1, mem2);
1379 } 1384 }
1380 1385
1381 1386
1382 #undef __ 1387 #undef __
1383 1388
1384 } // namespace dart 1389 } // namespace dart
1385 1390
1386 #endif // defined TARGET_ARCH_X64 1391 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698