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 |