Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: src/deoptimizer.cc

Issue 16779004: Allow the deoptimizer translation to track de-materialized objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Improved comments slightly. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/deoptimizer.h ('k') | src/hydrogen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698