Chromium Code Reviews

Side by Side Diff: src/builtins/builtins-promise.cc

Issue 2630593004: [promises] Remove runtime call from fastpath in PromiseReject (Closed)
Patch Set: split function Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/contexts.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/builtins/builtins-promise.h" 5 #include "src/builtins/builtins-promise.h"
6 #include "src/builtins/builtins-constructor.h" 6 #include "src/builtins/builtins-constructor.h"
7 #include "src/builtins/builtins-utils.h" 7 #include "src/builtins/builtins-utils.h"
8 #include "src/builtins/builtins.h" 8 #include "src/builtins/builtins.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stub-assembler.h" 10 #include "src/code-stub-assembler.h"
(...skipping 730 matching lines...)
741 Node* const has_handler = PromiseHasHandler(result); 741 Node* const has_handler = PromiseHasHandler(result);
742 742
743 // Promise has already been rejected, but had no handler. 743 // Promise has already been rejected, but had no handler.
744 // Revoke previously triggered reject event. 744 // Revoke previously triggered reject event.
745 GotoIf(has_handler, &reject); 745 GotoIf(has_handler, &reject);
746 CallRuntime(Runtime::kPromiseRevokeReject, context, result); 746 CallRuntime(Runtime::kPromiseRevokeReject, context, result);
747 Goto(&reject); 747 Goto(&reject);
748 748
749 Bind(&reject); 749 Bind(&reject);
750 // Don't cause a debug event as this case is forwarding a rejection 750 // Don't cause a debug event as this case is forwarding a rejection
751 CallRuntime(Runtime::kPromiseReject, context, promise, thenable_value, 751 InternalPromiseReject(context, promise, thenable_value, false);
752 FalseConstant());
753 PromiseSetHasHandler(result); 752 PromiseSetHasHandler(result);
754 Goto(&out); 753 Goto(&out);
755 } 754 }
756 } 755 }
757 } 756 }
758 757
759 Bind(&if_notnativepromise); 758 Bind(&if_notnativepromise);
760 { 759 {
761 // 8. Let then be Get(resolution, "then"). 760 // 8. Let then be Get(resolution, "then").
762 Node* const then_str = HeapConstant(isolate->factory()->then_string()); 761 Node* const then_str = HeapConstant(isolate->factory()->then_string());
(...skipping 66 matching lines...)
829 CallRuntime(Runtime::kNewTypeError, context, message_id, result); 828 CallRuntime(Runtime::kNewTypeError, context, message_id, result);
830 var_reason.Bind(error); 829 var_reason.Bind(error);
831 830
832 // 6.b Return RejectPromise(promise, selfResolutionError). 831 // 6.b Return RejectPromise(promise, selfResolutionError).
833 Goto(&if_rejectpromise); 832 Goto(&if_rejectpromise);
834 } 833 }
835 834
836 // 9.a Return RejectPromise(promise, then.[[Value]]). 835 // 9.a Return RejectPromise(promise, then.[[Value]]).
837 Bind(&if_rejectpromise); 836 Bind(&if_rejectpromise);
838 { 837 {
839 CallRuntime(Runtime::kPromiseReject, context, promise, var_reason.value(), 838 InternalPromiseReject(context, promise, var_reason.value(), true);
840 TrueConstant());
841 Goto(&out); 839 Goto(&out);
842 } 840 }
843 841
844 Bind(&out); 842 Bind(&out);
845 } 843 }
846 844
847 void PromiseBuiltinsAssembler::PromiseFulfill( 845 void PromiseBuiltinsAssembler::PromiseFulfill(
848 Node* context, Node* promise, Node* result, 846 Node* context, Node* promise, Node* result,
849 v8::Promise::PromiseState status) { 847 v8::Promise::PromiseState status) {
850 Label do_promisereset(this), debug_async_event_enqueue_recurring(this); 848 Label do_promisereset(this), debug_async_event_enqueue_recurring(this);
(...skipping 85 matching lines...)
936 { 934 {
937 Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context, 935 Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context,
938 promise_constructor), 936 promise_constructor),
939 BooleanConstant(true)), 937 BooleanConstant(true)),
940 &has_access, if_noaccess); 938 &has_access, if_noaccess);
941 } 939 }
942 940
943 Bind(&has_access); 941 Bind(&has_access);
944 } 942 }
945 943
944 void PromiseBuiltinsAssembler::InternalPromiseReject(Node* context,
Igor Sheludko 2017/01/17 11:54:13 I think you can merge this with the InternalPromis
gsathya 2017/01/17 14:51:34 Done.
945 Node* promise, Node* value,
946 bool debug_event) {
947 Label out(this);
948
949 if (debug_event) {
950 GotoUnless(IsDebugActive(), &out);
951 CallRuntime(Runtime::kDebugPromiseReject, context, promise, value);
952 Goto(&out);
953 } else {
954 Goto(&out);
955 }
956
957 Bind(&out);
958 InternalPromiseReject(context, promise, value);
959 }
960
961 void PromiseBuiltinsAssembler::InternalPromiseReject(Node* context,
962 Node* promise, Node* value,
963 Node* debug_event) {
964 Label out(this);
965 GotoUnless(IsDebugActive(), &out);
966 GotoUnless(WordEqual(TrueConstant(), debug_event), &out);
967 CallRuntime(Runtime::kDebugPromiseReject, context, promise, value);
968 Goto(&out);
969
970 Bind(&out);
971 InternalPromiseReject(context, promise, value);
Igor Sheludko 2017/01/17 11:54:14 ... and call InternalPromiseReject(context, promis
gsathya 2017/01/17 14:51:34 Done.
972 }
973
974 // This duplicates a lot of logic from PromiseRejectEvent in
975 // runtime-promise.cc
976 void PromiseBuiltinsAssembler::InternalPromiseReject(Node* context,
977 Node* promise,
978 Node* value) {
979 Label fulfill(this), report_unhandledpromise(this),
980 run_promise_hook(this, Label::kDeferred);
981
982 Branch(IsPromiseHookEnabled(), &run_promise_hook, &report_unhandledpromise);
983
984 Bind(&run_promise_hook);
985 {
986 CallRuntime(Runtime::kPromiseHookResolve, context, promise);
987 Goto(&report_unhandledpromise);
988 }
989
990 Bind(&report_unhandledpromise);
991 {
992 GotoIf(PromiseHasHandler(promise), &fulfill);
993 CallRuntime(Runtime::kReportPromiseReject, context, promise, value);
994 Goto(&fulfill);
995 }
996
997 Bind(&fulfill);
998 PromiseFulfill(context, promise, value, v8::Promise::kRejected);
999 }
1000
946 // ES#sec-promise-reject-functions 1001 // ES#sec-promise-reject-functions
947 // Promise Reject Functions 1002 // Promise Reject Functions
948 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { 1003 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) {
949 Node* const value = Parameter(1); 1004 Node* const value = Parameter(1);
950 Node* const context = Parameter(4); 1005 Node* const context = Parameter(4);
951 1006
952 Label out(this); 1007 Label out(this);
953 1008
954 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. 1009 // 3. Let alreadyResolved be F.[[AlreadyResolved]].
955 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; 1010 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot;
956 1011
957 Node* const has_already_visited = 1012 Node* const has_already_visited =
958 LoadContextElement(context, has_already_visited_slot); 1013 LoadContextElement(context, has_already_visited_slot);
959 1014
960 // 4. If alreadyResolved.[[Value]] is true, return undefined. 1015 // 4. If alreadyResolved.[[Value]] is true, return undefined.
961 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); 1016 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out);
962 1017
963 // 5.Set alreadyResolved.[[Value]] to true. 1018 // 5.Set alreadyResolved.[[Value]] to true.
964 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, 1019 StoreContextElementNoWriteBarrier(context, has_already_visited_slot,
965 SmiConstant(1)); 1020 SmiConstant(1));
966 1021
967 // 2. Let promise be F.[[Promise]]. 1022 // 2. Let promise be F.[[Promise]].
968 Node* const promise = 1023 Node* const promise =
969 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot)); 1024 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot));
970 Node* const debug_event = LoadContextElement( 1025 Node* const debug_event = LoadContextElement(
971 context, IntPtrConstant(PromiseUtils::kDebugEventSlot)); 1026 context, IntPtrConstant(PromiseUtils::kDebugEventSlot));
972 1027
973 CallRuntime(Runtime::kPromiseReject, context, promise, value, debug_event); 1028 InternalPromiseReject(context, promise, value, debug_event);
974 Return(UndefinedConstant()); 1029 Return(UndefinedConstant());
975 1030
976 Bind(&out); 1031 Bind(&out);
977 Return(UndefinedConstant()); 1032 Return(UndefinedConstant());
978 } 1033 }
979 1034
980 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { 1035 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
981 Node* const executor = Parameter(1); 1036 Node* const executor = Parameter(1);
982 Node* const new_target = Parameter(2); 1037 Node* const new_target = Parameter(2);
983 Node* const context = Parameter(4); 1038 Node* const context = Parameter(4);
(...skipping 216 matching lines...)
1200 Node* const context = Parameter(Descriptor::kContext); 1255 Node* const context = Parameter(Descriptor::kContext);
1201 1256
1202 Callable call_callable = CodeFactory::Call(isolate()); 1257 Callable call_callable = CodeFactory::Call(isolate());
1203 Variable var_unused(this, MachineRepresentation::kTagged); 1258 Variable var_unused(this, MachineRepresentation::kTagged);
1204 1259
1205 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 1260 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
1206 Branch(IsUndefined(on_reject), &if_internalhandler, &if_customhandler); 1261 Branch(IsUndefined(on_reject), &if_internalhandler, &if_customhandler);
1207 1262
1208 Bind(&if_internalhandler); 1263 Bind(&if_internalhandler);
1209 { 1264 {
1210 CallRuntime(Runtime::kPromiseReject, context, promise, exception, 1265 InternalPromiseReject(context, promise, exception, false);
1211 FalseConstant());
1212 Return(UndefinedConstant()); 1266 Return(UndefinedConstant());
1213 } 1267 }
1214 1268
1215 Bind(&if_customhandler); 1269 Bind(&if_customhandler);
1216 { 1270 {
1217 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); 1271 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
1218 Return(UndefinedConstant()); 1272 Return(UndefinedConstant());
1219 } 1273 }
1220 } 1274 }
1221 1275
(...skipping 275 matching lines...)
1497 Callable call_callable = CodeFactory::Call(isolate()); 1551 Callable call_callable = CodeFactory::Call(isolate());
1498 CallJS(call_callable, context, reject, UndefinedConstant(), reason); 1552 CallJS(call_callable, context, reject, UndefinedConstant(), reason);
1499 1553
1500 // 5. Return promiseCapability.[[Promise]]. 1554 // 5. Return promiseCapability.[[Promise]].
1501 Node* const promise = 1555 Node* const promise =
1502 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset); 1556 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset);
1503 Return(promise); 1557 Return(promise);
1504 } 1558 }
1505 } 1559 }
1506 1560
1561 TF_BUILTIN(InternalPromiseReject, PromiseBuiltinsAssembler) {
1562 Node* const promise = Parameter(1);
1563 Node* const reason = Parameter(2);
1564 Node* const debug_event = Parameter(3);
1565 Node* const context = Parameter(6);
1566
1567 InternalPromiseReject(context, promise, reason, debug_event);
1568 Return(UndefinedConstant());
1569 }
1570
1507 } // namespace internal 1571 } // namespace internal
1508 } // namespace v8 1572 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine