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