Chromium Code Reviews| Index: src/debug/debug.cc |
| diff --git a/src/debug/debug.cc b/src/debug/debug.cc |
| index a75ece1bf312ddc292a7cd66b267542a3116b0be..35f8b9e793a510138ebb32a8f5a1a501ca0c03e8 100644 |
| --- a/src/debug/debug.cc |
| +++ b/src/debug/debug.cc |
| @@ -401,6 +401,7 @@ void Debug::ThreadInit() { |
| thread_local_.last_fp_ = 0; |
| thread_local_.target_fp_ = 0; |
| thread_local_.return_value_ = Handle<Object>(); |
| + thread_local_.async_task_count_ = 0; |
| clear_suspended_generator(); |
| // TODO(isolates): frames_are_dropped_? |
| base::NoBarrier_Store(&thread_local_.current_debug_scope_, |
| @@ -1656,7 +1657,7 @@ MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script, |
| return CallFunction("MakeCompileEvent", arraysize(argv), argv); |
| } |
| -MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<String> type, |
| +MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<Smi> type, |
| Handle<Object> id, |
| Handle<String> name) { |
| DCHECK(id->IsNumber()); |
| @@ -1779,7 +1780,59 @@ void Debug::OnAfterCompile(Handle<Script> script) { |
| ProcessCompileEvent(v8::AfterCompile, script); |
| } |
| -void Debug::OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, |
| +namespace { |
| +struct CollectedCallbackData { |
| + Object** location; |
| + int id; |
| + Debug* debug; |
| + Isolate* isolate; |
| + |
| + CollectedCallbackData(Object** location, int id, Debug* debug, |
| + Isolate* isolate) |
| + : location(location), id(id), debug(debug), isolate(isolate) {} |
| +}; |
| + |
| +void SendAsyncTaskEventCancel(const v8::WeakCallbackInfo<void>& info) { |
| + std::unique_ptr<CollectedCallbackData> data( |
| + reinterpret_cast<CollectedCallbackData*>(info.GetParameter())); |
| + if (!data->debug->is_active()) return; |
| + HandleScope scope(data->isolate); |
| + data->debug->OnAsyncTaskEvent(debug::Cancel, |
|
Yang
2016/12/16 17:10:26
Can you add a comment explaining why we need a wea
kozy
2016/12/16 17:47:15
Done.
|
| + handle(Smi::FromInt(data->id), data->isolate), |
| + data->isolate->factory()->collected_string()); |
| +} |
| + |
| +void ResetPromiseHandle(const v8::WeakCallbackInfo<void>& info) { |
| + CollectedCallbackData* data = |
| + reinterpret_cast<CollectedCallbackData*>(info.GetParameter()); |
| + GlobalHandles::Destroy(data->location); |
| + info.SetSecondPassCallback(&SendAsyncTaskEventCancel); |
| +} |
| +} // namespace |
| + |
| +Handle<Object> Debug::NextAsyncTaskId(Handle<JSObject> promise) { |
|
gsathya
2016/12/16 15:37:11
Can this be a non JSPromise? If not, you can make
kozy
2016/12/16 16:29:26
I double checked that we always get JSPromise here
|
| + LookupIterator it(promise, isolate_->factory()->promise_async_id_symbol()); |
| + Maybe<bool> maybe = JSReceiver::HasProperty(&it); |
| + Handle<Smi> async_id; |
| + if (!maybe.ToChecked()) { |
| + async_id = |
| + handle(Smi::FromInt(thread_local_.async_task_count_++), isolate_); |
| + Object::SetProperty(&it, async_id, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED) |
| + .ToChecked(); |
| + } else { |
| + MaybeHandle<Object> result = Object::GetProperty(&it); |
| + async_id = Handle<Smi>::cast(result.ToHandleChecked()); |
| + } |
| + Handle<Object> global_handle = isolate_->global_handles()->Create(*promise); |
| + GlobalHandles::MakeWeak( |
| + global_handle.location(), |
| + new CollectedCallbackData(global_handle.location(), async_id->value(), |
| + this, isolate_), |
| + &ResetPromiseHandle, v8::WeakCallbackType::kParameter); |
| + return async_id; |
| +} |
| + |
| +void Debug::OnAsyncTaskEvent(debug::AsyncTaskEventType type, Handle<Object> id, |
| Handle<String> name) { |
| DCHECK(id->IsNumber()); |
| if (in_debug_scope() || ignore_events()) return; |
| @@ -1791,7 +1844,8 @@ void Debug::OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, |
| // Create the script collected state object. |
| Handle<Object> event_data; |
| // Bail out and don't call debugger if exception. |
| - if (!MakeAsyncTaskEvent(type, id, name).ToHandle(&event_data)) return; |
| + Handle<Smi> type_smi(Smi::FromInt(type), isolate_); |
| + if (!MakeAsyncTaskEvent(type_smi, id, name).ToHandle(&event_data)) return; |
| // Process debug event. |
| ProcessDebugEvent(v8::AsyncTaskEvent, Handle<JSObject>::cast(event_data), |