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