| 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 void Debug::ThreadInit() { | 396 void Debug::ThreadInit() { |
| 397 thread_local_.break_count_ = 0; | 397 thread_local_.break_count_ = 0; |
| 398 thread_local_.break_id_ = 0; | 398 thread_local_.break_id_ = 0; |
| 399 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 399 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
| 400 thread_local_.last_step_action_ = StepNone; | 400 thread_local_.last_step_action_ = StepNone; |
| 401 thread_local_.last_statement_position_ = kNoSourcePosition; | 401 thread_local_.last_statement_position_ = kNoSourcePosition; |
| 402 thread_local_.last_fp_ = 0; | 402 thread_local_.last_fp_ = 0; |
| 403 thread_local_.target_fp_ = 0; | 403 thread_local_.target_fp_ = 0; |
| 404 thread_local_.return_value_ = Smi::kZero; | 404 thread_local_.return_value_ = Smi::kZero; |
| 405 thread_local_.async_task_count_ = 0; | 405 thread_local_.async_task_count_ = 0; |
| 406 thread_local_.non_breakable_async_events_ = false; |
| 406 clear_suspended_generator(); | 407 clear_suspended_generator(); |
| 407 thread_local_.restart_fp_ = nullptr; | 408 thread_local_.restart_fp_ = nullptr; |
| 408 base::NoBarrier_Store(&thread_local_.current_debug_scope_, | 409 base::NoBarrier_Store(&thread_local_.current_debug_scope_, |
| 409 static_cast<base::AtomicWord>(0)); | 410 static_cast<base::AtomicWord>(0)); |
| 410 UpdateHookOnFunctionCall(); | 411 UpdateHookOnFunctionCall(); |
| 411 } | 412 } |
| 412 | 413 |
| 413 | 414 |
| 414 char* Debug::ArchiveDebug(char* storage) { | 415 char* Debug::ArchiveDebug(char* storage) { |
| 415 // Simply reset state. Don't archive anything. | 416 // Simply reset state. Don't archive anything. |
| (...skipping 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1920 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); | 1921 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); |
| 1921 } | 1922 } |
| 1922 | 1923 |
| 1923 // In an async function, reuse the existing stack related to the outer | 1924 // In an async function, reuse the existing stack related to the outer |
| 1924 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. | 1925 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. |
| 1925 // Promises with multiple reactions with one or more of them being async | 1926 // Promises with multiple reactions with one or more of them being async |
| 1926 // functions will not get a good stack trace, as async functions require | 1927 // functions will not get a good stack trace, as async functions require |
| 1927 // different stacks from direct Promise use, but we save and restore a | 1928 // different stacks from direct Promise use, but we save and restore a |
| 1928 // stack once for all reactions. | 1929 // stack once for all reactions. |
| 1929 // | 1930 // |
| 1930 // If this isn't a case of async function, we return false, otherwise | |
| 1931 // we set the correct id and return true. | |
| 1932 // | |
| 1933 // TODO(littledan): Improve this case. | 1931 // TODO(littledan): Improve this case. |
| 1934 int GetReferenceAsyncTaskId(Isolate* isolate, Handle<JSPromise> promise) { | 1932 int GetReferenceAsyncTaskId(Isolate* isolate, Handle<JSPromise> promise) { |
| 1935 Handle<Symbol> handled_by_symbol = | 1933 Handle<Symbol> handled_by_symbol = |
| 1936 isolate->factory()->promise_handled_by_symbol(); | 1934 isolate->factory()->promise_handled_by_symbol(); |
| 1937 Handle<Object> handled_by_promise = | 1935 Handle<Object> handled_by_promise = |
| 1938 JSObject::GetDataProperty(promise, handled_by_symbol); | 1936 JSObject::GetDataProperty(promise, handled_by_symbol); |
| 1939 if (!handled_by_promise->IsJSPromise()) { | 1937 if (!handled_by_promise->IsJSPromise()) { |
| 1940 return isolate->debug()->NextAsyncTaskId(promise); | 1938 return isolate->debug()->NextAsyncTaskId(promise); |
| 1941 } | 1939 } |
| 1942 Handle<JSPromise> handled_by_promise_js = | 1940 Handle<JSPromise> handled_by_promise_js = |
| 1943 Handle<JSPromise>::cast(handled_by_promise); | 1941 Handle<JSPromise>::cast(handled_by_promise); |
| 1944 Handle<Symbol> async_stack_id_symbol = | 1942 Handle<Symbol> async_stack_id_symbol = |
| 1945 isolate->factory()->promise_async_stack_id_symbol(); | 1943 isolate->factory()->promise_async_stack_id_symbol(); |
| 1946 Handle<Object> async_task_id = | 1944 Handle<Object> async_task_id = |
| 1947 JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); | 1945 JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); |
| 1948 if (!async_task_id->IsSmi()) { | 1946 if (!async_task_id->IsSmi()) { |
| 1949 return isolate->debug()->NextAsyncTaskId(promise); | 1947 return isolate->debug()->NextAsyncTaskId(promise); |
| 1950 } | 1948 } |
| 1951 return Handle<Smi>::cast(async_task_id)->value(); | 1949 return Handle<Smi>::cast(async_task_id)->value(); |
| 1952 } | 1950 } |
| 1953 } // namespace | 1951 } // namespace |
| 1954 | 1952 |
| 1955 void Debug::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, | 1953 void Debug::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, |
| 1956 Handle<Object> parent) { | 1954 Handle<Object> parent) { |
| 1957 if (!debug_delegate_) return; | 1955 if (!debug_delegate_) return; |
| 1958 int id = GetReferenceAsyncTaskId(isolate_, promise); | 1956 int id = GetReferenceAsyncTaskId(isolate_, promise); |
| 1959 switch (type) { | 1957 switch (type) { |
| 1960 case PromiseHookType::kInit: | 1958 case PromiseHookType::kInit: |
| 1961 debug_delegate_->PromiseEventOccurred( | 1959 debug_delegate_->PromiseCreatedEvent( |
| 1962 debug::kDebugPromiseCreated, id, | 1960 id, |
| 1963 parent->IsJSPromise() ? GetReferenceAsyncTaskId( | 1961 parent->IsJSPromise() ? GetReferenceAsyncTaskId( |
| 1964 isolate_, Handle<JSPromise>::cast(parent)) | 1962 isolate_, Handle<JSPromise>::cast(parent)) |
| 1965 : 0); | 1963 : 0, |
| 1964 !thread_local_.non_breakable_async_events_); |
| 1966 return; | 1965 return; |
| 1967 case PromiseHookType::kResolve: | 1966 case PromiseHookType::kResolve: |
| 1968 // We can't use this hook because it's called before promise object will | 1967 // We can't use this hook because it's called before promise object will |
| 1969 // get resolved status. | 1968 // get resolved status. |
| 1970 return; | 1969 return; |
| 1971 case PromiseHookType::kBefore: | 1970 case PromiseHookType::kBefore: |
| 1972 OnAsyncTaskEvent(debug::kDebugWillHandle, id); | 1971 OnAsyncTaskEvent(debug::kDebugWillHandle, id); |
| 1973 return; | 1972 return; |
| 1974 case PromiseHookType::kAfter: | 1973 case PromiseHookType::kAfter: |
| 1975 OnAsyncTaskEvent(debug::kDebugDidHandle, id); | 1974 OnAsyncTaskEvent(debug::kDebugDidHandle, id); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2036 shared->set_debug_is_blackboxed(is_blackboxed); | 2035 shared->set_debug_is_blackboxed(is_blackboxed); |
| 2037 shared->set_computed_debug_is_blackboxed(true); | 2036 shared->set_computed_debug_is_blackboxed(true); |
| 2038 } | 2037 } |
| 2039 return shared->debug_is_blackboxed(); | 2038 return shared->debug_is_blackboxed(); |
| 2040 } | 2039 } |
| 2041 | 2040 |
| 2042 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { | 2041 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { |
| 2043 if (in_debug_scope() || ignore_events()) return; | 2042 if (in_debug_scope() || ignore_events()) return; |
| 2044 | 2043 |
| 2045 if (debug_delegate_) { | 2044 if (debug_delegate_) { |
| 2046 debug_delegate_->PromiseEventOccurred(type, id, 0); | 2045 debug_delegate_->PromiseEventOccurred(type, id); |
| 2047 if (!non_inspector_listener_exists()) return; | 2046 if (!non_inspector_listener_exists()) return; |
| 2048 } | 2047 } |
| 2049 | 2048 |
| 2050 HandleScope scope(isolate_); | 2049 HandleScope scope(isolate_); |
| 2051 DebugScope debug_scope(this); | 2050 DebugScope debug_scope(this); |
| 2052 if (debug_scope.failed()) return; | 2051 if (debug_scope.failed()) return; |
| 2053 | 2052 |
| 2054 // Create the script collected state object. | 2053 // Create the script collected state object. |
| 2055 Handle<Object> event_data; | 2054 Handle<Object> event_data; |
| 2056 // Bail out and don't call debugger if exception. | 2055 // Bail out and don't call debugger if exception. |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2427 return v8::Utils::ToLocal(callback_data_); | 2426 return v8::Utils::ToLocal(callback_data_); |
| 2428 } | 2427 } |
| 2429 | 2428 |
| 2430 | 2429 |
| 2431 v8::Isolate* EventDetailsImpl::GetIsolate() const { | 2430 v8::Isolate* EventDetailsImpl::GetIsolate() const { |
| 2432 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); | 2431 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); |
| 2433 } | 2432 } |
| 2434 | 2433 |
| 2435 } // namespace internal | 2434 } // namespace internal |
| 2436 } // namespace v8 | 2435 } // namespace v8 |
| OLD | NEW |