| 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 |