OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 // Deferred code is the last part of the instruction sequence. Mark | 182 // Deferred code is the last part of the instruction sequence. Mark |
183 // the generated code as done unless we bailed out. | 183 // the generated code as done unless we bailed out. |
184 if (!is_aborted()) status_ = DONE; | 184 if (!is_aborted()) status_ = DONE; |
185 return !is_aborted(); | 185 return !is_aborted(); |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 bool LCodeGen::GenerateSafepointTable() { | 189 bool LCodeGen::GenerateSafepointTable() { |
190 ASSERT(is_done()); | 190 ASSERT(is_done()); |
| 191 // Ensure that patching a deoptimization point won't overwrite the table. |
| 192 for (int i = 0; i < Assembler::kCallInstructionLength; i++) { |
| 193 masm()->int3(); |
| 194 } |
191 safepoints_.Emit(masm(), StackSlotCount()); | 195 safepoints_.Emit(masm(), StackSlotCount()); |
192 return !is_aborted(); | 196 return !is_aborted(); |
193 } | 197 } |
194 | 198 |
195 | 199 |
196 Register LCodeGen::ToRegister(int index) const { | 200 Register LCodeGen::ToRegister(int index) const { |
197 return Register::FromAllocationIndex(index); | 201 return Register::FromAllocationIndex(index); |
198 } | 202 } |
199 | 203 |
200 | 204 |
(...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 __ push(rax); | 1388 __ push(rax); |
1385 __ CallRuntime(Runtime::kTraceExit, 1); | 1389 __ CallRuntime(Runtime::kTraceExit, 1); |
1386 } | 1390 } |
1387 __ movq(rsp, rbp); | 1391 __ movq(rsp, rbp); |
1388 __ pop(rbp); | 1392 __ pop(rbp); |
1389 __ ret((ParameterCount() + 1) * kPointerSize); | 1393 __ ret((ParameterCount() + 1) * kPointerSize); |
1390 } | 1394 } |
1391 | 1395 |
1392 | 1396 |
1393 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { | 1397 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { |
1394 Abort("Unimplemented: %s", "DoLoadGlobal"); | 1398 Register result = ToRegister(instr->result()); |
| 1399 if (result.is(rax)) { |
| 1400 __ load_rax(instr->hydrogen()->cell().location(), |
| 1401 RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1402 } else { |
| 1403 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1404 __ movq(result, Operand(result, 0)); |
| 1405 } |
| 1406 if (instr->hydrogen()->check_hole_value()) { |
| 1407 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 1408 DeoptimizeIf(equal, instr->environment()); |
| 1409 } |
1395 } | 1410 } |
1396 | 1411 |
1397 | 1412 |
1398 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { | 1413 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { |
1399 Abort("Unimplemented: %s", "DoStoreGlobal"); | 1414 Abort("Unimplemented: %s", "DoStoreGlobal"); |
1400 } | 1415 } |
1401 | 1416 |
1402 | 1417 |
1403 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 1418 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
1404 Abort("Unimplemented: %s", "DoLoadContextSlot"); | 1419 Abort("Unimplemented: %s", "DoLoadContextSlot"); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1464 Abort("Unimplemented: %s", "DoArgumentsLength"); |
1450 } | 1465 } |
1451 | 1466 |
1452 | 1467 |
1453 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1468 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
1454 Abort("Unimplemented: %s", "DoApplyArguments"); | 1469 Abort("Unimplemented: %s", "DoApplyArguments"); |
1455 } | 1470 } |
1456 | 1471 |
1457 | 1472 |
1458 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 1473 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
1459 Abort("Unimplemented: %s", "DoPushArgument"); | 1474 LOperand* argument = instr->InputAt(0); |
| 1475 if (argument->IsConstantOperand()) { |
| 1476 LConstantOperand* const_op = LConstantOperand::cast(argument); |
| 1477 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
| 1478 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 1479 if (r.IsInteger32()) { |
| 1480 ASSERT(literal->IsNumber()); |
| 1481 __ push(Immediate(static_cast<int32_t>(literal->Number()))); |
| 1482 } else if (r.IsDouble()) { |
| 1483 Abort("unsupported double immediate"); |
| 1484 } else { |
| 1485 ASSERT(r.IsTagged()); |
| 1486 __ Push(literal); |
| 1487 } |
| 1488 } else if (argument->IsRegister()) { |
| 1489 __ push(ToRegister(argument)); |
| 1490 } else { |
| 1491 ASSERT(!argument->IsDoubleRegister()); |
| 1492 __ push(ToOperand(argument)); |
| 1493 } |
1460 } | 1494 } |
1461 | 1495 |
1462 | 1496 |
1463 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { | 1497 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { |
1464 Register result = ToRegister(instr->result()); | 1498 Register result = ToRegister(instr->result()); |
1465 __ movq(result, GlobalObjectOperand()); | 1499 __ movq(result, GlobalObjectOperand()); |
1466 } | 1500 } |
1467 | 1501 |
1468 | 1502 |
1469 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 1503 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 Abort("Unimplemented: %s", "DoCallGlobal"); | 1591 Abort("Unimplemented: %s", "DoCallGlobal"); |
1558 } | 1592 } |
1559 | 1593 |
1560 | 1594 |
1561 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 1595 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
1562 Abort("Unimplemented: %s", "DoCallKnownGlobal"); | 1596 Abort("Unimplemented: %s", "DoCallKnownGlobal"); |
1563 } | 1597 } |
1564 | 1598 |
1565 | 1599 |
1566 void LCodeGen::DoCallNew(LCallNew* instr) { | 1600 void LCodeGen::DoCallNew(LCallNew* instr) { |
1567 Abort("Unimplemented: %s", "DoCallNew"); | 1601 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
| 1602 ASSERT(ToRegister(instr->result()).is(rax)); |
| 1603 |
| 1604 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); |
| 1605 __ Set(rax, instr->arity()); |
| 1606 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
1568 } | 1607 } |
1569 | 1608 |
1570 | 1609 |
1571 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 1610 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
1572 Abort("Unimplemented: %s", "DoCallRuntime"); | 1611 Abort("Unimplemented: %s", "DoCallRuntime"); |
1573 } | 1612 } |
1574 | 1613 |
1575 | 1614 |
1576 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 1615 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
1577 Abort("Unimplemented: %s", "DoStoreNamedField"); | 1616 Abort("Unimplemented: %s", "DoStoreNamedField"); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 Abort("Unimplemented: %s", "DoNumberUntagD"); | 1756 Abort("Unimplemented: %s", "DoNumberUntagD"); |
1718 } | 1757 } |
1719 | 1758 |
1720 | 1759 |
1721 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 1760 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
1722 Abort("Unimplemented: %s", "DoDoubleToI"); | 1761 Abort("Unimplemented: %s", "DoDoubleToI"); |
1723 } | 1762 } |
1724 | 1763 |
1725 | 1764 |
1726 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 1765 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
1727 Abort("Unimplemented: %s", "DoCheckSmi"); | 1766 LOperand* input = instr->InputAt(0); |
| 1767 ASSERT(input->IsRegister()); |
| 1768 Condition cc = masm()->CheckSmi(ToRegister(input)); |
| 1769 if (instr->condition() != equal) { |
| 1770 cc = NegateCondition(cc); |
| 1771 } |
| 1772 DeoptimizeIf(cc, instr->environment()); |
1728 } | 1773 } |
1729 | 1774 |
1730 | 1775 |
1731 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 1776 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
1732 Abort("Unimplemented: %s", "DoCheckInstanceType"); | 1777 Abort("Unimplemented: %s", "DoCheckInstanceType"); |
1733 } | 1778 } |
1734 | 1779 |
1735 | 1780 |
1736 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 1781 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
1737 Abort("Unimplemented: %s", "DoCheckFunction"); | 1782 Abort("Unimplemented: %s", "DoCheckFunction"); |
1738 } | 1783 } |
1739 | 1784 |
1740 | 1785 |
1741 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 1786 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
1742 Abort("Unimplemented: %s", "DoCheckMap"); | 1787 LOperand* input = instr->InputAt(0); |
| 1788 ASSERT(input->IsRegister()); |
| 1789 Register reg = ToRegister(input); |
| 1790 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1791 instr->hydrogen()->map()); |
| 1792 DeoptimizeIf(not_equal, instr->environment()); |
1743 } | 1793 } |
1744 | 1794 |
1745 | 1795 |
1746 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | 1796 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { |
1747 Abort("Unimplemented: %s", "LoadHeapObject"); | 1797 Abort("Unimplemented: %s", "LoadHeapObject"); |
1748 } | 1798 } |
1749 | 1799 |
1750 | 1800 |
1751 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 1801 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
1752 Abort("Unimplemented: %s", "DoCheckPrototypeMaps"); | 1802 Abort("Unimplemented: %s", "DoCheckPrototypeMaps"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 | 1944 |
1895 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 1945 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
1896 Abort("Unimplemented: %s", "DoOsrEntry"); | 1946 Abort("Unimplemented: %s", "DoOsrEntry"); |
1897 } | 1947 } |
1898 | 1948 |
1899 #undef __ | 1949 #undef __ |
1900 | 1950 |
1901 } } // namespace v8::internal | 1951 } } // namespace v8::internal |
1902 | 1952 |
1903 #endif // V8_TARGET_ARCH_X64 | 1953 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |