OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 function_(function), | 527 function_(function), |
528 bailout_id_(bailout_id), | 528 bailout_id_(bailout_id), |
529 bailout_type_(type), | 529 bailout_type_(type), |
530 from_(from), | 530 from_(from), |
531 fp_to_sp_delta_(fp_to_sp_delta), | 531 fp_to_sp_delta_(fp_to_sp_delta), |
532 has_alignment_padding_(0), | 532 has_alignment_padding_(0), |
533 input_(NULL), | 533 input_(NULL), |
534 output_count_(0), | 534 output_count_(0), |
535 jsframe_count_(0), | 535 jsframe_count_(0), |
536 output_(NULL), | 536 output_(NULL), |
537 deferred_objects_tagged_values_(0), | 537 deferred_arguments_objects_values_(0), |
538 deferred_objects_double_values_(0), | 538 deferred_arguments_objects_(0), |
539 deferred_objects_(0), | |
540 deferred_heap_numbers_(0), | 539 deferred_heap_numbers_(0), |
541 trace_(false) { | 540 trace_(false) { |
542 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 541 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
543 // indicating an internal frame. | 542 // indicating an internal frame. |
544 if (function->IsSmi()) { | 543 if (function->IsSmi()) { |
545 function = NULL; | 544 function = NULL; |
546 } | 545 } |
547 if (function != NULL && function->IsOptimized()) { | 546 if (function != NULL && function->IsOptimized()) { |
548 function->shared()->increment_deopt_count(); | 547 function->shared()->increment_deopt_count(); |
549 if (bailout_type_ == Deoptimizer::SOFT) { | 548 if (bailout_type_ == Deoptimizer::SOFT) { |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1560 Code* notify_failure = | 1559 Code* notify_failure = |
1561 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); | 1560 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); |
1562 output_frame->SetContinuation( | 1561 output_frame->SetContinuation( |
1563 reinterpret_cast<intptr_t>(notify_failure->entry())); | 1562 reinterpret_cast<intptr_t>(notify_failure->entry())); |
1564 } | 1563 } |
1565 | 1564 |
1566 | 1565 |
1567 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 1566 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
1568 ASSERT_NE(DEBUGGER, bailout_type_); | 1567 ASSERT_NE(DEBUGGER, bailout_type_); |
1569 | 1568 |
1570 // Handlify all tagged object values before triggering any allocation. | 1569 // Handlify all argument object values before triggering any allocation. |
1571 List<Handle<Object> > values(deferred_objects_tagged_values_.length()); | 1570 List<Handle<Object> > values(deferred_arguments_objects_values_.length()); |
1572 for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) { | 1571 for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) { |
1573 values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_)); | 1572 values.Add(Handle<Object>(deferred_arguments_objects_values_[i], |
| 1573 isolate_)); |
1574 } | 1574 } |
1575 | 1575 |
1576 // Play it safe and clear all unhandlified values before we continue. | 1576 // Play it safe and clear all unhandlified values before we continue. |
1577 deferred_objects_tagged_values_.Clear(); | 1577 deferred_arguments_objects_values_.Clear(); |
1578 | 1578 |
1579 // Materialize all heap numbers before looking at arguments because when the | 1579 // Materialize all heap numbers before looking at arguments because when the |
1580 // output frames are used to materialize arguments objects later on they need | 1580 // output frames are used to materialize arguments objects later on they need |
1581 // to already contain valid heap numbers. | 1581 // to already contain valid heap numbers. |
1582 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { | 1582 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { |
1583 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; | 1583 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; |
1584 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1584 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
1585 if (trace_) { | 1585 if (trace_) { |
1586 PrintF("Materializing a new heap number %p [%e] in slot %p\n", | 1586 PrintF("Materializing a new heap number %p [%e] in slot %p\n", |
1587 reinterpret_cast<void*>(*num), | 1587 reinterpret_cast<void*>(*num), |
1588 d.value(), | 1588 d.value(), |
1589 d.slot_address()); | 1589 d.slot_address()); |
1590 } | 1590 } |
1591 Memory::Object_at(d.slot_address()) = *num; | 1591 Memory::Object_at(d.slot_address()) = *num; |
1592 } | 1592 } |
1593 | 1593 |
1594 // Materialize all heap numbers required for arguments objects. | |
1595 for (int i = 0; i < values.length(); i++) { | |
1596 if (!values.at(i)->IsTheHole()) continue; | |
1597 double double_value = deferred_objects_double_values_[i]; | |
1598 Handle<Object> num = isolate_->factory()->NewNumber(double_value); | |
1599 if (trace_) { | |
1600 PrintF("Materializing a new heap number %p [%e] for arguments object\n", | |
1601 reinterpret_cast<void*>(*num), double_value); | |
1602 } | |
1603 values.Set(i, num); | |
1604 } | |
1605 | |
1606 // Materialize arguments objects one frame at a time. | 1594 // Materialize arguments objects one frame at a time. |
1607 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 1595 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
1608 if (frame_index != 0) it->Advance(); | 1596 if (frame_index != 0) it->Advance(); |
1609 JavaScriptFrame* frame = it->frame(); | 1597 JavaScriptFrame* frame = it->frame(); |
1610 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate_); | 1598 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate_); |
1611 Handle<JSObject> arguments; | 1599 Handle<JSObject> arguments; |
1612 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { | 1600 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { |
1613 if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) { | 1601 if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) { |
1614 ObjectMaterializationDescriptor descriptor = | 1602 ArgumentsObjectMaterializationDescriptor descriptor = |
1615 deferred_objects_.RemoveLast(); | 1603 deferred_arguments_objects_.RemoveLast(); |
1616 const int length = descriptor.object_length(); | 1604 const int length = descriptor.arguments_length(); |
1617 if (arguments.is_null()) { | 1605 if (arguments.is_null()) { |
1618 if (frame->has_adapted_arguments()) { | 1606 if (frame->has_adapted_arguments()) { |
1619 // Use the arguments adapter frame we just built to materialize the | 1607 // Use the arguments adapter frame we just built to materialize the |
1620 // arguments object. FunctionGetArguments can't throw an exception, | 1608 // arguments object. FunctionGetArguments can't throw an exception, |
1621 // so cast away the doubt with an assert. | 1609 // so cast away the doubt with an assert. |
1622 arguments = Handle<JSObject>(JSObject::cast( | 1610 arguments = Handle<JSObject>(JSObject::cast( |
1623 Accessors::FunctionGetArguments(*function, | 1611 Accessors::FunctionGetArguments(*function, |
1624 NULL)->ToObjectUnchecked())); | 1612 NULL)->ToObjectUnchecked())); |
1625 values.RewindBy(length); | 1613 values.RewindBy(length); |
1626 } else { | 1614 } else { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 index); | 1688 index); |
1701 } | 1689 } |
1702 | 1690 |
1703 info->SetExpression(index, *num); | 1691 info->SetExpression(index, *num); |
1704 } | 1692 } |
1705 } | 1693 } |
1706 } | 1694 } |
1707 #endif | 1695 #endif |
1708 | 1696 |
1709 | 1697 |
1710 static const char* TraceValueType(bool is_smi, bool is_native = false) { | 1698 static const char* TraceValueType(bool is_smi, bool is_native) { |
1711 if (is_native) { | 1699 if (is_native) { |
1712 return "native"; | 1700 return "native"; |
1713 } else if (is_smi) { | 1701 } else if (is_smi) { |
1714 return "smi"; | 1702 return "smi"; |
1715 } | 1703 } |
1716 | 1704 |
1717 return "heap number"; | 1705 return "heap number"; |
1718 } | 1706 } |
1719 | 1707 |
1720 | 1708 |
1721 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, | |
1722 int object_opcode, | |
1723 int field_index) { | |
1724 disasm::NameConverter converter; | |
1725 Address object_slot = deferred_objects_.last().slot_address(); | |
1726 | |
1727 // Ignore commands marked as duplicate and act on the first non-duplicate. | |
1728 Translation::Opcode opcode = | |
1729 static_cast<Translation::Opcode>(iterator->Next()); | |
1730 while (opcode == Translation::DUPLICATE) { | |
1731 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
1732 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | |
1733 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
1734 } | |
1735 | |
1736 switch (opcode) { | |
1737 case Translation::BEGIN: | |
1738 case Translation::JS_FRAME: | |
1739 case Translation::ARGUMENTS_ADAPTOR_FRAME: | |
1740 case Translation::CONSTRUCT_STUB_FRAME: | |
1741 case Translation::GETTER_STUB_FRAME: | |
1742 case Translation::SETTER_STUB_FRAME: | |
1743 case Translation::COMPILED_STUB_FRAME: | |
1744 case Translation::ARGUMENTS_OBJECT: | |
1745 case Translation::DUPLICATE: | |
1746 UNREACHABLE(); | |
1747 return; | |
1748 | |
1749 case Translation::REGISTER: { | |
1750 int input_reg = iterator->Next(); | |
1751 intptr_t input_value = input_->GetRegister(input_reg); | |
1752 if (trace_) { | |
1753 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1754 reinterpret_cast<intptr_t>(object_slot), | |
1755 field_index); | |
1756 PrintF("0x%08" V8PRIxPTR " ; %s ", input_value, | |
1757 converter.NameOfCPURegister(input_reg)); | |
1758 reinterpret_cast<Object*>(input_value)->ShortPrint(); | |
1759 PrintF("\n"); | |
1760 } | |
1761 AddObjectTaggedValue(input_value); | |
1762 return; | |
1763 } | |
1764 | |
1765 case Translation::INT32_REGISTER: { | |
1766 int input_reg = iterator->Next(); | |
1767 intptr_t value = input_->GetRegister(input_reg); | |
1768 bool is_smi = Smi::IsValid(value); | |
1769 if (trace_) { | |
1770 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1771 reinterpret_cast<intptr_t>(object_slot), | |
1772 field_index); | |
1773 PrintF("%" V8PRIdPTR " ; %s (%s)\n", value, | |
1774 converter.NameOfCPURegister(input_reg), | |
1775 TraceValueType(is_smi)); | |
1776 } | |
1777 if (is_smi) { | |
1778 intptr_t tagged_value = | |
1779 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | |
1780 AddObjectTaggedValue(tagged_value); | |
1781 } else { | |
1782 double double_value = static_cast<double>(static_cast<int32_t>(value)); | |
1783 AddObjectDoubleValue(double_value); | |
1784 } | |
1785 return; | |
1786 } | |
1787 | |
1788 case Translation::UINT32_REGISTER: { | |
1789 int input_reg = iterator->Next(); | |
1790 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | |
1791 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | |
1792 if (trace_) { | |
1793 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1794 reinterpret_cast<intptr_t>(object_slot), | |
1795 field_index); | |
1796 PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value, | |
1797 converter.NameOfCPURegister(input_reg), | |
1798 TraceValueType(is_smi)); | |
1799 } | |
1800 if (is_smi) { | |
1801 intptr_t tagged_value = | |
1802 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | |
1803 AddObjectTaggedValue(tagged_value); | |
1804 } else { | |
1805 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | |
1806 AddObjectDoubleValue(double_value); | |
1807 } | |
1808 return; | |
1809 } | |
1810 | |
1811 case Translation::DOUBLE_REGISTER: { | |
1812 int input_reg = iterator->Next(); | |
1813 double value = input_->GetDoubleRegister(input_reg); | |
1814 if (trace_) { | |
1815 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1816 reinterpret_cast<intptr_t>(object_slot), | |
1817 field_index); | |
1818 PrintF("%e ; %s\n", value, | |
1819 DoubleRegister::AllocationIndexToString(input_reg)); | |
1820 } | |
1821 AddObjectDoubleValue(value); | |
1822 return; | |
1823 } | |
1824 | |
1825 case Translation::STACK_SLOT: { | |
1826 int input_slot_index = iterator->Next(); | |
1827 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | |
1828 intptr_t input_value = input_->GetFrameSlot(input_offset); | |
1829 if (trace_) { | |
1830 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1831 reinterpret_cast<intptr_t>(object_slot), | |
1832 field_index); | |
1833 PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); | |
1834 reinterpret_cast<Object*>(input_value)->ShortPrint(); | |
1835 PrintF("\n"); | |
1836 } | |
1837 AddObjectTaggedValue(input_value); | |
1838 return; | |
1839 } | |
1840 | |
1841 case Translation::INT32_STACK_SLOT: { | |
1842 int input_slot_index = iterator->Next(); | |
1843 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | |
1844 intptr_t value = input_->GetFrameSlot(input_offset); | |
1845 bool is_smi = Smi::IsValid(value); | |
1846 if (trace_) { | |
1847 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1848 reinterpret_cast<intptr_t>(object_slot), | |
1849 field_index); | |
1850 PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n", | |
1851 value, input_offset, TraceValueType(is_smi)); | |
1852 } | |
1853 if (is_smi) { | |
1854 intptr_t tagged_value = | |
1855 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | |
1856 AddObjectTaggedValue(tagged_value); | |
1857 } else { | |
1858 double double_value = static_cast<double>(static_cast<int32_t>(value)); | |
1859 AddObjectDoubleValue(double_value); | |
1860 } | |
1861 return; | |
1862 } | |
1863 | |
1864 case Translation::UINT32_STACK_SLOT: { | |
1865 int input_slot_index = iterator->Next(); | |
1866 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | |
1867 uintptr_t value = | |
1868 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | |
1869 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | |
1870 if (trace_) { | |
1871 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1872 reinterpret_cast<intptr_t>(object_slot), | |
1873 field_index); | |
1874 PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", | |
1875 value, input_offset, TraceValueType(is_smi)); | |
1876 } | |
1877 if (is_smi) { | |
1878 intptr_t tagged_value = | |
1879 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | |
1880 AddObjectTaggedValue(tagged_value); | |
1881 } else { | |
1882 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | |
1883 AddObjectDoubleValue(double_value); | |
1884 } | |
1885 return; | |
1886 } | |
1887 | |
1888 case Translation::DOUBLE_STACK_SLOT: { | |
1889 int input_slot_index = iterator->Next(); | |
1890 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | |
1891 double value = input_->GetDoubleFrameSlot(input_offset); | |
1892 if (trace_) { | |
1893 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1894 reinterpret_cast<intptr_t>(object_slot), | |
1895 field_index); | |
1896 PrintF("%e ; [sp + %d]\n", value, input_offset); | |
1897 } | |
1898 AddObjectDoubleValue(value); | |
1899 return; | |
1900 } | |
1901 | |
1902 case Translation::LITERAL: { | |
1903 Object* literal = ComputeLiteral(iterator->Next()); | |
1904 if (trace_) { | |
1905 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | |
1906 reinterpret_cast<intptr_t>(object_slot), | |
1907 field_index); | |
1908 literal->ShortPrint(); | |
1909 PrintF(" ; literal\n"); | |
1910 } | |
1911 intptr_t value = reinterpret_cast<intptr_t>(literal); | |
1912 AddObjectTaggedValue(value); | |
1913 return; | |
1914 } | |
1915 } | |
1916 } | |
1917 | |
1918 | |
1919 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 1709 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
1920 int frame_index, | 1710 int frame_index, |
1921 unsigned output_offset, | 1711 unsigned output_offset, |
1922 DeoptimizerTranslatedValueType value_type) { | 1712 DeoptimizerTranslatedValueType value_type) { |
1923 disasm::NameConverter converter; | 1713 disasm::NameConverter converter; |
1924 // A GC-safe temporary placeholder that we can put in the output frame. | 1714 // A GC-safe temporary placeholder that we can put in the output frame. |
1925 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 1715 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
1926 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; | 1716 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; |
1927 | 1717 |
1928 // Ignore commands marked as duplicate and act on the first non-duplicate. | 1718 // Ignore commands marked as duplicate and act on the first non-duplicate. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 } | 1751 } |
1962 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 1752 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
1963 return; | 1753 return; |
1964 } | 1754 } |
1965 | 1755 |
1966 case Translation::INT32_REGISTER: { | 1756 case Translation::INT32_REGISTER: { |
1967 int input_reg = iterator->Next(); | 1757 int input_reg = iterator->Next(); |
1968 intptr_t value = input_->GetRegister(input_reg); | 1758 intptr_t value = input_->GetRegister(input_reg); |
1969 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 1759 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
1970 Smi::IsValid(value); | 1760 Smi::IsValid(value); |
| 1761 |
1971 if (trace_) { | 1762 if (trace_) { |
1972 PrintF( | 1763 PrintF( |
1973 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", | 1764 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", |
1974 output_[frame_index]->GetTop() + output_offset, | 1765 output_[frame_index]->GetTop() + output_offset, |
1975 output_offset, | 1766 output_offset, |
1976 value, | 1767 value, |
1977 converter.NameOfCPURegister(input_reg), | 1768 converter.NameOfCPURegister(input_reg), |
1978 TraceValueType(is_smi, is_native)); | 1769 TraceValueType(is_smi, is_native)); |
1979 } | 1770 } |
1980 if (is_smi) { | 1771 if (is_smi) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2038 } | 1829 } |
2039 // We save the untagged value on the side and store a GC-safe | 1830 // We save the untagged value on the side and store a GC-safe |
2040 // temporary placeholder in the frame. | 1831 // temporary placeholder in the frame. |
2041 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 1832 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
2042 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1833 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
2043 return; | 1834 return; |
2044 } | 1835 } |
2045 | 1836 |
2046 case Translation::STACK_SLOT: { | 1837 case Translation::STACK_SLOT: { |
2047 int input_slot_index = iterator->Next(); | 1838 int input_slot_index = iterator->Next(); |
2048 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 1839 unsigned input_offset = |
| 1840 input_->GetOffsetFromSlotIndex(input_slot_index); |
2049 intptr_t input_value = input_->GetFrameSlot(input_offset); | 1841 intptr_t input_value = input_->GetFrameSlot(input_offset); |
2050 if (trace_) { | 1842 if (trace_) { |
2051 PrintF(" 0x%08" V8PRIxPTR ": ", | 1843 PrintF(" 0x%08" V8PRIxPTR ": ", |
2052 output_[frame_index]->GetTop() + output_offset); | 1844 output_[frame_index]->GetTop() + output_offset); |
2053 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", | 1845 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", |
2054 output_offset, | 1846 output_offset, |
2055 input_value, | 1847 input_value, |
2056 input_offset); | 1848 input_offset); |
2057 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 1849 reinterpret_cast<Object*>(input_value)->ShortPrint(); |
2058 PrintF("\n"); | 1850 PrintF("\n"); |
2059 } | 1851 } |
2060 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 1852 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
2061 return; | 1853 return; |
2062 } | 1854 } |
2063 | 1855 |
2064 case Translation::INT32_STACK_SLOT: { | 1856 case Translation::INT32_STACK_SLOT: { |
2065 int input_slot_index = iterator->Next(); | 1857 int input_slot_index = iterator->Next(); |
2066 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 1858 unsigned input_offset = |
| 1859 input_->GetOffsetFromSlotIndex(input_slot_index); |
2067 intptr_t value = input_->GetFrameSlot(input_offset); | 1860 intptr_t value = input_->GetFrameSlot(input_offset); |
2068 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 1861 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
2069 Smi::IsValid(value); | 1862 Smi::IsValid(value); |
2070 if (trace_) { | 1863 if (trace_) { |
2071 PrintF(" 0x%08" V8PRIxPTR ": ", | 1864 PrintF(" 0x%08" V8PRIxPTR ": ", |
2072 output_[frame_index]->GetTop() + output_offset); | 1865 output_[frame_index]->GetTop() + output_offset); |
2073 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", | 1866 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", |
2074 output_offset, | 1867 output_offset, |
2075 value, | 1868 value, |
2076 input_offset, | 1869 input_offset, |
(...skipping 11 matching lines...) Expand all Loading... |
2088 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 1881 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
2089 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1882 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
2090 static_cast<double>(static_cast<int32_t>(value))); | 1883 static_cast<double>(static_cast<int32_t>(value))); |
2091 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1884 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
2092 } | 1885 } |
2093 return; | 1886 return; |
2094 } | 1887 } |
2095 | 1888 |
2096 case Translation::UINT32_STACK_SLOT: { | 1889 case Translation::UINT32_STACK_SLOT: { |
2097 int input_slot_index = iterator->Next(); | 1890 int input_slot_index = iterator->Next(); |
2098 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 1891 unsigned input_offset = |
| 1892 input_->GetOffsetFromSlotIndex(input_slot_index); |
2099 uintptr_t value = | 1893 uintptr_t value = |
2100 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 1894 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
2101 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 1895 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
2102 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 1896 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
2103 if (trace_) { | 1897 if (trace_) { |
2104 PrintF(" 0x%08" V8PRIxPTR ": ", | 1898 PrintF(" 0x%08" V8PRIxPTR ": ", |
2105 output_[frame_index]->GetTop() + output_offset); | 1899 output_[frame_index]->GetTop() + output_offset); |
2106 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", | 1900 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", |
2107 output_offset, | 1901 output_offset, |
2108 value, | 1902 value, |
(...skipping 12 matching lines...) Expand all Loading... |
2121 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 1915 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
2122 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1916 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
2123 static_cast<double>(static_cast<uint32_t>(value))); | 1917 static_cast<double>(static_cast<uint32_t>(value))); |
2124 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1918 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
2125 } | 1919 } |
2126 return; | 1920 return; |
2127 } | 1921 } |
2128 | 1922 |
2129 case Translation::DOUBLE_STACK_SLOT: { | 1923 case Translation::DOUBLE_STACK_SLOT: { |
2130 int input_slot_index = iterator->Next(); | 1924 int input_slot_index = iterator->Next(); |
2131 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 1925 unsigned input_offset = |
| 1926 input_->GetOffsetFromSlotIndex(input_slot_index); |
2132 double value = input_->GetDoubleFrameSlot(input_offset); | 1927 double value = input_->GetDoubleFrameSlot(input_offset); |
2133 if (trace_) { | 1928 if (trace_) { |
2134 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", | 1929 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", |
2135 output_[frame_index]->GetTop() + output_offset, | 1930 output_[frame_index]->GetTop() + output_offset, |
2136 output_offset, | 1931 output_offset, |
2137 value, | 1932 value, |
2138 input_offset); | 1933 input_offset); |
2139 } | 1934 } |
2140 // We save the untagged value on the side and store a GC-safe | 1935 // We save the untagged value on the side and store a GC-safe |
2141 // temporary placeholder in the frame. | 1936 // temporary placeholder in the frame. |
(...skipping 10 matching lines...) Expand all Loading... |
2152 output_offset); | 1947 output_offset); |
2153 literal->ShortPrint(); | 1948 literal->ShortPrint(); |
2154 PrintF(" ; literal\n"); | 1949 PrintF(" ; literal\n"); |
2155 } | 1950 } |
2156 intptr_t value = reinterpret_cast<intptr_t>(literal); | 1951 intptr_t value = reinterpret_cast<intptr_t>(literal); |
2157 output_[frame_index]->SetFrameSlot(output_offset, value); | 1952 output_[frame_index]->SetFrameSlot(output_offset, value); |
2158 return; | 1953 return; |
2159 } | 1954 } |
2160 | 1955 |
2161 case Translation::ARGUMENTS_OBJECT: { | 1956 case Translation::ARGUMENTS_OBJECT: { |
2162 int length = iterator->Next(); | 1957 bool args_known = iterator->Next(); |
| 1958 int args_index = iterator->Next() + 1; // Skip receiver. |
| 1959 int args_length = iterator->Next() - 1; // Skip receiver. |
2163 if (trace_) { | 1960 if (trace_) { |
2164 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 1961 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
2165 output_[frame_index]->GetTop() + output_offset, | 1962 output_[frame_index]->GetTop() + output_offset, |
2166 output_offset); | 1963 output_offset); |
2167 isolate_->heap()->arguments_marker()->ShortPrint(); | 1964 isolate_->heap()->arguments_marker()->ShortPrint(); |
2168 PrintF(" ; arguments object (length = %d)\n", length); | 1965 PrintF(" ; %sarguments object\n", args_known ? "" : "dummy "); |
2169 } | 1966 } |
2170 // Use the arguments marker value as a sentinel and fill in the arguments | 1967 // Use the arguments marker value as a sentinel and fill in the arguments |
2171 // object after the deoptimized frame is built. | 1968 // object after the deoptimized frame is built. |
2172 intptr_t value = reinterpret_cast<intptr_t>( | 1969 intptr_t value = reinterpret_cast<intptr_t>( |
2173 isolate_->heap()->arguments_marker()); | 1970 isolate_->heap()->arguments_marker()); |
2174 AddObjectStart(output_[frame_index]->GetTop() + output_offset, length); | 1971 AddArgumentsObject( |
| 1972 output_[frame_index]->GetTop() + output_offset, args_length); |
2175 output_[frame_index]->SetFrameSlot(output_offset, value); | 1973 output_[frame_index]->SetFrameSlot(output_offset, value); |
2176 // We save the argument values on the side and materialize the actual | 1974 // We save the tagged argument values on the side and materialize the |
2177 // arguments object after the deoptimized frame is built. | 1975 // actual arguments object after the deoptimized frame is built. |
2178 for (int i = 0; i < length; i++) { | 1976 for (int i = 0; i < args_length; i++) { |
2179 DoTranslateObject(iterator, Translation::ARGUMENTS_OBJECT, i); | 1977 unsigned input_offset = input_->GetOffsetFromSlotIndex(args_index + i); |
| 1978 intptr_t input_value = args_known |
| 1979 ? input_->GetFrameSlot(input_offset) |
| 1980 : reinterpret_cast<intptr_t>(isolate_->heap()->the_hole_value()); |
| 1981 AddArgumentsObjectValue(input_value); |
2180 } | 1982 } |
2181 return; | 1983 return; |
2182 } | 1984 } |
2183 } | 1985 } |
2184 } | 1986 } |
2185 | 1987 |
2186 | 1988 |
2187 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, | 1989 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, |
2188 int* input_offset) { | 1990 int* input_offset) { |
2189 disasm::NameConverter converter; | 1991 disasm::NameConverter converter; |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2515 | 2317 |
2516 | 2318 |
2517 Object* Deoptimizer::ComputeLiteral(int index) const { | 2319 Object* Deoptimizer::ComputeLiteral(int index) const { |
2518 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 2320 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
2519 compiled_code_->deoptimization_data()); | 2321 compiled_code_->deoptimization_data()); |
2520 FixedArray* literals = data->LiteralArray(); | 2322 FixedArray* literals = data->LiteralArray(); |
2521 return literals->get(index); | 2323 return literals->get(index); |
2522 } | 2324 } |
2523 | 2325 |
2524 | 2326 |
2525 void Deoptimizer::AddObjectStart(intptr_t slot_address, int length) { | 2327 void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) { |
2526 ObjectMaterializationDescriptor object_desc( | 2328 ArgumentsObjectMaterializationDescriptor object_desc( |
2527 reinterpret_cast<Address>(slot_address), length); | 2329 reinterpret_cast<Address>(slot_address), argc); |
2528 deferred_objects_.Add(object_desc); | 2330 deferred_arguments_objects_.Add(object_desc); |
2529 } | 2331 } |
2530 | 2332 |
2531 | 2333 |
2532 void Deoptimizer::AddObjectTaggedValue(intptr_t value) { | 2334 void Deoptimizer::AddArgumentsObjectValue(intptr_t value) { |
2533 deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); | 2335 deferred_arguments_objects_values_.Add(reinterpret_cast<Object*>(value)); |
2534 deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); | |
2535 } | 2336 } |
2536 | 2337 |
2537 | 2338 |
2538 void Deoptimizer::AddObjectDoubleValue(double value) { | |
2539 deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); | |
2540 deferred_objects_double_values_.Add(value); | |
2541 } | |
2542 | |
2543 | |
2544 void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) { | 2339 void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) { |
2545 HeapNumberMaterializationDescriptor value_desc( | 2340 HeapNumberMaterializationDescriptor value_desc( |
2546 reinterpret_cast<Address>(slot_address), value); | 2341 reinterpret_cast<Address>(slot_address), value); |
2547 deferred_heap_numbers_.Add(value_desc); | 2342 deferred_heap_numbers_.Add(value_desc); |
2548 } | 2343 } |
2549 | 2344 |
2550 | 2345 |
2551 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, | 2346 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, |
2552 BailoutType type, | 2347 BailoutType type, |
2553 int max_entry_id) { | 2348 int max_entry_id) { |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2754 buffer_->Add(literal_id, zone()); | 2549 buffer_->Add(literal_id, zone()); |
2755 buffer_->Add(height, zone()); | 2550 buffer_->Add(height, zone()); |
2756 } | 2551 } |
2757 | 2552 |
2758 | 2553 |
2759 void Translation::BeginCompiledStubFrame() { | 2554 void Translation::BeginCompiledStubFrame() { |
2760 buffer_->Add(COMPILED_STUB_FRAME, zone()); | 2555 buffer_->Add(COMPILED_STUB_FRAME, zone()); |
2761 } | 2556 } |
2762 | 2557 |
2763 | 2558 |
2764 void Translation::BeginArgumentsObject(int args_length) { | |
2765 buffer_->Add(ARGUMENTS_OBJECT, zone()); | |
2766 buffer_->Add(args_length, zone()); | |
2767 } | |
2768 | |
2769 | |
2770 void Translation::StoreRegister(Register reg) { | 2559 void Translation::StoreRegister(Register reg) { |
2771 buffer_->Add(REGISTER, zone()); | 2560 buffer_->Add(REGISTER, zone()); |
2772 buffer_->Add(reg.code(), zone()); | 2561 buffer_->Add(reg.code(), zone()); |
2773 } | 2562 } |
2774 | 2563 |
2775 | 2564 |
2776 void Translation::StoreInt32Register(Register reg) { | 2565 void Translation::StoreInt32Register(Register reg) { |
2777 buffer_->Add(INT32_REGISTER, zone()); | 2566 buffer_->Add(INT32_REGISTER, zone()); |
2778 buffer_->Add(reg.code(), zone()); | 2567 buffer_->Add(reg.code(), zone()); |
2779 } | 2568 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2814 buffer_->Add(index, zone()); | 2603 buffer_->Add(index, zone()); |
2815 } | 2604 } |
2816 | 2605 |
2817 | 2606 |
2818 void Translation::StoreLiteral(int literal_id) { | 2607 void Translation::StoreLiteral(int literal_id) { |
2819 buffer_->Add(LITERAL, zone()); | 2608 buffer_->Add(LITERAL, zone()); |
2820 buffer_->Add(literal_id, zone()); | 2609 buffer_->Add(literal_id, zone()); |
2821 } | 2610 } |
2822 | 2611 |
2823 | 2612 |
| 2613 void Translation::StoreArgumentsObject(bool args_known, |
| 2614 int args_index, |
| 2615 int args_length) { |
| 2616 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
| 2617 buffer_->Add(args_known, zone()); |
| 2618 buffer_->Add(args_index, zone()); |
| 2619 buffer_->Add(args_length, zone()); |
| 2620 } |
| 2621 |
| 2622 |
2824 void Translation::MarkDuplicate() { | 2623 void Translation::MarkDuplicate() { |
2825 buffer_->Add(DUPLICATE, zone()); | 2624 buffer_->Add(DUPLICATE, zone()); |
2826 } | 2625 } |
2827 | 2626 |
2828 | 2627 |
2829 int Translation::NumberOfOperandsFor(Opcode opcode) { | 2628 int Translation::NumberOfOperandsFor(Opcode opcode) { |
2830 switch (opcode) { | 2629 switch (opcode) { |
2831 case DUPLICATE: | 2630 case DUPLICATE: |
2832 return 0; | 2631 return 0; |
2833 case GETTER_STUB_FRAME: | 2632 case GETTER_STUB_FRAME: |
2834 case SETTER_STUB_FRAME: | 2633 case SETTER_STUB_FRAME: |
2835 case ARGUMENTS_OBJECT: | |
2836 case REGISTER: | 2634 case REGISTER: |
2837 case INT32_REGISTER: | 2635 case INT32_REGISTER: |
2838 case UINT32_REGISTER: | 2636 case UINT32_REGISTER: |
2839 case DOUBLE_REGISTER: | 2637 case DOUBLE_REGISTER: |
2840 case STACK_SLOT: | 2638 case STACK_SLOT: |
2841 case INT32_STACK_SLOT: | 2639 case INT32_STACK_SLOT: |
2842 case UINT32_STACK_SLOT: | 2640 case UINT32_STACK_SLOT: |
2843 case DOUBLE_STACK_SLOT: | 2641 case DOUBLE_STACK_SLOT: |
2844 case LITERAL: | 2642 case LITERAL: |
2845 case COMPILED_STUB_FRAME: | 2643 case COMPILED_STUB_FRAME: |
2846 return 1; | 2644 return 1; |
2847 case BEGIN: | 2645 case BEGIN: |
2848 case ARGUMENTS_ADAPTOR_FRAME: | 2646 case ARGUMENTS_ADAPTOR_FRAME: |
2849 case CONSTRUCT_STUB_FRAME: | 2647 case CONSTRUCT_STUB_FRAME: |
2850 return 2; | 2648 return 2; |
2851 case JS_FRAME: | 2649 case JS_FRAME: |
| 2650 case ARGUMENTS_OBJECT: |
2852 return 3; | 2651 return 3; |
2853 } | 2652 } |
2854 UNREACHABLE(); | 2653 UNREACHABLE(); |
2855 return -1; | 2654 return -1; |
2856 } | 2655 } |
2857 | 2656 |
2858 | 2657 |
2859 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 2658 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
2860 | 2659 |
2861 const char* Translation::StringFor(Opcode opcode) { | 2660 const char* Translation::StringFor(Opcode opcode) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3109 | 2908 |
3110 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2909 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3111 v->VisitPointer(BitCast<Object**>(&function_)); | 2910 v->VisitPointer(BitCast<Object**>(&function_)); |
3112 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2911 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3113 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2912 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3114 } | 2913 } |
3115 | 2914 |
3116 #endif // ENABLE_DEBUGGER_SUPPORT | 2915 #endif // ENABLE_DEBUGGER_SUPPORT |
3117 | 2916 |
3118 } } // namespace v8::internal | 2917 } } // namespace v8::internal |
OLD | NEW |