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

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

Issue 14238036: Improve type optimization reusing the type argument vector of the instantiator (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_ia32.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 Register instance_reg = locs()->in(0).reg(); 1435 Register instance_reg = locs()->in(0).reg();
1436 Register result_reg = locs()->out().reg(); 1436 Register result_reg = locs()->out().reg();
1437 1437
1438 __ LoadFromOffset(kLoadWord, result_reg, 1438 __ LoadFromOffset(kLoadWord, result_reg,
1439 instance_reg, offset_in_bytes() - kHeapObjectTag); 1439 instance_reg, offset_in_bytes() - kHeapObjectTag);
1440 } 1440 }
1441 1441
1442 1442
1443 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1443 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
1444 const intptr_t kNumInputs = 1; 1444 const intptr_t kNumInputs = 1;
1445 const intptr_t kNumTemps = 1; 1445 const intptr_t kNumTemps = 0;
1446 LocationSummary* locs = 1446 LocationSummary* locs =
1447 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1447 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1448 locs->set_in(0, Location::RegisterLocation(R0)); 1448 locs->set_in(0, Location::RegisterLocation(R0));
1449 locs->set_temp(0, Location::RegisterLocation(R1));
1450 locs->set_out(Location::RegisterLocation(R0)); 1449 locs->set_out(Location::RegisterLocation(R0));
1451 return locs; 1450 return locs;
1452 } 1451 }
1453 1452
1454 1453
1455 void InstantiateTypeArgumentsInstr::EmitNativeCode( 1454 void InstantiateTypeArgumentsInstr::EmitNativeCode(
1456 FlowGraphCompiler* compiler) { 1455 FlowGraphCompiler* compiler) {
1457 Register instantiator_reg = locs()->in(0).reg(); 1456 Register instantiator_reg = locs()->in(0).reg();
1458 Register temp = locs()->temp(0).reg();
1459 Register result_reg = locs()->out().reg(); 1457 Register result_reg = locs()->out().reg();
1460 1458
1461 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1459 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1462 // (or null). 1460 // (or null).
1463 // If the instantiator is null and if the type argument vector 1461 if (!type_arguments().IsUninstantiatedIdentity()) {
1464 // instantiated from null becomes a vector of dynamic, then use null as 1462 // If the instantiator is null and if the type argument vector
1465 // the type arguments. 1463 // instantiated from null becomes a vector of dynamic, then use null as
1466 Label type_arguments_instantiated; 1464 // the type arguments.
1467 const intptr_t len = type_arguments().Length(); 1465 Label type_arguments_instantiated;
1468 if (type_arguments().IsRawInstantiatedRaw(len)) { 1466 const intptr_t len = type_arguments().Length();
1469 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 1467 if (type_arguments().IsRawInstantiatedRaw(len)) {
1470 __ cmp(instantiator_reg, ShifterOperand(IP)); 1468 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
1471 __ b(&type_arguments_instantiated, EQ); 1469 __ cmp(instantiator_reg, ShifterOperand(IP));
1470 __ b(&type_arguments_instantiated, EQ);
1471 }
1472 // Instantiate non-null type arguments.
1473 // A runtime call to instantiate the type arguments is required.
1474 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1475 __ PushObject(type_arguments());
1476 __ Push(instantiator_reg); // Push instantiator type arguments.
1477 compiler->GenerateCallRuntime(token_pos(),
1478 deopt_id(),
1479 kInstantiateTypeArgumentsRuntimeEntry,
1480 locs());
1481 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1482 __ Pop(result_reg); // Pop instantiated type arguments.
1483 __ Bind(&type_arguments_instantiated);
1472 } 1484 }
1473 // Instantiate non-null type arguments.
1474 if (type_arguments().IsUninstantiatedIdentity()) {
1475 // Check if the instantiator type argument vector is a TypeArguments of a
1476 // matching length and, if so, use it as the instantiated type_arguments.
1477 // No need to check the instantiator ('instantiator_reg') for null here,
1478 // because a null instantiator will have the wrong class (Null instead of
1479 // TypeArguments).
1480 Label type_arguments_uninstantiated;
1481 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp);
1482 __ b(&type_arguments_uninstantiated, NE);
1483 __ ldr(temp,
1484 FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1485 __ CompareImmediate(temp, Smi::RawValue(len));
1486 __ b(&type_arguments_instantiated, EQ);
1487 __ Bind(&type_arguments_uninstantiated);
1488 }
1489 // A runtime call to instantiate the type arguments is required.
1490 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1491 __ PushObject(type_arguments());
1492 __ Push(instantiator_reg); // Push instantiator type arguments.
1493 compiler->GenerateCallRuntime(token_pos(),
1494 deopt_id(),
1495 kInstantiateTypeArgumentsRuntimeEntry,
1496 locs());
1497 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1498 __ Pop(result_reg); // Pop instantiated type arguments.
1499 __ Bind(&type_arguments_instantiated);
1500 ASSERT(instantiator_reg == result_reg); 1485 ASSERT(instantiator_reg == result_reg);
1501 // 'result_reg': Instantiated type arguments. 1486 // 'result_reg': Instantiated type arguments.
1502 } 1487 }
1503 1488
1504 1489
1505 LocationSummary* 1490 LocationSummary*
1506 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1491 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
1507 const intptr_t kNumInputs = 1; 1492 const intptr_t kNumInputs = 1;
1508 const intptr_t kNumTemps = 1; 1493 const intptr_t kNumTemps = 0;
1509 LocationSummary* locs = 1494 LocationSummary* locs =
1510 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1495 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1511 locs->set_in(0, Location::RequiresRegister()); 1496 locs->set_in(0, Location::RequiresRegister());
1512 locs->set_out(Location::SameAsFirstInput()); 1497 locs->set_out(Location::SameAsFirstInput());
1513 locs->set_temp(0, Location::RequiresRegister());
1514 return locs; 1498 return locs;
1515 } 1499 }
1516 1500
1517 1501
1518 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( 1502 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
1519 FlowGraphCompiler* compiler) { 1503 FlowGraphCompiler* compiler) {
1520 Register instantiator_reg = locs()->in(0).reg(); 1504 Register instantiator_reg = locs()->in(0).reg();
1521 Register result_reg = locs()->out().reg(); 1505 Register result_reg = locs()->out().reg();
1522 ASSERT(instantiator_reg == result_reg); 1506 ASSERT(instantiator_reg == result_reg);
1523 Register temp_reg = locs()->temp(0).reg();
1524 1507
1525 // instantiator_reg is the instantiator type argument vector, i.e. an 1508 // instantiator_reg is the instantiator type argument vector, i.e. an
1526 // AbstractTypeArguments object (or null). 1509 // AbstractTypeArguments object (or null).
1527 // If the instantiator is null and if the type argument vector 1510 if (!type_arguments().IsUninstantiatedIdentity()) {
1528 // instantiated from null becomes a vector of dynamic, then use null as 1511 // If the instantiator is null and if the type argument vector
1529 // the type arguments. 1512 // instantiated from null becomes a vector of dynamic, then use null as
1530 Label type_arguments_instantiated; 1513 // the type arguments.
1531 const intptr_t len = type_arguments().Length(); 1514 Label type_arguments_instantiated;
1532 if (type_arguments().IsRawInstantiatedRaw(len)) { 1515 const intptr_t len = type_arguments().Length();
1533 __ CompareImmediate(instantiator_reg, 1516 if (type_arguments().IsRawInstantiatedRaw(len)) {
1534 reinterpret_cast<intptr_t>(Object::null())); 1517 __ CompareImmediate(instantiator_reg,
1535 __ b(&type_arguments_instantiated, EQ); 1518 reinterpret_cast<intptr_t>(Object::null()));
1519 __ b(&type_arguments_instantiated, EQ);
1520 }
1521 // Instantiate non-null type arguments.
1522 // In the non-factory case, we rely on the allocation stub to
1523 // instantiate the type arguments.
1524 __ LoadObject(result_reg, type_arguments());
1525 // result_reg: uninstantiated type arguments.
1526 __ Bind(&type_arguments_instantiated);
1536 } 1527 }
1537 // Instantiate non-null type arguments. 1528 ASSERT(instantiator_reg == result_reg);
1538 if (type_arguments().IsUninstantiatedIdentity()) {
1539 // Check if the instantiator type argument vector is a TypeArguments of a
1540 // matching length and, if so, use it as the instantiated type_arguments.
1541 // No need to check instantiator_reg for null here, because a null
1542 // instantiator will have the wrong class (Null instead of TypeArguments).
1543 Label type_arguments_uninstantiated;
1544 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
1545 __ b(&type_arguments_uninstantiated, NE);
1546 __ ldr(temp_reg,
1547 FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1548 __ CompareImmediate(temp_reg, Smi::RawValue(type_arguments().Length()));
1549 __ b(&type_arguments_instantiated, EQ);
1550 __ Bind(&type_arguments_uninstantiated);
1551 }
1552 // In the non-factory case, we rely on the allocation stub to
1553 // instantiate the type arguments.
1554 __ LoadObject(result_reg, type_arguments());
1555 // result_reg: uninstantiated type arguments.
1556 __ Bind(&type_arguments_instantiated);
1557 // result_reg: uninstantiated or instantiated type arguments. 1529 // result_reg: uninstantiated or instantiated type arguments.
1558 } 1530 }
1559 1531
1560 1532
1561 LocationSummary* 1533 LocationSummary*
1562 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1534 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
1563 const intptr_t kNumInputs = 1; 1535 const intptr_t kNumInputs = 1;
1564 const intptr_t kNumTemps = 1; 1536 const intptr_t kNumTemps = 0;
1565 LocationSummary* locs = 1537 LocationSummary* locs =
1566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1538 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1567 locs->set_in(0, Location::RequiresRegister()); 1539 locs->set_in(0, Location::RequiresRegister());
1568 locs->set_out(Location::SameAsFirstInput()); 1540 locs->set_out(Location::SameAsFirstInput());
1569 locs->set_temp(0, Location::RequiresRegister());
1570 return locs; 1541 return locs;
1571 } 1542 }
1572 1543
1573 1544
1574 void ExtractConstructorInstantiatorInstr::EmitNativeCode( 1545 void ExtractConstructorInstantiatorInstr::EmitNativeCode(
1575 FlowGraphCompiler* compiler) { 1546 FlowGraphCompiler* compiler) {
1576 Register instantiator_reg = locs()->in(0).reg(); 1547 Register instantiator_reg = locs()->in(0).reg();
1577 ASSERT(locs()->out().reg() == instantiator_reg); 1548 ASSERT(locs()->out().reg() == instantiator_reg);
1578 Register temp_reg = locs()->temp(0).reg();
1579 1549
1580 // instantiator_reg is the instantiator AbstractTypeArguments object 1550 // instantiator_reg is the instantiator AbstractTypeArguments object
1581 // (or null). If the instantiator is null and if the type argument vector 1551 // (or null).
1582 // instantiated from null becomes a vector of dynamic, then use null as
1583 // the type arguments and do not pass the instantiator.
1584 Label done;
1585 const intptr_t len = type_arguments().Length();
1586 if (type_arguments().IsRawInstantiatedRaw(len)) {
1587 Label instantiator_not_null;
1588 __ CompareImmediate(instantiator_reg,
1589 reinterpret_cast<intptr_t>(Object::null()));
1590 __ b(&instantiator_not_null, NE);
1591 // Null was used in VisitExtractConstructorTypeArguments as the
1592 // instantiated type arguments, no proper instantiator needed.
1593 __ LoadImmediate(instantiator_reg,
1594 Smi::RawValue(StubCode::kNoInstantiator));
1595 __ b(&done);
1596 __ Bind(&instantiator_not_null);
1597 }
1598 // Instantiate non-null type arguments.
1599 if (type_arguments().IsUninstantiatedIdentity()) { 1552 if (type_arguments().IsUninstantiatedIdentity()) {
1600 // TODO(regis): The following emitted code is duplicated in
1601 // VisitExtractConstructorTypeArguments above. The reason is that the code
1602 // is split between two computations, so that each one produces a
1603 // single value, rather than producing a pair of values.
1604 // If this becomes an issue, we should expose these tests at the IL level.
1605
1606 // Check if the instantiator type argument vector is a TypeArguments of a
1607 // matching length and, if so, use it as the instantiated type_arguments.
1608 // No need to check the instantiator ('instantiator_reg') for null here,
1609 // because a null instantiator will have the wrong class (Null instead of
1610 // TypeArguments).
1611 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
1612 __ b(&done, NE);
1613 __ ldr(temp_reg,
1614 FieldAddress(instantiator_reg, TypeArguments::length_offset()));
1615 __ CompareImmediate(temp_reg, Smi::RawValue(type_arguments().Length()));
1616 __ b(&done, NE);
1617 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1553 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1618 // instantiated type arguments, no proper instantiator needed. 1554 // instantiated type arguments, no proper instantiator needed.
1619 __ LoadImmediate(instantiator_reg, 1555 __ LoadImmediate(instantiator_reg,
1620 Smi::RawValue(StubCode::kNoInstantiator)); 1556 Smi::RawValue(StubCode::kNoInstantiator));
1557 } else {
1558 // If the instantiator is null and if the type argument vector
1559 // instantiated from null becomes a vector of dynamic, then use null as
1560 // the type arguments and do not pass the instantiator.
1561 const intptr_t len = type_arguments().Length();
1562 if (type_arguments().IsRawInstantiatedRaw(len)) {
1563 Label instantiator_not_null;
1564 __ CompareImmediate(instantiator_reg,
1565 reinterpret_cast<intptr_t>(Object::null()));
1566 __ b(&instantiator_not_null, NE);
1567 // Null was used in VisitExtractConstructorTypeArguments as the
1568 // instantiated type arguments, no proper instantiator needed.
1569 __ LoadImmediate(instantiator_reg,
1570 Smi::RawValue(StubCode::kNoInstantiator));
1571 __ Bind(&instantiator_not_null);
1572 }
1621 } 1573 }
1622 __ Bind(&done);
1623 // instantiator_reg: instantiator or kNoInstantiator. 1574 // instantiator_reg: instantiator or kNoInstantiator.
1624 } 1575 }
1625 1576
1626 1577
1627 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1578 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
1628 const intptr_t kNumInputs = 0; 1579 const intptr_t kNumInputs = 0;
1629 const intptr_t kNumTemps = 1; 1580 const intptr_t kNumTemps = 1;
1630 LocationSummary* locs = 1581 LocationSummary* locs =
1631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1582 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1632 locs->set_temp(0, Location::RegisterLocation(R1)); 1583 locs->set_temp(0, Location::RegisterLocation(R1));
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 &label, 2580 &label,
2630 PcDescriptors::kOther, 2581 PcDescriptors::kOther,
2631 locs()); 2582 locs());
2632 __ Drop(2); // Discard type arguments and receiver. 2583 __ Drop(2); // Discard type arguments and receiver.
2633 } 2584 }
2634 2585
2635 } // namespace dart 2586 } // namespace dart
2636 2587
2637 #endif // defined TARGET_ARCH_ARM 2588 #endif // defined TARGET_ARCH_ARM
2638 2589
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698