1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Performance improvement for indexing template based source code.

This commit is contained in:
Markus Schorn 2008-04-18 07:56:46 +00:00
parent 501ebcad7f
commit 324a584c99
6 changed files with 156 additions and 122 deletions

View file

@ -256,8 +256,7 @@ public class PDOM extends PlatformObject implements IPDOM {
}
public void accept(IPDOMVisitor visitor) throws CoreException {
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage = iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
linkage.accept(visitor);
}
}
@ -454,8 +453,7 @@ public class PDOM extends PlatformObject implements IPDOM {
monitor= new NullProgressMonitor();
}
BindingFinder finder = new BindingFinder(pattern, isFullyQualified, filter, monitor);
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage = iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
try {
linkage.accept(finder);
@ -475,8 +473,7 @@ public class PDOM extends PlatformObject implements IPDOM {
monitor= new NullProgressMonitor();
}
MacroContainerPatternCollector finder = new MacroContainerPatternCollector(this, pattern, monitor);
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage = iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
try {
linkage.getMacroIndex().accept(finder);
@ -497,8 +494,7 @@ public class PDOM extends PlatformObject implements IPDOM {
}
ArrayList<PDOMBinding> result= new ArrayList<PDOMBinding>();
ArrayList<PDOMNamedNode> nodes= new ArrayList<PDOMNamedNode>();
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage = iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
nodes.add(linkage);
for (int i=0; i < names.length-1; i++) {
@ -753,8 +749,8 @@ public class PDOM extends PlatformObject implements IPDOM {
findNamesForMyBinding(pdomBinding, options, names);
if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) {
PDOMBinding[] xlangBindings= getCrossLanguageBindings(binding);
for (int j = 0; j < xlangBindings.length; j++) {
findNamesForMyBinding(xlangBindings[j], options, names);
for (PDOMBinding xlangBinding : xlangBindings) {
findNamesForMyBinding(xlangBinding, options, names);
}
}
}
@ -763,8 +759,8 @@ public class PDOM extends PlatformObject implements IPDOM {
findNamesForMyBinding(macroContainer, options, names);
if ((options & SEARCH_ACCROSS_LANGUAGE_BOUNDARIES) != 0) {
PDOMMacroContainer[] xlangBindings= getCrossLanguageBindings(macroContainer);
for (int j = 0; j < xlangBindings.length; j++) {
findNamesForMyBinding(xlangBindings[j], options, names);
for (PDOMMacroContainer xlangBinding : xlangBindings) {
findNamesForMyBinding(xlangBinding, options, names);
}
}
}
@ -831,8 +827,7 @@ public class PDOM extends PlatformObject implements IPDOM {
public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>();
for (Iterator<PDOMLinkage> iter= fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage= iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
PDOMBinding[] bindings;
BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false);
@ -847,8 +842,8 @@ public class PDOM extends PlatformObject implements IPDOM {
}
bindings= visitor.getBindings();
for (int j = 0; j < bindings.length; j++) {
result.add(bindings[j]);
for (PDOMBinding binding : bindings) {
result.add(binding);
}
}
}
@ -857,8 +852,7 @@ public class PDOM extends PlatformObject implements IPDOM {
public IIndexFragmentBinding[] findBindings(char[] name, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
ArrayList<IIndexFragmentBinding> result= new ArrayList<IIndexFragmentBinding>();
for (Iterator<PDOMLinkage> iter= fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage= iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
PDOMBinding[] bindings;
BindingCollector visitor = new BindingCollector(linkage, name, filter, false, true);
@ -873,8 +867,8 @@ public class PDOM extends PlatformObject implements IPDOM {
}
bindings= visitor.getBindings();
for (int j = 0; j < bindings.length; j++) {
result.add(bindings[j]);
for (PDOMBinding binding : bindings) {
result.add(binding);
}
}
}
@ -886,8 +880,7 @@ public class PDOM extends PlatformObject implements IPDOM {
MacroContainerCollector visitor = new MacroContainerCollector(this, prefix, isPrefix, isCaseSensitive);
visitor.setMonitor(monitor);
try {
for (Iterator<PDOMLinkage> iter = fLinkageIDCache.values().iterator(); iter.hasNext();) {
PDOMLinkage linkage = iter.next();
for (PDOMLinkage linkage : fLinkageIDCache.values()) {
if (filter.acceptLinkage(linkage)) {
linkage.getMacroIndex().accept(visitor);
}
@ -955,7 +948,13 @@ public class PDOM extends PlatformObject implements IPDOM {
fResultCache.put(key, result);
}
}
public void removeCachedResult(Object key) {
synchronized(fResultCache) {
fResultCache.remove(key);
}
}
public String createKeyForCache(int record, char[] name) {
return new StringBuilder(name.length+2).append((char) (record >> 16)).append((char) record).append(name).toString();
}

View file

@ -38,6 +38,8 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
protected final PDOM pdom;
protected final int record;
private PDOMBinding fCachedBaseClass;
public PDOMCPPBase(PDOM pdom, int record) {
this.pdom = pdom;
this.record = record;
@ -73,7 +75,7 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
return pdom.getDB().getByte(record + FLAGS);
}
public PDOMName getBaseClassSpecifierNameImpl() {
public PDOMName getBaseClassSpecifierName() {
try {
int rec = pdom.getDB().getInt(record + BASECLASS_SPECIFIER);
if (rec != 0) {
@ -84,20 +86,19 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
}
return null;
}
public IName getBaseClassSpecifierName() {
return getBaseClassSpecifierNameImpl();
}
public IBinding getBaseClass() {
if (fCachedBaseClass != null)
return fCachedBaseClass;
try {
PDOMName name= getBaseClassSpecifierNameImpl();
PDOMName name= getBaseClassSpecifierName();
if (name != null) {
PDOMBinding b = name.getBinding();
while( b instanceof PDOMCPPTypedef && ((PDOMCPPTypedef)b).getType() instanceof PDOMBinding ){
b = (PDOMBinding) ((PDOMCPPTypedef)b).getType();
}
return b;
return fCachedBaseClass= b;
}
} catch (CoreException e) {
CCorePlugin.log(e);

View file

@ -115,7 +115,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
PDOMCPPBase predecessor= null;
int nameRec= pdomName.getRecord();
while (base != null) {
PDOMName name = base.getBaseClassSpecifierNameImpl();
PDOMName name = base.getBaseClassSpecifierName();
if (name != null && name.getRecord() == nameRec) {
break;
}
@ -157,8 +157,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
if (pdomBases != null) {
ICPPBase[] result = null;
for (int i = 0; i < pdomBases.length; i++) {
ICPPBase origBase = pdomBases[i];
for (ICPPBase origBase : pdomBases) {
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone();
IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) {
@ -271,8 +270,8 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
private ObjectMap specMap;
public SpecializationFinder(IBinding[] specialized) {
specMap = new ObjectMap(specialized.length);
for (int i = 0; i < specialized.length; i++) {
specMap.put(specialized[i], null);
for (IBinding element : specialized) {
specMap.put(element, null);
}
}
public boolean visit(IPDOMNode node) throws CoreException {

View file

@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
@ -36,11 +35,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -146,69 +143,12 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
public ICPPTemplateDefinition getTemplateDefinition() throws DOMException {
return null;
}
@Override
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
try {
if (getDBName().equals(name.toCharArray())) {
if (CPPClassScope.isConstructorReference(name)) {
return CPPSemantics.resolveAmbiguities(name, getConstructors());
}
//9.2 ... The class-name is also inserted into the scope of the class itself
return this;
}
IndexFilter filter = new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization);
}
@Override
public boolean acceptLinkage(ILinkage linkage) {
return linkage.getLinkageID() == ILinkage.CPP_LINKAGE_ID;
}
};
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter,
false, true);
accept(visitor);
return CPPSemantics.resolveAmbiguities(name, visitor.getBindings());
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet)
throws DOMException {
IBinding[] result = null;
try {
if ((!prefixLookup && getDBName().compare(name.toCharArray(), true) == 0)
|| (prefixLookup && getDBName().comparePrefix(name.toCharArray(), false) == 0)) {
// 9.2 ... The class-name is also inserted into the scope of
// the class itself
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, this);
}
IndexFilter filter = new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization);
}
@Override
public boolean acceptLinkage(ILinkage linkage) {
return linkage.getLinkageID() == ILinkage.CPP_LINKAGE_ID;
}
};
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter,
prefixLookup, !prefixLookup);
accept(visitor);
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings());
} catch (CoreException e) {
CCorePlugin.log(e);
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
protected void bindingsOfScopeAccept(IPDOMVisitor visitor) throws CoreException {
// don't visit parameters and instances
super.accept(visitor);
}
private class PDOMCPPTemplateScope implements ICPPTemplateScope, IIndexScope {

View file

@ -12,9 +12,10 @@
* Bryan Wilkinson (QNX)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@ -28,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
@ -41,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.CharArrayMap;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope;
@ -73,6 +76,9 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 12;
private static final int CACHE_MEMBERS= 0;
private static final int CACHE_BASES = 1;
public PDOMCPPClassType(PDOM pdom, PDOMNode parent, ICPPClassType classType)
throws CoreException {
super(pdom, parent, classType.getNameCharArray());
@ -103,6 +109,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
}
public void addMember(PDOMNode member) throws CoreException {
pdom.removeCachedResult(record+CACHE_MEMBERS);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl());
list.addMember(member);
}
@ -117,7 +124,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
return IIndexCPPBindingConstants.CPPCLASSTYPE;
}
public PDOMCPPBase getFirstBase() throws CoreException {
private PDOMCPPBase getFirstBase() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRSTBASE);
return rec != 0 ? new PDOMCPPBase(pdom, rec) : null;
}
@ -128,6 +135,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
}
public void addBase(PDOMCPPBase base) throws CoreException {
pdom.removeCachedResult(record+CACHE_BASES);
PDOMCPPBase firstBase = getFirstBase();
base.setNextBase(firstBase);
setFirstBase(base);
@ -161,12 +169,18 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
}
public ICPPBase[] getBases() throws DOMException {
Integer key= record + 1;
ICPPBase[] bases= (ICPPBase[]) pdom.getCachedResult(key);
if (bases != null)
return bases;
try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
list.add(base);
Collections.reverse(list);
ICPPBase[] bases = list.toArray(new ICPPBase[list.size()]);
bases = list.toArray(new ICPPBase[list.size()]);
pdom.putCachedResult(key, bases);
return bases;
} catch (CoreException e) {
CCorePlugin.log(e);
@ -184,7 +198,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPMethod[] getDeclaredMethods() throws DOMException {
try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
accept(methods);
cachedBindingsAccept(methods);
return methods.getMethods();
} catch (CoreException e) {
return new ICPPMethod[0];
@ -263,7 +277,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPField[] getDeclaredFields() throws DOMException {
try {
PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector();
accept(visitor);
cachedBindingsAccept(visitor);
return visitor.getFields();
} catch (CoreException e) {
CCorePlugin.log(e);
@ -288,7 +302,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPClassType[] getNestedClasses() throws DOMException {
try {
NestedClassCollector visitor = new NestedClassCollector();
accept(visitor);
cachedBindingsAccept(visitor);
return visitor.getNestedClasses();
} catch (CoreException e) {
CCorePlugin.log(e);
@ -296,6 +310,33 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
}
}
private void cachedBindingsAccept(IPDOMVisitor visitor) throws CoreException {
CharArrayMap<Object> map= getBindingMap();
for (Object obj : map.values()) {
if (obj instanceof List) {
for (Object binding : (List<?>)obj) {
if (binding instanceof IPDOMNode) {
final IPDOMNode node = (IPDOMNode) binding;
if (visitor.visit(node))
return;
visitor.leave(node);
}
}
}
else if (obj instanceof Object[]) {
Object[] array= (Object[]) obj;
for (Object binding : array) {
if (binding instanceof IPDOMNode) {
final IPDOMNode node = (IPDOMNode) binding;
if (visitor.visit(node))
return;
visitor.leave(node);
}
}
}
}
}
public IScope getCompositeScope() throws DOMException {
return this;
}
@ -330,7 +371,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
public ICPPConstructor[] getConstructors() throws DOMException {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
try {
accept(visitor);
cachedBindingsAccept(visitor);
} catch (CoreException e) {
CCorePlugin.log(e);
}
@ -377,7 +418,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
visitor.visit(this);
}
visitor.setVisitAnonymousClassTypes(true);
accept(visitor);
bindingsOfScopeAccept(visitor);
result= visitor.getBindings();
} catch (CoreException e) {
CCorePlugin.log(e);
@ -385,21 +426,73 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
return result;
}
private IBinding[] getBindingsViaCache(final char[] name) throws CoreException {
final String key = pdom.createKeyForCache(record, name);
IBinding[] result= (IBinding[]) pdom.getCachedResult(key);
if (result != null) {
return result;
/**
* Return whether or not the nested binding should go into the cache.
* @throws CoreException
* @since 5.0
*/
protected boolean isBindingOfScope(IBinding member) throws CoreException {
return IndexFilter.ALL_DECLARED_OR_IMPLICIT.acceptBinding(member);
}
IBinding[] getBindingsViaCache(final char[] name) throws CoreException {
CharArrayMap<Object> map = getBindingMap();
Object result= map.get(name);
if (result instanceof IBinding[])
return (IBinding[]) result;
if (result instanceof List) {
final List<?> list = (List<?>) result;
final IBinding[] bresult= list.toArray(new IBinding[list.size()]);
map.put(name, bresult);
return bresult;
}
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, IndexFilter.ALL_DECLARED_OR_IMPLICIT, false, true);
if (getDBName().compare(name, true) == 0) {
return IBinding.EMPTY_BINDING_ARRAY;
}
private CharArrayMap<Object> getBindingMap() throws CoreException {
final Integer key= record;
@SuppressWarnings("unchecked")
Reference<CharArrayMap<Object>> cached= (Reference<CharArrayMap<Object>>) pdom.getCachedResult(key);
CharArrayMap<Object> map= cached == null ? null : cached.get();
if (map == null) {
// there is no cache, build it:
final CharArrayMap<Object> result= new CharArrayMap<Object>();
IPDOMVisitor visitor= new IPDOMVisitor() {
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof IBinding) {
final IBinding binding= (IBinding) node;
final char[] nchars = binding.getNameCharArray();
if (nchars.length > 0 && isBindingOfScope(binding)) {
@SuppressWarnings("unchecked")
List<IBinding> list= (List<IBinding>) result.get(nchars);
if (list == null) {
list= new ArrayList<IBinding>();
result.put(nchars, list);
}
list.add(binding);
if (binding instanceof ICompositeType && nchars[0] == '{') {
return true; // visit children
}
}
}
return false;
}
public void leave(IPDOMNode node){}
};
visitor.visit(this);
bindingsOfScopeAccept(visitor);
map= result;
pdom.putCachedResult(key, new SoftReference<CharArrayMap<?>>(map));
}
visitor.setVisitAnonymousClassTypes(true);
accept(visitor);
result = visitor.getBindings();
pdom.putCachedResult(key, result);
return result;
return map;
}
protected void bindingsOfScopeAccept(IPDOMVisitor visitor) throws CoreException {
this.accept(visitor);
}
public IBinding[] find(String name) throws DOMException {
@ -419,11 +512,13 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType,
}
public void removeBase(PDOMName pdomName) throws CoreException {
pdom.removeCachedResult(record+CACHE_BASES);
PDOMCPPBase base= getFirstBase();
PDOMCPPBase predecessor= null;
int nameRec= pdomName.getRecord();
while (base != null) {
PDOMName name = base.getBaseClassSpecifierNameImpl();
PDOMName name = base.getBaseClassSpecifierName();
if (name != null && name.getRecord() == nameRec) {
break;
}

View file

@ -166,12 +166,12 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
return IIndexCPPBindingConstants.CPPFUNCTION;
}
public PDOMCPPParameter getFirstParameter() throws CoreException {
private PDOMCPPParameter getFirstParameter() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRST_PARAM);
return rec != 0 ? new PDOMCPPParameter(pdom, rec) : null;
}
public void setFirstParameter(PDOMCPPParameter param) throws CoreException {
private void setFirstParameter(PDOMCPPParameter param) throws CoreException {
if (param != null)
param.setNextParameter(getFirstParameter());
int rec = param != null ? param.getRecord() : 0;