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

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
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_optimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 // Testing against an instantiated type with no arguments, without 186 // Testing against an instantiated type with no arguments, without
186 // SubtypeTestCache. 187 // SubtypeTestCache.
187 // RAX: instance to test against (preserved). 188 // RAX: instance to test against (preserved).
188 // Clobbers R10, R13. 189 // Clobbers R10, R13.
189 // Returns true if there is a fallthrough. 190 // Returns true if there is a fallthrough.
190 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 191 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
191 intptr_t token_pos, 192 intptr_t token_pos,
192 const AbstractType& type, 193 const AbstractType& type,
193 Label* is_instance_lbl, 194 Label* is_instance_lbl,
194 Label* is_not_instance_lbl) { 195 Label* is_not_instance_lbl) {
196 __ Comment("InstantiatedTypeNoArgumentsTest");
195 ASSERT(type.IsInstantiated()); 197 ASSERT(type.IsInstantiated());
196 const Class& type_class = Class::Handle(type.type_class()); 198 const Class& type_class = Class::Handle(type.type_class());
197 ASSERT(!type_class.HasTypeArguments()); 199 ASSERT(!type_class.HasTypeArguments());
198 200
199 const Register kInstanceReg = RAX; 201 const Register kInstanceReg = RAX;
200 Label compare_classes; 202 Label compare_classes;
201 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 203 __ testq(kInstanceReg, Immediate(kSmiTagMask));
202 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); 204 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump);
203 // Instance is Smi, check directly. 205 // Instance is Smi, check directly.
204 const Class& smi_class = Class::Handle(Smi::Class()); 206 const Class& smi_class = Class::Handle(Smi::Class());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 // Clobbers R10, R13. 258 // Clobbers R10, R13.
257 // Immediate class test already done. 259 // Immediate class test already done.
258 // TODO(srdjan): Implement a quicker subtype check, as type test 260 // TODO(srdjan): Implement a quicker subtype check, as type test
259 // arrays can grow too high, but they may be useful when optimizing 261 // arrays can grow too high, but they may be useful when optimizing
260 // code (type-feedback). 262 // code (type-feedback).
261 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 263 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
262 intptr_t token_pos, 264 intptr_t token_pos,
263 const Class& type_class, 265 const Class& type_class,
264 Label* is_instance_lbl, 266 Label* is_instance_lbl,
265 Label* is_not_instance_lbl) { 267 Label* is_not_instance_lbl) {
268 __ Comment("Subtype1TestCacheLookup");
266 const Register kInstanceReg = RAX; 269 const Register kInstanceReg = RAX;
267 __ LoadClass(R10, kInstanceReg); 270 __ LoadClass(R10, kInstanceReg);
268 // R10: instance class. 271 // R10: instance class.
269 // Check immediate superclass equality. 272 // Check immediate superclass equality.
270 __ movq(R13, FieldAddress(R10, Class::super_type_offset())); 273 __ movq(R13, FieldAddress(R10, Class::super_type_offset()));
271 __ movq(R13, FieldAddress(R13, Type::type_class_offset())); 274 __ movq(R13, FieldAddress(R13, Type::type_class_offset()));
272 __ CompareObject(R13, type_class); 275 __ CompareObject(R13, type_class);
273 __ j(EQUAL, is_instance_lbl); 276 __ j(EQUAL, is_instance_lbl);
274 277
275 const Register kTypeArgumentsReg = kNoRegister; 278 const Register kTypeArgumentsReg = kNoRegister;
276 const Register kTempReg = R10; 279 const Register kTempReg = R10;
277 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 280 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
278 kInstanceReg, 281 kInstanceReg,
279 kTypeArgumentsReg, 282 kTypeArgumentsReg,
280 kTempReg, 283 kTempReg,
281 is_instance_lbl, 284 is_instance_lbl,
282 is_not_instance_lbl); 285 is_not_instance_lbl);
283 } 286 }
284 287
285 288
286 // Generates inlined check if 'type' is a type parameter or type itsef 289 // Generates inlined check if 'type' is a type parameter or type itsef
287 // RAX: instance (preserved). 290 // RAX: instance (preserved).
288 // Clobbers RDI, RDX, R10. 291 // Clobbers RDI, RDX, R10.
289 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 292 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
290 intptr_t token_pos, 293 intptr_t token_pos,
291 const AbstractType& type, 294 const AbstractType& type,
292 Label* is_instance_lbl, 295 Label* is_instance_lbl,
293 Label* is_not_instance_lbl) { 296 Label* is_not_instance_lbl) {
297 __ Comment("UninstantiatedTypeTest");
294 ASSERT(!type.IsInstantiated()); 298 ASSERT(!type.IsInstantiated());
295 // Skip check if destination is a dynamic type. 299 // Skip check if destination is a dynamic type.
296 const Immediate raw_null = 300 const Immediate raw_null =
297 Immediate(reinterpret_cast<intptr_t>(Object::null())); 301 Immediate(reinterpret_cast<intptr_t>(Object::null()));
298 if (type.IsTypeParameter()) { 302 if (type.IsTypeParameter()) {
299 const TypeParameter& type_param = TypeParameter::Cast(type); 303 const TypeParameter& type_param = TypeParameter::Cast(type);
300 // Load instantiator (or null) and instantiator type arguments on stack. 304 // Load instantiator (or null) and instantiator type arguments on stack.
301 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 305 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
302 // RDX: instantiator type arguments. 306 // RDX: instantiator type arguments.
303 // Check if type argument is dynamic. 307 // Check if type argument is dynamic.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // Returns: 379 // Returns:
376 // - preserved instance in RAX and optional instantiator type arguments in RDX. 380 // - preserved instance in RAX and optional instantiator type arguments in RDX.
377 // Note that this inlined code must be followed by the runtime_call code, as it 381 // Note that this inlined code must be followed by the runtime_call code, as it
378 // may fall through to it. Otherwise, this inline code will jump to the label 382 // may fall through to it. Otherwise, this inline code will jump to the label
379 // is_instance or to the label is_not_instance. 383 // is_instance or to the label is_not_instance.
380 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 384 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
381 intptr_t token_pos, 385 intptr_t token_pos,
382 const AbstractType& type, 386 const AbstractType& type,
383 Label* is_instance_lbl, 387 Label* is_instance_lbl,
384 Label* is_not_instance_lbl) { 388 Label* is_not_instance_lbl) {
389 __ Comment("InlineInstanceof");
385 if (type.IsVoidType()) { 390 if (type.IsVoidType()) {
386 // A non-null value is returned from a void function, which will result in a 391 // A non-null value is returned from a void function, which will result in a
387 // type error. A null value is handled prior to executing this inline code. 392 // type error. A null value is handled prior to executing this inline code.
388 return SubtypeTestCache::null(); 393 return SubtypeTestCache::null();
389 } 394 }
390 if (TypeCheckAsClassEquality(type)) { 395 if (TypeCheckAsClassEquality(type)) {
391 const intptr_t type_cid = Class::Handle(type.type_class()).id(); 396 const intptr_t type_cid = Class::Handle(type.type_class()).id();
392 const Register kInstanceReg = RAX; 397 const Register kInstanceReg = RAX;
393 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 398 __ testq(kInstanceReg, Immediate(kSmiTagMask));
394 if (type_cid == kSmiCid) { 399 if (type_cid == kSmiCid) {
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1409 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1405 __ Exchange(mem1, mem2); 1410 __ Exchange(mem1, mem2);
1406 } 1411 }
1407 1412
1408 1413
1409 #undef __ 1414 #undef __
1410 1415
1411 } // namespace dart 1416 } // namespace dart
1412 1417
1413 #endif // defined TARGET_ARCH_X64 1418 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698