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

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

Issue 10414026: Started porting inlined type checks to x64 (will be the future pattern for other architectures). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler_x64.h » ('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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 intptr_t node_id, 1225 intptr_t node_id,
1226 intptr_t token_index, 1226 intptr_t token_index,
1227 const Class& type_class, 1227 const Class& type_class,
1228 Label* is_instance_lbl, 1228 Label* is_instance_lbl,
1229 Label* is_not_instance_lbl) { 1229 Label* is_not_instance_lbl) {
1230 const SubtypeTestCache& type_test_cache = 1230 const SubtypeTestCache& type_test_cache =
1231 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 1231 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1232 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1232 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1233 const Immediate raw_null = 1233 const Immediate raw_null =
1234 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1234 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1235 Label loop, found_in_cache, runtime_call;
1236 // Check immediate equality. 1235 // Check immediate equality.
1237 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1236 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1238 // ECX: instance class. 1237 // ECX: instance class.
1239 __ CompareObject(ECX, type_class); 1238 __ CompareObject(ECX, type_class);
1240 __ j(EQUAL, is_instance_lbl); 1239 __ j(EQUAL, is_instance_lbl);
1241 1240
1242 // Check immediate superclass equality. 1241 // Check immediate superclass equality.
1243 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset())); 1242 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset()));
1244 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset())); 1243 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset()));
1245 __ CompareObject(EDI, type_class); 1244 __ CompareObject(EDI, type_class);
1246 __ j(EQUAL, is_instance_lbl); 1245 __ j(EQUAL, is_instance_lbl);
1247 1246
1248 __ LoadObject(EDX, type_test_cache); 1247 __ LoadObject(EDX, type_test_cache);
1249 __ pushl(EDX); // Cache array. 1248 __ pushl(EDX); // Cache array.
1250 __ pushl(EAX); // Instance. 1249 __ pushl(EAX); // Instance.
1251 __ pushl(raw_null); // Unused 1250 __ pushl(raw_null); // Unused
1252 __ call(&StubCode::Subtype1TestCacheLabel()); 1251 __ call(&StubCode::Subtype1TestCacheLabel());
1253 __ popl(EAX); // Discard. 1252 __ popl(EAX); // Discard.
1254 __ popl(EAX); // Restore receiver. 1253 __ popl(EAX); // Restore receiver.
1255 __ popl(EDX); // Discard. 1254 __ popl(EDX); // Discard.
1256 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False. 1255 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
1257 1256
1257 Label runtime_call;
1258 __ cmpl(ECX, raw_null); 1258 __ cmpl(ECX, raw_null);
1259 __ j(EQUAL, &runtime_call, Assembler::kNearJump); 1259 __ j(EQUAL, &runtime_call, Assembler::kNearJump);
1260 __ CompareObject(ECX, bool_true); 1260 __ CompareObject(ECX, bool_true);
1261 __ j(EQUAL, is_instance_lbl); 1261 __ j(EQUAL, is_instance_lbl);
1262 __ jmp(is_not_instance_lbl); 1262 __ jmp(is_not_instance_lbl);
1263 __ Bind(&runtime_call); 1263 __ Bind(&runtime_call);
1264 return type_test_cache.raw(); 1264 return type_test_cache.raw();
1265 } 1265 }
1266 1266
1267 1267
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 // non-parameterized class or with a raw dst type of a parameterized class. 1448 // non-parameterized class or with a raw dst type of a parameterized class.
1449 __ testl(EAX, Immediate(kSmiTagMask)); 1449 __ testl(EAX, Immediate(kSmiTagMask));
1450 __ j(ZERO, is_not_instance_lbl); 1450 __ j(ZERO, is_not_instance_lbl);
1451 const AbstractTypeArguments& type_arguments = 1451 const AbstractTypeArguments& type_arguments =
1452 AbstractTypeArguments::ZoneHandle(type.arguments()); 1452 AbstractTypeArguments::ZoneHandle(type.arguments());
1453 const bool is_raw_type = type_arguments.IsNull() || 1453 const bool is_raw_type = type_arguments.IsNull() ||
1454 type_arguments.IsRaw(type_arguments.Length()); 1454 type_arguments.IsRaw(type_arguments.Length());
1455 if (is_raw_type) { 1455 if (is_raw_type) {
1456 // Dynamic type argument, check only classes. 1456 // Dynamic type argument, check only classes.
1457 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1457 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1458 if (!type_class.is_interface()) {
1459 __ CompareObject(ECX, type_class);
1460 __ j(EQUAL, is_instance_lbl);
1461 }
1458 if (type.IsListInterface()) { 1462 if (type.IsListInterface()) {
1459 // TODO(srdjan) also accept List<Object>. 1463 // TODO(srdjan) also accept List<Object>.
1460 __ CompareObject(ECX, *CoreClass("ObjectArray")); 1464 __ CompareObject(ECX, *CoreClass("ObjectArray"));
1461 __ j(EQUAL, is_instance_lbl); 1465 __ j(EQUAL, is_instance_lbl);
1462 __ CompareObject(ECX, *CoreClass("GrowableObjectArray")); 1466 __ CompareObject(ECX, *CoreClass("GrowableObjectArray"));
1463 __ j(EQUAL, is_instance_lbl); 1467 __ j(EQUAL, is_instance_lbl);
1464 } 1468 }
1465 return 1469 return
1466 GenerateSubtype1TestCacheLookup(node_id, token_index, type_class, 1470 GenerateSubtype1TestCacheLookup(node_id, token_index, type_class,
1467 is_instance_lbl, is_not_instance_lbl); 1471 is_instance_lbl, is_not_instance_lbl);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 1550
1547 // Checking against interface. 1551 // Checking against interface.
1548 // However, for specific core library interfaces, we can check for 1552 // However, for specific core library interfaces, we can check for
1549 // specific core library classes. 1553 // specific core library classes.
1550 if (type.IsBoolInterface()) { 1554 if (type.IsBoolInterface()) {
1551 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1555 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1552 const Class& bool_class = Class::ZoneHandle( 1556 const Class& bool_class = Class::ZoneHandle(
1553 Isolate::Current()->object_store()->bool_class()); 1557 Isolate::Current()->object_store()->bool_class());
1554 __ CompareObject(ECX, bool_class); 1558 __ CompareObject(ECX, bool_class);
1555 __ j(EQUAL, is_instance_lbl); 1559 __ j(EQUAL, is_instance_lbl);
1560 __ jmp(is_not_instance_lbl);
1556 return; 1561 return;
1557 } 1562 }
1558 // If type is an interface, we can skip the class equality check, 1563 // If type is an interface, we can skip the class equality check,
1559 // because instances cannot be of an interface type. 1564 // because instances cannot be of an interface type.
1560 if (!type_class.is_interface()) { 1565 if (!type_class.is_interface()) {
1561 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1566 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1562 __ CompareObject(ECX, type_class); 1567 __ CompareObject(ECX, type_class);
1563 __ j(EQUAL, is_instance_lbl); 1568 __ j(EQUAL, is_instance_lbl);
1564 } 1569 }
1565 if (type.IsSubtypeOf( 1570 if (type.IsSubtypeOf(
1566 Type::Handle(Type::NumberInterface()), &malformed_error)) { 1571 Type::Handle(Type::NumberInterface()), &malformed_error)) {
1567 // Custom checking for numbers (Smi, Mint, Bigint and Double) 1572 // Custom checking for numbers (Smi, Mint, Bigint and Double)
1568 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1573 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1569 if (type.IsIntInterface() || type.IsNumberInterface()) { 1574 if (type.IsIntInterface() || type.IsNumberInterface()) {
1570 // We already checked for Smi above. 1575 // We already checked for Smi above.
1571 const Class& mint_class = Class::ZoneHandle( 1576 const Class& mint_class = Class::ZoneHandle(
1572 Isolate::Current()->object_store()->mint_class()); 1577 Isolate::Current()->object_store()->mint_class());
1573 const Class& bigint_class = Class::ZoneHandle( 1578 const Class& bigint_class = Class::ZoneHandle(
1574 Isolate::Current()->object_store()->bigint_class()); 1579 Isolate::Current()->object_store()->bigint_class());
1575 __ CompareObject(ECX, mint_class); 1580 __ CompareObject(ECX, mint_class);
1576 __ j(EQUAL, is_instance_lbl); 1581 __ j(EQUAL, is_instance_lbl);
1577 __ CompareObject(ECX, bigint_class); 1582 __ CompareObject(ECX, bigint_class);
1578 __ j(EQUAL, is_instance_lbl); 1583 __ j(EQUAL, is_instance_lbl);
1584 if (type.IsIntInterface()) {
1585 __ jmp(is_not_instance_lbl);
1586 }
1579 } 1587 }
1580 if (type.IsDoubleInterface() || type.IsNumberInterface()) { 1588 if (type.IsDoubleInterface() || type.IsNumberInterface()) {
1581 const Class& double_class = Class::ZoneHandle( 1589 const Class& double_class = Class::ZoneHandle(
1582 Isolate::Current()->object_store()->double_class()); 1590 Isolate::Current()->object_store()->double_class());
1583 __ CompareObject(ECX, double_class); 1591 __ CompareObject(ECX, double_class);
1584 __ j(EQUAL, is_instance_lbl); 1592 __ j(EQUAL, is_instance_lbl);
1593 __ jmp(is_not_instance_lbl);
1585 } 1594 }
1586 } else if (type.IsStringInterface()) { 1595 } else if (type.IsStringInterface()) {
1587 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1596 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1588 const Class& one_byte_string_class = Class::ZoneHandle( 1597 const Class& one_byte_string_class = Class::ZoneHandle(
1589 Isolate::Current()->object_store()->one_byte_string_class()); 1598 Isolate::Current()->object_store()->one_byte_string_class());
1590 const Class& two_byte_string_class = Class::ZoneHandle( 1599 const Class& two_byte_string_class = Class::ZoneHandle(
1591 Isolate::Current()->object_store()->two_byte_string_class()); 1600 Isolate::Current()->object_store()->two_byte_string_class());
1592 const Class& four_byte_string_class = Class::ZoneHandle( 1601 const Class& four_byte_string_class = Class::ZoneHandle(
1593 Isolate::Current()->object_store()->four_byte_string_class()); 1602 Isolate::Current()->object_store()->four_byte_string_class());
1594 __ CompareObject(ECX, one_byte_string_class); 1603 __ CompareObject(ECX, one_byte_string_class);
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after
2974 const Error& error = Error::Handle( 2983 const Error& error = Error::Handle(
2975 Parser::FormatError(script, token_index, "Error", format, args)); 2984 Parser::FormatError(script, token_index, "Error", format, args));
2976 va_end(args); 2985 va_end(args);
2977 Isolate::Current()->long_jump_base()->Jump(1, error); 2986 Isolate::Current()->long_jump_base()->Jump(1, error);
2978 UNREACHABLE(); 2987 UNREACHABLE();
2979 } 2988 }
2980 2989
2981 } // namespace dart 2990 } // namespace dart
2982 2991
2983 #endif // defined TARGET_ARCH_IA32 2992 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698