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

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

Issue 10317026: Inline type checks for complex uninstantiated types, e.g., List<T>. (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
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 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } 787 }
788 ASSERT(function.context_scope() != ContextScope::null()); 788 ASSERT(function.context_scope() != ContextScope::null());
789 789
790 // The function type of a closure may have type arguments. In that case, pass 790 // The function type of a closure may have type arguments. In that case, pass
791 // the type arguments of the instantiator. 791 // the type arguments of the instantiator.
792 const Class& cls = Class::Handle(function.signature_class()); 792 const Class& cls = Class::Handle(function.signature_class());
793 ASSERT(!cls.IsNull()); 793 ASSERT(!cls.IsNull());
794 const bool requires_type_arguments = cls.HasTypeArguments(); 794 const bool requires_type_arguments = cls.HasTypeArguments();
795 if (requires_type_arguments) { 795 if (requires_type_arguments) {
796 ASSERT(!function.IsImplicitStaticClosureFunction()); 796 ASSERT(!function.IsImplicitStaticClosureFunction());
797 GenerateInstantiatorTypeArguments(node->token_index()); 797 GenerateInstantiatorTypeArguments(node->token_index(), false);
regis 2012/05/04 21:53:39 Document what false means.
srdjan 2012/05/04 23:01:58 Done.
798 } 798 }
799 const Code& stub = Code::Handle( 799 const Code& stub = Code::Handle(
800 StubCode::GetAllocationStubForClosure(function)); 800 StubCode::GetAllocationStubForClosure(function));
801 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 801 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
802 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); 802 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
803 if (requires_type_arguments) { 803 if (requires_type_arguments) {
804 __ popl(ECX); // Pop type arguments. 804 __ popl(ECX); // Pop type arguments.
805 } 805 }
806 if (function.IsImplicitInstanceClosureFunction()) { 806 if (function.IsImplicitInstanceClosureFunction()) {
807 __ popl(ECX); // Pop receiver. 807 __ popl(ECX); // Pop receiver.
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 type, 1271 type,
1272 is_instance_lbl, 1272 is_instance_lbl,
1273 is_not_instance_lbl); 1273 is_not_instance_lbl);
1274 // If test non-conclusive so far, try the inlined type-test cache. 1274 // If test non-conclusive so far, try the inlined type-test cache.
1275 // 'type' is known at compile time. 1275 // 'type' is known at compile time.
1276 return GenerateSubtype1TestCacheLookup( 1276 return GenerateSubtype1TestCacheLookup(
1277 node_id, token_index, type_class, 1277 node_id, token_index, type_class,
1278 is_instance_lbl, is_not_instance_lbl); 1278 is_instance_lbl, is_not_instance_lbl);
1279 } 1279 }
1280 } else { 1280 } else {
1281 GenerateUninstantiatedTypeTest(type, 1281 return GenerateUninstantiatedTypeTest(type,
1282 token_index, 1282 node_id,
1283 is_instance_lbl); 1283 token_index,
1284 is_instance_lbl,
1285 is_not_instance_lbl);
1284 } 1286 }
1285 return SubtypeTestCache::null(); 1287 return SubtypeTestCache::null();
1286 } 1288 }
1287 1289
1288 1290
1289 // If instanceof type test cannot be performed successfully at compile time and 1291 // If instanceof type test cannot be performed successfully at compile time and
1290 // therefore eliminated, optimize it by adding inlined tests for: 1292 // therefore eliminated, optimize it by adding inlined tests for:
1291 // - NULL -> return false. 1293 // - NULL -> return false.
1292 // - Smi -> compile time subtype check (only if dst class is not parameterized). 1294 // - Smi -> compile time subtype check (only if dst class is not parameterized).
1293 // - Class equality (only if class is not parameterized). 1295 // - Class equality (only if class is not parameterized).
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 test_cache = GenerateInlineInstanceof(node_id, token_index, type, 1369 test_cache = GenerateInlineInstanceof(node_id, token_index, type,
1368 &is_instance_of, &is_not_instance_of); 1370 &is_instance_of, &is_not_instance_of);
1369 1371
1370 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1372 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1371 const Immediate location = Immediate(Smi::RawValue(token_index)); 1373 const Immediate location = Immediate(Smi::RawValue(token_index));
1372 const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id)); 1374 const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id));
1373 __ pushl(location); // Push the source location. 1375 __ pushl(location); // Push the source location.
1374 __ pushl(node_id_as_smi); // node-id. 1376 __ pushl(node_id_as_smi); // node-id.
1375 __ pushl(EAX); // Push the instance. 1377 __ pushl(EAX); // Push the instance.
1376 __ PushObject(type); // Push the type. 1378 __ PushObject(type); // Push the type.
1377 if (!type.IsInstantiated()) { 1379 if (type.IsInstantiated()) {
1378 GenerateInstantiatorTypeArguments(token_index); 1380 __ pushl(raw_null); // Null instantiator.
1381 __ pushl(raw_null); // Null instantiator.
1379 } else { 1382 } else {
1380 __ pushl(raw_null); // Null instantiator. 1383 GenerateInstantiatorTypeArguments(token_index, true);
regis 2012/05/04 21:53:39 Document what true means.
srdjan 2012/05/04 23:01:58 Done.
1381 } 1384 }
1382 __ LoadObject(EAX, test_cache); 1385 __ LoadObject(EAX, test_cache);
1383 __ pushl(EAX); 1386 __ pushl(EAX);
1384 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); 1387 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry);
1385 // Pop the two parameters supplied to the runtime entry. The result of the 1388 // Pop the two parameters supplied to the runtime entry. The result of the
1386 // instanceof runtime call will be left as the result of the operation. 1389 // instanceof runtime call will be left as the result of the operation.
1387 __ addl(ESP, Immediate(6 * kWordSize)); 1390 __ addl(ESP, Immediate(7 * kWordSize));
1388 if (negate_result) { 1391 if (negate_result) {
1389 __ popl(EDX); 1392 __ popl(EDX);
1390 __ CompareObject(EDX, bool_false); 1393 __ CompareObject(EDX, bool_false);
1391 __ j(EQUAL, &is_not_instance_of, Assembler::kNearJump); 1394 __ j(EQUAL, &is_not_instance_of, Assembler::kNearJump);
1392 // Fall through to is_instance_of. 1395 // Fall through to is_instance_of.
1393 } else { 1396 } else {
1394 __ jmp(&done); 1397 __ jmp(&done);
1395 } 1398 }
1396 1399
1397 __ Bind(&is_instance_of); 1400 __ Bind(&is_instance_of);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 // Instance class test only necessary. 1465 // Instance class test only necessary.
1463 return GenerateSubtype1TestCacheLookup( 1466 return GenerateSubtype1TestCacheLookup(
1464 node_id, token_index, type_class, is_instance_lbl, is_not_instance_lbl); 1467 node_id, token_index, type_class, is_instance_lbl, is_not_instance_lbl);
1465 } 1468 }
1466 const SubtypeTestCache& type_test_cache = 1469 const SubtypeTestCache& type_test_cache =
1467 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 1470 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1468 Label inlined_check, fall_through; 1471 Label inlined_check, fall_through;
1469 const Immediate raw_null = 1472 const Immediate raw_null =
1470 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1473 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1471 __ LoadObject(EDX, type_test_cache); 1474 __ LoadObject(EDX, type_test_cache);
1472 __ pushl(EDX); // Cache array. 1475 __ pushl(EDX); // Subtype test cache.
1473 __ pushl(EAX); // Instance. 1476 __ pushl(EAX); // Instance.
1474 __ pushl(raw_null); // Unused. 1477 __ pushl(raw_null); // Unused.
1475 __ call(&StubCode::Subtype2TestCacheLabel()); 1478 __ call(&StubCode::Subtype2TestCacheLabel());
1476 __ popl(EAX); // Discard. 1479 __ popl(EAX); // Discard.
1477 __ popl(EAX); // Restore receiver. 1480 __ popl(EAX); // Restore receiver.
1478 __ popl(EDX); // Discard. 1481 __ popl(EDX); // Discard.
1479 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False. 1482 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
1480 1483
1481 __ cmpl(ECX, raw_null); 1484 __ cmpl(ECX, raw_null);
1482 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1485 __ j(EQUAL, &fall_through, Assembler::kNearJump);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 __ movl(ECX, FieldAddress(ECX, Class::signature_function_offset())); 1583 __ movl(ECX, FieldAddress(ECX, Class::signature_function_offset()));
1581 __ cmpl(ECX, raw_null); 1584 __ cmpl(ECX, raw_null);
1582 __ j(NOT_EQUAL, is_instance_lbl); 1585 __ j(NOT_EQUAL, is_instance_lbl);
1583 } 1586 }
1584 // Otherwise fallthrough. 1587 // Otherwise fallthrough.
1585 } 1588 }
1586 1589
1587 1590
1588 // EAX: instance to test. 1591 // EAX: instance to test.
1589 // Clobbers: EBX, EDX, ECX. 1592 // Clobbers: EBX, EDX, ECX.
1590 void CodeGenerator::GenerateUninstantiatedTypeTest( 1593 RawSubtypeTestCache* CodeGenerator::GenerateUninstantiatedTypeTest(
1591 const AbstractType& type, 1594 const AbstractType& type,
1595 intptr_t node_id,
1592 intptr_t token_index, 1596 intptr_t token_index,
1593 Label* is_instance_lbl) { 1597 Label* is_instance_lbl,
1598 Label* is_not_instance_lbl) {
1594 ASSERT(!type.IsInstantiated()); 1599 ASSERT(!type.IsInstantiated());
1595 // Skip check if destination is a dynamic type. 1600 // Skip check if destination is a dynamic type.
1601 const Immediate raw_null =
1602 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1596 if (type.IsTypeParameter()) { 1603 if (type.IsTypeParameter()) {
1597 const Immediate raw_null =
1598 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1599 // EAX must be preserved! 1604 // EAX must be preserved!
1600 Label fall_through; 1605 Label fall_through;
1601 GenerateInstantiatorTypeArguments(token_index); 1606 GenerateInstantiatorTypeArguments(token_index, false);
regis 2012/05/04 21:53:39 ditto
srdjan 2012/05/04 23:01:58 Done.
1602 // Type arguments are on stack. 1607 // Type arguments are on stack.
1603 __ popl(EBX); 1608 __ popl(EBX);
1604 // Check if type argument is dynamic. 1609 // Check if type argument is dynamic.
1605 __ cmpl(EBX, raw_null); 1610 __ cmpl(EBX, raw_null);
1606 __ j(EQUAL, is_instance_lbl); 1611 __ j(EQUAL, is_instance_lbl);
1607 1612
1608 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. 1613 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
1609 __ movl(EDX, FieldAddress(EBX, Object::class_offset())); 1614 __ movl(EDX, FieldAddress(EBX, Object::class_offset()));
1610 __ CompareObject(EDX, Object::ZoneHandle(Object::type_arguments_class())); 1615 __ CompareObject(EDX, Object::ZoneHandle(Object::type_arguments_class()));
1611 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1616 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 // We have a non-parameterized class in EDX, compare with class of 1656 // We have a non-parameterized class in EDX, compare with class of
1652 // value in EAX. EAX, EDX are preserved in stub. 1657 // value in EAX. EAX, EDX are preserved in stub.
1653 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1658 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1654 __ call(&StubCode::IsRawSubTypeLabel()); 1659 __ call(&StubCode::IsRawSubTypeLabel());
1655 // Result in EBX: 1 is raw subtype. 1660 // Result in EBX: 1 is raw subtype.
1656 __ cmpl(EBX, Immediate(1)); 1661 __ cmpl(EBX, Immediate(1));
1657 __ j(EQUAL, is_instance_lbl); 1662 __ j(EQUAL, is_instance_lbl);
1658 1663
1659 // Test not conclusive. 1664 // Test not conclusive.
1660 __ Bind(&fall_through); 1665 __ Bind(&fall_through);
1666 return SubtypeTestCache::null();
1661 } 1667 }
1668 if (type.IsType()) {
1669 Label fall_through;
1670 __ testl(EAX, Immediate(kSmiTagMask)); // Is instance Smi?
1671 __ j(ZERO, is_not_instance_lbl, Assembler::kNearJump);
1672 // Uninstantiated type class is known at compile time, but the type
1673 // arguments are determined at runtime by the instantiator.
1674 const SubtypeTestCache& type_test_cache =
1675 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
1676 __ LoadObject(EDX, type_test_cache);
1677 __ pushl(EDX); // Subtype test cache.
1678 __ pushl(EAX); // Instance.
1679 GenerateInstantiatorTypeArguments(token_index, false); // type arguments.
regis 2012/05/04 21:53:39 ditto
srdjan 2012/05/04 23:01:58 Done.
1680 __ call(&StubCode::Subtype3TestCacheLabel());
1681 __ popl(EDX); // Discard type arguments.
1682 __ popl(EAX); // Restore receiver.
1683 __ popl(EDX); // Discard subtype test cache.
1684 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
1685 __ cmpl(ECX, raw_null);
1686 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1687 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1688 __ CompareObject(ECX, bool_true);
1689 __ j(EQUAL, is_instance_lbl);
1690 __ jmp(is_not_instance_lbl);
1691 __ Bind(&fall_through);
1692 return type_test_cache.raw();
1693 }
1694 return SubtypeTestCache::null();
1662 } 1695 }
1663 1696
1664 1697
1665 // If type check cannot be performed successfully at compile time and therefore 1698 // If type check cannot be performed successfully at compile time and therefore
1666 // eliminated, optimize it by adding inlined tests for: 1699 // eliminated, optimize it by adding inlined tests for:
1667 // - NULL -> return NULL. 1700 // - NULL -> return NULL.
1668 // - Smi -> compile time subtype check (only if dst class is not parameterized). 1701 // - Smi -> compile time subtype check (only if dst class is not parameterized).
1669 // - Class equality (only if class is not parameterized). 1702 // - Class equality (only if class is not parameterized).
1670 // Inputs: 1703 // Inputs:
1671 // - EAX: object. 1704 // - EAX: object.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 &done, &runtime_call); 1783 &done, &runtime_call);
1751 1784
1752 __ Bind(&runtime_call); 1785 __ Bind(&runtime_call);
1753 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1786 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1754 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. 1787 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
1755 __ pushl(Immediate(Smi::RawValue(node_id))); // node-id. 1788 __ pushl(Immediate(Smi::RawValue(node_id))); // node-id.
1756 __ pushl(EAX); // Push the source object. 1789 __ pushl(EAX); // Push the source object.
1757 __ PushObject(dst_type); // Push the type of the destination. 1790 __ PushObject(dst_type); // Push the type of the destination.
1758 if (dst_type.IsInstantiated()) { 1791 if (dst_type.IsInstantiated()) {
1759 __ pushl(raw_null); // Null instantiator. 1792 __ pushl(raw_null); // Null instantiator.
1793 __ pushl(raw_null); // Null instantiator type argument.
1760 } else { 1794 } else {
1761 GenerateInstantiatorTypeArguments(token_index); 1795 GenerateInstantiatorTypeArguments(token_index, true);
regis 2012/05/04 21:53:39 ditto
srdjan 2012/05/04 23:01:58 Done.
1762 } 1796 }
1763 __ PushObject(dst_name); // Push the name of the destination. 1797 __ PushObject(dst_name); // Push the name of the destination.
1764 __ LoadObject(EAX, test_cache); 1798 __ LoadObject(EAX, test_cache);
1765 __ pushl(EAX); 1799 __ pushl(EAX);
1766 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry); 1800 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry);
1767 // Pop the parameters supplied to the runtime entry. The result of the 1801 // Pop the parameters supplied to the runtime entry. The result of the
1768 // type check runtime call is the checked value. 1802 // type check runtime call is the checked value.
1769 __ addl(ESP, Immediate(7 * kWordSize)); 1803 __ addl(ESP, Immediate(8 * kWordSize));
1770 __ popl(EAX); 1804 __ popl(EAX);
1771 1805
1772 // EAX: value. 1806 // EAX: value.
1773 __ Bind(&done); 1807 __ Bind(&done);
1774 } 1808 }
1775 1809
1776 1810
1777 void CodeGenerator::GenerateArgumentTypeChecks() { 1811 void CodeGenerator::GenerateArgumentTypeChecks() {
1778 const Function& function = parsed_function_.function(); 1812 const Function& function = parsed_function_.function();
1779 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 1813 const SequenceNode& sequence_node = *parsed_function_.node_sequence();
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 __ popl(CTX); 2390 __ popl(CTX);
2357 // Result is in EAX. 2391 // Result is in EAX.
2358 if (IsResultNeeded(node)) { 2392 if (IsResultNeeded(node)) {
2359 __ pushl(EAX); 2393 __ pushl(EAX);
2360 } 2394 }
2361 } 2395 }
2362 2396
2363 2397
2364 // Pushes the type arguments of the instantiator on the stack. 2398 // Pushes the type arguments of the instantiator on the stack.
2365 // Destroys EBX. 2399 // Destroys EBX.
2366 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { 2400 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index,
2401 bool push_instantiator) {
2402 if (push_instantiator) {
2403 const Immediate raw_null =
2404 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2405 __ pushl(raw_null); // Initial instantiator.
2406 }
2367 const Class& instantiator_class = Class::Handle( 2407 const Class& instantiator_class = Class::Handle(
2368 parsed_function().function().owner()); 2408 parsed_function().function().owner());
2369 if (instantiator_class.NumTypeParameters() == 0) { 2409 if (instantiator_class.NumTypeParameters() == 0) {
2370 // The type arguments are compile time constants. 2410 // The type arguments are compile time constants.
2371 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2411 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2372 // TODO(regis): Temporary type should be allocated in new gen heap. 2412 // TODO(regis): Temporary type should be allocated in new gen heap.
2373 Type& type = Type::Handle( 2413 Type& type = Type::Handle(
2374 Type::New(instantiator_class, type_arguments, token_index)); 2414 Type::New(instantiator_class, type_arguments, token_index));
2375 type ^= ClassFinalizer::FinalizeType( 2415 type ^= ClassFinalizer::FinalizeType(
2376 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); 2416 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed);
2377 type_arguments = type.arguments(); 2417 type_arguments = type.arguments();
2378 __ PushObject(type_arguments); 2418 __ PushObject(type_arguments);
2379 } else { 2419 } else {
2380 ASSERT(parsed_function().instantiator() != NULL); 2420 ASSERT(parsed_function().instantiator() != NULL);
2381 parsed_function().instantiator()->Visit(this); 2421 parsed_function().instantiator()->Visit(this);
2382 Function& outer_function = 2422 Function& outer_function =
2383 Function::Handle(parsed_function().function().raw()); 2423 Function::Handle(parsed_function().function().raw());
2384 while (outer_function.IsLocalFunction()) { 2424 while (outer_function.IsLocalFunction()) {
2385 outer_function = outer_function.parent_function(); 2425 outer_function = outer_function.parent_function();
2386 } 2426 }
2387 if (!outer_function.IsFactory()) { 2427 if (!outer_function.IsFactory()) {
2388 __ popl(EBX); // Pop instantiator. 2428 if (push_instantiator) {
2429 __ popl(EBX); // Pop instantiator.
2430 __ popl(ECX); // Discard null instantiator.
2431 __ pushl(EBX); // Replace it with the real one.
2432 } else {
2433 __ popl(EBX); // Pop instantiator.
2434 }
2435 // EBX: instantiator.
2389 // The instantiator is the receiver of the caller, which is not a factory. 2436 // The instantiator is the receiver of the caller, which is not a factory.
2390 // The receiver cannot be null; extract its AbstractTypeArguments object. 2437 // The receiver cannot be null; extract its AbstractTypeArguments object.
2391 // Note that in the factory case, the instantiator is the first parameter 2438 // Note that in the factory case, the instantiator is the first parameter
2392 // of the factory, i.e. already an AbstractTypeArguments object. 2439 // of the factory, i.e. already an AbstractTypeArguments object.
2393 intptr_t type_arguments_instance_field_offset = 2440 intptr_t type_arguments_instance_field_offset =
2394 instantiator_class.type_arguments_instance_field_offset(); 2441 instantiator_class.type_arguments_instance_field_offset();
2395 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 2442 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
2396 __ movl(EBX, FieldAddress(EBX, type_arguments_instance_field_offset)); 2443 __ movl(EBX, FieldAddress(EBX, type_arguments_instance_field_offset));
2397 __ pushl(EBX); 2444 __ pushl(EBX);
2398 } 2445 }
(...skipping 18 matching lines...) Expand all
2417 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2464 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2418 // The type arguments are instantiated. 2465 // The type arguments are instantiated.
2419 __ PushObject(type_arguments); 2466 __ PushObject(type_arguments);
2420 if (!instantiate_type_arguments) { 2467 if (!instantiate_type_arguments) {
2421 // The type arguments of the instantiator are not needed, since the 2468 // The type arguments of the instantiator are not needed, since the
2422 // type arguments are instantiated. 2469 // type arguments are instantiated.
2423 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 2470 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2424 } 2471 }
2425 } else { 2472 } else {
2426 // The type arguments are uninstantiated. 2473 // The type arguments are uninstantiated.
2427 GenerateInstantiatorTypeArguments(token_index); 2474 GenerateInstantiatorTypeArguments(token_index, false);
regis 2012/05/04 21:53:39 Document false
srdjan 2012/05/04 23:01:58 Done.
2428 __ popl(EAX); // Pop instantiator. 2475 __ popl(EAX); // Pop instantiator.
2429 // EAX is the instantiator AbstractTypeArguments object (or null). 2476 // EAX is the instantiator AbstractTypeArguments object (or null).
2430 // If the instantiator is null and if the type argument vector 2477 // If the instantiator is null and if the type argument vector
2431 // instantiated from null becomes a vector of Dynamic, then use null as 2478 // instantiated from null becomes a vector of Dynamic, then use null as
2432 // the type arguments. 2479 // the type arguments.
2433 Label type_arguments_instantiated; 2480 Label type_arguments_instantiated;
2434 const intptr_t len = type_arguments.Length(); 2481 const intptr_t len = type_arguments.Length();
2435 if (type_arguments.IsRawInstantiatedRaw(len)) { 2482 if (type_arguments.IsRawInstantiatedRaw(len)) {
2436 __ cmpl(EAX, raw_null); 2483 __ cmpl(EAX, raw_null);
2437 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2484 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
2905 const Error& error = Error::Handle( 2952 const Error& error = Error::Handle(
2906 Parser::FormatError(script, token_index, "Error", format, args)); 2953 Parser::FormatError(script, token_index, "Error", format, args));
2907 va_end(args); 2954 va_end(args);
2908 Isolate::Current()->long_jump_base()->Jump(1, error); 2955 Isolate::Current()->long_jump_base()->Jump(1, error);
2909 UNREACHABLE(); 2956 UNREACHABLE();
2910 } 2957 }
2911 2958
2912 } // namespace dart 2959 } // namespace dart
2913 2960
2914 #endif // defined TARGET_ARCH_IA32 2961 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698