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()->NewJSObjectFromMap(map, NOT_TENURED, false); |
| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 | 2699 |
2548 | 2700 |
2549 Object* Deoptimizer::ComputeLiteral(int index) const { | 2701 Object* Deoptimizer::ComputeLiteral(int index) const { |
2550 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 2702 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
2551 compiled_code_->deoptimization_data()); | 2703 compiled_code_->deoptimization_data()); |
2552 FixedArray* literals = data->LiteralArray(); | 2704 FixedArray* literals = data->LiteralArray(); |
2553 return literals->get(index); | 2705 return literals->get(index); |
2554 } | 2706 } |
2555 | 2707 |
2556 | 2708 |
2557 void Deoptimizer::AddObjectStart(intptr_t slot_address, int length) { | 2709 void Deoptimizer::AddObjectStart(intptr_t slot, int length, bool is_args) { |
2558 ObjectMaterializationDescriptor object_desc( | 2710 ObjectMaterializationDescriptor object_desc( |
2559 reinterpret_cast<Address>(slot_address), length); | 2711 reinterpret_cast<Address>(slot), jsframe_count_, length, -1, is_args); |
2560 deferred_objects_.Add(object_desc); | 2712 deferred_objects_.Add(object_desc); |
2561 } | 2713 } |
2562 | 2714 |
| 2715 |
| 2716 void Deoptimizer::AddObjectDuplication(intptr_t slot, int object_index) { |
| 2717 ObjectMaterializationDescriptor object_desc( |
| 2718 reinterpret_cast<Address>(slot), jsframe_count_, -1, object_index, false); |
| 2719 deferred_objects_.Add(object_desc); |
| 2720 } |
| 2721 |
2563 | 2722 |
2564 void Deoptimizer::AddObjectTaggedValue(intptr_t value) { | 2723 void Deoptimizer::AddObjectTaggedValue(intptr_t value) { |
2565 deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); | 2724 deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); |
2566 deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); | 2725 deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); |
2567 } | 2726 } |
2568 | 2727 |
2569 | 2728 |
2570 void Deoptimizer::AddObjectDoubleValue(double value) { | 2729 void Deoptimizer::AddObjectDoubleValue(double value) { |
2571 deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); | 2730 deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); |
2572 deferred_objects_double_values_.Add(value); | 2731 deferred_objects_double_values_.Add(value); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2777 buffer_->Add(COMPILED_STUB_FRAME, zone()); | 2936 buffer_->Add(COMPILED_STUB_FRAME, zone()); |
2778 } | 2937 } |
2779 | 2938 |
2780 | 2939 |
2781 void Translation::BeginArgumentsObject(int args_length) { | 2940 void Translation::BeginArgumentsObject(int args_length) { |
2782 buffer_->Add(ARGUMENTS_OBJECT, zone()); | 2941 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
2783 buffer_->Add(args_length, zone()); | 2942 buffer_->Add(args_length, zone()); |
2784 } | 2943 } |
2785 | 2944 |
2786 | 2945 |
| 2946 void Translation::BeginCapturedObject(int length) { |
| 2947 buffer_->Add(CAPTURED_OBJECT, zone()); |
| 2948 buffer_->Add(length, zone()); |
| 2949 } |
| 2950 |
| 2951 |
| 2952 void Translation::DuplicateObject(int object_index) { |
| 2953 buffer_->Add(DUPLICATED_OBJECT, zone()); |
| 2954 buffer_->Add(object_index, zone()); |
| 2955 } |
| 2956 |
| 2957 |
2787 void Translation::StoreRegister(Register reg) { | 2958 void Translation::StoreRegister(Register reg) { |
2788 buffer_->Add(REGISTER, zone()); | 2959 buffer_->Add(REGISTER, zone()); |
2789 buffer_->Add(reg.code(), zone()); | 2960 buffer_->Add(reg.code(), zone()); |
2790 } | 2961 } |
2791 | 2962 |
2792 | 2963 |
2793 void Translation::StoreInt32Register(Register reg) { | 2964 void Translation::StoreInt32Register(Register reg) { |
2794 buffer_->Add(INT32_REGISTER, zone()); | 2965 buffer_->Add(INT32_REGISTER, zone()); |
2795 buffer_->Add(reg.code(), zone()); | 2966 buffer_->Add(reg.code(), zone()); |
2796 } | 2967 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2845 buffer_->Add(args_known, zone()); | 3016 buffer_->Add(args_known, zone()); |
2846 buffer_->Add(args_index, zone()); | 3017 buffer_->Add(args_index, zone()); |
2847 buffer_->Add(args_length, zone()); | 3018 buffer_->Add(args_length, zone()); |
2848 } | 3019 } |
2849 | 3020 |
2850 | 3021 |
2851 int Translation::NumberOfOperandsFor(Opcode opcode) { | 3022 int Translation::NumberOfOperandsFor(Opcode opcode) { |
2852 switch (opcode) { | 3023 switch (opcode) { |
2853 case GETTER_STUB_FRAME: | 3024 case GETTER_STUB_FRAME: |
2854 case SETTER_STUB_FRAME: | 3025 case SETTER_STUB_FRAME: |
| 3026 case DUPLICATED_OBJECT: |
2855 case ARGUMENTS_OBJECT: | 3027 case ARGUMENTS_OBJECT: |
| 3028 case CAPTURED_OBJECT: |
2856 case REGISTER: | 3029 case REGISTER: |
2857 case INT32_REGISTER: | 3030 case INT32_REGISTER: |
2858 case UINT32_REGISTER: | 3031 case UINT32_REGISTER: |
2859 case DOUBLE_REGISTER: | 3032 case DOUBLE_REGISTER: |
2860 case STACK_SLOT: | 3033 case STACK_SLOT: |
2861 case INT32_STACK_SLOT: | 3034 case INT32_STACK_SLOT: |
2862 case UINT32_STACK_SLOT: | 3035 case UINT32_STACK_SLOT: |
2863 case DOUBLE_STACK_SLOT: | 3036 case DOUBLE_STACK_SLOT: |
2864 case LITERAL: | 3037 case LITERAL: |
2865 case COMPILED_STUB_FRAME: | 3038 case COMPILED_STUB_FRAME: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2905 case STACK_SLOT: | 3078 case STACK_SLOT: |
2906 return "STACK_SLOT"; | 3079 return "STACK_SLOT"; |
2907 case INT32_STACK_SLOT: | 3080 case INT32_STACK_SLOT: |
2908 return "INT32_STACK_SLOT"; | 3081 return "INT32_STACK_SLOT"; |
2909 case UINT32_STACK_SLOT: | 3082 case UINT32_STACK_SLOT: |
2910 return "UINT32_STACK_SLOT"; | 3083 return "UINT32_STACK_SLOT"; |
2911 case DOUBLE_STACK_SLOT: | 3084 case DOUBLE_STACK_SLOT: |
2912 return "DOUBLE_STACK_SLOT"; | 3085 return "DOUBLE_STACK_SLOT"; |
2913 case LITERAL: | 3086 case LITERAL: |
2914 return "LITERAL"; | 3087 return "LITERAL"; |
| 3088 case DUPLICATED_OBJECT: |
| 3089 return "DUPLICATED_OBJECT"; |
2915 case ARGUMENTS_OBJECT: | 3090 case ARGUMENTS_OBJECT: |
2916 return "ARGUMENTS_OBJECT"; | 3091 return "ARGUMENTS_OBJECT"; |
| 3092 case CAPTURED_OBJECT: |
| 3093 return "CAPTURED_OBJECT"; |
2917 } | 3094 } |
2918 UNREACHABLE(); | 3095 UNREACHABLE(); |
2919 return ""; | 3096 return ""; |
2920 } | 3097 } |
2921 | 3098 |
2922 #endif | 3099 #endif |
2923 | 3100 |
2924 | 3101 |
2925 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { | 3102 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { |
2926 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); | 3103 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); |
(...skipping 23 matching lines...) Expand all Loading... |
2950 switch (opcode) { | 3127 switch (opcode) { |
2951 case Translation::BEGIN: | 3128 case Translation::BEGIN: |
2952 case Translation::JS_FRAME: | 3129 case Translation::JS_FRAME: |
2953 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3130 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
2954 case Translation::CONSTRUCT_STUB_FRAME: | 3131 case Translation::CONSTRUCT_STUB_FRAME: |
2955 case Translation::GETTER_STUB_FRAME: | 3132 case Translation::GETTER_STUB_FRAME: |
2956 case Translation::SETTER_STUB_FRAME: | 3133 case Translation::SETTER_STUB_FRAME: |
2957 // Peeled off before getting here. | 3134 // Peeled off before getting here. |
2958 break; | 3135 break; |
2959 | 3136 |
| 3137 case Translation::DUPLICATED_OBJECT: |
2960 case Translation::ARGUMENTS_OBJECT: | 3138 case Translation::ARGUMENTS_OBJECT: |
| 3139 case Translation::CAPTURED_OBJECT: |
2961 // This can be only emitted for local slots not for argument slots. | 3140 // This can be only emitted for local slots not for argument slots. |
2962 break; | 3141 break; |
2963 | 3142 |
2964 case Translation::REGISTER: | 3143 case Translation::REGISTER: |
2965 case Translation::INT32_REGISTER: | 3144 case Translation::INT32_REGISTER: |
2966 case Translation::UINT32_REGISTER: | 3145 case Translation::UINT32_REGISTER: |
2967 case Translation::DOUBLE_REGISTER: | 3146 case Translation::DOUBLE_REGISTER: |
2968 // We are at safepoint which corresponds to call. All registers are | 3147 // We are at safepoint which corresponds to call. All registers are |
2969 // saved by caller so there would be no live registers at this | 3148 // saved by caller so there would be no live registers at this |
2970 // point. Thus these translation commands should not be used. | 3149 // point. Thus these translation commands should not be used. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 | 3305 |
3127 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3306 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3128 v->VisitPointer(BitCast<Object**>(&function_)); | 3307 v->VisitPointer(BitCast<Object**>(&function_)); |
3129 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3308 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3130 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3309 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3131 } | 3310 } |
3132 | 3311 |
3133 #endif // ENABLE_DEBUGGER_SUPPORT | 3312 #endif // ENABLE_DEBUGGER_SUPPORT |
3134 | 3313 |
3135 } } // namespace v8::internal | 3314 } } // namespace v8::internal |
OLD | NEW |