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 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1883 HandleScope scope(data->isolate); | 1883 HandleScope scope(data->isolate); |
1884 data->debug->OnAsyncTaskEvent(debug::kDebugPromiseCollected, data->id); | 1884 data->debug->OnAsyncTaskEvent(debug::kDebugPromiseCollected, data->id); |
1885 } | 1885 } |
1886 | 1886 |
1887 void ResetPromiseHandle(const v8::WeakCallbackInfo<void>& info) { | 1887 void ResetPromiseHandle(const v8::WeakCallbackInfo<void>& info) { |
1888 CollectedCallbackData* data = | 1888 CollectedCallbackData* data = |
1889 reinterpret_cast<CollectedCallbackData*>(info.GetParameter()); | 1889 reinterpret_cast<CollectedCallbackData*>(info.GetParameter()); |
1890 GlobalHandles::Destroy(data->location); | 1890 GlobalHandles::Destroy(data->location); |
1891 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); | 1891 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); |
1892 } | 1892 } |
1893 | |
1894 // In an async function, reuse the existing stack related to the outer | |
1895 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. | |
1896 // Promises with multiple reactions with one or more of them being async | |
1897 // functions will not get a good stack trace, as async functions require | |
1898 // different stacks from direct Promise use, but we save and restore a | |
1899 // stack once for all reactions. | |
1900 // | |
1901 // If this isn't a case of async function, we return false, otherwise | |
1902 // we set the correct id and return true. | |
1903 // | |
1904 // TODO(littledan): Improve this case. | |
1905 int GetReferenceAsyncTaskId(Isolate* isolate, Handle<JSPromise> promise) { | |
1906 Handle<Symbol> handled_by_symbol = | |
1907 isolate->factory()->promise_handled_by_symbol(); | |
1908 Handle<Object> handled_by_promise = | |
1909 JSObject::GetDataProperty(promise, handled_by_symbol); | |
1910 if (!handled_by_promise->IsJSPromise()) { | |
1911 return isolate->debug()->NextAsyncTaskId(promise); | |
1912 } | |
1913 Handle<JSPromise> handled_by_promise_js = | |
1914 Handle<JSPromise>::cast(handled_by_promise); | |
1915 Handle<Symbol> async_stack_id_symbol = | |
1916 isolate->factory()->promise_async_stack_id_symbol(); | |
1917 Handle<Object> async_task_id = | |
1918 JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); | |
1919 if (!async_task_id->IsSmi()) { | |
1920 return isolate->debug()->NextAsyncTaskId(promise); | |
1921 } | |
1922 return Handle<Smi>::cast(async_task_id)->value(); | |
1923 } | |
1893 } // namespace | 1924 } // namespace |
1894 | 1925 |
1926 void Debug::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, | |
1927 Handle<Object> parent) { | |
1928 if (!debug_delegate_) return; | |
1929 bool is_async = false; | |
dgozman
2017/01/24 18:13:51
Remove.
kozy
2017/01/24 18:41:41
Done.
| |
1930 int id = GetReferenceAsyncTaskId(isolate_, promise); | |
1931 int parent_id = 0; | |
dgozman
2017/01/24 18:13:51
Let's move this under kInit case.
kozy
2017/01/24 18:41:41
Done.
| |
1932 if (parent->IsJSPromise()) { | |
1933 parent_id = | |
1934 GetReferenceAsyncTaskId(isolate_, Handle<JSPromise>::cast(parent)); | |
1935 } | |
1936 switch (type) { | |
1937 case PromiseHookType::kInit: | |
1938 debug_delegate_->PromiseEventOccurred(debug::kDebugPromiseCreated, id, | |
1939 parent_id); | |
1940 return; | |
1941 case PromiseHookType::kResolve: | |
1942 // We can't use this hook because it's called before promise object will | |
1943 // get resolved status. | |
1944 return; | |
1945 case PromiseHookType::kBefore: | |
1946 OnAsyncTaskEvent(debug::kDebugWillHandle, id); | |
1947 return; | |
1948 case PromiseHookType::kAfter: | |
1949 OnAsyncTaskEvent(debug::kDebugDidHandle, id); | |
1950 return; | |
1951 } | |
1952 } | |
1953 | |
1895 int Debug::NextAsyncTaskId(Handle<JSObject> promise) { | 1954 int Debug::NextAsyncTaskId(Handle<JSObject> promise) { |
1896 LookupIterator it(promise, isolate_->factory()->promise_async_id_symbol()); | 1955 LookupIterator it(promise, isolate_->factory()->promise_async_id_symbol()); |
1897 Maybe<bool> maybe = JSReceiver::HasProperty(&it); | 1956 Maybe<bool> maybe = JSReceiver::HasProperty(&it); |
1898 if (maybe.ToChecked()) { | 1957 if (maybe.ToChecked()) { |
1899 MaybeHandle<Object> result = Object::GetProperty(&it); | 1958 MaybeHandle<Object> result = Object::GetProperty(&it); |
1900 return Handle<Smi>::cast(result.ToHandleChecked())->value(); | 1959 return Handle<Smi>::cast(result.ToHandleChecked())->value(); |
1901 } | 1960 } |
1902 Handle<Smi> async_id = | 1961 Handle<Smi> async_id = |
1903 handle(Smi::FromInt(++thread_local_.async_task_count_), isolate_); | 1962 handle(Smi::FromInt(++thread_local_.async_task_count_), isolate_); |
1904 Object::SetProperty(&it, async_id, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED) | 1963 Object::SetProperty(&it, async_id, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1951 shared->set_debug_is_blackboxed(is_blackboxed); | 2010 shared->set_debug_is_blackboxed(is_blackboxed); |
1952 shared->set_computed_debug_is_blackboxed(true); | 2011 shared->set_computed_debug_is_blackboxed(true); |
1953 } | 2012 } |
1954 return shared->debug_is_blackboxed(); | 2013 return shared->debug_is_blackboxed(); |
1955 } | 2014 } |
1956 | 2015 |
1957 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { | 2016 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { |
1958 if (in_debug_scope() || ignore_events()) return; | 2017 if (in_debug_scope() || ignore_events()) return; |
1959 | 2018 |
1960 if (debug_delegate_) { | 2019 if (debug_delegate_) { |
1961 debug_delegate_->PromiseEventOccurred(type, id); | 2020 debug_delegate_->PromiseEventOccurred(type, id, 0); |
1962 if (!non_inspector_listener_exists()) return; | 2021 if (!non_inspector_listener_exists()) return; |
1963 } | 2022 } |
1964 | 2023 |
1965 HandleScope scope(isolate_); | 2024 HandleScope scope(isolate_); |
1966 DebugScope debug_scope(this); | 2025 DebugScope debug_scope(this); |
1967 if (debug_scope.failed()) return; | 2026 if (debug_scope.failed()) return; |
1968 | 2027 |
1969 // Create the script collected state object. | 2028 // Create the script collected state object. |
1970 Handle<Object> event_data; | 2029 Handle<Object> event_data; |
1971 // Bail out and don't call debugger if exception. | 2030 // Bail out and don't call debugger if exception. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2086 if (is_active || in_debug_scope()) { | 2145 if (is_active || in_debug_scope()) { |
2087 // Note that the debug context could have already been loaded to | 2146 // Note that the debug context could have already been loaded to |
2088 // bootstrap test cases. | 2147 // bootstrap test cases. |
2089 isolate_->compilation_cache()->Disable(); | 2148 isolate_->compilation_cache()->Disable(); |
2090 is_active = Load(); | 2149 is_active = Load(); |
2091 } else if (is_loaded()) { | 2150 } else if (is_loaded()) { |
2092 isolate_->compilation_cache()->Enable(); | 2151 isolate_->compilation_cache()->Enable(); |
2093 Unload(); | 2152 Unload(); |
2094 } | 2153 } |
2095 is_active_ = is_active; | 2154 is_active_ = is_active; |
2155 isolate_->DebugStateUpdated(); | |
2096 } | 2156 } |
2097 | 2157 |
2098 void Debug::UpdateHookOnFunctionCall() { | 2158 void Debug::UpdateHookOnFunctionCall() { |
2099 STATIC_ASSERT(StepFrame > StepIn); | 2159 STATIC_ASSERT(StepFrame > StepIn); |
2100 STATIC_ASSERT(LastStepAction == StepFrame); | 2160 STATIC_ASSERT(LastStepAction == StepFrame); |
2101 hook_on_function_call_ = thread_local_.last_step_action_ >= StepIn || | 2161 hook_on_function_call_ = thread_local_.last_step_action_ >= StepIn || |
2102 isolate_->needs_side_effect_check(); | 2162 isolate_->needs_side_effect_check(); |
2103 } | 2163 } |
2104 | 2164 |
2105 MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) { | 2165 MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2334 return v8::Utils::ToLocal(callback_data_); | 2394 return v8::Utils::ToLocal(callback_data_); |
2335 } | 2395 } |
2336 | 2396 |
2337 | 2397 |
2338 v8::Isolate* EventDetailsImpl::GetIsolate() const { | 2398 v8::Isolate* EventDetailsImpl::GetIsolate() const { |
2339 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); | 2399 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); |
2340 } | 2400 } |
2341 | 2401 |
2342 } // namespace internal | 2402 } // namespace internal |
2343 } // namespace v8 | 2403 } // namespace v8 |
OLD | NEW |