-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
8289613: Drop use of Thread.stop in jshell #10166
Conversation
👋 Welcome back asotona! A progress list of the required criteria for merging this PR into |
Webrevs
|
This is the last usage of Thread.stop in the JDK so this change is welcome. The instrumentation to check a flag at jump instrumentation looks reasonable, and works here because the method is public on a public class in an exported package. I hadn't noticed that jdk.jshell.execution is exported and the addition to LocalExecutionControl means it's a new API so I assume forces you to write javadoc. If a user presses control-C in jshell does it also interrupt the thread or will it just set the stop flag? If it also interrupts then you have another choice to check the interrupt status (assumes all code is well behaved of course). Is there one or many LocalExecutionControl objects when I execute a snippet, control-C, execute another? I'm wondering because the allStop flag is static but STOP_LOCK is per instance. |
I've checked the code, same question as Alan, i believe you can have multiple instances of LocalExecutionControl, but Usually, the way to get an instance at runtime is either to use a ClassValue on the generated class or to store the instance in a ClassLoader and several one class loaders. |
I believe that one instance of JShell will use only once instance of I think one way to resolve this is, for every A positive side-effect of this would be that we wouldn't need a new method in the public API, which I think would be preferred. |
yes, this is a good plan. |
I think @AlanBateman proposal to monitor interrupted status is easy to implement and also does not require a new public method nor synthetic class. |
@asotona, the problem is that user code may also react to the interrupted status, |
…ng Thread::interrupted
Right, let's try the synthetic class. |
…y checking Thread::interrupted" This reverts commit 0f0e0dd.
LocalExecutionControl.stop invoking Thread::interrupt is good as that will cause any interruptible methods to wakeup. I'm less sure about instrumenting every "if" and "goto" to invoke Thread::interrupted but more recent comment suggests are going back to a stop field that polled by code in a generated class so I'll wait until you are done. |
The latest version combines all comments. It instruments user code, delegates "allStop" to generated REPL.$Cancel$ class (loaded by specific LoaderDelegate), triggers REPL.$Cancel$.allStop and also interrupts all related threads to wake them up. |
src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java
Outdated
Show resolved
Hide resolved
src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java
Outdated
Show resolved
Hide resolved
src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java
Outdated
Show resolved
Hide resolved
Otherwise, it looks good to me |
Would it be possible to summarize how the loader delegate work in jshell? Instrumenting the code to invoke REPL/$Cancel$.stopCheck looks reasonable but I can't immediately see how the generated REPL/$Cancel$ has access to LocalExecutionControl.allStop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me.
Not sure what you mean - as far as I can tell, neither the generated class, nor the snippets access |
Okay, I see it now. REPL.$Cancel$.allStop is public so there is no issue accessing it from LEC.invoke. |
src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java
Show resolved
Hide resolved
@asotona This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 52 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/integrate |
Going to push as commit ffc249a.
Your commit was automatically rebased without conflicts. |
LocalExecutionControl in jdk.jshell actually uses Thread::stop to cancel execution of (long-running or infinite loops) user code in JShell, however Thread::stop is deprecated and planned for removal.
Proposed patch instruments all user code to call LocalExecutionControl::stopCheck method before every branch instruction.
Thread::stop call is replaced by setting global field LocalExecutionControl.allStop to true and stopCheck method then throws ThreadDead when called from the instrumented code.
Proposed patch requires jdk.jshell access to java.base jdk.internal.org.objectweb.asm package.
Please review.
Thanks,
Adam
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/10166/head:pull/10166
$ git checkout pull/10166
Update a local copy of the PR:
$ git checkout pull/10166
$ git pull https://git.openjdk.org/jdk pull/10166/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 10166
View PR using the GUI difftool:
$ git pr show -t 10166
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/10166.diff