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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 fp_to_sp_delta_(fp_to_sp_delta), | 595 fp_to_sp_delta_(fp_to_sp_delta), |
596 has_alignment_padding_(0), | 596 has_alignment_padding_(0), |
597 input_(NULL), | 597 input_(NULL), |
598 output_count_(0), | 598 output_count_(0), |
599 jsframe_count_(0), | 599 jsframe_count_(0), |
600 output_(NULL), | 600 output_(NULL), |
601 deferred_objects_tagged_values_(0), | 601 deferred_objects_tagged_values_(0), |
602 deferred_objects_double_values_(0), | 602 deferred_objects_double_values_(0), |
603 deferred_objects_(0), | 603 deferred_objects_(0), |
604 deferred_heap_numbers_(0), | 604 deferred_heap_numbers_(0), |
| 605 jsframe_functions_(0), |
| 606 jsframe_has_adapted_arguments_(0), |
| 607 materialized_values_(NULL), |
| 608 materialized_objects_(NULL), |
| 609 materialization_value_index_(0), |
| 610 materialization_object_index_(0), |
605 trace_(false) { | 611 trace_(false) { |
606 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 612 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
607 // indicating an internal frame. | 613 // indicating an internal frame. |
608 if (function->IsSmi()) { | 614 if (function->IsSmi()) { |
609 function = NULL; | 615 function = NULL; |
610 } | 616 } |
611 ASSERT(from != NULL); | 617 ASSERT(from != NULL); |
612 if (function != NULL && function->IsOptimized()) { | 618 if (function != NULL && function->IsOptimized()) { |
613 function->shared()->increment_deopt_count(); | 619 function->shared()->increment_deopt_count(); |
614 if (bailout_type_ == Deoptimizer::SOFT) { | 620 if (bailout_type_ == Deoptimizer::SOFT) { |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 // frame's top and this frame's size. | 1207 // frame's top and this frame's size. |
1202 intptr_t top_address; | 1208 intptr_t top_address; |
1203 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1209 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
1204 output_frame->SetTop(top_address); | 1210 output_frame->SetTop(top_address); |
1205 | 1211 |
1206 // Compute the incoming parameter translation. | 1212 // Compute the incoming parameter translation. |
1207 int parameter_count = height; | 1213 int parameter_count = height; |
1208 unsigned output_offset = output_frame_size; | 1214 unsigned output_offset = output_frame_size; |
1209 for (int i = 0; i < parameter_count; ++i) { | 1215 for (int i = 0; i < parameter_count; ++i) { |
1210 output_offset -= kPointerSize; | 1216 output_offset -= kPointerSize; |
| 1217 int deferred_object_index = deferred_objects_.length(); |
1211 DoTranslateCommand(iterator, frame_index, output_offset); | 1218 DoTranslateCommand(iterator, frame_index, output_offset); |
| 1219 // The allocated receiver of a construct stub frame is passed as the |
| 1220 // receiver parameter through the translation. It might be encoding |
| 1221 // a captured object, patch the slot address for a captured object. |
| 1222 if (i == 0 && deferred_objects_.length() > deferred_object_index) { |
| 1223 ASSERT(!deferred_objects_[deferred_object_index].is_arguments()); |
| 1224 deferred_objects_[deferred_object_index].patch_slot_address(top_address); |
| 1225 } |
1212 } | 1226 } |
1213 | 1227 |
1214 // Read caller's PC from the previous frame. | 1228 // Read caller's PC from the previous frame. |
1215 output_offset -= kPCOnStackSize; | 1229 output_offset -= kPCOnStackSize; |
1216 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1230 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
1217 output_frame->SetCallerPc(output_offset, callers_pc); | 1231 output_frame->SetCallerPc(output_offset, callers_pc); |
1218 if (trace_) { | 1232 if (trace_) { |
1219 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1233 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
1220 V8PRIxPTR " ; caller's pc\n", | 1234 V8PRIxPTR " ; caller's pc\n", |
1221 top_address + output_offset, output_offset, callers_pc); | 1235 top_address + output_offset, output_offset, callers_pc); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 output_frame->SetPc(reinterpret_cast<intptr_t>( | 1640 output_frame->SetPc(reinterpret_cast<intptr_t>( |
1627 trampoline->instruction_start())); | 1641 trampoline->instruction_start())); |
1628 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); | 1642 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); |
1629 Code* notify_failure = | 1643 Code* notify_failure = |
1630 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); | 1644 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); |
1631 output_frame->SetContinuation( | 1645 output_frame->SetContinuation( |
1632 reinterpret_cast<intptr_t>(notify_failure->entry())); | 1646 reinterpret_cast<intptr_t>(notify_failure->entry())); |
1633 } | 1647 } |
1634 | 1648 |
1635 | 1649 |
| 1650 Handle<Object> Deoptimizer::MaterializeNextHeapObject() { |
| 1651 int object_index = materialization_object_index_++; |
| 1652 ObjectMaterializationDescriptor desc = deferred_objects_[object_index]; |
| 1653 const int length = desc.object_length(); |
| 1654 |
| 1655 if (desc.duplicate_object() >= 0) { |
| 1656 // Found a previously materialized object by de-duplication. |
| 1657 object_index = desc.duplicate_object(); |
| 1658 materialized_objects_->Add(Handle<Object>()); |
| 1659 } else if (desc.is_arguments() && ArgumentsObjectIsAdapted(object_index)) { |
| 1660 // Use the arguments adapter frame we just built to materialize the |
| 1661 // arguments object. FunctionGetArguments can't throw an exception. |
| 1662 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); |
| 1663 Handle<JSObject> arguments = Handle<JSObject>::cast( |
| 1664 Accessors::FunctionGetArguments(function)); |
| 1665 materialized_objects_->Add(arguments); |
| 1666 materialization_value_index_ += length; |
| 1667 } else if (desc.is_arguments()) { |
| 1668 // Construct an arguments object and copy the parameters to a newly |
| 1669 // allocated arguments object backing store. |
| 1670 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); |
| 1671 Handle<JSObject> arguments = |
| 1672 isolate_->factory()->NewArgumentsObject(function, length); |
| 1673 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); |
| 1674 ASSERT(array->length() == length); |
| 1675 arguments->set_elements(*array); |
| 1676 materialized_objects_->Add(arguments); |
| 1677 for (int i = 0; i < length; ++i) { |
| 1678 array->set(i, *MaterializeNextValue()); |
| 1679 } |
| 1680 } else { |
| 1681 // Dispatch on the instance type of the object to be materialized. |
| 1682 Handle<Map> map = Handle<Map>::cast(MaterializeNextValue()); |
| 1683 switch (map->instance_type()) { |
| 1684 case HEAP_NUMBER_TYPE: { |
| 1685 Handle<HeapNumber> number = |
| 1686 Handle<HeapNumber>::cast(MaterializeNextValue()); |
| 1687 materialized_objects_->Add(number); |
| 1688 materialization_value_index_ += kDoubleSize / kPointerSize - 1; |
| 1689 break; |
| 1690 } |
| 1691 case JS_OBJECT_TYPE: { |
| 1692 Handle<JSObject> object = |
| 1693 isolate_->factory()->NewJSObjectFromMapForDeoptimizer(map); |
| 1694 materialized_objects_->Add(object); |
| 1695 object->set_properties(FixedArray::cast(*MaterializeNextValue())); |
| 1696 object->set_elements(FixedArray::cast(*MaterializeNextValue())); |
| 1697 for (int i = 0; i < length - 3; ++i) { |
| 1698 object->FastPropertyAtPut(i, *MaterializeNextValue()); |
| 1699 } |
| 1700 break; |
| 1701 } |
| 1702 default: |
| 1703 PrintF("[couldn't handle instance type %d]\n", map->instance_type()); |
| 1704 UNREACHABLE(); |
| 1705 } |
| 1706 } |
| 1707 |
| 1708 return materialized_objects_->at(object_index); |
| 1709 } |
| 1710 |
| 1711 |
| 1712 Handle<Object> Deoptimizer::MaterializeNextValue() { |
| 1713 int value_index = materialization_value_index_++; |
| 1714 Handle<Object> value = materialized_values_->at(value_index); |
| 1715 if (*value == isolate_->heap()->arguments_marker()) { |
| 1716 value = MaterializeNextHeapObject(); |
| 1717 } |
| 1718 return value; |
| 1719 } |
| 1720 |
| 1721 |
1636 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 1722 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
1637 ASSERT_NE(DEBUGGER, bailout_type_); | 1723 ASSERT_NE(DEBUGGER, bailout_type_); |
1638 | 1724 |
| 1725 // Walk all JavaScript output frames with the given frame iterator. |
| 1726 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
| 1727 if (frame_index != 0) it->Advance(); |
| 1728 JavaScriptFrame* frame = it->frame(); |
| 1729 jsframe_functions_.Add(handle(frame->function(), isolate_)); |
| 1730 jsframe_has_adapted_arguments_.Add(frame->has_adapted_arguments()); |
| 1731 } |
| 1732 |
1639 // Handlify all tagged object values before triggering any allocation. | 1733 // Handlify all tagged object values before triggering any allocation. |
1640 List<Handle<Object> > values(deferred_objects_tagged_values_.length()); | 1734 List<Handle<Object> > values(deferred_objects_tagged_values_.length()); |
1641 for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) { | 1735 for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) { |
1642 values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_)); | 1736 values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_)); |
1643 } | 1737 } |
1644 | 1738 |
1645 // Play it safe and clear all unhandlified values before we continue. | 1739 // Play it safe and clear all unhandlified values before we continue. |
1646 deferred_objects_tagged_values_.Clear(); | 1740 deferred_objects_tagged_values_.Clear(); |
1647 | 1741 |
1648 // Materialize all heap numbers before looking at arguments because when the | 1742 // Materialize all heap numbers before looking at arguments because when the |
1649 // output frames are used to materialize arguments objects later on they need | 1743 // output frames are used to materialize arguments objects later on they need |
1650 // to already contain valid heap numbers. | 1744 // to already contain valid heap numbers. |
1651 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { | 1745 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { |
1652 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; | 1746 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; |
1653 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1747 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
1654 if (trace_) { | 1748 if (trace_) { |
1655 PrintF("Materializing a new heap number %p [%e] in slot %p\n", | 1749 PrintF("Materialized a new heap number %p [%e] in slot %p\n", |
1656 reinterpret_cast<void*>(*num), | 1750 reinterpret_cast<void*>(*num), |
1657 d.value(), | 1751 d.value(), |
1658 d.slot_address()); | 1752 d.slot_address()); |
1659 } | 1753 } |
1660 Memory::Object_at(d.slot_address()) = *num; | 1754 Memory::Object_at(d.slot_address()) = *num; |
1661 } | 1755 } |
1662 | 1756 |
1663 // Materialize all heap numbers required for arguments objects. | 1757 // Materialize all heap numbers required for arguments/captured objects. |
1664 for (int i = 0; i < values.length(); i++) { | 1758 for (int i = 0; i < values.length(); i++) { |
1665 if (!values.at(i)->IsTheHole()) continue; | 1759 if (!values.at(i)->IsTheHole()) continue; |
1666 double double_value = deferred_objects_double_values_[i]; | 1760 double double_value = deferred_objects_double_values_[i]; |
1667 Handle<Object> num = isolate_->factory()->NewNumber(double_value); | 1761 Handle<Object> num = isolate_->factory()->NewNumber(double_value); |
1668 if (trace_) { | 1762 if (trace_) { |
1669 PrintF("Materializing a new heap number %p [%e] for arguments object\n", | 1763 PrintF("Materialized a new heap number %p [%e] for object\n", |
1670 reinterpret_cast<void*>(*num), double_value); | 1764 reinterpret_cast<void*>(*num), double_value); |
1671 } | 1765 } |
1672 values.Set(i, num); | 1766 values.Set(i, num); |
1673 } | 1767 } |
1674 | 1768 |
1675 // Materialize arguments objects one frame at a time. | 1769 // Materialize arguments/captured objects. |
1676 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 1770 if (!deferred_objects_.is_empty()) { |
1677 if (frame_index != 0) it->Advance(); | 1771 List<Handle<Object> > materialized_objects(deferred_objects_.length()); |
1678 JavaScriptFrame* frame = it->frame(); | 1772 materialized_objects_ = &materialized_objects; |
1679 Handle<JSFunction> function(frame->function(), isolate_); | 1773 materialized_values_ = &values; |
1680 Handle<JSObject> arguments; | 1774 |
1681 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { | 1775 while (materialization_object_index_ < deferred_objects_.length()) { |
1682 if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) { | 1776 int object_index = materialization_object_index_; |
1683 ObjectMaterializationDescriptor descriptor = | 1777 ObjectMaterializationDescriptor descriptor = |
1684 deferred_objects_.RemoveLast(); | 1778 deferred_objects_.at(object_index); |
1685 const int length = descriptor.object_length(); | 1779 |
1686 if (arguments.is_null()) { | 1780 // Find a previously materialized object by de-duplication or |
1687 if (frame->has_adapted_arguments()) { | 1781 // materialize a new instance of the object if necessary. Store |
1688 // Use the arguments adapter frame we just built to materialize the | 1782 // the materialized object into the frame slot. |
1689 // arguments object. FunctionGetArguments can't throw an exception. | 1783 Handle<Object> object = MaterializeNextHeapObject(); |
1690 arguments = Handle<JSObject>::cast( | 1784 Memory::Object_at(descriptor.slot_address()) = *object; |
1691 Accessors::FunctionGetArguments(function)); | 1785 if (trace_) { |
1692 values.RewindBy(length); | 1786 if (descriptor.is_arguments()) { |
1693 } else { | 1787 PrintF("Materialized %sarguments object of length %d for %p: ", |
1694 // Construct an arguments object and copy the parameters to a newly | 1788 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", |
1695 // allocated arguments object backing store. | 1789 Handle<JSObject>::cast(object)->elements()->length(), |
1696 arguments = | 1790 reinterpret_cast<void*>(descriptor.slot_address())); |
1697 isolate_->factory()->NewArgumentsObject(function, length); | 1791 } else { |
1698 Handle<FixedArray> array = | 1792 PrintF("Materialized captured object of size %d for %p: ", |
1699 isolate_->factory()->NewFixedArray(length); | 1793 Handle<HeapObject>::cast(object)->Size(), |
1700 ASSERT(array->length() == length); | 1794 reinterpret_cast<void*>(descriptor.slot_address())); |
1701 for (int i = length - 1; i >= 0 ; --i) { | |
1702 array->set(i, *values.RemoveLast()); | |
1703 } | |
1704 arguments->set_elements(*array); | |
1705 } | |
1706 } | 1795 } |
1707 frame->SetExpression(i, *arguments); | 1796 object->ShortPrint(); |
1708 ASSERT_EQ(Memory::Object_at(descriptor.slot_address()), *arguments); | 1797 PrintF("\n"); |
1709 if (trace_) { | |
1710 PrintF("Materializing %sarguments object of length %d for %p: ", | |
1711 frame->has_adapted_arguments() ? "(adapted) " : "", | |
1712 arguments->elements()->length(), | |
1713 reinterpret_cast<void*>(descriptor.slot_address())); | |
1714 arguments->ShortPrint(); | |
1715 PrintF("\n"); | |
1716 } | |
1717 } | 1798 } |
1718 } | 1799 } |
| 1800 |
| 1801 ASSERT(materialization_object_index_ == materialized_objects_->length()); |
| 1802 ASSERT(materialization_value_index_ == materialized_values_->length()); |
1719 } | 1803 } |
1720 } | 1804 } |
1721 | 1805 |
1722 | 1806 |
1723 #ifdef ENABLE_DEBUGGER_SUPPORT | 1807 #ifdef ENABLE_DEBUGGER_SUPPORT |
1724 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( | 1808 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( |
1725 Address parameters_top, | 1809 Address parameters_top, |
1726 uint32_t parameters_size, | 1810 uint32_t parameters_size, |
1727 Address expressions_top, | 1811 Address expressions_top, |
1728 uint32_t expressions_size, | 1812 uint32_t expressions_size, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1779 return "native"; | 1863 return "native"; |
1780 } else if (is_smi) { | 1864 } else if (is_smi) { |
1781 return "smi"; | 1865 return "smi"; |
1782 } | 1866 } |
1783 | 1867 |
1784 return "heap number"; | 1868 return "heap number"; |
1785 } | 1869 } |
1786 | 1870 |
1787 | 1871 |
1788 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, | 1872 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
1789 int object_opcode, | 1873 int object_index, |
1790 int field_index) { | 1874 int field_index) { |
1791 disasm::NameConverter converter; | 1875 disasm::NameConverter converter; |
1792 Address object_slot = deferred_objects_.last().slot_address(); | 1876 Address object_slot = deferred_objects_[object_index].slot_address(); |
1793 | 1877 |
1794 Translation::Opcode opcode = | 1878 Translation::Opcode opcode = |
1795 static_cast<Translation::Opcode>(iterator->Next()); | 1879 static_cast<Translation::Opcode>(iterator->Next()); |
1796 | 1880 |
1797 switch (opcode) { | 1881 switch (opcode) { |
1798 case Translation::BEGIN: | 1882 case Translation::BEGIN: |
1799 case Translation::JS_FRAME: | 1883 case Translation::JS_FRAME: |
1800 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1884 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
1801 case Translation::CONSTRUCT_STUB_FRAME: | 1885 case Translation::CONSTRUCT_STUB_FRAME: |
1802 case Translation::GETTER_STUB_FRAME: | 1886 case Translation::GETTER_STUB_FRAME: |
1803 case Translation::SETTER_STUB_FRAME: | 1887 case Translation::SETTER_STUB_FRAME: |
1804 case Translation::COMPILED_STUB_FRAME: | 1888 case Translation::COMPILED_STUB_FRAME: |
1805 case Translation::ARGUMENTS_OBJECT: | |
1806 UNREACHABLE(); | 1889 UNREACHABLE(); |
1807 return; | 1890 return; |
1808 | 1891 |
1809 case Translation::REGISTER: { | 1892 case Translation::REGISTER: { |
1810 int input_reg = iterator->Next(); | 1893 int input_reg = iterator->Next(); |
1811 intptr_t input_value = input_->GetRegister(input_reg); | 1894 intptr_t input_value = input_->GetRegister(input_reg); |
1812 if (trace_) { | 1895 if (trace_) { |
1813 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1896 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
1814 reinterpret_cast<intptr_t>(object_slot), | 1897 reinterpret_cast<intptr_t>(object_slot), |
1815 field_index); | 1898 field_index); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2048 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
1966 reinterpret_cast<intptr_t>(object_slot), | 2049 reinterpret_cast<intptr_t>(object_slot), |
1967 field_index); | 2050 field_index); |
1968 literal->ShortPrint(); | 2051 literal->ShortPrint(); |
1969 PrintF(" ; literal\n"); | 2052 PrintF(" ; literal\n"); |
1970 } | 2053 } |
1971 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2054 intptr_t value = reinterpret_cast<intptr_t>(literal); |
1972 AddObjectTaggedValue(value); | 2055 AddObjectTaggedValue(value); |
1973 return; | 2056 return; |
1974 } | 2057 } |
| 2058 |
| 2059 case Translation::DUPLICATED_OBJECT: { |
| 2060 int object_index = iterator->Next(); |
| 2061 if (trace_) { |
| 2062 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2063 reinterpret_cast<intptr_t>(object_slot), |
| 2064 field_index); |
| 2065 isolate_->heap()->arguments_marker()->ShortPrint(); |
| 2066 PrintF(" ; duplicate of object #%d\n", object_index); |
| 2067 } |
| 2068 // Use the materialization marker value as a sentinel and fill in |
| 2069 // the object after the deoptimized frame is built. |
| 2070 intptr_t value = reinterpret_cast<intptr_t>( |
| 2071 isolate_->heap()->arguments_marker()); |
| 2072 AddObjectDuplication(0, object_index); |
| 2073 AddObjectTaggedValue(value); |
| 2074 return; |
| 2075 } |
| 2076 |
| 2077 case Translation::ARGUMENTS_OBJECT: |
| 2078 case Translation::CAPTURED_OBJECT: { |
| 2079 int length = iterator->Next(); |
| 2080 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2081 if (trace_) { |
| 2082 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2083 reinterpret_cast<intptr_t>(object_slot), |
| 2084 field_index); |
| 2085 isolate_->heap()->arguments_marker()->ShortPrint(); |
| 2086 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2087 } |
| 2088 // Use the materialization marker value as a sentinel and fill in |
| 2089 // the object after the deoptimized frame is built. |
| 2090 intptr_t value = reinterpret_cast<intptr_t>( |
| 2091 isolate_->heap()->arguments_marker()); |
| 2092 AddObjectStart(0, length, is_args); |
| 2093 AddObjectTaggedValue(value); |
| 2094 // We save the object values on the side and materialize the actual |
| 2095 // object after the deoptimized frame is built. |
| 2096 int object_index = deferred_objects_.length() - 1; |
| 2097 for (int i = 0; i < length; i++) { |
| 2098 DoTranslateObject(iterator, object_index, i); |
| 2099 } |
| 2100 return; |
| 2101 } |
1975 } | 2102 } |
1976 } | 2103 } |
1977 | 2104 |
1978 | 2105 |
1979 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 2106 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
1980 int frame_index, | 2107 int frame_index, |
1981 unsigned output_offset, | 2108 unsigned output_offset, |
1982 DeoptimizerTranslatedValueType value_type) { | 2109 DeoptimizerTranslatedValueType value_type) { |
1983 disasm::NameConverter converter; | 2110 disasm::NameConverter converter; |
1984 // A GC-safe temporary placeholder that we can put in the output frame. | 2111 // A GC-safe temporary placeholder that we can put in the output frame. |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 output_[frame_index]->GetTop() + output_offset, | 2331 output_[frame_index]->GetTop() + output_offset, |
2205 output_offset); | 2332 output_offset); |
2206 literal->ShortPrint(); | 2333 literal->ShortPrint(); |
2207 PrintF(" ; literal\n"); | 2334 PrintF(" ; literal\n"); |
2208 } | 2335 } |
2209 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2336 intptr_t value = reinterpret_cast<intptr_t>(literal); |
2210 output_[frame_index]->SetFrameSlot(output_offset, value); | 2337 output_[frame_index]->SetFrameSlot(output_offset, value); |
2211 return; | 2338 return; |
2212 } | 2339 } |
2213 | 2340 |
2214 case Translation::ARGUMENTS_OBJECT: { | 2341 case Translation::DUPLICATED_OBJECT: { |
2215 int length = iterator->Next(); | 2342 int object_index = iterator->Next(); |
2216 if (trace_) { | 2343 if (trace_) { |
2217 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2344 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
2218 output_[frame_index]->GetTop() + output_offset, | 2345 output_[frame_index]->GetTop() + output_offset, |
2219 output_offset); | 2346 output_offset); |
2220 isolate_->heap()->arguments_marker()->ShortPrint(); | 2347 isolate_->heap()->arguments_marker()->ShortPrint(); |
2221 PrintF(" ; arguments object (length = %d)\n", length); | 2348 PrintF(" ; duplicate of object #%d\n", object_index); |
2222 } | 2349 } |
2223 // Use the arguments marker value as a sentinel and fill in the arguments | 2350 // Use the materialization marker value as a sentinel and fill in |
2224 // object after the deoptimized frame is built. | 2351 // the object after the deoptimized frame is built. |
2225 intptr_t value = reinterpret_cast<intptr_t>( | 2352 intptr_t value = reinterpret_cast<intptr_t>( |
2226 isolate_->heap()->arguments_marker()); | 2353 isolate_->heap()->arguments_marker()); |
2227 AddObjectStart(output_[frame_index]->GetTop() + output_offset, length); | 2354 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, |
| 2355 object_index); |
2228 output_[frame_index]->SetFrameSlot(output_offset, value); | 2356 output_[frame_index]->SetFrameSlot(output_offset, value); |
2229 // We save the argument values on the side and materialize the actual | 2357 return; |
2230 // arguments object after the deoptimized frame is built. | 2358 } |
| 2359 |
| 2360 case Translation::ARGUMENTS_OBJECT: |
| 2361 case Translation::CAPTURED_OBJECT: { |
| 2362 int length = iterator->Next(); |
| 2363 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2364 if (trace_) { |
| 2365 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2366 output_[frame_index]->GetTop() + output_offset, |
| 2367 output_offset); |
| 2368 isolate_->heap()->arguments_marker()->ShortPrint(); |
| 2369 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2370 } |
| 2371 // Use the materialization marker value as a sentinel and fill in |
| 2372 // the object after the deoptimized frame is built. |
| 2373 intptr_t value = reinterpret_cast<intptr_t>( |
| 2374 isolate_->heap()->arguments_marker()); |
| 2375 AddObjectStart(output_[frame_index]->GetTop() + output_offset, |
| 2376 length, is_args); |
| 2377 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2378 // We save the object values on the side and materialize the actual |
| 2379 // object after the deoptimized frame is built. |
| 2380 int object_index = deferred_objects_.length() - 1; |
2231 for (int i = 0; i < length; i++) { | 2381 for (int i = 0; i < length; i++) { |
2232 DoTranslateObject(iterator, Translation::ARGUMENTS_OBJECT, i); | 2382 DoTranslateObject(iterator, object_index, i); |
2233 } | 2383 } |
2234 return; | 2384 return; |
2235 } | 2385 } |
2236 } | 2386 } |
2237 } | 2387 } |
2238 | 2388 |
2239 | 2389 |
2240 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, | 2390 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, |
2241 int* input_offset) { | 2391 int* input_offset) { |
2242 disasm::NameConverter converter; | 2392 disasm::NameConverter converter; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 output->SetFrameSlot(output_offset + kUpperOffset, upper); | 2549 output->SetFrameSlot(output_offset + kUpperOffset, upper); |
2400 break; | 2550 break; |
2401 } | 2551 } |
2402 | 2552 |
2403 case Translation::LITERAL: { | 2553 case Translation::LITERAL: { |
2404 // Just ignore non-materialized literals. | 2554 // Just ignore non-materialized literals. |
2405 iterator->Next(); | 2555 iterator->Next(); |
2406 break; | 2556 break; |
2407 } | 2557 } |
2408 | 2558 |
2409 case Translation::ARGUMENTS_OBJECT: { | 2559 case Translation::DUPLICATED_OBJECT: |
| 2560 case Translation::ARGUMENTS_OBJECT: |
| 2561 case Translation::CAPTURED_OBJECT: { |
2410 // Optimized code assumes that the argument object has not been | 2562 // Optimized code assumes that the argument object has not been |
2411 // materialized and so bypasses it when doing arguments access. | 2563 // materialized and so bypasses it when doing arguments access. |
2412 // We should have bailed out before starting the frame | 2564 // We should have bailed out before starting the frame |
2413 // translation. | 2565 // translation. |
2414 UNREACHABLE(); | 2566 UNREACHABLE(); |
2415 return false; | 2567 return false; |
2416 } | 2568 } |
2417 } | 2569 } |
2418 | 2570 |
2419 *input_offset -= kPointerSize; | 2571 *input_offset -= kPointerSize; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 | 2716 |
2565 | 2717 |
2566 Object* Deoptimizer::ComputeLiteral(int index) const { | 2718 Object* Deoptimizer::ComputeLiteral(int index) const { |
2567 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 2719 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
2568 compiled_code_->deoptimization_data()); | 2720 compiled_code_->deoptimization_data()); |
2569 FixedArray* literals = data->LiteralArray(); | 2721 FixedArray* literals = data->LiteralArray(); |
2570 return literals->get(index); | 2722 return literals->get(index); |
2571 } | 2723 } |
2572 | 2724 |
2573 | 2725 |
2574 void Deoptimizer::AddObjectStart(intptr_t slot_address, int length) { | 2726 void Deoptimizer::AddObjectStart(intptr_t slot, int length, bool is_args) { |
2575 ObjectMaterializationDescriptor object_desc( | 2727 ObjectMaterializationDescriptor object_desc( |
2576 reinterpret_cast<Address>(slot_address), length); | 2728 reinterpret_cast<Address>(slot), jsframe_count_, length, -1, is_args); |
2577 deferred_objects_.Add(object_desc); | 2729 deferred_objects_.Add(object_desc); |
2578 } | 2730 } |
2579 | 2731 |
| 2732 |
| 2733 void Deoptimizer::AddObjectDuplication(intptr_t slot, int object_index) { |
| 2734 ObjectMaterializationDescriptor object_desc( |
| 2735 reinterpret_cast<Address>(slot), jsframe_count_, -1, object_index, false); |
| 2736 deferred_objects_.Add(object_desc); |
| 2737 } |
| 2738 |
2580 | 2739 |
2581 void Deoptimizer::AddObjectTaggedValue(intptr_t value) { | 2740 void Deoptimizer::AddObjectTaggedValue(intptr_t value) { |
2582 deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); | 2741 deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); |
2583 deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); | 2742 deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); |
2584 } | 2743 } |
2585 | 2744 |
2586 | 2745 |
2587 void Deoptimizer::AddObjectDoubleValue(double value) { | 2746 void Deoptimizer::AddObjectDoubleValue(double value) { |
2588 deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); | 2747 deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); |
2589 deferred_objects_double_values_.Add(value); | 2748 deferred_objects_double_values_.Add(value); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 buffer_->Add(COMPILED_STUB_FRAME, zone()); | 2953 buffer_->Add(COMPILED_STUB_FRAME, zone()); |
2795 } | 2954 } |
2796 | 2955 |
2797 | 2956 |
2798 void Translation::BeginArgumentsObject(int args_length) { | 2957 void Translation::BeginArgumentsObject(int args_length) { |
2799 buffer_->Add(ARGUMENTS_OBJECT, zone()); | 2958 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
2800 buffer_->Add(args_length, zone()); | 2959 buffer_->Add(args_length, zone()); |
2801 } | 2960 } |
2802 | 2961 |
2803 | 2962 |
| 2963 void Translation::BeginCapturedObject(int length) { |
| 2964 buffer_->Add(CAPTURED_OBJECT, zone()); |
| 2965 buffer_->Add(length, zone()); |
| 2966 } |
| 2967 |
| 2968 |
| 2969 void Translation::DuplicateObject(int object_index) { |
| 2970 buffer_->Add(DUPLICATED_OBJECT, zone()); |
| 2971 buffer_->Add(object_index, zone()); |
| 2972 } |
| 2973 |
| 2974 |
2804 void Translation::StoreRegister(Register reg) { | 2975 void Translation::StoreRegister(Register reg) { |
2805 buffer_->Add(REGISTER, zone()); | 2976 buffer_->Add(REGISTER, zone()); |
2806 buffer_->Add(reg.code(), zone()); | 2977 buffer_->Add(reg.code(), zone()); |
2807 } | 2978 } |
2808 | 2979 |
2809 | 2980 |
2810 void Translation::StoreInt32Register(Register reg) { | 2981 void Translation::StoreInt32Register(Register reg) { |
2811 buffer_->Add(INT32_REGISTER, zone()); | 2982 buffer_->Add(INT32_REGISTER, zone()); |
2812 buffer_->Add(reg.code(), zone()); | 2983 buffer_->Add(reg.code(), zone()); |
2813 } | 2984 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 buffer_->Add(args_known, zone()); | 3033 buffer_->Add(args_known, zone()); |
2863 buffer_->Add(args_index, zone()); | 3034 buffer_->Add(args_index, zone()); |
2864 buffer_->Add(args_length, zone()); | 3035 buffer_->Add(args_length, zone()); |
2865 } | 3036 } |
2866 | 3037 |
2867 | 3038 |
2868 int Translation::NumberOfOperandsFor(Opcode opcode) { | 3039 int Translation::NumberOfOperandsFor(Opcode opcode) { |
2869 switch (opcode) { | 3040 switch (opcode) { |
2870 case GETTER_STUB_FRAME: | 3041 case GETTER_STUB_FRAME: |
2871 case SETTER_STUB_FRAME: | 3042 case SETTER_STUB_FRAME: |
| 3043 case DUPLICATED_OBJECT: |
2872 case ARGUMENTS_OBJECT: | 3044 case ARGUMENTS_OBJECT: |
| 3045 case CAPTURED_OBJECT: |
2873 case REGISTER: | 3046 case REGISTER: |
2874 case INT32_REGISTER: | 3047 case INT32_REGISTER: |
2875 case UINT32_REGISTER: | 3048 case UINT32_REGISTER: |
2876 case DOUBLE_REGISTER: | 3049 case DOUBLE_REGISTER: |
2877 case STACK_SLOT: | 3050 case STACK_SLOT: |
2878 case INT32_STACK_SLOT: | 3051 case INT32_STACK_SLOT: |
2879 case UINT32_STACK_SLOT: | 3052 case UINT32_STACK_SLOT: |
2880 case DOUBLE_STACK_SLOT: | 3053 case DOUBLE_STACK_SLOT: |
2881 case LITERAL: | 3054 case LITERAL: |
2882 case COMPILED_STUB_FRAME: | 3055 case COMPILED_STUB_FRAME: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2922 case STACK_SLOT: | 3095 case STACK_SLOT: |
2923 return "STACK_SLOT"; | 3096 return "STACK_SLOT"; |
2924 case INT32_STACK_SLOT: | 3097 case INT32_STACK_SLOT: |
2925 return "INT32_STACK_SLOT"; | 3098 return "INT32_STACK_SLOT"; |
2926 case UINT32_STACK_SLOT: | 3099 case UINT32_STACK_SLOT: |
2927 return "UINT32_STACK_SLOT"; | 3100 return "UINT32_STACK_SLOT"; |
2928 case DOUBLE_STACK_SLOT: | 3101 case DOUBLE_STACK_SLOT: |
2929 return "DOUBLE_STACK_SLOT"; | 3102 return "DOUBLE_STACK_SLOT"; |
2930 case LITERAL: | 3103 case LITERAL: |
2931 return "LITERAL"; | 3104 return "LITERAL"; |
| 3105 case DUPLICATED_OBJECT: |
| 3106 return "DUPLICATED_OBJECT"; |
2932 case ARGUMENTS_OBJECT: | 3107 case ARGUMENTS_OBJECT: |
2933 return "ARGUMENTS_OBJECT"; | 3108 return "ARGUMENTS_OBJECT"; |
| 3109 case CAPTURED_OBJECT: |
| 3110 return "CAPTURED_OBJECT"; |
2934 } | 3111 } |
2935 UNREACHABLE(); | 3112 UNREACHABLE(); |
2936 return ""; | 3113 return ""; |
2937 } | 3114 } |
2938 | 3115 |
2939 #endif | 3116 #endif |
2940 | 3117 |
2941 | 3118 |
2942 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { | 3119 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { |
2943 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); | 3120 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); |
(...skipping 23 matching lines...) Expand all Loading... |
2967 switch (opcode) { | 3144 switch (opcode) { |
2968 case Translation::BEGIN: | 3145 case Translation::BEGIN: |
2969 case Translation::JS_FRAME: | 3146 case Translation::JS_FRAME: |
2970 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3147 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
2971 case Translation::CONSTRUCT_STUB_FRAME: | 3148 case Translation::CONSTRUCT_STUB_FRAME: |
2972 case Translation::GETTER_STUB_FRAME: | 3149 case Translation::GETTER_STUB_FRAME: |
2973 case Translation::SETTER_STUB_FRAME: | 3150 case Translation::SETTER_STUB_FRAME: |
2974 // Peeled off before getting here. | 3151 // Peeled off before getting here. |
2975 break; | 3152 break; |
2976 | 3153 |
| 3154 case Translation::DUPLICATED_OBJECT: |
2977 case Translation::ARGUMENTS_OBJECT: | 3155 case Translation::ARGUMENTS_OBJECT: |
| 3156 case Translation::CAPTURED_OBJECT: |
2978 // This can be only emitted for local slots not for argument slots. | 3157 // This can be only emitted for local slots not for argument slots. |
2979 break; | 3158 break; |
2980 | 3159 |
2981 case Translation::REGISTER: | 3160 case Translation::REGISTER: |
2982 case Translation::INT32_REGISTER: | 3161 case Translation::INT32_REGISTER: |
2983 case Translation::UINT32_REGISTER: | 3162 case Translation::UINT32_REGISTER: |
2984 case Translation::DOUBLE_REGISTER: | 3163 case Translation::DOUBLE_REGISTER: |
2985 // We are at safepoint which corresponds to call. All registers are | 3164 // We are at safepoint which corresponds to call. All registers are |
2986 // saved by caller so there would be no live registers at this | 3165 // saved by caller so there would be no live registers at this |
2987 // point. Thus these translation commands should not be used. | 3166 // point. Thus these translation commands should not be used. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3143 | 3322 |
3144 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3323 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3145 v->VisitPointer(BitCast<Object**>(&function_)); | 3324 v->VisitPointer(BitCast<Object**>(&function_)); |
3146 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3325 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3147 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3326 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3148 } | 3327 } |
3149 | 3328 |
3150 #endif // ENABLE_DEBUGGER_SUPPORT | 3329 #endif // ENABLE_DEBUGGER_SUPPORT |
3151 | 3330 |
3152 } } // namespace v8::internal | 3331 } } // namespace v8::internal |
OLD | NEW |