Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Side by Side Diff: src/isolate.cc

Issue 2406343002: [promises] Move PromiseReactionJob to c++ (Closed)
Patch Set: fix promisedebugeventscope Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/isolate.h ('k') | src/js/promise.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/isolate.h" 5 #include "src/isolate.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <fstream> // NOLINT(readability/streams) 9 #include <fstream> // NOLINT(readability/streams)
10 #include <sstream> 10 #include <sstream>
11 11
12 #include "src/ast/context-slot-cache.h" 12 #include "src/ast/context-slot-cache.h"
13 #include "src/base/hashmap.h" 13 #include "src/base/hashmap.h"
14 #include "src/base/platform/platform.h" 14 #include "src/base/platform/platform.h"
15 #include "src/base/sys-info.h" 15 #include "src/base/sys-info.h"
16 #include "src/base/utils/random-number-generator.h" 16 #include "src/base/utils/random-number-generator.h"
17 #include "src/basic-block-profiler.h" 17 #include "src/basic-block-profiler.h"
18 #include "src/bootstrapper.h" 18 #include "src/bootstrapper.h"
19 #include "src/cancelable-task.h" 19 #include "src/cancelable-task.h"
20 #include "src/codegen.h" 20 #include "src/codegen.h"
21 #include "src/compilation-cache.h" 21 #include "src/compilation-cache.h"
22 #include "src/compilation-statistics.h" 22 #include "src/compilation-statistics.h"
23 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" 23 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
24 #include "src/crankshaft/hydrogen.h" 24 #include "src/crankshaft/hydrogen.h"
25 #include "src/debug/debug.h" 25 #include "src/debug/debug.h"
26 #include "src/deoptimizer.h" 26 #include "src/deoptimizer.h"
27 #include "src/elements.h"
27 #include "src/external-reference-table.h" 28 #include "src/external-reference-table.h"
28 #include "src/frames-inl.h" 29 #include "src/frames-inl.h"
29 #include "src/ic/access-compiler-data.h" 30 #include "src/ic/access-compiler-data.h"
30 #include "src/ic/stub-cache.h" 31 #include "src/ic/stub-cache.h"
31 #include "src/interface-descriptors.h" 32 #include "src/interface-descriptors.h"
32 #include "src/interpreter/interpreter.h" 33 #include "src/interpreter/interpreter.h"
33 #include "src/isolate-inl.h" 34 #include "src/isolate-inl.h"
34 #include "src/libsampler/sampler.h" 35 #include "src/libsampler/sampler.h"
35 #include "src/log.h" 36 #include "src/log.h"
36 #include "src/messages.h" 37 #include "src/messages.h"
(...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 if (promise_reject_callback_ == NULL) return; 3002 if (promise_reject_callback_ == NULL) return;
3002 Handle<JSArray> stack_trace; 3003 Handle<JSArray> stack_trace;
3003 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { 3004 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) {
3004 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); 3005 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value));
3005 } 3006 }
3006 promise_reject_callback_(v8::PromiseRejectMessage( 3007 promise_reject_callback_(v8::PromiseRejectMessage(
3007 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), 3008 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value),
3008 v8::Utils::StackTraceToLocal(stack_trace))); 3009 v8::Utils::StackTraceToLocal(stack_trace)));
3009 } 3010 }
3010 3011
3012 namespace {
3013 class PromiseDebugEventScope {
3014 public:
3015 PromiseDebugEventScope(Isolate* isolate, Object* before, Object* after)
3016 : isolate_(isolate),
3017 after_(after, isolate_),
3018 is_debug_active_(isolate_->debug()->is_active() &&
3019 before->IsJSObject() && after->IsJSObject()) {
3020 if (is_debug_active_) {
3021 isolate_->debug()->OnAsyncTaskEvent(
3022 handle(JSObject::cast(before), isolate_));
3023 }
3024 }
3025
3026 ~PromiseDebugEventScope() {
3027 if (is_debug_active_) {
3028 isolate_->debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_));
3029 }
3030 }
3031
3032 private:
3033 Isolate* isolate_;
3034 Handle<Object> after_;
3035 bool is_debug_active_;
3036 };
3037 } // namespace
3038
3039 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info,
3040 MaybeHandle<Object>* result,
3041 MaybeHandle<Object>* maybe_exception) {
3042 PromiseDebugEventScope helper(this, info->before_debug_event(),
3043 info->after_debug_event());
3044
3045 Handle<Object> value(info->value(), this);
3046 Handle<Object> tasks(info->tasks(), this);
3047 Handle<JSFunction> promise_handle_fn = promise_handle();
3048 Handle<Object> undefined = factory()->undefined_value();
3049
3050 // If tasks is an array we have multiple onFulfilled/onRejected callbacks
3051 // associated with the promise. The deferred object for each callback
3052 // is attached to this array as well.
3053 // Otherwise, there is a single callback and the deferred object is attached
3054 // directly to PromiseReactionJobInfo.
3055 if (tasks->IsJSArray()) {
3056 Handle<JSArray> array = Handle<JSArray>::cast(tasks);
3057 DCHECK(array->length()->IsSmi());
3058 int length = Smi::cast(array->length())->value();
3059 ElementsAccessor* accessor = array->GetElementsAccessor();
3060 DCHECK(length % 2 == 0);
3061 for (int i = 0; i < length; i += 2) {
3062 DCHECK(accessor->HasElement(array, i));
3063 DCHECK(accessor->HasElement(array, i + 1));
3064 Handle<Object> argv[] = {value, accessor->Get(array, i),
3065 accessor->Get(array, i + 1)};
3066 *result = Execution::TryCall(this, promise_handle_fn, undefined,
3067 arraysize(argv), argv, maybe_exception);
3068 // If execution is terminating, just bail out.
3069 if (result->is_null() && maybe_exception->is_null()) {
3070 return;
3071 }
3072 }
3073 } else {
3074 Handle<Object> deferred(info->deferred(), this);
3075 Handle<Object> argv[] = {value, tasks, deferred};
3076 *result = Execution::TryCall(this, promise_handle_fn, undefined,
3077 arraysize(argv), argv, maybe_exception);
3078 }
3079 }
3080
3011 void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container, 3081 void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container,
3012 MaybeHandle<Object>* result, 3082 MaybeHandle<Object>* result,
3013 MaybeHandle<Object>* maybe_exception) { 3083 MaybeHandle<Object>* maybe_exception) {
3014 if (debug()->is_active()) { 3084 PromiseDebugEventScope helper(this, container->before_debug_event(),
3015 Handle<Object> before_debug_event(container->before_debug_event(), this); 3085 container->after_debug_event());
3016 if (before_debug_event->IsJSObject()) {
3017 debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(before_debug_event));
3018 }
3019 }
3020 3086
3021 Handle<JSReceiver> thenable(container->thenable(), this); 3087 Handle<JSReceiver> thenable(container->thenable(), this);
3022 Handle<JSFunction> resolve(container->resolve(), this); 3088 Handle<JSFunction> resolve(container->resolve(), this);
3023 Handle<JSFunction> reject(container->reject(), this); 3089 Handle<JSFunction> reject(container->reject(), this);
3024 Handle<JSReceiver> then(container->then(), this); 3090 Handle<JSReceiver> then(container->then(), this);
3025 Handle<Object> argv[] = {resolve, reject}; 3091 Handle<Object> argv[] = {resolve, reject};
3026 *result = Execution::TryCall(this, then, thenable, arraysize(argv), argv, 3092 *result = Execution::TryCall(this, then, thenable, arraysize(argv), argv,
3027 maybe_exception); 3093 maybe_exception);
3028 3094
3029 Handle<Object> reason; 3095 Handle<Object> reason;
3030 if (maybe_exception->ToHandle(&reason)) { 3096 if (maybe_exception->ToHandle(&reason)) {
3031 DCHECK(result->is_null()); 3097 DCHECK(result->is_null());
3032 Handle<Object> reason_arg[] = {reason}; 3098 Handle<Object> reason_arg[] = {reason};
3033 *result = 3099 *result =
3034 Execution::TryCall(this, reject, factory()->undefined_value(), 3100 Execution::TryCall(this, reject, factory()->undefined_value(),
3035 arraysize(reason_arg), reason_arg, maybe_exception); 3101 arraysize(reason_arg), reason_arg, maybe_exception);
3036 } 3102 }
3037
3038 if (debug()->is_active()) {
3039 Handle<Object> after_debug_event(container->after_debug_event(), this);
3040 if (after_debug_event->IsJSObject()) {
3041 debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_debug_event));
3042 }
3043 }
3044 } 3103 }
3045 3104
3046 void Isolate::EnqueueMicrotask(Handle<Object> microtask) { 3105 void Isolate::EnqueueMicrotask(Handle<Object> microtask) {
3047 DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo() || 3106 DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo() ||
3048 microtask->IsPromiseContainer()); 3107 microtask->IsPromiseContainer() ||
3108 microtask->IsPromiseReactionJobInfo());
3049 Handle<FixedArray> queue(heap()->microtask_queue(), this); 3109 Handle<FixedArray> queue(heap()->microtask_queue(), this);
3050 int num_tasks = pending_microtask_count(); 3110 int num_tasks = pending_microtask_count();
3051 DCHECK(num_tasks <= queue->length()); 3111 DCHECK(num_tasks <= queue->length());
3052 if (num_tasks == 0) { 3112 if (num_tasks == 0) {
3053 queue = factory()->NewFixedArray(8); 3113 queue = factory()->NewFixedArray(8);
3054 heap()->set_microtask_queue(*queue); 3114 heap()->set_microtask_queue(*queue);
3055 } else if (num_tasks == queue->length()) { 3115 } else if (num_tasks == queue->length()) {
3056 queue = factory()->CopyFixedArrayAndGrow(queue, num_tasks); 3116 queue = factory()->CopyFixedArrayAndGrow(queue, num_tasks);
3057 heap()->set_microtask_queue(*queue); 3117 heap()->set_microtask_queue(*queue);
3058 } 3118 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 3150
3091 if (microtask->IsCallHandlerInfo()) { 3151 if (microtask->IsCallHandlerInfo()) {
3092 Handle<CallHandlerInfo> callback_info = 3152 Handle<CallHandlerInfo> callback_info =
3093 Handle<CallHandlerInfo>::cast(microtask); 3153 Handle<CallHandlerInfo>::cast(microtask);
3094 v8::MicrotaskCallback callback = 3154 v8::MicrotaskCallback callback =
3095 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); 3155 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback());
3096 void* data = v8::ToCData<void*>(callback_info->data()); 3156 void* data = v8::ToCData<void*>(callback_info->data());
3097 callback(data); 3157 callback(data);
3098 } else { 3158 } else {
3099 SaveContext save(this); 3159 SaveContext save(this);
3100 Context* context = microtask->IsJSFunction() 3160 Context* context;
3101 ? Handle<JSFunction>::cast(microtask)->context() 3161 if (microtask->IsJSFunction()) {
3102 : Handle<PromiseContainer>::cast(microtask) 3162 context = Handle<JSFunction>::cast(microtask)->context();
3103 ->resolve() 3163 } else if (microtask->IsPromiseContainer()) {
3104 ->context(); 3164 context =
3165 Handle<PromiseContainer>::cast(microtask)->resolve()->context();
3166 } else {
3167 context = Handle<PromiseReactionJobInfo>::cast(microtask)->context();
3168 }
3169
3105 set_context(context->native_context()); 3170 set_context(context->native_context());
3106 handle_scope_implementer_->EnterMicrotaskContext( 3171 handle_scope_implementer_->EnterMicrotaskContext(
3107 Handle<Context>(context, this)); 3172 Handle<Context>(context, this));
3108 3173
3109 MaybeHandle<Object> result; 3174 MaybeHandle<Object> result;
3110 MaybeHandle<Object> maybe_exception; 3175 MaybeHandle<Object> maybe_exception;
3111 3176
3112 if (microtask->IsJSFunction()) { 3177 if (microtask->IsJSFunction()) {
3113 Handle<JSFunction> microtask_function = 3178 Handle<JSFunction> microtask_function =
3114 Handle<JSFunction>::cast(microtask); 3179 Handle<JSFunction>::cast(microtask);
3115 result = Execution::TryCall(this, microtask_function, 3180 result = Execution::TryCall(this, microtask_function,
3116 factory()->undefined_value(), 0, NULL, 3181 factory()->undefined_value(), 0, NULL,
3117 &maybe_exception); 3182 &maybe_exception);
3118 } else { 3183 } else if (microtask->IsPromiseContainer()) {
3119 PromiseResolveThenableJob(Handle<PromiseContainer>::cast(microtask), 3184 PromiseResolveThenableJob(Handle<PromiseContainer>::cast(microtask),
3120 &result, &maybe_exception); 3185 &result, &maybe_exception);
3186 } else {
3187 PromiseReactionJob(Handle<PromiseReactionJobInfo>::cast(microtask),
3188 &result, &maybe_exception);
3121 } 3189 }
3122 3190
3123 handle_scope_implementer_->LeaveMicrotaskContext(); 3191 handle_scope_implementer_->LeaveMicrotaskContext();
3124 3192
3125 // If execution is terminating, just bail out. 3193 // If execution is terminating, just bail out.
3126 if (result.is_null() && maybe_exception.is_null()) { 3194 if (result.is_null() && maybe_exception.is_null()) {
3127 // Clear out any remaining callbacks in the queue. 3195 // Clear out any remaining callbacks in the queue.
3128 heap()->set_microtask_queue(heap()->empty_fixed_array()); 3196 heap()->set_microtask_queue(heap()->empty_fixed_array());
3129 set_pending_microtask_count(0); 3197 set_pending_microtask_count(0);
3130 return; 3198 return;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
3323 // Then check whether this scope intercepts. 3391 // Then check whether this scope intercepts.
3324 if ((flag & intercept_mask_)) { 3392 if ((flag & intercept_mask_)) {
3325 intercepted_flags_ |= flag; 3393 intercepted_flags_ |= flag;
3326 return true; 3394 return true;
3327 } 3395 }
3328 return false; 3396 return false;
3329 } 3397 }
3330 3398
3331 } // namespace internal 3399 } // namespace internal
3332 } // namespace v8 3400 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/js/promise.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698