A few contention optimizations

This commit is contained in:
Maxim Shafirov
2009-10-27 20:48:11 +03:00
parent cf7980dc51
commit 2f78f91ec3
5 changed files with 81 additions and 73 deletions
@@ -20,17 +20,17 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import gnu.trove.THashSet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Set;
public class JavaLexer extends LexerBase {
private JavaLexer(boolean isAssertKeywordEnabled, boolean isJDK15) {
myTable = isAssertKeywordEnabled
? isJDK15 ? ourTableWithAssertAndJDK15 : ourTableWithAssert
: isJDK15 ? ourTableWithJDK15 : ourTableWithoutAssert;
myTable = getTable(isAssertKeywordEnabled, isJDK15);
myFlexlexer = new _JavaLexer(isAssertKeywordEnabled, isJDK15);
}
@@ -38,6 +38,21 @@ public class JavaLexer extends LexerBase {
this(level.hasAssertKeyword(), level.hasEnumKeywordAndAutoboxing());
}
private static HashTable getTable(boolean isAssertKeywordEnabled, boolean isJDK15) {
return isAssertKeywordEnabled
? isJDK15 ? ourTableWithAssertAndJDK15 : ourTableWithAssert
: isJDK15 ? ourTableWithJDK15 : ourTableWithoutAssert;
}
private static HashTable getTable(LanguageLevel level) {
return getTable(level.hasAssertKeyword(), level.hasEnumKeywordAndAutoboxing());
}
public static boolean isKeyword(String id, LanguageLevel level) {
return getTable(level).contains(id);
}
private CharSequence myBuffer;
private int myBufferIndex;
private int myBufferEndOffset;
@@ -54,6 +69,7 @@ public class JavaLexer extends LexerBase {
private final char[][] myTable = new char[NUM_ENTRIES][];
private final IElementType[] myKeywords = new IElementType[NUM_ENTRIES];
private final Set<String> myKeywordsInSet = new THashSet<String>();
private void add(String s, IElementType tokenType) {
char[] chars = s.toCharArray();
@@ -66,6 +82,11 @@ public class JavaLexer extends LexerBase {
myTable[modHashCode] = chars;
myKeywords[modHashCode] = tokenType;
myKeywordsInSet.add(s);
}
public boolean contains(String s) {
return myKeywordsInSet.contains(s);
}
private boolean contains(int hashCode, final CharSequence buffer, int offset) {
@@ -26,9 +26,11 @@ package com.intellij.psi.controlFlow;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -42,10 +44,18 @@ public class ControlFlowFactory {
// psiElements hold weakly, controlFlows softly
private final ConcurrentMap<PsiElement, Reference<CopyOnWriteArrayList<ControlFlowContext>>> cachedFlows = new ConcurrentWeakHashMap<PsiElement, Reference<CopyOnWriteArrayList<ControlFlowContext>>>();
private static final NotNullLazyKey<ControlFlowFactory, Project> INSTANCE_KEY = NotNullLazyKey.create("ControlFlowFactory.Instance.Cache", new NotNullFunction<Project, ControlFlowFactory>() {
@NotNull
public ControlFlowFactory fun(final Project project) {
return ServiceManager.getService(project, ControlFlowFactory.class);
}
});
public static ControlFlowFactory getInstance(Project project) {
return ServiceManager.getService(project, ControlFlowFactory.class);
return INSTANCE_KEY.getValue(project);
}
public ControlFlowFactory(PsiManagerEx psiManager) {
psiManager.registerRunnableToRunOnChange(new Runnable(){
public void run() {
@@ -1,94 +1,52 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl;
import com.intellij.lexer.JavaLexer;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiNameHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiNameHelperImpl extends PsiNameHelper{
private final JavaPsiFacade myManager;
private Lexer myLexer;
private LanguageLevel myLastLanguageLevel;
private final Object LOCK = new Object();
public class PsiNameHelperImpl extends PsiNameHelper {
private final LanguageLevelProjectExtension myLanguageLevelExtension;
public PsiNameHelperImpl(JavaPsiFacade manager) {
myManager = manager;
myLastLanguageLevel = LanguageLevelProjectExtension.getInstance(manager.getProject()).getLanguageLevel();
myLexer = new JavaLexer(myLastLanguageLevel);
}
private void updateLexer(LanguageLevel languageLevel){
if (!myLastLanguageLevel.equals(languageLevel)){
myLastLanguageLevel = languageLevel;
myLexer = new JavaLexer(myLastLanguageLevel);
}
myLanguageLevelExtension = LanguageLevelProjectExtension.getInstance(manager.getProject());
}
public boolean isIdentifier(@Nullable String text) {
ApplicationManager.getApplication().assertReadAccessAllowed();
if (text == null) return false;
synchronized (LOCK) {
updateLexer(LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel());
myLexer.start(text);
if (myLexer.getTokenType() != JavaTokenType.IDENTIFIER) return false;
myLexer.advance();
return myLexer.getTokenType() == null;
}
return isIdentifier(text, myLanguageLevelExtension.getLanguageLevel());
}
public boolean isIdentifier(@Nullable String text, @NotNull LanguageLevel languageLevel) {
ApplicationManager.getApplication().assertReadAccessAllowed();
if (text == null) return false;
synchronized (LOCK) {
updateLexer(languageLevel);
myLexer.start(text);
if (myLexer.getTokenType() != JavaTokenType.IDENTIFIER) return false;
myLexer.advance();
return myLexer.getTokenType() == null;
}
return text != null && StringUtil.isJavaIdentifier(text) && !JavaLexer.isKeyword(text, languageLevel);
}
public boolean isKeyword(@Nullable String text) {
ApplicationManager.getApplication().assertReadAccessAllowed();
if (text == null) return false;
synchronized (LOCK) {
updateLexer(LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel());
myLexer.start(text);
if (myLexer.getTokenType() == null || !JavaTokenType.KEYWORD_BIT_SET.contains(myLexer.getTokenType())) return false;
myLexer.advance();
return myLexer.getTokenType() == null;
}
return text != null && JavaLexer.isKeyword(text, myLanguageLevelExtension.getLanguageLevel());
}
public boolean isQualifiedName(@Nullable String text){
public boolean isQualifiedName(@Nullable String text) {
if (text == null) return false;
int index = 0;
while(true){
while (true) {
int index1 = text.indexOf('.', index);
if (index1 < 0) index1 = text.length();
if (!isIdentifier(text.substring(index, index1))) return false;
@@ -23,6 +23,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
@@ -30,6 +31,7 @@ import com.intellij.psi.PsiVariable;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -42,8 +44,15 @@ import java.util.concurrent.ConcurrentMap;
public class JavaResolveCache {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.JavaResolveCache");
private static final NotNullLazyKey<JavaResolveCache, Project> INSTANCE_KEY = NotNullLazyKey.create("JavaResolveCache.Instance.Cache", new NotNullFunction<Project, JavaResolveCache>() {
@NotNull
public JavaResolveCache fun(final Project project) {
return ServiceManager.getService(project, JavaResolveCache.class);
}
});
public static JavaResolveCache getInstance(Project project) {
return ServiceManager.getService(project, JavaResolveCache.class);
return INSTANCE_KEY.getValue(project);
}
private final ConcurrentMap<PsiExpression, PsiType> myCalculatedTypes = new ConcurrentWeakHashMap<PsiExpression, PsiType>();
@@ -114,4 +123,4 @@ public class JavaResolveCache {
public interface ConstValueComputer{
Object execute(PsiVariable variable, Set<PsiVariable> visitedVars);
}
}
}