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

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

Issue 10191020: Revert change 6946. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/object.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 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 1278
1279 static const Class* CoreClass(const char* c_name) { 1279 static const Class* CoreClass(const char* c_name) {
1280 const String& class_name = String::Handle(String::NewSymbol(c_name)); 1280 const String& class_name = String::Handle(String::NewSymbol(c_name));
1281 const Class& cls = Class::ZoneHandle(Library::Handle( 1281 const Class& cls = Class::ZoneHandle(Library::Handle(
1282 Library::CoreImplLibrary()).LookupClass(class_name)); 1282 Library::CoreImplLibrary()).LookupClass(class_name));
1283 ASSERT(!cls.IsNull()); 1283 ASSERT(!cls.IsNull());
1284 return &cls; 1284 return &cls;
1285 } 1285 }
1286 1286
1287 1287
1288 // Instance to test is in EAX, test if it is a subtype of type_class.
1289 // The instance may not be a Smi (test before calling this).
1290 // The instance may not be NULL (test before calling this).
1291 // TODO(srdjan): Implement a quicker subtype check, as type test
1292 // arrays can grow too high, but they may be useful when optimizing
1293 // code (type-feedback).
1294 void CodeGenerator::GenerateClassTestCache(intptr_t node_id,
1295 intptr_t token_index,
1296 const Class& type_class,
1297 Label* is_instance_lbl,
1298 Label* is_not_instance_lbl) {
1299 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1300 const Immediate raw_null =
1301 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1302 Label loop, found_in_cache, runtime_call;
1303 // Check immediate equality.
1304 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1305 // ECX: instance class.
1306 __ CompareObject(ECX, type_class);
1307 __ j(EQUAL, is_instance_lbl);
1308
1309 // Check immediate superclass equality.
1310 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset()));
1311 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset()));
1312 __ CompareObject(EDI, type_class);
1313 __ j(EQUAL, is_instance_lbl);
1314
1315 // ECX: instance class.
1316 AddCurrentDescriptor(PcDescriptors::kTypeTest, node_id, token_index);
1317 __ LoadObject(EDX, Array::ZoneHandle(Array::New(2)));
1318 __ addl(EDX, Immediate(Array::data_offset() - kHeapObjectTag));
1319 __ Bind(&loop);
1320 __ movl(EBX, Address(EDX, 0));
1321 __ cmpl(ECX, EBX);
1322 __ j(EQUAL, &found_in_cache, Assembler::kNearJump);
1323 __ addl(EDX, Immediate(kWordSize * 2));
1324 __ cmpl(EBX, raw_null);
1325 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1326 __ jmp(&runtime_call, Assembler::kNearJump);
1327
1328 __ Bind(&found_in_cache);
1329 __ movl(EDX, Address(EDX, kWordSize));
1330 __ CompareObject(EDX, bool_true);
1331 __ j(EQUAL, is_instance_lbl);
1332 __ jmp(is_not_instance_lbl);
1333 __ Bind(&runtime_call);
1334 }
1335
1336
1337 // Inline tests according to the 'type' being tested. Jump to labels 1288 // Inline tests according to the 'type' being tested. Jump to labels
1338 // if we can compute the type-test, otherwise fallthrough. 1289 // if we can compute the type-test, otherwise fallthrough.
1339 // EAX: instance to be tested. 1290 // EAX: instance to be tested.
1340 // Clobbers many registers. 1291 // Clobbers many registers.
1341 void CodeGenerator::GenerateInlineInstanceof(intptr_t node_id, 1292 void CodeGenerator::GenerateInlineInstanceof(intptr_t node_id,
1342 intptr_t token_index, 1293 intptr_t token_index,
1343 const AbstractType& type, 1294 const AbstractType& type,
1344 Label* is_instance_lbl, 1295 Label* is_instance_lbl,
1345 Label* is_not_instance_lbl) { 1296 Label* is_not_instance_lbl) {
1346 if (type.IsInstantiated()) { 1297 if (type.IsInstantiated()) {
1347 const Class& type_class = Class::ZoneHandle(type.type_class()); 1298 const Class& type_class = Class::ZoneHandle(type.type_class());
1348 // A Smi object cannot be the instance of a parameterized class. 1299 // A Smi object cannot be the instance of a parameterized class.
1349 // A class equality check is only applicable with a dst type of a 1300 // A class equality check is only applicable with a dst type of a
1350 // non-parameterized class or with a raw dst type of a parameterized class. 1301 // non-parameterized class or with a raw dst type of a parameterized class.
1351 if (type_class.HasTypeArguments()) { 1302 if (type_class.HasTypeArguments()) {
1352 GenerateInstantiatedTypeWithArgumentsTest(node_id, 1303 GenerateInstantiatedTypeWithArgumentsTest(type,
1353 token_index,
1354 type,
1355 is_instance_lbl, 1304 is_instance_lbl,
1356 is_not_instance_lbl); 1305 is_not_instance_lbl);
1357 // Fall through to runtime call. 1306 // Fall through to runtime call.
1358 } else { 1307 } else {
1359 GenerateInstantiatedTypeNoArgumentsTest(node_id, 1308 GenerateInstantiatedTypeNoArgumentsTest(node_id,
1360 token_index, 1309 token_index,
1361 type, 1310 type,
1362 is_instance_lbl, 1311 is_instance_lbl,
1363 is_not_instance_lbl); 1312 is_not_instance_lbl);
1364 // If test non-conclusive so far, try the inlined type-test cache. 1313 // If test non-conclusive so far, try the inlined type-test cache.
1365 // 'type' is known at compile time. 1314 // 'type' is known at compile time.
1366 GenerateClassTestCache(node_id, token_index, type_class, 1315 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1367 is_instance_lbl, is_not_instance_lbl); 1316 const Immediate raw_null =
1317 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1318 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1319 AddCurrentDescriptor(PcDescriptors::kTypeTest, node_id, token_index);
1320 __ LoadObject(EDX, Array::ZoneHandle(Array::New(2)));
1321 __ addl(EDX, Immediate(Array::data_offset() - kHeapObjectTag));
1322 Label loop, found_in_cache, runtime_call;
1323 __ Bind(&loop);
1324 __ movl(EBX, Address(EDX, 0));
1325 __ cmpl(ECX, EBX);
1326 __ j(EQUAL, &found_in_cache, Assembler::kNearJump);
1327 __ addl(EDX, Immediate(kWordSize * 2));
1328 __ cmpl(EBX, raw_null);
1329 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1330 __ jmp(&runtime_call, Assembler::kNearJump);
1331
1332 __ Bind(&found_in_cache);
1333 __ movl(EDX, Address(EDX, kWordSize));
1334 __ CompareObject(EDX, bool_true);
1335 __ j(EQUAL, is_instance_lbl);
1336 __ jmp(is_not_instance_lbl);
1337 __ Bind(&runtime_call);
1368 } 1338 }
1369 } else { 1339 } else {
1370 GenerateUninstantiatedTypeTest(type, 1340 GenerateUninstantiatedTypeTest(type,
1371 token_index, 1341 token_index,
1372 is_instance_lbl); 1342 is_instance_lbl);
1373 } 1343 }
1374 } 1344 }
1375 1345
1376 1346
1377 // If instanceof type test cannot be performed successfully at compile time and 1347 // If instanceof type test cannot be performed successfully at compile time and
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 __ Bind(&done); 1460 __ Bind(&done);
1491 } 1461 }
1492 1462
1493 1463
1494 // EAX: instance to test. 1464 // EAX: instance to test.
1495 // Clobbers: ECX. 1465 // Clobbers: ECX.
1496 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 1466 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
1497 // type test is conclusive, otherwise fallthrough if a type test could not 1467 // type test is conclusive, otherwise fallthrough if a type test could not
1498 // be completed. 1468 // be completed.
1499 void CodeGenerator::GenerateInstantiatedTypeWithArgumentsTest( 1469 void CodeGenerator::GenerateInstantiatedTypeWithArgumentsTest(
1500 intptr_t node_id,
1501 intptr_t token_index,
1502 const AbstractType& type, 1470 const AbstractType& type,
1503 Label* is_instance_lbl, 1471 Label* is_instance_lbl,
1504 Label* is_not_instance_lbl) { 1472 Label* is_not_instance_lbl) {
1505 ASSERT(type.IsInstantiated()); 1473 ASSERT(type.IsInstantiated());
1506 const Class& type_class = Class::ZoneHandle(type.type_class()); 1474 const Class& type_class = Class::ZoneHandle(type.type_class());
1507 ASSERT(type_class.HasTypeArguments()); 1475 ASSERT(type_class.HasTypeArguments());
1508 // A Smi object cannot be the instance of a parameterized class. 1476 // A Smi object cannot be the instance of a parameterized class.
1509 // A class equality check is only applicable with a dst type of a 1477 // A class equality check is only applicable with a dst type of a
1510 // non-parameterized class or with a raw dst type of a parameterized class. 1478 // non-parameterized class or with a raw dst type of a parameterized class.
1511 __ testl(EAX, Immediate(kSmiTagMask)); 1479 __ testl(EAX, Immediate(kSmiTagMask));
1512 __ j(ZERO, is_not_instance_lbl); 1480 __ j(ZERO, is_not_instance_lbl);
1513 const AbstractTypeArguments& type_arguments = 1481 const AbstractTypeArguments& type_arguments =
1514 AbstractTypeArguments::Handle(type.arguments()); 1482 AbstractTypeArguments::Handle(type.arguments());
1515 const bool is_raw_type = type_arguments.IsNull() || 1483 const bool is_raw_type = type_arguments.IsNull() ||
1516 type_arguments.IsRaw(type_arguments.Length()); 1484 type_arguments.IsRaw(type_arguments.Length());
1517 if (is_raw_type) { 1485 if (is_raw_type) {
1518 // Dynamic type argument, check only classes. 1486 // Dynamic type argument, check only classes.
1519 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1487 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1520 if (type.IsListInterface()) { 1488 if (type.IsListInterface()) {
1521 // TODO(srdjan) also accept List<Object>. 1489 // TODO(srdjan) also accept List<Object>.
1522 __ CompareObject(ECX, *CoreClass("ObjectArray")); 1490 __ CompareObject(ECX, *CoreClass("ObjectArray"));
1523 __ j(EQUAL, is_instance_lbl); 1491 __ j(EQUAL, is_instance_lbl);
1524 __ CompareObject(ECX, *CoreClass("GrowableObjectArray")); 1492 __ CompareObject(ECX, *CoreClass("GrowableObjectArray"));
1525 __ j(EQUAL, is_instance_lbl); 1493 __ j(EQUAL, is_instance_lbl);
1494 } else if (!type_class.is_interface()) {
1495 __ CompareObject(ECX, type_class);
1496 __ j(EQUAL, is_instance_lbl);
1526 } 1497 }
1527 GenerateClassTestCache(node_id, token_index, type_class, 1498 } else {
1528 is_instance_lbl, is_not_instance_lbl); 1499 // TODO(srdjan): do type test on type arguments.
1529 } 1500 }
1530 // TODO(srdjan): do type test on type arguments.
1531 // Fall through if type test is not conclusive 1501 // Fall through if type test is not conclusive
1532 } 1502 }
1533 1503
1534 1504
1535 // EAX: instance to test. 1505 // EAX: instance to test.
1536 // Clobbers: EBX, ECX, EDX. 1506 // Clobbers: EBX, ECX, EDX.
1537 void CodeGenerator::GenerateInstantiatedTypeNoArgumentsTest( 1507 void CodeGenerator::GenerateInstantiatedTypeNoArgumentsTest(
1538 intptr_t node_id, 1508 intptr_t node_id,
1539 intptr_t token_index, 1509 intptr_t token_index,
1540 const AbstractType& type, 1510 const AbstractType& type,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 // InstantiatedType. It is therefore necessary to check its class. 1647 // InstantiatedType. It is therefore necessary to check its class.
1678 __ movl(ECX, FieldAddress(EDX, Object::class_offset())); 1648 __ movl(ECX, FieldAddress(EDX, Object::class_offset()));
1679 __ CompareObject(ECX, Object::ZoneHandle(Object::type_class())); 1649 __ CompareObject(ECX, Object::ZoneHandle(Object::type_class()));
1680 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1650 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1681 1651
1682 __ movl(EDX, FieldAddress(EDX, Type::type_class_offset())); 1652 __ movl(EDX, FieldAddress(EDX, Type::type_class_offset()));
1683 __ movl(ECX, FieldAddress(EDX, Class::type_parameters_offset())); 1653 __ movl(ECX, FieldAddress(EDX, Class::type_parameters_offset()));
1684 // Check that class of type has no type parameters. 1654 // Check that class of type has no type parameters.
1685 __ cmpl(ECX, raw_null); 1655 __ cmpl(ECX, raw_null);
1686 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1656 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1687 // EAX has non-parameterized class.
1688 // Check class equality
1689 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1690 __ movl(ECX, FieldAddress(ECX, Type::Type::type_class_offset()));
1691 __ cmpl(ECX, EDX);
1692 __ j(EQUAL, is_instance_lbl);
1693
1694 // We have a non-parameterized class in EDX, compare with class of 1657 // We have a non-parameterized class in EDX, compare with class of
1695 // value in EAX. EAX, EDX are preserved in stub. 1658 // value in EAX. EAX, EDX are preserved in stub.
1696 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1697 __ call(&StubCode::IsRawSubTypeLabel()); 1659 __ call(&StubCode::IsRawSubTypeLabel());
1698 // Result in EBX: 1 is raw subtype. 1660 // Result in EBX: 1 is raw subtype.
1699 __ cmpl(EBX, Immediate(1)); 1661 __ cmpl(EBX, Immediate(1));
1700 __ j(EQUAL, is_instance_lbl); 1662 __ j(EQUAL, is_instance_lbl);
1701 1663
1702 // Test not conclusive. 1664 // Test not conclusive.
1703 __ Bind(&fall_through); 1665 __ Bind(&fall_through);
1704 } 1666 }
1705 } 1667 }
1706 1668
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 const Error& error = Error::Handle( 2881 const Error& error = Error::Handle(
2920 Parser::FormatError(script, token_index, "Error", format, args)); 2882 Parser::FormatError(script, token_index, "Error", format, args));
2921 va_end(args); 2883 va_end(args);
2922 Isolate::Current()->long_jump_base()->Jump(1, error); 2884 Isolate::Current()->long_jump_base()->Jump(1, error);
2923 UNREACHABLE(); 2885 UNREACHABLE();
2924 } 2886 }
2925 2887
2926 } // namespace dart 2888 } // namespace dart
2927 2889
2928 #endif // defined TARGET_ARCH_IA32 2890 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698