Bug 65556 [implementation] JavaAutoIndentStrategy performance?
Build: 3.0 RC1 Ok, this is a bit of a silly test case, but it might point to possible performance improvements in the auto-indent code. These times are on a 2.5 Ghz PIV with plenty of RAM. 1) Copy, for example, an Eclipse book or a Tolstoy novel onto the clipboard (in my example, 110,000 words, 14,000 lines) 2) Paste into an empty text editor. -> Wow! It is *really* fast, faster than Notepad. Less than a second. 3) Paste into an empty Java editor. -> Still quite good, about three seconds. 4) Create a trivial Java file: package p1; public class A { } 5) Now paste the clipboard contents between the braces. -> Eclipse becomes unresponsive for 5 minutes. During this time, CPU is pegged but memory usage is stable and reasonable. I did stack dumps once a minute, and they were all inside JavaAutoIndentStrategy. See below for an example stack trace. After it came back to life, everything was fine and the editor was reasonably responsive. In org/eclipse/jface/text/GapTextStore.replace(IILjava/lang/String;)V In org/eclipse/jface/text/AbstractDocument.replace(IILjava/lang/String;) V In org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.addInden t(Lorg/eclipse/jface/text/Document;ILjava/lang/CharSequence;)V In org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.smartPas te(Lorg/eclipse/jface/text/IDocument;Lorg/eclipse/jface/text/DocumentCommand;)V In org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.customiz eDocumentCommand(Lorg/eclipse/jface/text/IDocument;Lorg/eclipse/jface/text/Docum entCommand;)V In org/eclipse/jface/text/TextViewer.customizeDocumentCommand(Lorg/eclip se/jface/text/DocumentCommand;)V In org/eclipse/jdt/internal/ui/javaeditor/CompilationUnitEditor$AdaptedS ourceViewer.customizeDocumentCommand(Lorg/eclipse/jface/text/DocumentCommand;)V In org/eclipse/jface/text/TextViewer.handleVerifyEvent(Lorg/eclipse/swt/ events/VerifyEvent;)V In org/eclipse/jface/text/source/projection/ProjectionViewer.handleVerif yEvent(Lorg/eclipse/swt/events/VerifyEvent;)V In org/eclipse/jface/text/TextViewer$TextVerifyListener.verifyText(Lorg/ eclipse/swt/events/VerifyEvent;)V In org/eclipse/swt/widgets/TypedListener.handleEvent(Lorg/eclipse/swt/wi dgets/Event;)V In org/eclipse/swt/widgets/EventTable.sendEvent(Lorg/eclipse/swt/widgets /Event;)V In org/eclipse/swt/widgets/Widget.sendEvent(Lorg/eclipse/swt/widgets/Eve nt;)V In org/eclipse/swt/widgets/Widget.sendEvent(ILorg/eclipse/swt/widgets/Ev ent;Z)V In org/eclipse/swt/widgets/Widget.sendEvent(ILorg/eclipse/swt/widgets/Ev ent;)V In org/eclipse/swt/widgets/Widget.notifyListeners(ILorg/eclipse/swt/widg ets/Event;)V In org/eclipse/swt/custom/StyledText.modifyContent(Lorg/eclipse/swt/widg ets/Event;Z)V In org/eclipse/swt/custom/StyledText.sendKeyEvent(Lorg/eclipse/swt/widge ts/Event;)V In org/eclipse/swt/custom/StyledText.paste()V In org/eclipse/jface/text/TextViewer.doOperation(I)V In org/eclipse/jface/text/source/SourceViewer.doOperation(I)V In org/eclipse/jface/text/source/projection/ProjectionViewer.doOperation (I)V In org/eclipse/jdt/internal/ui/javaeditor/JavaSourceViewer.doOperation(I )V In org/eclipse/jdt/internal/ui/javaeditor/CompilationUnitEditor$AdaptedS ourceViewer.doOperation(I)V In org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.doPas teWithImportsOperation()V In org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.inter nalDoOperation()V In org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction$1.run ()V In org/eclipse/swt/custom/BusyIndicator.showWhile(Lorg/eclipse/swt/widge ts/Display;Ljava/lang/Runnable;)V In org/eclipse/jdt/internal/ui/javaeditor/ClipboardOperationAction.run() V In org/eclipse/jface/action/Action.runWithEvent(Lorg/eclipse/swt/widgets /Event;)V In org/eclipse/ui/commands/ActionHandler.execute(Ljava/util/Map;)Ljava/l ang/Object; In org/eclipse/ui/internal/commands/Command.execute(Ljava/util/Map;)Ljav a/lang/Object; In org/eclipse/ui/internal/keys/WorkbenchKeyboard.executeCommand(Ljava/l ang/String;)Z In org/eclipse/ui/internal/keys/WorkbenchKeyboard.press(Ljava/util/List; Lorg/eclipse/swt/widgets/Event;)Z In org/eclipse/ui/internal/keys/WorkbenchKeyboard.processKeyEvent(Ljava/ util/List;Lorg/eclipse/swt/widgets/Event;)V In org/eclipse/ui/internal/keys/WorkbenchKeyboard.filterKeySequenceBindi ngs(Lorg/eclipse/swt/widgets/Event;)V In org/eclipse/ui/internal/keys/WorkbenchKeyboard.access$2(Lorg/eclipse/ ui/internal/keys/WorkbenchKeyboard;Lorg/eclipse/swt/widgets/Event;)V In org/eclipse/ui/internal/keys/WorkbenchKeyboard$1.handleEvent(Lorg/ecl ipse/swt/widgets/Event;)V In org/eclipse/swt/widgets/EventTable.sendEvent(Lorg/eclipse/swt/widgets /Event;)V In org/eclipse/swt/widgets/Display.filterEvent(Lorg/eclipse/swt/widgets/ Event;)Z In org/eclipse/swt/widgets/Widget.sendEvent(Lorg/eclipse/swt/widgets/Eve nt;)V In org/eclipse/swt/widgets/Widget.sendEvent(ILorg/eclipse/swt/widgets/Ev ent;Z)V In org/eclipse/swt/widgets/Widget.sendEvent(ILorg/eclipse/swt/widgets/Ev ent;)V In org/eclipse/swt/widgets/Control.sendKeyEvent(IIIILorg/eclipse/swt/wid gets/Event;)Z In org/eclipse/swt/widgets/Control.sendKeyEvent(IIII)Z In org/eclipse/swt/widgets/Control.WM_CHAR(II)Lorg/eclipse/swt/internal/ win32/LRESULT; In org/eclipse/swt/widgets/Control.windowProc(IIII)I In org/eclipse/swt/widgets/Display.windowProc(IIII)I In org/eclipse/swt/internal/win32/OS.DispatchMessageW(Lorg/eclipse/swt/i nternal/win32/MSG;)I In org/eclipse/swt/internal/win32/OS.DispatchMessage(Lorg/eclipse/swt/in ternal/win32/MSG;)I In org/eclipse/swt/widgets/Display.readAndDispatch()Z In org/eclipse/ui/internal/Workbench.runEventLoop(Lorg/eclipse/jface/win dow/Window$IExceptionHandler;Lorg/eclipse/swt/widgets/Display;)V In org/eclipse/ui/internal/Workbench.runUI()I In org/eclipse/ui/internal/Workbench.createAndRunWorkbench(Lorg/eclipse/ swt/widgets/Display;Lorg/eclipse/ui/application/WorkbenchAdvisor;)I In org/eclipse/ui/PlatformUI.createAndRunWorkbench(Lorg/eclipse/swt/widg ets/Display;Lorg/eclipse/ui/application/WorkbenchAdvisor;)I In org/eclipse/ui/internal/ide/IDEApplication.run(Ljava/lang/Object;)Lja va/lang/Object; In org/eclipse/core/internal/runtime/PlatformActivator$1.run(Ljava/lang/ Object;)Ljava/lang/Object; In org/eclipse/core/runtime/adaptor/EclipseStarter.run(Ljava/lang/Object ;)Ljava/lang/Object; In org/eclipse/core/runtime/adaptor/EclipseStarter.run([Ljava/lang/Strin g;Ljava/lang/Runnable;)Ljava/lang/Object; In sun/reflect/NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Metho d;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; In sun/reflect/NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/ lang/Object;)Ljava/lang/Object; In sun/reflect/DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Lj ava/lang/Object;)Ljava/lang/Object; In java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object; )Ljava/lang/Object; In org/eclipse/core/launcher/Main.basicRun([Ljava/lang/String;)Ljava/lan g/Object; In org/eclipse/core/launcher/Main.run([Ljava/lang/String;)I In org/eclipse/core/launcher/Main.main([Ljava/lang/String;)V
org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java
if (openingParen < 1)
				break;
			
			if (openingParen > pos)
				continue;
			if (looksLikeAnonymousClassDef(document, partitioning, scanner, openingParen - 1))
				return closingParen + 1;
		}
		return -1;
	}
	/**
	 * Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
	 * separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
	 *
	 * @param scanner the java heuristic scanner set up on the document
	 * @param position the first character position in <code>document</code> to be considered
	 * @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
	 */
	private static int findClosingParenToLeft(JavaHeuristicScanner scanner, int position) {
		if (position < 1)
			return position;
		if (scanner.previousToken(position - 1, JavaHeuristicScanner.UNBOUND) == Symbols.TokenRPAREN)
			return scanner.getPosition() + 1;
		return position;
	}
	/**
	 * Checks whether the content of <code>document</code> in the range (<code>offset</code>, <code>length</code>)
	 * contains the <code>new</code> keyword.
	 *
	 * @param document the document being modified