OLD | NEW |
---|---|
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 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 1797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1808 data->debug->OnAsyncTaskEvent(debug::kDebugCancel, data->id, | 1808 data->debug->OnAsyncTaskEvent(debug::kDebugCancel, data->id, |
1809 kDebugPromiseCollected); | 1809 kDebugPromiseCollected); |
1810 } | 1810 } |
1811 | 1811 |
1812 void ResetPromiseHandle(const v8::WeakCallbackInfo<void>& info) { | 1812 void ResetPromiseHandle(const v8::WeakCallbackInfo<void>& info) { |
1813 CollectedCallbackData* data = | 1813 CollectedCallbackData* data = |
1814 reinterpret_cast<CollectedCallbackData*>(info.GetParameter()); | 1814 reinterpret_cast<CollectedCallbackData*>(info.GetParameter()); |
1815 GlobalHandles::Destroy(data->location); | 1815 GlobalHandles::Destroy(data->location); |
1816 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); | 1816 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); |
1817 } | 1817 } |
1818 | |
1819 debug::PromiseDebugActionName ToInterfaceDebugActionName( | |
1820 PromiseDebugActionName name) { | |
1821 switch (name) { | |
1822 case kDebugAsyncFunction: | |
1823 return debug::kDebugAsyncFunction; | |
1824 case kDebugPromiseResolve: | |
1825 return debug::kDebugPromiseResolve; | |
1826 case kDebugPromiseReject: | |
1827 return debug::kDebugPromiseReject; | |
1828 case kDebugPromiseResolveThenableJob: | |
1829 return debug::kDebugPromiseResolveThenableJob; | |
1830 case kDebugPromiseCollected: | |
1831 return debug::kDebugPromiseCollected; | |
1832 case kDebugNotActive: | |
1833 UNREACHABLE(); | |
1834 return debug::kDebugAsyncFunction; | |
1835 } | |
1836 UNREACHABLE(); | |
1837 return debug::kDebugAsyncFunction; | |
1838 } | |
1818 } // namespace | 1839 } // namespace |
1819 | 1840 |
1820 int Debug::NextAsyncTaskId(Handle<JSObject> promise) { | 1841 int Debug::NextAsyncTaskId(Handle<JSObject> promise) { |
1821 LookupIterator it(promise, isolate_->factory()->promise_async_id_symbol()); | 1842 LookupIterator it(promise, isolate_->factory()->promise_async_id_symbol()); |
1822 Maybe<bool> maybe = JSReceiver::HasProperty(&it); | 1843 Maybe<bool> maybe = JSReceiver::HasProperty(&it); |
1823 if (maybe.ToChecked()) { | 1844 if (maybe.ToChecked()) { |
1824 MaybeHandle<Object> result = Object::GetProperty(&it); | 1845 MaybeHandle<Object> result = Object::GetProperty(&it); |
1825 return Handle<Smi>::cast(result.ToHandleChecked())->value(); | 1846 return Handle<Smi>::cast(result.ToHandleChecked())->value(); |
1826 } | 1847 } |
1827 Handle<Smi> async_id = | 1848 Handle<Smi> async_id = |
1828 handle(Smi::FromInt(++thread_local_.async_task_count_), isolate_); | 1849 handle(Smi::FromInt(++thread_local_.async_task_count_), isolate_); |
1829 Object::SetProperty(&it, async_id, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED) | 1850 Object::SetProperty(&it, async_id, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED) |
1830 .ToChecked(); | 1851 .ToChecked(); |
1831 Handle<Object> global_handle = isolate_->global_handles()->Create(*promise); | 1852 Handle<Object> global_handle = isolate_->global_handles()->Create(*promise); |
1832 // We send EnqueueRecurring async task event when promise is fulfilled or | 1853 // We send EnqueueRecurring async task event when promise is fulfilled or |
1833 // rejected, WillHandle and DidHandle for every scheduled microtask for this | 1854 // rejected, WillHandle and DidHandle for every scheduled microtask for this |
1834 // promise. | 1855 // promise. |
1835 // We need to send a cancel event when no other microtasks can be | 1856 // We need to send a cancel event when no other microtasks can be |
1836 // started for this promise and all current microtasks are finished. | 1857 // started for this promise and all current microtasks are finished. |
1837 // Since we holding promise when at least one microtask is scheduled (inside | 1858 // Since we holding promise when at least one microtask is scheduled (inside |
1838 // PromiseReactionJobInfo), we can send cancel event in weak callback. | 1859 // PromiseReactionJobInfo), we can send cancel event in weak callback. |
1839 GlobalHandles::MakeWeak( | 1860 GlobalHandles::MakeWeak( |
1840 global_handle.location(), | 1861 global_handle.location(), |
1841 new CollectedCallbackData(global_handle.location(), async_id->value(), | 1862 new CollectedCallbackData(global_handle.location(), async_id->value(), |
1842 this, isolate_), | 1863 this, isolate_), |
1843 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); | 1864 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); |
1844 return async_id->value(); | 1865 return async_id->value(); |
1845 } | 1866 } |
1846 | 1867 |
1868 void Debug::SetAsyncTaskListener(debug::AsyncTaskListener listener, | |
1869 void* data) { | |
1870 async_task_listener_ = listener; | |
1871 async_task_listener_data_ = data; | |
1872 UpdateState(); | |
1873 } | |
1874 | |
1847 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, | 1875 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, |
1848 PromiseDebugActionName name) { | 1876 PromiseDebugActionName name) { |
1849 if (in_debug_scope() || ignore_events()) return; | 1877 if (in_debug_scope() || ignore_events()) return; |
1850 | 1878 |
1879 if (async_task_listener_) { | |
1880 async_task_listener_(type, id, ToInterfaceDebugActionName(name), | |
1881 async_task_listener_data_); | |
1882 if (message_handler_ == NULL && | |
dgozman
2017/01/13 00:01:48
nullptr
dgozman
2017/01/13 00:01:48
Let's extract variable |only_foreign_listener_pres
kozy
2017/01/13 15:59:13
Done.
kozy
2017/01/13 15:59:13
Done.
| |
1883 (event_listener_.is_null() || event_listener_->IsForeign())) { | |
1884 return; | |
1885 } | |
1886 } | |
1887 | |
1851 HandleScope scope(isolate_); | 1888 HandleScope scope(isolate_); |
1852 DebugScope debug_scope(this); | 1889 DebugScope debug_scope(this); |
1853 if (debug_scope.failed()) return; | 1890 if (debug_scope.failed()) return; |
1854 | 1891 |
1855 // Create the script collected state object. | 1892 // Create the script collected state object. |
1856 Handle<Object> event_data; | 1893 Handle<Object> event_data; |
1857 // Bail out and don't call debugger if exception. | 1894 // Bail out and don't call debugger if exception. |
1858 if (!MakeAsyncTaskEvent(handle(Smi::FromInt(type), isolate_), | 1895 if (!MakeAsyncTaskEvent(handle(Smi::FromInt(type), isolate_), |
1859 handle(Smi::FromInt(id), isolate_), | 1896 handle(Smi::FromInt(id), isolate_), |
1860 handle(Smi::FromInt(name), isolate_)) | 1897 handle(Smi::FromInt(name), isolate_)) |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2124 message_handler_ = handler; | 2161 message_handler_ = handler; |
2125 UpdateState(); | 2162 UpdateState(); |
2126 if (handler == NULL && in_debug_scope()) { | 2163 if (handler == NULL && in_debug_scope()) { |
2127 // Send an empty command to the debugger if in a break to make JavaScript | 2164 // Send an empty command to the debugger if in a break to make JavaScript |
2128 // run again if the debugger is closed. | 2165 // run again if the debugger is closed. |
2129 EnqueueCommandMessage(Vector<const uint16_t>::empty()); | 2166 EnqueueCommandMessage(Vector<const uint16_t>::empty()); |
2130 } | 2167 } |
2131 } | 2168 } |
2132 | 2169 |
2133 void Debug::UpdateState() { | 2170 void Debug::UpdateState() { |
2134 bool is_active = message_handler_ != NULL || !event_listener_.is_null(); | 2171 bool is_active = message_handler_ != NULL || !event_listener_.is_null() || |
2172 async_task_listener_ != NULL; | |
2135 if (is_active || in_debug_scope()) { | 2173 if (is_active || in_debug_scope()) { |
2136 // Note that the debug context could have already been loaded to | 2174 // Note that the debug context could have already been loaded to |
2137 // bootstrap test cases. | 2175 // bootstrap test cases. |
2138 isolate_->compilation_cache()->Disable(); | 2176 isolate_->compilation_cache()->Disable(); |
2139 is_active = Load(); | 2177 is_active = Load(); |
2140 } else if (is_loaded()) { | 2178 } else if (is_loaded()) { |
2141 isolate_->compilation_cache()->Enable(); | 2179 isolate_->compilation_cache()->Enable(); |
2142 Unload(); | 2180 Unload(); |
2143 } | 2181 } |
2144 is_active_ = is_active; | 2182 is_active_ = is_active; |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2612 logger_->DebugEvent("Put", message.text()); | 2650 logger_->DebugEvent("Put", message.text()); |
2613 } | 2651 } |
2614 | 2652 |
2615 void LockingCommandMessageQueue::Clear() { | 2653 void LockingCommandMessageQueue::Clear() { |
2616 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2654 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2617 queue_.Clear(); | 2655 queue_.Clear(); |
2618 } | 2656 } |
2619 | 2657 |
2620 } // namespace internal | 2658 } // namespace internal |
2621 } // namespace v8 | 2659 } // namespace v8 |
OLD | NEW |