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

ContentAssist / CompletionScanner running into deadlock #1100

Closed
Kademlia opened this issue May 29, 2023 · 7 comments · Fixed by #1194
Closed

ContentAssist / CompletionScanner running into deadlock #1100

Kademlia opened this issue May 29, 2023 · 7 comments · Fixed by #1194
Assignees

Comments

@Kademlia
Copy link

Kademlia commented May 29, 2023

Hey,
I recently ran into a case that would freeze up Eclipse completely trough the ContentAssist-Popup.
Freeze seems to be originating from AsyncCompletionProposalPopup inner Lambda expression.

I was able to roughly reproduce this with a unedited version of eclipse-java-2023-03-R-win32-x86_64. The IDE freezes nearly the whole computer for about 20 seconds (5950x 16 core), content Assist fails with OutOfMemoryException in the end. Writing "boolean test" and pressing CTRL+Space as shown in the screenshot will cause CPU/Mem to spike.

openjdk 17.0.6 2023-01-17
OpenJDK Runtime Environment JBR-17.0.6+10-829.5-jcef (build 17.0.6+10-b829.5)

All of the load seems to come from created instances of CompletionScanner < CompletionJavadocParser < CompletionParser < AssistParser < CompletionParser

Timestamp of this happening: https://www.twitch.tv/videos/1831458336?t=05h40m22s

Minified example code freezing my instance:

package gg;

import java.lang.StackWalker.Option;

public class PlanetTravelActionLagTest {

	private void test() {
		Option opt = Option.RETAIN_CLASS_REFERENCE;

		switch (opt) { // <- Write 'boolean test' here and press CTRL+Space
			case RETAIN_CLASS_REFERENCE -> {
			}
			case SHOW_HIDDEN_FRAMES -> {
			}
			case SHOW_REFLECT_FRAMES -> throw new UnsupportedOperationException("Unimplemented case: ");
		}

	}

}
}

002934_

grafik

grafik

grafik

grafik

grafik

Originally posted by @Kademlia in #1098 (comment)

@Kademlia
Copy link
Author

Confirmed for 2023-06 (Win 10 & Win 11). Now the Task will never stop and consume ~1 CPU-Core forever. Even after the affected file is deleted from workspace. Only fix is to reboot the whole IDE.

@iloveeclipse
Copy link
Member

switch (opt) { // <- Write 'boolean test' here and press CTRL+Space

Here the snippet I've used and it is reproducible at current master in plain SDK

package gg;
import java.lang.StackWalker.Option;
public class PlanetTravelActionLagTest {
	private void test() {
		Option opt = Option.RETAIN_CLASS_REFERENCE;
		boolean test|switch (opt) { // <- remove pipe and press CTRL+Space
			case RETAIN_CLASS_REFERENCE -> {
			}
			case SHOW_HIDDEN_FRAMES -> {
			}
			case SHOW_REFLECT_FRAMES -> throw new UnsupportedOperationException("Unimplemented case: ");
		}
	}
}

Thread below will run in endless loop:

Daemon Thread [ForkJoinPool.commonPool-worker-5] (Suspended)	
	CompletionParser(AssistParser).copyState(Parser) line: 161	
	CompletionParser.copyState(Parser) line: 5612	
	CompletionParser(AssistParser).commit() line: 2348	
	CompletionParser(AssistParser).triggerRecoveryUponLambdaClosure(Statement, boolean) line: 627	
	CompletionParser(AssistParser).consumeBlockStatements() line: 748	
	CompletionParser(Parser).consumeRule(int) line: 7554	
	CompletionParser(Parser).parse() line: 13183	
	CompletionParser.parseSomeStatements(int, int, int, CompilationUnitDeclaration) line: 5895	
	UnresolvedReferenceNameFinder.findAfter(char[], Scope, int, int, int, boolean, char[][], UnresolvedReferenceNameFinder$UnresolvedReferenceNameRequestor) line: 155	
	UnresolvedReferenceNameFinder.find(char[], AbstractMethodDeclaration, int, char[][], UnresolvedReferenceNameFinder$UnresolvedReferenceNameRequestor) line: 101	
	CompletionEngine.findVariableFromUnresolvedReference(LocalDeclaration, BlockScope, char[][]) line: 13005	
	CompletionEngine.completionOnLocalOrArgumentName(ASTNode, Scope) line: 3062	
	CompletionEngine.complete(ASTNode, ASTNode, ASTNode, CompilationUnitDeclaration, Binding, Scope, boolean) line: 2057	
	CompletionEngine.complete(ICompilationUnit, int, int, ITypeRoot) line: 2356	
	CompilationUnit(Openable).codeComplete(ICompilationUnit, ICompilationUnit, int, CompletionRequestor, WorkingCopyOwner, ITypeRoot, IProgressMonitor) line: 136	
	CompilationUnit.codeComplete(int, CompletionRequestor, WorkingCopyOwner, IProgressMonitor) line: 367	
	CompilationUnit.codeComplete(int, CompletionRequestor, IProgressMonitor) line: 357	
	JavaAllCompletionProposalComputer(JavaCompletionProposalComputer).internalComputeCompletionProposals(int, JavaContentAssistInvocationContext) line: 256	
	JavaAllCompletionProposalComputer(JavaCompletionProposalComputer).computeCompletionProposals(ContentAssistInvocationContext, IProgressMonitor) line: 218	
	JavaAllCompletionProposalComputer(JavaTypeCompletionProposalComputer).computeCompletionProposals(ContentAssistInvocationContext, IProgressMonitor) line: 65	
	CompletionProposalComputerDescriptor.computeCompletionProposals(ContentAssistInvocationContext, IProgressMonitor) line: 348	
	CompletionProposalCategory.computeCompletionProposals(ContentAssistInvocationContext, String, SubProgressMonitor) line: 340	
	JavaCompletionProcessor(ContentAssistProcessor).collectProposals(ITextViewer, int, IProgressMonitor, ContentAssistInvocationContext) line: 333	
	JavaCompletionProcessor(ContentAssistProcessor).computeCompletionProposals(ITextViewer, int) line: 289	
	AsyncCompletionProposalPopup.lambda$10(IContentAssistProcessor, int, AtomicReference) line: 378	
	0x0000000801727a40.run() line: not available	
	SafeRunner.run(ISafeRunnable) line: 45	
	AsyncCompletionProposalPopup.lambda$9(IContentAssistProcessor, int) line: 377	
	0x00000008017275d0.get() line: not available	
	CompletableFuture$AsyncSupply<T>.run() line: 1768	
	CompletableFuture$AsyncSupply<T>.exec() line: 1760	
	CompletableFuture$AsyncSupply<T>(ForkJoinTask<V>).doExec() line: 373	
	ForkJoinPool$WorkQueue.topLevelExec(ForkJoinTask<?>, WorkQueue) line: 1182	
	ForkJoinPool.scan(ForkJoinPool$WorkQueue, int, int) line: 1655	
	ForkJoinPool.runWorker(ForkJoinPool$WorkQueue) line: 1622	
	ForkJoinWorkerThread.run() line: 165	

@Kademlia : I'm not sure how your snippet should finally look like, and why do you have such strange code (it doesn't compile).

Is it supposed to look like this below may be? Just trying to understand your use case, hanging thread is without doubt not OK.

package gg;
import java.lang.StackWalker.Option;
public class X {
	public void test() {
		Option opt = Option.RETAIN_CLASS_REFERENCE;
		boolean test = switch (opt) {
			case RETAIN_CLASS_REFERENCE -> true;
			case SHOW_HIDDEN_FRAMES -> false;
			default -> throw new IllegalArgumentException("Unexpected value: " + opt);
		};
		System.out.println(test);
	}
}

@Kademlia
Copy link
Author

@iloveeclipse
You can see my use case in the linked video in the first post. I just tried to create a minified version of the code for the example.

@iloveeclipse
Copy link
Member

OK, I see it now. So you've tried to refactor the code basically to something like in my smaller snippet, and during this you've opened content assist on "unfinished" code.

@srikanth-sankaran: are you familiar with the code in question (see stack in comment above)?
IDE shouldn't hang just because of an incomplete code state.

@srikanth-sankaran srikanth-sankaran self-assigned this Jun 21, 2023
@srikanth-sankaran
Copy link
Contributor

OK, I see it now. So you've tried to refactor the code basically to something like in my smaller snippet, and during this you've opened content assist on "unfinished" code.

@srikanth-sankaran: are you familiar with the code in question (see stack in comment above)? IDE shouldn't hang just because of an incomplete code state.

I was familiar long ago. I will add this to my queue.

@srikanth-sankaran
Copy link
Contributor

Hmm. A very interesting bug! The CompletionParser sees a lambda expression in the code while the normal parser (correctly) sees none! Looking into it ...

@srikanth-sankaran
Copy link
Contributor

See also #968 and
#708

#708 is basically a case where the -> of a switch expression was confused for a lambda and its fix brings about #968

srikanth-sankaran added a commit to srikanth-sankaran/eclipse.jdt.core that referenced this issue Jun 28, 2023
srikanth-sankaran added a commit that referenced this issue Jun 28, 2023
* Ensure that attempts to nudge recovery along don't stuck reducing empty statements

* Fixes #1100
mpalat pushed a commit to mpalat/eclipse.jdt.core that referenced this issue Jul 6, 2023
* Ensure that attempts to nudge recovery along don't stuck reducing empty statements

* Fixes eclipse-jdt#1100
robstryker pushed a commit to robstryker/eclipse.jdt.core that referenced this issue Jul 18, 2024
* Ensure that attempts to nudge recovery along don't stuck reducing empty statements

* Fixes eclipse-jdt#1100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants