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

Side by Side Diff: src/deoptimizer.cc

Issue 21055011: First implementation of allocation elimination in Hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/deoptimizer.h ('k') | src/factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698