OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 // may never create a SharedFunctionInfo object. | 818 // may never create a SharedFunctionInfo object. |
819 void FunctionCode(Handle<Code> function_code) { | 819 void FunctionCode(Handle<Code> function_code) { |
820 FunctionInfoWrapper info = | 820 FunctionInfoWrapper info = |
821 FunctionInfoWrapper::cast( | 821 FunctionInfoWrapper::cast( |
822 result_->GetElementNoExceptionThrown(current_parent_index_)); | 822 result_->GetElementNoExceptionThrown(current_parent_index_)); |
823 info.SetFunctionCode(function_code, Handle<Object>(HEAP->null_value())); | 823 info.SetFunctionCode(function_code, Handle<Object>(HEAP->null_value())); |
824 } | 824 } |
825 | 825 |
826 // Saves full information about a function: its code, its scope info | 826 // Saves full information about a function: its code, its scope info |
827 // and a SharedFunctionInfo object. | 827 // and a SharedFunctionInfo object. |
828 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope) { | 828 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope, |
| 829 Zone* zone) { |
829 if (!shared->IsSharedFunctionInfo()) { | 830 if (!shared->IsSharedFunctionInfo()) { |
830 return; | 831 return; |
831 } | 832 } |
832 FunctionInfoWrapper info = | 833 FunctionInfoWrapper info = |
833 FunctionInfoWrapper::cast( | 834 FunctionInfoWrapper::cast( |
834 result_->GetElementNoExceptionThrown(current_parent_index_)); | 835 result_->GetElementNoExceptionThrown(current_parent_index_)); |
835 info.SetFunctionCode(Handle<Code>(shared->code()), | 836 info.SetFunctionCode(Handle<Code>(shared->code()), |
836 Handle<Object>(shared->scope_info())); | 837 Handle<Object>(shared->scope_info())); |
837 info.SetSharedFunctionInfo(shared); | 838 info.SetSharedFunctionInfo(shared); |
838 | 839 |
839 Handle<Object> scope_info_list(SerializeFunctionScope(scope)); | 840 Handle<Object> scope_info_list(SerializeFunctionScope(scope, zone)); |
840 info.SetOuterScopeInfo(scope_info_list); | 841 info.SetOuterScopeInfo(scope_info_list); |
841 } | 842 } |
842 | 843 |
843 Handle<JSArray> GetResult() { return result_; } | 844 Handle<JSArray> GetResult() { return result_; } |
844 | 845 |
845 private: | 846 private: |
846 Object* SerializeFunctionScope(Scope* scope) { | 847 Object* SerializeFunctionScope(Scope* scope, Zone* zone) { |
847 HandleScope handle_scope; | 848 HandleScope handle_scope; |
848 | 849 |
849 Handle<JSArray> scope_info_list = FACTORY->NewJSArray(10); | 850 Handle<JSArray> scope_info_list = FACTORY->NewJSArray(10); |
850 int scope_info_length = 0; | 851 int scope_info_length = 0; |
851 | 852 |
852 // Saves some description of scope. It stores name and indexes of | 853 // Saves some description of scope. It stores name and indexes of |
853 // variables in the whole scope chain. Null-named slots delimit | 854 // variables in the whole scope chain. Null-named slots delimit |
854 // scopes of this chain. | 855 // scopes of this chain. |
855 Scope* outer_scope = scope->outer_scope(); | 856 Scope* outer_scope = scope->outer_scope(); |
856 if (outer_scope == NULL) { | 857 if (outer_scope == NULL) { |
857 return HEAP->undefined_value(); | 858 return HEAP->undefined_value(); |
858 } | 859 } |
859 do { | 860 do { |
860 ZoneList<Variable*> stack_list(outer_scope->StackLocalCount()); | 861 ZoneList<Variable*> stack_list(outer_scope->StackLocalCount(), zone); |
861 ZoneList<Variable*> context_list(outer_scope->ContextLocalCount()); | 862 ZoneList<Variable*> context_list(outer_scope->ContextLocalCount(), zone); |
862 outer_scope->CollectStackAndContextLocals(&stack_list, &context_list); | 863 outer_scope->CollectStackAndContextLocals(&stack_list, &context_list); |
863 context_list.Sort(&Variable::CompareIndex); | 864 context_list.Sort(&Variable::CompareIndex); |
864 | 865 |
865 for (int i = 0; i < context_list.length(); i++) { | 866 for (int i = 0; i < context_list.length(); i++) { |
866 SetElementNonStrict(scope_info_list, | 867 SetElementNonStrict(scope_info_list, |
867 scope_info_length, | 868 scope_info_length, |
868 context_list[i]->name()); | 869 context_list[i]->name()); |
869 scope_info_length++; | 870 scope_info_length++; |
870 SetElementNonStrict( | 871 SetElementNonStrict( |
871 scope_info_list, | 872 scope_info_list, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 SetElementNonStrict(array, i, info_wrapper.GetJSArray()); | 921 SetElementNonStrict(array, i, info_wrapper.GetJSArray()); |
921 } | 922 } |
922 } | 923 } |
923 | 924 |
924 | 925 |
925 // Visitor that collects all references to a particular code object, | 926 // Visitor that collects all references to a particular code object, |
926 // including "CODE_TARGET" references in other code objects. | 927 // including "CODE_TARGET" references in other code objects. |
927 // It works in context of ZoneScope. | 928 // It works in context of ZoneScope. |
928 class ReferenceCollectorVisitor : public ObjectVisitor { | 929 class ReferenceCollectorVisitor : public ObjectVisitor { |
929 public: | 930 public: |
930 explicit ReferenceCollectorVisitor(Code* original) | 931 ReferenceCollectorVisitor(Code* original, Zone* zone) |
931 : original_(original), rvalues_(10), reloc_infos_(10), code_entries_(10) { | 932 : original_(original), |
| 933 rvalues_(10, zone), |
| 934 reloc_infos_(10, zone), |
| 935 code_entries_(10, zone), |
| 936 zone_(zone) { |
932 } | 937 } |
933 | 938 |
934 virtual void VisitPointers(Object** start, Object** end) { | 939 virtual void VisitPointers(Object** start, Object** end) { |
935 for (Object** p = start; p < end; p++) { | 940 for (Object** p = start; p < end; p++) { |
936 if (*p == original_) { | 941 if (*p == original_) { |
937 rvalues_.Add(p); | 942 rvalues_.Add(p, zone_); |
938 } | 943 } |
939 } | 944 } |
940 } | 945 } |
941 | 946 |
942 virtual void VisitCodeEntry(Address entry) { | 947 virtual void VisitCodeEntry(Address entry) { |
943 if (Code::GetObjectFromEntryAddress(entry) == original_) { | 948 if (Code::GetObjectFromEntryAddress(entry) == original_) { |
944 code_entries_.Add(entry); | 949 code_entries_.Add(entry, zone_); |
945 } | 950 } |
946 } | 951 } |
947 | 952 |
948 virtual void VisitCodeTarget(RelocInfo* rinfo) { | 953 virtual void VisitCodeTarget(RelocInfo* rinfo) { |
949 if (RelocInfo::IsCodeTarget(rinfo->rmode()) && | 954 if (RelocInfo::IsCodeTarget(rinfo->rmode()) && |
950 Code::GetCodeFromTargetAddress(rinfo->target_address()) == original_) { | 955 Code::GetCodeFromTargetAddress(rinfo->target_address()) == original_) { |
951 reloc_infos_.Add(*rinfo); | 956 reloc_infos_.Add(*rinfo, zone_); |
952 } | 957 } |
953 } | 958 } |
954 | 959 |
955 virtual void VisitDebugTarget(RelocInfo* rinfo) { | 960 virtual void VisitDebugTarget(RelocInfo* rinfo) { |
956 VisitCodeTarget(rinfo); | 961 VisitCodeTarget(rinfo); |
957 } | 962 } |
958 | 963 |
959 // Post-visiting method that iterates over all collected references and | 964 // Post-visiting method that iterates over all collected references and |
960 // modifies them. | 965 // modifies them. |
961 void Replace(Code* substitution) { | 966 void Replace(Code* substitution) { |
962 for (int i = 0; i < rvalues_.length(); i++) { | 967 for (int i = 0; i < rvalues_.length(); i++) { |
963 *(rvalues_[i]) = substitution; | 968 *(rvalues_[i]) = substitution; |
964 } | 969 } |
965 Address substitution_entry = substitution->instruction_start(); | 970 Address substitution_entry = substitution->instruction_start(); |
966 for (int i = 0; i < reloc_infos_.length(); i++) { | 971 for (int i = 0; i < reloc_infos_.length(); i++) { |
967 reloc_infos_[i].set_target_address(substitution_entry); | 972 reloc_infos_[i].set_target_address(substitution_entry); |
968 } | 973 } |
969 for (int i = 0; i < code_entries_.length(); i++) { | 974 for (int i = 0; i < code_entries_.length(); i++) { |
970 Address entry = code_entries_[i]; | 975 Address entry = code_entries_[i]; |
971 Memory::Address_at(entry) = substitution_entry; | 976 Memory::Address_at(entry) = substitution_entry; |
972 } | 977 } |
973 } | 978 } |
974 | 979 |
975 private: | 980 private: |
976 Code* original_; | 981 Code* original_; |
977 ZoneList<Object**> rvalues_; | 982 ZoneList<Object**> rvalues_; |
978 ZoneList<RelocInfo> reloc_infos_; | 983 ZoneList<RelocInfo> reloc_infos_; |
979 ZoneList<Address> code_entries_; | 984 ZoneList<Address> code_entries_; |
| 985 Zone* zone_; |
980 }; | 986 }; |
981 | 987 |
982 | 988 |
983 // Finds all references to original and replaces them with substitution. | 989 // Finds all references to original and replaces them with substitution. |
984 static void ReplaceCodeObject(Code* original, Code* substitution) { | 990 static void ReplaceCodeObject(Code* original, Code* substitution) { |
985 ASSERT(!HEAP->InNewSpace(substitution)); | 991 ASSERT(!HEAP->InNewSpace(substitution)); |
986 | 992 |
987 HeapIterator iterator; | 993 HeapIterator iterator; |
988 AssertNoAllocation no_allocations_please; | 994 AssertNoAllocation no_allocations_please; |
989 | 995 |
990 // A zone scope for ReferenceCollectorVisitor. | 996 // A zone scope for ReferenceCollectorVisitor. |
991 ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT); | 997 ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT); |
992 | 998 |
993 ReferenceCollectorVisitor visitor(original); | 999 ReferenceCollectorVisitor visitor(original, Isolate::Current()->zone()); |
994 | 1000 |
995 // Iterate over all roots. Stack frames may have pointer into original code, | 1001 // Iterate over all roots. Stack frames may have pointer into original code, |
996 // so temporary replace the pointers with offset numbers | 1002 // so temporary replace the pointers with offset numbers |
997 // in prologue/epilogue. | 1003 // in prologue/epilogue. |
998 { | 1004 { |
999 HEAP->IterateStrongRoots(&visitor, VISIT_ALL); | 1005 HEAP->IterateStrongRoots(&visitor, VISIT_ALL); |
1000 } | 1006 } |
1001 | 1007 |
1002 // Now iterate over all pointers of all objects, including code_target | 1008 // Now iterate over all pointers of all objects, including code_target |
1003 // implicit pointers. | 1009 // implicit pointers. |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1585 } | 1591 } |
1586 | 1592 |
1587 | 1593 |
1588 static bool IsDropableFrame(StackFrame* frame) { | 1594 static bool IsDropableFrame(StackFrame* frame) { |
1589 return !frame->is_exit(); | 1595 return !frame->is_exit(); |
1590 } | 1596 } |
1591 | 1597 |
1592 // Fills result array with statuses of functions. Modifies the stack | 1598 // Fills result array with statuses of functions. Modifies the stack |
1593 // removing all listed function if possible and if do_drop is true. | 1599 // removing all listed function if possible and if do_drop is true. |
1594 static const char* DropActivationsInActiveThread( | 1600 static const char* DropActivationsInActiveThread( |
1595 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) { | 1601 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop, |
| 1602 Zone* zone) { |
1596 Isolate* isolate = Isolate::Current(); | 1603 Isolate* isolate = Isolate::Current(); |
1597 Debug* debug = isolate->debug(); | 1604 Debug* debug = isolate->debug(); |
1598 ZoneScope scope(isolate, DELETE_ON_EXIT); | 1605 ZoneScope scope(isolate, DELETE_ON_EXIT); |
1599 Vector<StackFrame*> frames = CreateStackMap(); | 1606 Vector<StackFrame*> frames = CreateStackMap(zone); |
1600 | 1607 |
1601 int array_len = Smi::cast(shared_info_array->length())->value(); | 1608 int array_len = Smi::cast(shared_info_array->length())->value(); |
1602 | 1609 |
1603 int top_frame_index = -1; | 1610 int top_frame_index = -1; |
1604 int frame_index = 0; | 1611 int frame_index = 0; |
1605 for (; frame_index < frames.length(); frame_index++) { | 1612 for (; frame_index < frames.length(); frame_index++) { |
1606 StackFrame* frame = frames[frame_index]; | 1613 StackFrame* frame = frames[frame_index]; |
1607 if (frame->id() == debug->break_frame_id()) { | 1614 if (frame->id() == debug->break_frame_id()) { |
1608 top_frame_index = frame_index; | 1615 top_frame_index = frame_index; |
1609 break; | 1616 break; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 } | 1723 } |
1717 | 1724 |
1718 private: | 1725 private: |
1719 Handle<JSArray> shared_info_array_; | 1726 Handle<JSArray> shared_info_array_; |
1720 Handle<JSArray> result_; | 1727 Handle<JSArray> result_; |
1721 bool has_blocked_functions_; | 1728 bool has_blocked_functions_; |
1722 }; | 1729 }; |
1723 | 1730 |
1724 | 1731 |
1725 Handle<JSArray> LiveEdit::CheckAndDropActivations( | 1732 Handle<JSArray> LiveEdit::CheckAndDropActivations( |
1726 Handle<JSArray> shared_info_array, bool do_drop) { | 1733 Handle<JSArray> shared_info_array, bool do_drop, Zone* zone) { |
1727 int len = Smi::cast(shared_info_array->length())->value(); | 1734 int len = Smi::cast(shared_info_array->length())->value(); |
1728 | 1735 |
1729 Handle<JSArray> result = FACTORY->NewJSArray(len); | 1736 Handle<JSArray> result = FACTORY->NewJSArray(len); |
1730 | 1737 |
1731 // Fill the default values. | 1738 // Fill the default values. |
1732 for (int i = 0; i < len; i++) { | 1739 for (int i = 0; i < len; i++) { |
1733 SetElementNonStrict( | 1740 SetElementNonStrict( |
1734 result, | 1741 result, |
1735 i, | 1742 i, |
1736 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); | 1743 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); |
1737 } | 1744 } |
1738 | 1745 |
1739 | 1746 |
1740 // First check inactive threads. Fail if some functions are blocked there. | 1747 // First check inactive threads. Fail if some functions are blocked there. |
1741 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array, | 1748 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array, |
1742 result); | 1749 result); |
1743 Isolate::Current()->thread_manager()->IterateArchivedThreads( | 1750 Isolate::Current()->thread_manager()->IterateArchivedThreads( |
1744 &inactive_threads_checker); | 1751 &inactive_threads_checker); |
1745 if (inactive_threads_checker.HasBlockedFunctions()) { | 1752 if (inactive_threads_checker.HasBlockedFunctions()) { |
1746 return result; | 1753 return result; |
1747 } | 1754 } |
1748 | 1755 |
1749 // Try to drop activations from the current stack. | 1756 // Try to drop activations from the current stack. |
1750 const char* error_message = | 1757 const char* error_message = |
1751 DropActivationsInActiveThread(shared_info_array, result, do_drop); | 1758 DropActivationsInActiveThread(shared_info_array, result, do_drop, zone); |
1752 if (error_message != NULL) { | 1759 if (error_message != NULL) { |
1753 // Add error message as an array extra element. | 1760 // Add error message as an array extra element. |
1754 Vector<const char> vector_message(error_message, StrLength(error_message)); | 1761 Vector<const char> vector_message(error_message, StrLength(error_message)); |
1755 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); | 1762 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); |
1756 SetElementNonStrict(result, len, str); | 1763 SetElementNonStrict(result, len, str); |
1757 } | 1764 } |
1758 return result; | 1765 return result; |
1759 } | 1766 } |
1760 | 1767 |
1761 | 1768 |
1762 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, | 1769 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, |
1763 FunctionLiteral* fun) | 1770 FunctionLiteral* fun) |
1764 : isolate_(isolate) { | 1771 : isolate_(isolate) { |
1765 if (isolate_->active_function_info_listener() != NULL) { | 1772 if (isolate_->active_function_info_listener() != NULL) { |
1766 isolate_->active_function_info_listener()->FunctionStarted(fun); | 1773 isolate_->active_function_info_listener()->FunctionStarted(fun); |
1767 } | 1774 } |
1768 } | 1775 } |
1769 | 1776 |
1770 | 1777 |
1771 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1778 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
1772 if (isolate_->active_function_info_listener() != NULL) { | 1779 if (isolate_->active_function_info_listener() != NULL) { |
1773 isolate_->active_function_info_listener()->FunctionDone(); | 1780 isolate_->active_function_info_listener()->FunctionDone(); |
1774 } | 1781 } |
1775 } | 1782 } |
1776 | 1783 |
1777 | 1784 |
1778 void LiveEditFunctionTracker::RecordFunctionInfo( | 1785 void LiveEditFunctionTracker::RecordFunctionInfo( |
1779 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { | 1786 Handle<SharedFunctionInfo> info, FunctionLiteral* lit, |
| 1787 Zone* zone) { |
1780 if (isolate_->active_function_info_listener() != NULL) { | 1788 if (isolate_->active_function_info_listener() != NULL) { |
1781 isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope()); | 1789 isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope(), |
| 1790 zone); |
1782 } | 1791 } |
1783 } | 1792 } |
1784 | 1793 |
1785 | 1794 |
1786 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { | 1795 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
1787 isolate_->active_function_info_listener()->FunctionCode(code); | 1796 isolate_->active_function_info_listener()->FunctionCode(code); |
1788 } | 1797 } |
1789 | 1798 |
1790 | 1799 |
1791 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 1800 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
(...skipping 25 matching lines...) Expand all Loading... |
1817 | 1826 |
1818 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 1827 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1819 return false; | 1828 return false; |
1820 } | 1829 } |
1821 | 1830 |
1822 #endif // ENABLE_DEBUGGER_SUPPORT | 1831 #endif // ENABLE_DEBUGGER_SUPPORT |
1823 | 1832 |
1824 | 1833 |
1825 | 1834 |
1826 } } // namespace v8::internal | 1835 } } // namespace v8::internal |
OLD | NEW |