OLD | NEW |
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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 __ CompareImmediate( | 1499 __ CompareImmediate( |
1500 FieldAddress(value_reg, | 1500 FieldAddress(value_reg, |
1501 field().guarded_list_length_in_object_offset()), | 1501 field().guarded_list_length_in_object_offset()), |
1502 Immediate(Smi::RawValue(field().guarded_list_length())), | 1502 Immediate(Smi::RawValue(field().guarded_list_length())), |
1503 PP); | 1503 PP); |
1504 __ j(NOT_EQUAL, deopt); | 1504 __ j(NOT_EQUAL, deopt); |
1505 } | 1505 } |
1506 } | 1506 } |
1507 | 1507 |
1508 | 1508 |
1509 class StoreInstanceFieldSlowPath : public SlowPathCode { | 1509 class BoxAllocationSlowPath : public SlowPathCode { |
1510 public: | 1510 public: |
1511 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, | 1511 BoxAllocationSlowPath(Instruction* instruction, |
1512 const Class& cls) | 1512 const Class& cls, |
1513 : instruction_(instruction), cls_(cls) { } | 1513 Register result) |
| 1514 : instruction_(instruction), |
| 1515 cls_(cls), |
| 1516 result_(result) { } |
1514 | 1517 |
1515 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1518 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
1516 __ Comment("StoreInstanceFieldSlowPath"); | |
1517 __ Bind(entry_label()); | |
1518 Isolate* isolate = compiler->isolate(); | 1519 Isolate* isolate = compiler->isolate(); |
1519 StubCode* stub_code = isolate->stub_code(); | 1520 StubCode* stub_code = isolate->stub_code(); |
1520 const Code& stub = Code::Handle(isolate, | 1521 |
1521 stub_code->GetAllocationStubForClass(cls_)); | 1522 if (Assembler::EmittingComments()) { |
| 1523 __ Comment("%s slow path allocation of %s", |
| 1524 instruction_->DebugName(), |
| 1525 String::Handle(cls_.PrettyName()).ToCString()); |
| 1526 } |
| 1527 __ Bind(entry_label()); |
| 1528 |
| 1529 const Code& stub = |
| 1530 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); |
1522 const ExternalLabel label(stub.EntryPoint()); | 1531 const ExternalLabel label(stub.EntryPoint()); |
1523 | 1532 |
1524 LocationSummary* locs = instruction_->locs(); | 1533 LocationSummary* locs = instruction_->locs(); |
1525 locs->live_registers()->Remove(locs->temp(0)); | 1534 |
| 1535 locs->live_registers()->Remove(Location::RegisterLocation(result_)); |
1526 | 1536 |
1527 compiler->SaveLiveRegisters(locs); | 1537 compiler->SaveLiveRegisters(locs); |
1528 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 1538 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
1529 &label, | 1539 &label, |
1530 RawPcDescriptors::kOther, | 1540 RawPcDescriptors::kOther, |
1531 locs); | 1541 locs); |
1532 __ MoveRegister(locs->temp(0).reg(), RAX); | 1542 __ MoveRegister(result_, RAX); |
1533 compiler->RestoreLiveRegisters(locs); | 1543 compiler->RestoreLiveRegisters(locs); |
1534 | |
1535 __ jmp(exit_label()); | 1544 __ jmp(exit_label()); |
1536 } | 1545 } |
1537 | 1546 |
| 1547 static void Allocate(FlowGraphCompiler* compiler, |
| 1548 Instruction* instruction, |
| 1549 const Class& cls, |
| 1550 Register result) { |
| 1551 BoxAllocationSlowPath* slow_path = |
| 1552 new BoxAllocationSlowPath(instruction, cls, result); |
| 1553 compiler->AddSlowPathCode(slow_path); |
| 1554 |
| 1555 __ TryAllocate(cls, |
| 1556 slow_path->entry_label(), |
| 1557 Assembler::kFarJump, |
| 1558 result, |
| 1559 PP); |
| 1560 __ Bind(slow_path->exit_label()); |
| 1561 } |
| 1562 |
1538 private: | 1563 private: |
1539 StoreInstanceFieldInstr* instruction_; | 1564 Instruction* instruction_; |
1540 const Class& cls_; | 1565 const Class& cls_; |
| 1566 Register result_; |
1541 }; | 1567 }; |
1542 | 1568 |
1543 | 1569 |
1544 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, | 1570 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, |
1545 bool opt) const { | 1571 bool opt) const { |
1546 const intptr_t kNumInputs = 2; | 1572 const intptr_t kNumInputs = 2; |
1547 const intptr_t kNumTemps = | 1573 const intptr_t kNumTemps = |
1548 (IsUnboxedStore() && opt) ? 2 : | 1574 (IsUnboxedStore() && opt) ? 2 : |
1549 ((IsPotentialUnboxedStore()) ? 3 : 0); | 1575 ((IsPotentialUnboxedStore()) ? 3 : 0); |
1550 LocationSummary* summary = new(isolate) LocationSummary( | 1576 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 18 matching lines...) Expand all Loading... |
1569 : Location::FpuRegisterLocation(XMM1)); | 1595 : Location::FpuRegisterLocation(XMM1)); |
1570 } else { | 1596 } else { |
1571 summary->set_in(1, ShouldEmitStoreBarrier() | 1597 summary->set_in(1, ShouldEmitStoreBarrier() |
1572 ? Location::WritableRegister() | 1598 ? Location::WritableRegister() |
1573 : Location::RegisterOrConstant(value())); | 1599 : Location::RegisterOrConstant(value())); |
1574 } | 1600 } |
1575 return summary; | 1601 return summary; |
1576 } | 1602 } |
1577 | 1603 |
1578 | 1604 |
| 1605 static void EnsureMutableBox(FlowGraphCompiler* compiler, |
| 1606 StoreInstanceFieldInstr* instruction, |
| 1607 Register box_reg, |
| 1608 const Class& cls, |
| 1609 Register instance_reg, |
| 1610 intptr_t offset, |
| 1611 Register temp) { |
| 1612 Label done; |
| 1613 __ movq(box_reg, FieldAddress(instance_reg, offset)); |
| 1614 __ CompareObject(box_reg, Object::null_object(), PP); |
| 1615 __ j(NOT_EQUAL, &done); |
| 1616 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg); |
| 1617 __ movq(temp, box_reg); |
| 1618 __ StoreIntoObject(instance_reg, |
| 1619 FieldAddress(instance_reg, offset), |
| 1620 temp); |
| 1621 |
| 1622 __ Bind(&done); |
| 1623 } |
| 1624 |
| 1625 |
1579 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1626 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1580 Label skip_store; | 1627 Label skip_store; |
1581 | 1628 |
1582 Register instance_reg = locs()->in(0).reg(); | 1629 Register instance_reg = locs()->in(0).reg(); |
1583 | 1630 |
1584 if (IsUnboxedStore() && compiler->is_optimizing()) { | 1631 if (IsUnboxedStore() && compiler->is_optimizing()) { |
1585 XmmRegister value = locs()->in(1).fpu_reg(); | 1632 XmmRegister value = locs()->in(1).fpu_reg(); |
1586 Register temp = locs()->temp(0).reg(); | 1633 Register temp = locs()->temp(0).reg(); |
1587 Register temp2 = locs()->temp(1).reg(); | 1634 Register temp2 = locs()->temp(1).reg(); |
1588 const intptr_t cid = field().UnboxedFieldCid(); | 1635 const intptr_t cid = field().UnboxedFieldCid(); |
1589 | 1636 |
1590 if (is_initialization_) { | 1637 if (is_initialization_) { |
1591 const Class* cls = NULL; | 1638 const Class* cls = NULL; |
1592 switch (cid) { | 1639 switch (cid) { |
1593 case kDoubleCid: | 1640 case kDoubleCid: |
1594 cls = &compiler->double_class(); | 1641 cls = &compiler->double_class(); |
1595 break; | 1642 break; |
1596 case kFloat32x4Cid: | 1643 case kFloat32x4Cid: |
1597 cls = &compiler->float32x4_class(); | 1644 cls = &compiler->float32x4_class(); |
1598 break; | 1645 break; |
1599 case kFloat64x2Cid: | 1646 case kFloat64x2Cid: |
1600 cls = &compiler->float64x2_class(); | 1647 cls = &compiler->float64x2_class(); |
1601 break; | 1648 break; |
1602 default: | 1649 default: |
1603 UNREACHABLE(); | 1650 UNREACHABLE(); |
1604 } | 1651 } |
1605 | 1652 |
1606 StoreInstanceFieldSlowPath* slow_path = | 1653 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp); |
1607 new StoreInstanceFieldSlowPath(this, *cls); | |
1608 compiler->AddSlowPathCode(slow_path); | |
1609 | |
1610 __ TryAllocate(*cls, | |
1611 slow_path->entry_label(), | |
1612 Assembler::kFarJump, | |
1613 temp, | |
1614 PP); | |
1615 __ Bind(slow_path->exit_label()); | |
1616 __ movq(temp2, temp); | 1654 __ movq(temp2, temp); |
1617 __ StoreIntoObject(instance_reg, | 1655 __ StoreIntoObject(instance_reg, |
1618 FieldAddress(instance_reg, offset_in_bytes_), | 1656 FieldAddress(instance_reg, offset_in_bytes_), |
1619 temp2); | 1657 temp2); |
1620 } else { | 1658 } else { |
1621 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1659 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
1622 } | 1660 } |
1623 switch (cid) { | 1661 switch (cid) { |
1624 case kDoubleCid: | 1662 case kDoubleCid: |
1625 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1663 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 // Fall through. | 1713 // Fall through. |
1676 __ jmp(&store_pointer); | 1714 __ jmp(&store_pointer); |
1677 | 1715 |
1678 if (!compiler->is_optimizing()) { | 1716 if (!compiler->is_optimizing()) { |
1679 locs()->live_registers()->Add(locs()->in(0)); | 1717 locs()->live_registers()->Add(locs()->in(0)); |
1680 locs()->live_registers()->Add(locs()->in(1)); | 1718 locs()->live_registers()->Add(locs()->in(1)); |
1681 } | 1719 } |
1682 | 1720 |
1683 { | 1721 { |
1684 __ Bind(&store_double); | 1722 __ Bind(&store_double); |
1685 Label copy_double; | 1723 EnsureMutableBox(compiler, |
1686 StoreInstanceFieldSlowPath* slow_path = | 1724 this, |
1687 new StoreInstanceFieldSlowPath(this, compiler->double_class()); | 1725 temp, |
1688 compiler->AddSlowPathCode(slow_path); | 1726 compiler->double_class(), |
1689 | 1727 instance_reg, |
1690 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1728 offset_in_bytes_, |
1691 __ CompareObject(temp, Object::null_object(), PP); | 1729 temp2); |
1692 __ j(NOT_EQUAL, ©_double); | |
1693 | |
1694 __ TryAllocate(compiler->double_class(), | |
1695 slow_path->entry_label(), | |
1696 Assembler::kFarJump, | |
1697 temp, | |
1698 PP); | |
1699 __ Bind(slow_path->exit_label()); | |
1700 __ movq(temp2, temp); | |
1701 __ StoreIntoObject(instance_reg, | |
1702 FieldAddress(instance_reg, offset_in_bytes_), | |
1703 temp2); | |
1704 | |
1705 __ Bind(©_double); | |
1706 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); | 1730 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); |
1707 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); | 1731 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); |
1708 __ jmp(&skip_store); | 1732 __ jmp(&skip_store); |
1709 } | 1733 } |
1710 | 1734 |
1711 { | 1735 { |
1712 __ Bind(&store_float32x4); | 1736 __ Bind(&store_float32x4); |
1713 Label copy_float32x4; | 1737 EnsureMutableBox(compiler, |
1714 StoreInstanceFieldSlowPath* slow_path = | 1738 this, |
1715 new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); | 1739 temp, |
1716 compiler->AddSlowPathCode(slow_path); | 1740 compiler->float32x4_class(), |
1717 | 1741 instance_reg, |
1718 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1742 offset_in_bytes_, |
1719 __ CompareObject(temp, Object::null_object(), PP); | 1743 temp2); |
1720 __ j(NOT_EQUAL, ©_float32x4); | |
1721 | |
1722 __ TryAllocate(compiler->float32x4_class(), | |
1723 slow_path->entry_label(), | |
1724 Assembler::kFarJump, | |
1725 temp, | |
1726 PP); | |
1727 __ Bind(slow_path->exit_label()); | |
1728 __ movq(temp2, temp); | |
1729 __ StoreIntoObject(instance_reg, | |
1730 FieldAddress(instance_reg, offset_in_bytes_), | |
1731 temp2); | |
1732 | |
1733 __ Bind(©_float32x4); | |
1734 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); | 1744 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); |
1735 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); | 1745 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); |
1736 __ jmp(&skip_store); | 1746 __ jmp(&skip_store); |
1737 } | 1747 } |
1738 | 1748 |
1739 { | 1749 { |
1740 __ Bind(&store_float64x2); | 1750 __ Bind(&store_float64x2); |
1741 Label copy_float64x2; | 1751 EnsureMutableBox(compiler, |
1742 | 1752 this, |
1743 StoreInstanceFieldSlowPath* slow_path = | 1753 temp, |
1744 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); | 1754 compiler->float64x2_class(), |
1745 compiler->AddSlowPathCode(slow_path); | 1755 instance_reg, |
1746 | 1756 offset_in_bytes_, |
1747 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1757 temp2); |
1748 __ CompareObject(temp, Object::null_object(), PP); | |
1749 __ j(NOT_EQUAL, ©_float64x2); | |
1750 | |
1751 __ TryAllocate(compiler->float64x2_class(), | |
1752 slow_path->entry_label(), | |
1753 Assembler::kFarJump, | |
1754 temp, | |
1755 temp2); | |
1756 __ Bind(slow_path->exit_label()); | |
1757 __ movq(temp2, temp); | |
1758 __ StoreIntoObject(instance_reg, | |
1759 FieldAddress(instance_reg, offset_in_bytes_), | |
1760 temp2); | |
1761 | |
1762 __ Bind(©_float64x2); | |
1763 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); | 1758 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); |
1764 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); | 1759 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); |
1765 __ jmp(&skip_store); | 1760 __ jmp(&skip_store); |
1766 } | 1761 } |
1767 | 1762 |
1768 __ Bind(&store_pointer); | 1763 __ Bind(&store_pointer); |
1769 } | 1764 } |
1770 | 1765 |
1771 if (ShouldEmitStoreBarrier()) { | 1766 if (ShouldEmitStoreBarrier()) { |
1772 Register value_reg = locs()->in(1).reg(); | 1767 Register value_reg = locs()->in(1).reg(); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 StubCode* stub_code = compiler->isolate()->stub_code(); | 1982 StubCode* stub_code = compiler->isolate()->stub_code(); |
1988 compiler->GenerateCall(token_pos(), | 1983 compiler->GenerateCall(token_pos(), |
1989 &stub_code->AllocateArrayLabel(), | 1984 &stub_code->AllocateArrayLabel(), |
1990 RawPcDescriptors::kOther, | 1985 RawPcDescriptors::kOther, |
1991 locs()); | 1986 locs()); |
1992 __ Bind(&done); | 1987 __ Bind(&done); |
1993 ASSERT(locs()->out(0).reg() == kResultReg); | 1988 ASSERT(locs()->out(0).reg() == kResultReg); |
1994 } | 1989 } |
1995 | 1990 |
1996 | 1991 |
1997 class BoxDoubleSlowPath : public SlowPathCode { | |
1998 public: | |
1999 explicit BoxDoubleSlowPath(Instruction* instruction) | |
2000 : instruction_(instruction) { } | |
2001 | |
2002 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2003 __ Comment("BoxDoubleSlowPath"); | |
2004 __ Bind(entry_label()); | |
2005 Isolate* isolate = compiler->isolate(); | |
2006 StubCode* stub_code = isolate->stub_code(); | |
2007 const Class& double_class = compiler->double_class(); | |
2008 const Code& stub = | |
2009 Code::Handle(isolate, | |
2010 stub_code->GetAllocationStubForClass(double_class)); | |
2011 const ExternalLabel label(stub.EntryPoint()); | |
2012 | |
2013 LocationSummary* locs = instruction_->locs(); | |
2014 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2015 | |
2016 compiler->SaveLiveRegisters(locs); | |
2017 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2018 &label, | |
2019 RawPcDescriptors::kOther, | |
2020 locs); | |
2021 __ MoveRegister(locs->out(0).reg(), RAX); | |
2022 compiler->RestoreLiveRegisters(locs); | |
2023 | |
2024 __ jmp(exit_label()); | |
2025 } | |
2026 | |
2027 private: | |
2028 Instruction* instruction_; | |
2029 }; | |
2030 | |
2031 | |
2032 class BoxFloat32x4SlowPath : public SlowPathCode { | |
2033 public: | |
2034 explicit BoxFloat32x4SlowPath(Instruction* instruction) | |
2035 : instruction_(instruction) { } | |
2036 | |
2037 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2038 __ Comment("BoxFloat32x4SlowPath"); | |
2039 __ Bind(entry_label()); | |
2040 Isolate* isolate = compiler->isolate(); | |
2041 StubCode* stub_code = isolate->stub_code(); | |
2042 const Class& float32x4_class = compiler->float32x4_class(); | |
2043 const Code& stub = | |
2044 Code::Handle(isolate, | |
2045 stub_code->GetAllocationStubForClass(float32x4_class)); | |
2046 const ExternalLabel label(stub.EntryPoint()); | |
2047 | |
2048 LocationSummary* locs = instruction_->locs(); | |
2049 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2050 | |
2051 compiler->SaveLiveRegisters(locs); | |
2052 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2053 &label, | |
2054 RawPcDescriptors::kOther, | |
2055 locs); | |
2056 __ MoveRegister(locs->out(0).reg(), RAX); | |
2057 compiler->RestoreLiveRegisters(locs); | |
2058 | |
2059 __ jmp(exit_label()); | |
2060 } | |
2061 | |
2062 private: | |
2063 Instruction* instruction_; | |
2064 }; | |
2065 | |
2066 | |
2067 class BoxFloat64x2SlowPath : public SlowPathCode { | |
2068 public: | |
2069 explicit BoxFloat64x2SlowPath(Instruction* instruction) | |
2070 : instruction_(instruction) { } | |
2071 | |
2072 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2073 __ Comment("BoxFloat64x2SlowPath"); | |
2074 __ Bind(entry_label()); | |
2075 Isolate* isolate = compiler->isolate(); | |
2076 StubCode* stub_code = isolate->stub_code(); | |
2077 const Class& float64x2_class = compiler->float64x2_class(); | |
2078 const Code& stub = | |
2079 Code::Handle(isolate, | |
2080 stub_code->GetAllocationStubForClass(float64x2_class)); | |
2081 const ExternalLabel label(stub.EntryPoint()); | |
2082 | |
2083 LocationSummary* locs = instruction_->locs(); | |
2084 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2085 | |
2086 compiler->SaveLiveRegisters(locs); | |
2087 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2088 &label, | |
2089 RawPcDescriptors::kOther, | |
2090 locs); | |
2091 __ MoveRegister(locs->out(0).reg(), RAX); | |
2092 compiler->RestoreLiveRegisters(locs); | |
2093 | |
2094 __ jmp(exit_label()); | |
2095 } | |
2096 | |
2097 private: | |
2098 Instruction* instruction_; | |
2099 }; | |
2100 | |
2101 | |
2102 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, | 1992 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, |
2103 bool opt) const { | 1993 bool opt) const { |
2104 const intptr_t kNumInputs = 1; | 1994 const intptr_t kNumInputs = 1; |
2105 const intptr_t kNumTemps = | 1995 const intptr_t kNumTemps = |
2106 (IsUnboxedLoad() && opt) ? 1 : | 1996 (IsUnboxedLoad() && opt) ? 1 : |
2107 ((IsPotentialUnboxedLoad()) ? 2 : 0); | 1997 ((IsPotentialUnboxedLoad()) ? 2 : 0); |
2108 LocationSummary* locs = new(isolate) LocationSummary( | 1998 LocationSummary* locs = new(isolate) LocationSummary( |
2109 isolate, kNumInputs, kNumTemps, | 1999 isolate, kNumInputs, kNumTemps, |
2110 (opt && !IsPotentialUnboxedLoad()) | 2000 (opt && !IsPotentialUnboxedLoad()) |
2111 ? LocationSummary::kNoCall | 2001 ? LocationSummary::kNoCall |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2182 | 2072 |
2183 // Fall through. | 2073 // Fall through. |
2184 __ jmp(&load_pointer); | 2074 __ jmp(&load_pointer); |
2185 | 2075 |
2186 if (!compiler->is_optimizing()) { | 2076 if (!compiler->is_optimizing()) { |
2187 locs()->live_registers()->Add(locs()->in(0)); | 2077 locs()->live_registers()->Add(locs()->in(0)); |
2188 } | 2078 } |
2189 | 2079 |
2190 { | 2080 { |
2191 __ Bind(&load_double); | 2081 __ Bind(&load_double); |
2192 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2082 BoxAllocationSlowPath::Allocate( |
2193 compiler->AddSlowPathCode(slow_path); | 2083 compiler, this, compiler->double_class(), result); |
2194 | |
2195 __ TryAllocate(compiler->double_class(), | |
2196 slow_path->entry_label(), | |
2197 Assembler::kFarJump, | |
2198 result, | |
2199 PP); | |
2200 __ Bind(slow_path->exit_label()); | |
2201 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2084 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2202 __ movsd(value, FieldAddress(temp, Double::value_offset())); | 2085 __ movsd(value, FieldAddress(temp, Double::value_offset())); |
2203 __ movsd(FieldAddress(result, Double::value_offset()), value); | 2086 __ movsd(FieldAddress(result, Double::value_offset()), value); |
2204 __ jmp(&done); | 2087 __ jmp(&done); |
2205 } | 2088 } |
2206 | 2089 |
2207 { | 2090 { |
2208 __ Bind(&load_float32x4); | 2091 __ Bind(&load_float32x4); |
2209 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 2092 BoxAllocationSlowPath::Allocate( |
2210 compiler->AddSlowPathCode(slow_path); | 2093 compiler, this, compiler->float32x4_class(), result); |
2211 | |
2212 __ TryAllocate(compiler->float32x4_class(), | |
2213 slow_path->entry_label(), | |
2214 Assembler::kFarJump, | |
2215 result, | |
2216 PP); | |
2217 __ Bind(slow_path->exit_label()); | |
2218 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2094 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2219 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); | 2095 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); |
2220 __ movups(FieldAddress(result, Float32x4::value_offset()), value); | 2096 __ movups(FieldAddress(result, Float32x4::value_offset()), value); |
2221 __ jmp(&done); | 2097 __ jmp(&done); |
2222 } | 2098 } |
2223 | 2099 |
2224 { | 2100 { |
2225 __ Bind(&load_float64x2); | 2101 __ Bind(&load_float64x2); |
2226 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 2102 BoxAllocationSlowPath::Allocate( |
2227 compiler->AddSlowPathCode(slow_path); | 2103 compiler, this, compiler->float64x2_class(), result); |
2228 | |
2229 __ TryAllocate(compiler->float64x2_class(), | |
2230 slow_path->entry_label(), | |
2231 Assembler::kFarJump, | |
2232 result, | |
2233 temp); | |
2234 __ Bind(slow_path->exit_label()); | |
2235 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2104 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2236 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); | 2105 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); |
2237 __ movups(FieldAddress(result, Float64x2::value_offset()), value); | 2106 __ movups(FieldAddress(result, Float64x2::value_offset()), value); |
2238 __ jmp(&done); | 2107 __ jmp(&done); |
2239 } | 2108 } |
2240 | 2109 |
2241 __ Bind(&load_pointer); | 2110 __ Bind(&load_pointer); |
2242 } | 2111 } |
2243 __ movq(result, FieldAddress(instance_reg, offset_in_bytes())); | 2112 __ movq(result, FieldAddress(instance_reg, offset_in_bytes())); |
2244 __ Bind(&done); | 2113 __ Bind(&done); |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 isolate, kNumInputs, | 3059 isolate, kNumInputs, |
3191 kNumTemps, | 3060 kNumTemps, |
3192 LocationSummary::kCallOnSlowPath); | 3061 LocationSummary::kCallOnSlowPath); |
3193 summary->set_in(0, Location::RequiresFpuRegister()); | 3062 summary->set_in(0, Location::RequiresFpuRegister()); |
3194 summary->set_out(0, Location::RequiresRegister()); | 3063 summary->set_out(0, Location::RequiresRegister()); |
3195 return summary; | 3064 return summary; |
3196 } | 3065 } |
3197 | 3066 |
3198 | 3067 |
3199 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3068 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3200 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | |
3201 compiler->AddSlowPathCode(slow_path); | |
3202 | |
3203 Register out_reg = locs()->out(0).reg(); | 3069 Register out_reg = locs()->out(0).reg(); |
3204 XmmRegister value = locs()->in(0).fpu_reg(); | 3070 XmmRegister value = locs()->in(0).fpu_reg(); |
3205 | 3071 |
3206 __ TryAllocate(compiler->double_class(), | 3072 BoxAllocationSlowPath::Allocate( |
3207 slow_path->entry_label(), | 3073 compiler, this, compiler->double_class(), out_reg); |
3208 Assembler::kFarJump, | |
3209 out_reg, | |
3210 PP); | |
3211 __ Bind(slow_path->exit_label()); | |
3212 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 3074 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
3213 } | 3075 } |
3214 | 3076 |
3215 | 3077 |
3216 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3078 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, |
3217 bool opt) const { | 3079 bool opt) const { |
3218 const intptr_t kNumInputs = 1; | 3080 const intptr_t kNumInputs = 1; |
3219 const intptr_t kNumTemps = 0; | 3081 const intptr_t kNumTemps = 0; |
3220 LocationSummary* summary = new(isolate) LocationSummary( | 3082 LocationSummary* summary = new(isolate) LocationSummary( |
3221 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3083 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3275 isolate, kNumInputs, | 3137 isolate, kNumInputs, |
3276 kNumTemps, | 3138 kNumTemps, |
3277 LocationSummary::kCallOnSlowPath); | 3139 LocationSummary::kCallOnSlowPath); |
3278 summary->set_in(0, Location::RequiresFpuRegister()); | 3140 summary->set_in(0, Location::RequiresFpuRegister()); |
3279 summary->set_out(0, Location::RequiresRegister()); | 3141 summary->set_out(0, Location::RequiresRegister()); |
3280 return summary; | 3142 return summary; |
3281 } | 3143 } |
3282 | 3144 |
3283 | 3145 |
3284 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3146 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3285 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | |
3286 compiler->AddSlowPathCode(slow_path); | |
3287 | |
3288 Register out_reg = locs()->out(0).reg(); | 3147 Register out_reg = locs()->out(0).reg(); |
3289 XmmRegister value = locs()->in(0).fpu_reg(); | 3148 XmmRegister value = locs()->in(0).fpu_reg(); |
3290 | 3149 |
3291 __ TryAllocate(compiler->float32x4_class(), | 3150 BoxAllocationSlowPath::Allocate( |
3292 slow_path->entry_label(), | 3151 compiler, this, compiler->float32x4_class(), out_reg); |
3293 Assembler::kFarJump, | |
3294 out_reg, | |
3295 PP); | |
3296 __ Bind(slow_path->exit_label()); | |
3297 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | 3152 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); |
3298 } | 3153 } |
3299 | 3154 |
3300 | 3155 |
3301 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3156 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, |
3302 bool opt) const { | 3157 bool opt) const { |
3303 const intptr_t kNumInputs = 1; | 3158 const intptr_t kNumInputs = 1; |
3304 return LocationSummary::Make(isolate, | 3159 return LocationSummary::Make(isolate, |
3305 kNumInputs, | 3160 kNumInputs, |
3306 Location::RequiresFpuRegister(), | 3161 Location::RequiresFpuRegister(), |
(...skipping 25 matching lines...) Expand all Loading... |
3332 isolate, kNumInputs, | 3187 isolate, kNumInputs, |
3333 kNumTemps, | 3188 kNumTemps, |
3334 LocationSummary::kCallOnSlowPath); | 3189 LocationSummary::kCallOnSlowPath); |
3335 summary->set_in(0, Location::RequiresFpuRegister()); | 3190 summary->set_in(0, Location::RequiresFpuRegister()); |
3336 summary->set_out(0, Location::RequiresRegister()); | 3191 summary->set_out(0, Location::RequiresRegister()); |
3337 return summary; | 3192 return summary; |
3338 } | 3193 } |
3339 | 3194 |
3340 | 3195 |
3341 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3196 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3342 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | |
3343 compiler->AddSlowPathCode(slow_path); | |
3344 | |
3345 Register out_reg = locs()->out(0).reg(); | 3197 Register out_reg = locs()->out(0).reg(); |
3346 XmmRegister value = locs()->in(0).fpu_reg(); | 3198 XmmRegister value = locs()->in(0).fpu_reg(); |
3347 | 3199 |
3348 __ TryAllocate(compiler->float64x2_class(), | 3200 BoxAllocationSlowPath::Allocate( |
3349 slow_path->entry_label(), | 3201 compiler, this, compiler->float64x2_class(), out_reg); |
3350 Assembler::kFarJump, | |
3351 out_reg, | |
3352 kNoRegister); | |
3353 __ Bind(slow_path->exit_label()); | |
3354 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); | 3202 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); |
3355 } | 3203 } |
3356 | 3204 |
3357 | 3205 |
3358 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | 3206 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, |
3359 bool opt) const { | 3207 bool opt) const { |
3360 const intptr_t value_cid = value()->Type()->ToCid(); | 3208 const intptr_t value_cid = value()->Type()->ToCid(); |
3361 const intptr_t kNumInputs = 1; | 3209 const intptr_t kNumInputs = 1; |
3362 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | 3210 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
3363 LocationSummary* summary = new(isolate) LocationSummary( | 3211 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 27 matching lines...) Expand all Loading... |
3391 LocationSummary* summary = new(isolate) LocationSummary( | 3239 LocationSummary* summary = new(isolate) LocationSummary( |
3392 isolate, kNumInputs, | 3240 isolate, kNumInputs, |
3393 kNumTemps, | 3241 kNumTemps, |
3394 LocationSummary::kCallOnSlowPath); | 3242 LocationSummary::kCallOnSlowPath); |
3395 summary->set_in(0, Location::RequiresFpuRegister()); | 3243 summary->set_in(0, Location::RequiresFpuRegister()); |
3396 summary->set_out(0, Location::RequiresRegister()); | 3244 summary->set_out(0, Location::RequiresRegister()); |
3397 return summary; | 3245 return summary; |
3398 } | 3246 } |
3399 | 3247 |
3400 | 3248 |
3401 class BoxInt32x4SlowPath : public SlowPathCode { | |
3402 public: | |
3403 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) | |
3404 : instruction_(instruction) { } | |
3405 | |
3406 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
3407 __ Comment("BoxInt32x4SlowPath"); | |
3408 __ Bind(entry_label()); | |
3409 Isolate* isolate = compiler->isolate(); | |
3410 StubCode* stub_code = isolate->stub_code(); | |
3411 const Class& int32x4_class = compiler->int32x4_class(); | |
3412 const Code& stub = | |
3413 Code::Handle(isolate, | |
3414 stub_code->GetAllocationStubForClass(int32x4_class)); | |
3415 const ExternalLabel label(stub.EntryPoint()); | |
3416 | |
3417 LocationSummary* locs = instruction_->locs(); | |
3418 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
3419 | |
3420 compiler->SaveLiveRegisters(locs); | |
3421 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
3422 &label, | |
3423 RawPcDescriptors::kOther, | |
3424 locs); | |
3425 __ MoveRegister(locs->out(0).reg(), RAX); | |
3426 compiler->RestoreLiveRegisters(locs); | |
3427 | |
3428 __ jmp(exit_label()); | |
3429 } | |
3430 | |
3431 private: | |
3432 BoxInt32x4Instr* instruction_; | |
3433 }; | |
3434 | |
3435 | |
3436 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3249 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3437 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); | |
3438 compiler->AddSlowPathCode(slow_path); | |
3439 | |
3440 Register out_reg = locs()->out(0).reg(); | 3250 Register out_reg = locs()->out(0).reg(); |
3441 XmmRegister value = locs()->in(0).fpu_reg(); | 3251 XmmRegister value = locs()->in(0).fpu_reg(); |
3442 | 3252 |
3443 __ TryAllocate(compiler->int32x4_class(), | 3253 BoxAllocationSlowPath::Allocate( |
3444 slow_path->entry_label(), | 3254 compiler, this, compiler->int32x4_class(), out_reg); |
3445 Assembler::kFarJump, | |
3446 out_reg, | |
3447 PP); | |
3448 __ Bind(slow_path->exit_label()); | |
3449 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); | 3255 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
3450 } | 3256 } |
3451 | 3257 |
3452 | 3258 |
3453 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3259 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, |
3454 bool opt) const { | 3260 bool opt) const { |
3455 const intptr_t kNumInputs = 1; | 3261 const intptr_t kNumInputs = 1; |
3456 const intptr_t kNumTemps = 0; | 3262 const intptr_t kNumTemps = 0; |
3457 LocationSummary* summary = new(isolate) LocationSummary( | 3263 LocationSummary* summary = new(isolate) LocationSummary( |
3458 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3264 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5962 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5768 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5963 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5769 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5964 #endif | 5770 #endif |
5965 } | 5771 } |
5966 | 5772 |
5967 } // namespace dart | 5773 } // namespace dart |
5968 | 5774 |
5969 #undef __ | 5775 #undef __ |
5970 | 5776 |
5971 #endif // defined TARGET_ARCH_X64 | 5777 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |