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

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

Issue 10381045: Improve type checking, remove unused stub (removed also in x64 in preparation of porting the better… (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 | « runtime/vm/code_generator.cc ('k') | runtime/vm/flow_graph_compiler_x64.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_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 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 // TODO(srdjan) also accept List<Object>. 1438 // TODO(srdjan) also accept List<Object>.
1439 __ CompareObject(ECX, *CoreClass("ObjectArray")); 1439 __ CompareObject(ECX, *CoreClass("ObjectArray"));
1440 __ j(EQUAL, is_instance_lbl); 1440 __ j(EQUAL, is_instance_lbl);
1441 __ CompareObject(ECX, *CoreClass("GrowableObjectArray")); 1441 __ CompareObject(ECX, *CoreClass("GrowableObjectArray"));
1442 __ j(EQUAL, is_instance_lbl); 1442 __ j(EQUAL, is_instance_lbl);
1443 } 1443 }
1444 return 1444 return
1445 GenerateSubtype1TestCacheLookup(node_id, token_index, type_class, 1445 GenerateSubtype1TestCacheLookup(node_id, token_index, type_class,
1446 is_instance_lbl, is_not_instance_lbl); 1446 is_instance_lbl, is_not_instance_lbl);
1447 } 1447 }
1448 // Note that the test below must be synced with the tests in 1448 // If one type argument only, quick check.
1449 // CodeGenerator::UpdateTestCache. 1449 if (type_arguments.Length() == 1) {
1450 // Inline checks for one type argument only. 1450 const AbstractType& tp_argument = AbstractType::ZoneHandle(
1451 if (type_arguments.Length() != 1) { 1451 type_arguments.TypeAt(0));
1452 return SubtypeTestCache::null(); 1452 if (tp_argument.IsType()) {
1453 } 1453 // Malformed type has been caught in the caller chain of this function.
1454 const AbstractType& tp_argument = 1454 ASSERT(tp_argument.HasResolvedTypeClass());
1455 AbstractType::ZoneHandle(type_arguments.TypeAt(0)); 1455 // Check if type argument is dynamic or Object.
1456 if (!tp_argument.IsType()) { 1456 const Type& object_type =
1457 // E.g., it is a TypeParameter. 1457 Type::Handle(Isolate::Current()->object_store()->object_type());
1458 return SubtypeTestCache::null(); 1458 Error& malformed_error = Error::Handle();
1459 } 1459 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) {
1460 // Malformed type has been caught in the caller chain of this function. 1460 // Instance class test only necessary.
1461 ASSERT(tp_argument.HasResolvedTypeClass()); 1461 return GenerateSubtype1TestCacheLookup(
1462 // Check if type argument is dynamic or Object. 1462 node_id,
1463 const Type& object_type = 1463 token_index,
1464 Type::Handle(Isolate::Current()->object_store()->object_type()); 1464 type_class,
1465 Error& malformed_error = Error::Handle(); 1465 is_instance_lbl,
1466 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) { 1466 is_not_instance_lbl);
1467 // Instance class test only necessary. 1467 }
1468 return GenerateSubtype1TestCacheLookup( 1468 }
1469 node_id, token_index, type_class, is_instance_lbl, is_not_instance_lbl);
1470 } 1469 }
1471 const SubtypeTestCache& type_test_cache = 1470 const SubtypeTestCache& type_test_cache =
1472 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 1471 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1473 Label inlined_check, fall_through; 1472 Label inlined_check, fall_through;
1474 const Immediate raw_null = 1473 const Immediate raw_null =
1475 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1474 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1476 __ LoadObject(EDX, type_test_cache); 1475 __ LoadObject(EDX, type_test_cache);
1477 __ pushl(EDX); // Subtype test cache. 1476 __ pushl(EDX); // Subtype test cache.
1478 __ pushl(EAX); // Instance. 1477 __ pushl(EAX); // Instance.
1479 __ pushl(raw_null); // Unused. 1478 __ pushl(raw_null); // Unused.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 // EAX must be preserved! 1605 // EAX must be preserved!
1607 Label fall_through; 1606 Label fall_through;
1608 const bool kPushInstantiator = false; 1607 const bool kPushInstantiator = false;
1609 GenerateInstantiatorTypeArguments(token_index, kPushInstantiator); 1608 GenerateInstantiatorTypeArguments(token_index, kPushInstantiator);
1610 // Type arguments are on stack. 1609 // Type arguments are on stack.
1611 __ popl(EBX); 1610 __ popl(EBX);
1612 // Check if type argument is dynamic. 1611 // Check if type argument is dynamic.
1613 __ cmpl(EBX, raw_null); 1612 __ cmpl(EBX, raw_null);
1614 __ j(EQUAL, is_instance_lbl); 1613 __ j(EQUAL, is_instance_lbl);
1615 1614
1615 // EBX: instantiator type arguments.
1616 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. 1616 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
1617 // We expect that frequently checked objects wull have their type arguments
1618 // converted into instance of TypeArguments.
1617 __ movl(EDX, FieldAddress(EBX, Object::class_offset())); 1619 __ movl(EDX, FieldAddress(EBX, Object::class_offset()));
1618 __ CompareObject(EDX, Object::ZoneHandle(Object::type_arguments_class())); 1620 __ CompareObject(EDX, Object::ZoneHandle(Object::type_arguments_class()));
1619 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1621 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1620 1622
1621 // EBX: Instance of TypeArguments.
1622 __ movl(EDX, 1623 __ movl(EDX,
1623 FieldAddress(EBX, TypeArguments::type_at_offset(type.Index()))); 1624 FieldAddress(EBX, TypeArguments::type_at_offset(type.Index())));
1624 // EDX: concrete type of type. 1625 // EDX: concrete type of type.
1625 // Check if type argument is dynamic. 1626 // Check if type argument is dynamic.
1626 __ CompareObject(EDX, Type::ZoneHandle(Type::DynamicType())); 1627 __ CompareObject(EDX, Type::ZoneHandle(Type::DynamicType()));
1627 __ j(EQUAL, is_instance_lbl); 1628 __ j(EQUAL, is_instance_lbl);
1629 __ cmpl(EDX, raw_null);
1630 __ j(EQUAL, is_instance_lbl);
1628 1631
1629 // Check if the type has type parameters, if not do the class comparison. 1632 // For Smi check quickly against int and num interfaces.
1630 Label not_smi; 1633 Label not_smi;
1631 __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi? 1634 __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi?
1632 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 1635 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1633 // For Smi check quickly against int and num interfaces.
1634 __ CompareObject(EDX, Type::ZoneHandle(Type::IntInterface())); 1636 __ CompareObject(EDX, Type::ZoneHandle(Type::IntInterface()));
1635 __ j(EQUAL, is_instance_lbl); 1637 __ j(EQUAL, is_instance_lbl);
1636 __ CompareObject(EDX, Type::ZoneHandle(Type::NumberInterface())); 1638 __ CompareObject(EDX, Type::ZoneHandle(Type::NumberInterface()));
1637 __ j(EQUAL, is_instance_lbl); 1639 __ j(EQUAL, is_instance_lbl);
1638 __ jmp(&fall_through); 1640 __ jmp(&fall_through);
1639 1641
1640 __ Bind(&not_smi); 1642 __ Bind(&not_smi);
1643 // EBX: instantiator type arguments.
1644 // EAX: instance
1641 // The instantiated type parameter may not be a Type, but could be an 1645 // The instantiated type parameter may not be a Type, but could be an
1642 // InstantiatedType. It is therefore necessary to check its class. 1646 // InstantiatedType. It is therefore necessary to check its class.
1643 __ movl(ECX, FieldAddress(EDX, Object::class_offset())); 1647 const SubtypeTestCache& type_test_cache =
1644 __ CompareObject(ECX, Object::ZoneHandle(Object::type_class())); 1648 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1645 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1649 __ LoadObject(ECX, type_test_cache);
1646 1650 __ pushl(ECX); // Subtype test cache.
1647 __ movl(EDX, FieldAddress(EDX, Type::type_class_offset())); 1651 __ pushl(EAX); // Instance.
1648 __ movl(ECX, FieldAddress(EDX, Class::type_parameters_offset())); 1652 __ pushl(EBX); // Instantator type arguments.
1649 // Check that class of type has no type parameters. 1653 __ call(&StubCode::Subtype3TestCacheLabel());
1654 __ popl(EDX); // Discard type arguments.
1655 __ popl(EAX); // Restore receiver.
1656 __ popl(EDX); // Discard subtype test cache.
1657 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
1650 __ cmpl(ECX, raw_null); 1658 __ cmpl(ECX, raw_null);
1651 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1659 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1652 // EAX has non-parameterized class. 1660 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1653 // Check class equality 1661 __ CompareObject(ECX, bool_true);
1654 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1655 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset()));
1656 __ cmpl(ECX, EDX);
1657 __ j(EQUAL, is_instance_lbl); 1662 __ j(EQUAL, is_instance_lbl);
1658 1663 __ jmp(is_not_instance_lbl);
1659 // We have a non-parameterized class in EDX, compare with class of
1660 // value in EAX. EAX, EDX are preserved in stub.
1661 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1662 __ call(&StubCode::IsRawSubTypeLabel());
1663 // Result in EBX: 1 is raw subtype.
1664 __ cmpl(EBX, Immediate(1));
1665 __ j(EQUAL, is_instance_lbl);
1666
1667 // Test not conclusive.
1668 __ Bind(&fall_through); 1664 __ Bind(&fall_through);
1669 return SubtypeTestCache::null(); 1665 return type_test_cache.raw();
1670 } 1666 }
1671 if (type.IsType()) { 1667 if (type.IsType()) {
1672 Label fall_through; 1668 Label fall_through;
1673 __ testl(EAX, Immediate(kSmiTagMask)); // Is instance Smi? 1669 __ testl(EAX, Immediate(kSmiTagMask)); // Is instance Smi?
1674 __ j(ZERO, is_not_instance_lbl, Assembler::kNearJump); 1670 __ j(ZERO, is_not_instance_lbl, Assembler::kNearJump);
1675 // Uninstantiated type class is known at compile time, but the type 1671 // Uninstantiated type class is known at compile time, but the type
1676 // arguments are determined at runtime by the instantiator. 1672 // arguments are determined at runtime by the instantiator.
1677 const SubtypeTestCache& type_test_cache = 1673 const SubtypeTestCache& type_test_cache =
1678 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 1674 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1679 __ LoadObject(EDX, type_test_cache); 1675 __ LoadObject(EDX, type_test_cache);
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2958 const Error& error = Error::Handle( 2954 const Error& error = Error::Handle(
2959 Parser::FormatError(script, token_index, "Error", format, args)); 2955 Parser::FormatError(script, token_index, "Error", format, args));
2960 va_end(args); 2956 va_end(args);
2961 Isolate::Current()->long_jump_base()->Jump(1, error); 2957 Isolate::Current()->long_jump_base()->Jump(1, error);
2962 UNREACHABLE(); 2958 UNREACHABLE();
2963 } 2959 }
2964 2960
2965 } // namespace dart 2961 } // namespace dart
2966 2962
2967 #endif // defined TARGET_ARCH_IA32 2963 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698