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

Side by Side Diff: src/liveedit.cc

Issue 273433002: Revert "Prevent liveedit on or under generators with open activations" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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/liveedit.h ('k') | src/liveedit-debugger.js » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 #include "v8.h" 6 #include "v8.h"
7 7
8 #include "liveedit.h" 8 #include "liveedit.h"
9 9
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 for (Address a = unused_stack_top; 1675 for (Address a = unused_stack_top;
1676 a < unused_stack_bottom; 1676 a < unused_stack_bottom;
1677 a += kPointerSize) { 1677 a += kPointerSize) {
1678 Memory::Object_at(a) = Smi::FromInt(0); 1678 Memory::Object_at(a) = Smi::FromInt(0);
1679 } 1679 }
1680 1680
1681 return NULL; 1681 return NULL;
1682 } 1682 }
1683 1683
1684 1684
1685 static bool IsDropableFrame(StackFrame* frame) {
1686 return !frame->is_exit();
1687 }
1688
1689
1685 // Describes a set of call frames that execute any of listed functions. 1690 // Describes a set of call frames that execute any of listed functions.
1686 // Finding no such frames does not mean error. 1691 // Finding no such frames does not mean error.
1687 class MultipleFunctionTarget { 1692 class MultipleFunctionTarget {
1688 public: 1693 public:
1689 MultipleFunctionTarget(Handle<JSArray> shared_info_array, 1694 MultipleFunctionTarget(Handle<JSArray> shared_info_array,
1690 Handle<JSArray> result) 1695 Handle<JSArray> result)
1691 : m_shared_info_array(shared_info_array), 1696 : m_shared_info_array(shared_info_array),
1692 m_result(result) {} 1697 m_result(result) {}
1693 bool MatchActivation(StackFrame* frame, 1698 bool MatchActivation(StackFrame* frame,
1694 LiveEdit::FunctionPatchabilityStatus status) { 1699 LiveEdit::FunctionPatchabilityStatus status) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 } 1733 }
1729 } 1734 }
1730 1735
1731 if (top_frame_index == -1) { 1736 if (top_frame_index == -1) {
1732 // We haven't found break frame, but no function is blocking us anyway. 1737 // We haven't found break frame, but no function is blocking us anyway.
1733 return target.GetNotFoundMessage(); 1738 return target.GetNotFoundMessage();
1734 } 1739 }
1735 1740
1736 bool target_frame_found = false; 1741 bool target_frame_found = false;
1737 int bottom_js_frame_index = top_frame_index; 1742 int bottom_js_frame_index = top_frame_index;
1738 bool non_droppable_frame_found = false; 1743 bool c_code_found = false;
1739 LiveEdit::FunctionPatchabilityStatus non_droppable_reason;
1740 1744
1741 for (; frame_index < frames.length(); frame_index++) { 1745 for (; frame_index < frames.length(); frame_index++) {
1742 StackFrame* frame = frames[frame_index]; 1746 StackFrame* frame = frames[frame_index];
1743 if (frame->is_exit()) { 1747 if (!IsDropableFrame(frame)) {
1744 non_droppable_frame_found = true; 1748 c_code_found = true;
1745 non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE;
1746 break;
1747 }
1748 if (!frame->is_java_script()) continue;
1749 if (JavaScriptFrame::cast(frame)->function()->shared()->is_generator()) {
1750 non_droppable_frame_found = true;
1751 non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
1752 break; 1749 break;
1753 } 1750 }
1754 if (target.MatchActivation( 1751 if (target.MatchActivation(
1755 frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { 1752 frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
1756 target_frame_found = true; 1753 target_frame_found = true;
1757 bottom_js_frame_index = frame_index; 1754 bottom_js_frame_index = frame_index;
1758 } 1755 }
1759 } 1756 }
1760 1757
1761 if (non_droppable_frame_found) { 1758 if (c_code_found) {
1762 // There is a C or generator frame on stack. We can't drop C frames, and we 1759 // There is a C frames on stack. Check that there are no target frames
1763 // can't restart generators. Check that there are no target frames below 1760 // below them.
1764 // them.
1765 for (; frame_index < frames.length(); frame_index++) { 1761 for (; frame_index < frames.length(); frame_index++) {
1766 StackFrame* frame = frames[frame_index]; 1762 StackFrame* frame = frames[frame_index];
1767 if (frame->is_java_script()) { 1763 if (frame->is_java_script()) {
1768 if (target.MatchActivation(frame, non_droppable_reason)) { 1764 if (target.MatchActivation(
1769 // Fail. 1765 frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
1766 // Cannot drop frame under C frames.
1770 return NULL; 1767 return NULL;
1771 } 1768 }
1772 } 1769 }
1773 } 1770 }
1774 } 1771 }
1775 1772
1776 if (!do_drop) { 1773 if (!do_drop) {
1777 // We are in check-only mode. 1774 // We are in check-only mode.
1778 return NULL; 1775 return NULL;
1779 } 1776 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { 1826 if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
1830 Handle<Object> replaced( 1827 Handle<Object> replaced(
1831 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate); 1828 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
1832 SetElementSloppy(result, i, replaced); 1829 SetElementSloppy(result, i, replaced);
1833 } 1830 }
1834 } 1831 }
1835 return NULL; 1832 return NULL;
1836 } 1833 }
1837 1834
1838 1835
1839 bool LiveEdit::FindActiveGenerators(Handle<FixedArray> shared_info_array,
1840 Handle<FixedArray> result,
1841 int len) {
1842 Isolate* isolate = shared_info_array->GetIsolate();
1843 Heap* heap = isolate->heap();
1844 heap->EnsureHeapIsIterable();
1845 bool found_suspended_activations = false;
1846
1847 ASSERT_LE(len, result->length());
1848
1849 DisallowHeapAllocation no_allocation;
1850
1851 FunctionPatchabilityStatus active = FUNCTION_BLOCKED_ACTIVE_GENERATOR;
1852
1853 HeapIterator iterator(heap);
1854 HeapObject* obj = NULL;
1855 while ((obj = iterator.next()) != NULL) {
1856 if (!obj->IsJSGeneratorObject()) continue;
1857
1858 JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
1859 if (gen->is_closed()) continue;
1860
1861 HandleScope scope(isolate);
1862
1863 for (int i = 0; i < len; i++) {
1864 Handle<JSValue> jsvalue =
1865 Handle<JSValue>::cast(FixedArray::get(shared_info_array, i));
1866 Handle<SharedFunctionInfo> shared =
1867 UnwrapSharedFunctionInfoFromJSValue(jsvalue);
1868
1869 if (gen->function()->shared() == *shared) {
1870 result->set(i, Smi::FromInt(active));
1871 found_suspended_activations = true;
1872 }
1873 }
1874 }
1875
1876 return found_suspended_activations;
1877 }
1878
1879
1880 class InactiveThreadActivationsChecker : public ThreadVisitor { 1836 class InactiveThreadActivationsChecker : public ThreadVisitor {
1881 public: 1837 public:
1882 InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array, 1838 InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array,
1883 Handle<JSArray> result) 1839 Handle<JSArray> result)
1884 : shared_info_array_(shared_info_array), result_(result), 1840 : shared_info_array_(shared_info_array), result_(result),
1885 has_blocked_functions_(false) { 1841 has_blocked_functions_(false) {
1886 } 1842 }
1887 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1843 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1888 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1844 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1889 has_blocked_functions_ |= CheckActivation( 1845 has_blocked_functions_ |= CheckActivation(
(...skipping 10 matching lines...) Expand all
1900 Handle<JSArray> result_; 1856 Handle<JSArray> result_;
1901 bool has_blocked_functions_; 1857 bool has_blocked_functions_;
1902 }; 1858 };
1903 1859
1904 1860
1905 Handle<JSArray> LiveEdit::CheckAndDropActivations( 1861 Handle<JSArray> LiveEdit::CheckAndDropActivations(
1906 Handle<JSArray> shared_info_array, bool do_drop) { 1862 Handle<JSArray> shared_info_array, bool do_drop) {
1907 Isolate* isolate = shared_info_array->GetIsolate(); 1863 Isolate* isolate = shared_info_array->GetIsolate();
1908 int len = GetArrayLength(shared_info_array); 1864 int len = GetArrayLength(shared_info_array);
1909 1865
1910 CHECK(shared_info_array->HasFastElements());
1911 Handle<FixedArray> shared_info_array_elements(
1912 FixedArray::cast(shared_info_array->elements()));
1913
1914 Handle<JSArray> result = isolate->factory()->NewJSArray(len); 1866 Handle<JSArray> result = isolate->factory()->NewJSArray(len);
1915 Handle<FixedArray> result_elements =
1916 JSObject::EnsureWritableFastElements(result);
1917 1867
1918 // Fill the default values. 1868 // Fill the default values.
1919 for (int i = 0; i < len; i++) { 1869 for (int i = 0; i < len; i++) {
1920 FunctionPatchabilityStatus status = FUNCTION_AVAILABLE_FOR_PATCH; 1870 SetElementSloppy(
1921 result_elements->set(i, Smi::FromInt(status)); 1871 result,
1872 i,
1873 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH), isolate));
1922 } 1874 }
1923 1875
1924 // Scan the heap for active generators -- those that are either currently
1925 // running (as we wouldn't want to restart them, because we don't know where
1926 // to restart them from) or suspended. Fail if any one corresponds to the set
1927 // of functions being edited.
1928 if (FindActiveGenerators(shared_info_array_elements, result_elements, len)) {
1929 return result;
1930 }
1931 1876
1932 // Check inactive threads. Fail if some functions are blocked there. 1877 // First check inactive threads. Fail if some functions are blocked there.
1933 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array, 1878 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
1934 result); 1879 result);
1935 isolate->thread_manager()->IterateArchivedThreads( 1880 isolate->thread_manager()->IterateArchivedThreads(
1936 &inactive_threads_checker); 1881 &inactive_threads_checker);
1937 if (inactive_threads_checker.HasBlockedFunctions()) { 1882 if (inactive_threads_checker.HasBlockedFunctions()) {
1938 return result; 1883 return result;
1939 } 1884 }
1940 1885
1941 // Try to drop activations from the current stack. 1886 // Try to drop activations from the current stack.
1942 const char* error_message = 1887 const char* error_message =
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1985 SingleFrameTarget target(frame); 1930 SingleFrameTarget target(frame);
1986 1931
1987 const char* result = DropActivationsInActiveThreadImpl( 1932 const char* result = DropActivationsInActiveThreadImpl(
1988 frame->isolate(), target, true); 1933 frame->isolate(), target, true);
1989 if (result != NULL) { 1934 if (result != NULL) {
1990 return result; 1935 return result;
1991 } 1936 }
1992 if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) { 1937 if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
1993 return "Function is blocked under native code"; 1938 return "Function is blocked under native code";
1994 } 1939 }
1995 if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR) {
1996 return "Function is blocked under a generator activation";
1997 }
1998 return NULL; 1940 return NULL;
1999 } 1941 }
2000 1942
2001 1943
2002 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, 1944 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
2003 FunctionLiteral* fun) 1945 FunctionLiteral* fun)
2004 : isolate_(isolate) { 1946 : isolate_(isolate) {
2005 if (isolate_->active_function_info_listener() != NULL) { 1947 if (isolate_->active_function_info_listener() != NULL) {
2006 isolate_->active_function_info_listener()->FunctionStarted(fun); 1948 isolate_->active_function_info_listener()->FunctionStarted(fun);
2007 } 1949 }
(...skipping 20 matching lines...) Expand all
2028 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { 1970 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) {
2029 isolate_->active_function_info_listener()->FunctionCode(code); 1971 isolate_->active_function_info_listener()->FunctionCode(code);
2030 } 1972 }
2031 1973
2032 1974
2033 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { 1975 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
2034 return isolate->active_function_info_listener() != NULL; 1976 return isolate->active_function_info_listener() != NULL;
2035 } 1977 }
2036 1978
2037 } } // namespace v8::internal 1979 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/liveedit.h ('k') | src/liveedit-debugger.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698