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