Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JSC] exception from handleHostCall for tail-call should be handled correctly #22528

Conversation

Constellation
Copy link
Member

@Constellation Constellation commented Jan 9, 2024

e94a54e

[JSC] exception from handleHostCall for tail-call should be handled correctly
https://bugs.webkit.org/show_bug.cgi?id=267249
rdar://120662635

Reviewed by Mark Lam.

272580@main introduced failing in the fast path in polymorphic thunk (calling operationLinkPolymorphicFromRegularCall etc.).
In this case,

1. We should anyway use the top-most CallFrame* for NativeCallFrameTracer since it confuses StackVisitor (It assumes vm.topCallFrame is the top-most CallFrame*).
   We use calleeFrame instead of callerFrame.
2. Then, we should make StackVisitor work with CallFrame* which has non-cell JSCallee (when calling a non-function value). We rename stackOverflowFrameCallee to
   partiallyInitializedFrameCallee and use it. This tells StackVisitor that it should skip the first frame since it is pre-baked one. Also, make it possible to throw
   exception from this frame since exception catching code assumes that Callee is some cells.
3. To throw an exception from the current calleeFrame, this patch adds throwExceptionFromCallGenerator thunk, which throws an exception from the current frame when
   it is called as a normal JS function.

* JSTests/stress/tail-call-callee-frame-polymorphic.js: Added.
* Source/JavaScriptCore/bytecode/RepatchInlines.h:
(JSC::handleHostCall):
* Source/JavaScriptCore/interpreter/CallFrame.h:
* Source/JavaScriptCore/interpreter/CallFrameInlines.h:
(JSC::CallFrame::isHandleHostCallExceptionFrame const):
* Source/JavaScriptCore/interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracerForTailCall::NativeCallFrameTracerForTailCall): Deleted.
* Source/JavaScriptCore/interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITThunks.h:
* Source/JavaScriptCore/jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallGenerator):
(JSC::polymorphicThunkFor):
* Source/JavaScriptCore/jit/ThunkGenerators.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::handleHostCallExceptionCallee const):
* Source/JavaScriptCore/runtime/VMInlines.h:
(JSC::VM::topJSCallFrame const):

Canonical link: https://commits.webkit.org/272816@main

49b120d

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ›  gtk
βœ… πŸ›  πŸ§ͺ jsc βœ… πŸ§ͺ api-ios   πŸ§ͺ mac-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  πŸ§ͺ jsc-arm64 βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv-sim βœ… πŸ›  jsc-armv7
βœ… πŸ›  watch βœ… πŸ§ͺ jsc-armv7-tests
βœ… πŸ›  πŸ§ͺ unsafe-merge βœ… πŸ›  watch-sim

@Constellation Constellation requested a review from a team as a code owner January 9, 2024 00:47
@Constellation Constellation self-assigned this Jan 9, 2024
@Constellation Constellation added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Jan 9, 2024
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 3629fca to f757fe3 Compare January 9, 2024 00:55
@@ -96,6 +96,13 @@ inline bool CallFrame::isStackOverflowFrame() const
return jsCallee() == jsCallee()->globalObject()->stackOverflowFrameCallee();
}

inline bool CallFrame::isHandleHostCallExceptionFrame() const
Copy link

@MenloDorian MenloDorian Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: based on this patch, I don't see a need to distinguish handleHostCallExceptionCallee from stackOverflowFrameCallee. We could just rename stackOverflowFrameCallee to partiallyInitializedFrameCallee and just use that instead. This way, we don't have to spend time, code, and memory instantiating and checking for a second instance of this callee per global.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good.

Copy link

@MenloDorian MenloDorian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me

jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm.topEntryFrame, GPRInfo::argumentGPR0);
jit.setupArguments<decltype(operationLookupExceptionHandler)>(CCallHelpers::TrustedImmPtr(&vm));
jit.prepareCallOperation(vm);
jit.move(CCallHelpers::TrustedImmPtr(tagCFunction<OperationPtrTag>(operationLookupExceptionHandler)), GPRInfo::nonArgGPR0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you convert isStackOverflowFrame to isPartiallyInitializedFrame (which is used both by you here and by stack overflow), you can use operationLookupExceptionHandlerFromCallerFrame here. It is semantically the same except for the extra ASSERTs. However, it communicates more clearly that we intend to throw from the caller, and that the current frame is a partially initialized frame.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can be used for non partially initialized frame case (calling a function caused an error). So we should use operationLookupExceptionHandler

@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from f757fe3 to 69e7f7c Compare January 9, 2024 01:38
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 69e7f7c to fd65834 Compare January 9, 2024 04:24
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from fd65834 to c3a7c4a Compare January 9, 2024 04:52
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for c3a7c4a. Live statuses available at the PR page, #22528

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from c3a7c4a to eb6ff6e Compare January 9, 2024 05:18
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for eb6ff6e. Live statuses available at the PR page, #22528

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from eb6ff6e to 62231e0 Compare January 9, 2024 06:23
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 62231e0. Live statuses available at the PR page, #22528

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 9, 2024
@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 62231e0 to 36f1eab Compare January 9, 2024 06:30
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 36f1eab. Live statuses available at the PR page, #22528

@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 36f1eab to 16d6732 Compare January 9, 2024 06:55
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 16d6732. Live statuses available at the PR page, #22528

@Constellation Constellation force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 16d6732 to 49b120d Compare January 9, 2024 08:56
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 49b120d. Live statuses available at the PR page, #22528

@Constellation Constellation added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Jan 9, 2024
…orrectly

https://bugs.webkit.org/show_bug.cgi?id=267249
rdar://120662635

Reviewed by Mark Lam.

272580@main introduced failing in the fast path in polymorphic thunk (calling operationLinkPolymorphicFromRegularCall etc.).
In this case,

1. We should anyway use the top-most CallFrame* for NativeCallFrameTracer since it confuses StackVisitor (It assumes vm.topCallFrame is the top-most CallFrame*).
   We use calleeFrame instead of callerFrame.
2. Then, we should make StackVisitor work with CallFrame* which has non-cell JSCallee (when calling a non-function value). We rename stackOverflowFrameCallee to
   partiallyInitializedFrameCallee and use it. This tells StackVisitor that it should skip the first frame since it is pre-baked one. Also, make it possible to throw
   exception from this frame since exception catching code assumes that Callee is some cells.
3. To throw an exception from the current calleeFrame, this patch adds throwExceptionFromCallGenerator thunk, which throws an exception from the current frame when
   it is called as a normal JS function.

* JSTests/stress/tail-call-callee-frame-polymorphic.js: Added.
* Source/JavaScriptCore/bytecode/RepatchInlines.h:
(JSC::handleHostCall):
* Source/JavaScriptCore/interpreter/CallFrame.h:
* Source/JavaScriptCore/interpreter/CallFrameInlines.h:
(JSC::CallFrame::isHandleHostCallExceptionFrame const):
* Source/JavaScriptCore/interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracerForTailCall::NativeCallFrameTracerForTailCall): Deleted.
* Source/JavaScriptCore/interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITThunks.h:
* Source/JavaScriptCore/jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallGenerator):
(JSC::polymorphicThunkFor):
* Source/JavaScriptCore/jit/ThunkGenerators.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::handleHostCallExceptionCallee const):
* Source/JavaScriptCore/runtime/VMInlines.h:
(JSC::VM::topJSCallFrame const):

Canonical link: https://commits.webkit.org/272816@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/JSC-exception-from-handleHostCall-for-tail-call-should-be-handled-correctly branch from 49b120d to e94a54e Compare January 9, 2024 15:28
@webkit-commit-queue
Copy link
Collaborator

Committed 272816@main (e94a54e): https://commits.webkit.org/272816@main

Reviewed commits have been landed. Closing PR #22528 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit e94a54e into WebKit:main Jan 9, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.
Projects
None yet
5 participants