1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 09:15:38 +02:00

See 180164, caching for binding-adaptation and scope-lookups in pdom.

This commit is contained in:
Markus Schorn 2007-05-08 14:07:00 +00:00
parent 258b67f8fc
commit a9b596be37
6 changed files with 128 additions and 38 deletions

View file

@ -514,6 +514,8 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private long lastWriteAccess= 0; private long lastWriteAccess= 0;
private long lastReadAccess= 0; private long lastReadAccess= 0;
private HashMap fResultCache= new HashMap();
public void acquireReadLock() throws InterruptedException { public void acquireReadLock() throws InterruptedException {
synchronized (mutex) { synchronized (mutex) {
++waitingReaders; ++waitingReaders;
@ -529,12 +531,19 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
} }
public void releaseReadLock() { public void releaseReadLock() {
boolean clearCache= false;
synchronized (mutex) { synchronized (mutex) {
assert lockCount > 0: "No lock to release"; //$NON-NLS-1$ assert lockCount > 0: "No lock to release"; //$NON-NLS-1$
lastReadAccess= System.currentTimeMillis(); lastReadAccess= System.currentTimeMillis();
if (lockCount > 0) if (lockCount > 0)
--lockCount; --lockCount;
mutex.notifyAll(); mutex.notifyAll();
clearCache= lockCount == 0;
}
if (clearCache) {
synchronized (fResultCache) {
fResultCache.clear();
}
} }
} }
@ -568,6 +577,9 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
} }
public void releaseWriteLock(int establishReadLocks, boolean flush) { public void releaseWriteLock(int establishReadLocks, boolean flush) {
synchronized(fResultCache) {
fResultCache.clear();
}
try { try {
db.setReadOnly(flush); db.setReadOnly(flush);
} catch (CoreException e) { } catch (CoreException e) {
@ -741,4 +753,20 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
public void flush() throws CoreException { public void flush() throws CoreException {
db.flush(); db.flush();
} }
public Object getCachedResult(Object binding) {
synchronized(fResultCache) {
return fResultCache.get(binding);
}
}
public void putCachedResult(Object key, Object result) {
synchronized(fResultCache) {
fResultCache.put(key, result);
}
}
public String createKeyForCache(int record, char[] name) {
return new StringBuffer(name.length+2).append((char) (record >> 16)).append((char) record).append(name).toString();
}
} }

View file

@ -147,7 +147,8 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
return 0; return 0;
} }
public PDOMBinding adaptBinding(IBinding binding) throws CoreException { public PDOMBinding adaptBinding(final IBinding inputBinding) throws CoreException {
IBinding binding= inputBinding;
if (binding instanceof PDOMBinding) { if (binding instanceof PDOMBinding) {
// there is no guarantee, that the binding is from the same PDOM object. // there is no guarantee, that the binding is from the same PDOM object.
PDOMBinding pdomBinding = (PDOMBinding) binding; PDOMBinding pdomBinding = (PDOMBinding) binding;
@ -163,15 +164,24 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
return null; return null;
} }
} }
PDOMBinding result= (PDOMBinding) pdom.getCachedResult(inputBinding);
if (result != null) {
return result;
}
PDOMNode parent = getAdaptedParent(binding, false, false); PDOMNode parent = getAdaptedParent(binding, false, false);
if (parent == this) { if (parent == this) {
return FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}); result= FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)});
} else if (parent instanceof IPDOMMemberOwner) { } else if (parent instanceof IPDOMMemberOwner) {
return FindBinding.findBinding(parent, getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}); result= FindBinding.findBinding(parent, getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)});
} }
return null; if (result != null) {
pdom.putCachedResult(inputBinding, result);
}
return result;
} }
public PDOMNode getNode(int record) throws CoreException { public PDOMNode getNode(int record) throws CoreException {

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
@ -74,7 +75,7 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom
} }
public int getNodeType() { public int getNodeType() {
return PDOMCLinkage.CSTRUCTURE; return IIndexCBindingConstants.CSTRUCTURE;
} }
public Object clone() { public Object clone() {
@ -136,19 +137,30 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom
} }
public IField findField(String name) throws DOMException { public IField findField(String name) throws DOMException {
FindField field = new FindField(name); final String key= pdom.createKeyForCache(record, name.toCharArray());
IField result= (IField) pdom.getCachedResult(key);
if (result != null) {
return result;
}
FindField visitor = new FindField(name);
try { try {
accept(field); accept(visitor);
// returned => not found // returned => not found
return null; return null;
} catch (CoreException e) { } catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS)) if (e.getStatus().equals(Status.OK_STATUS)) {
return field.getField(); result= visitor.getField();
}
else { else {
CCorePlugin.log(e); CCorePlugin.log(e);
return null; return null;
} }
} }
if (result != null) {
pdom.putCachedResult(key, result);
}
return result;
} }
public IScope getCompositeScope() throws DOMException { public IScope getCompositeScope() throws DOMException {

View file

@ -37,11 +37,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; 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.CPPClassScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
@ -92,7 +92,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
} }
public int getNodeType() { public int getNodeType() {
return PDOMCPPLinkage.CPPCLASSTYPE; return IIndexCPPBindingConstants.CPPCLASSTYPE;
} }
public PDOMCPPBase getFirstBase() throws CoreException { public PDOMCPPBase getFirstBase() throws CoreException {
@ -312,7 +312,8 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { public IBinding getBinding(IASTName name, boolean resolve) throws DOMException {
try { try {
if (getDBName().equals(name.toCharArray())) { final char[] nameChars = name.toCharArray();
if (getDBName().equals(nameChars)) {
if (CPPClassScope.isConstructorReference(name)){ if (CPPClassScope.isConstructorReference(name)){
return CPPSemantics.resolveAmbiguities(name, getConstructors()); return CPPSemantics.resolveAmbiguities(name, getConstructors());
} }
@ -320,9 +321,8 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
return this; return this;
} }
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray()); final IBinding[] candidates = getBindingsViaCache(nameChars);
accept(visitor); return CPPSemantics.resolveAmbiguities(name, candidates);
return CPPSemantics.resolveAmbiguities(name, visitor.getBindings());
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
@ -332,20 +332,39 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException {
IBinding[] result = null; IBinding[] result = null;
try { try {
if ((!prefixLookup && getDBName().compare(name.toCharArray(), true) == 0) final char[] nameChars = name.toCharArray();
|| (prefixLookup && getDBName().comparePrefix(name.toCharArray(), false) == 0)) { if (!prefixLookup) {
return getBindingsViaCache(nameChars);
}
BindingCollector visitor = new BindingCollector(getLinkageImpl(), nameChars, null, prefixLookup, !prefixLookup);
if (getDBName().comparePrefix(nameChars, false) == 0) {
// 9.2 ... The class-name is also inserted into the scope of // 9.2 ... The class-name is also inserted into the scope of
// the class itself // the class itself
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, this); visitor.visit(this);
} }
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup);
accept(visitor); accept(visitor);
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings()); result= visitor.getBindings();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); 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;
}
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, null, false, true);
if (getDBName().compare(name, true) == 0) {
visitor.visit(this);
}
accept(visitor);
result = visitor.getBindings();
pdom.putCachedResult(key, result);
return result;
} }
public IBinding[] find(String name) throws DOMException { public IBinding[] find(String name) throws DOMException {

View file

@ -496,10 +496,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
/** /**
* Find the equivalent binding, or binding placeholder within this PDOM * Find the equivalent binding, or binding placeholder within this PDOM
*/ */
public PDOMBinding adaptBinding(IBinding binding) throws CoreException { public PDOMBinding adaptBinding(final IBinding inputBinding) throws CoreException {
if (binding == null || binding instanceof IProblemBinding) if (inputBinding == null || inputBinding instanceof IProblemBinding)
return null; return null;
IBinding binding= inputBinding;
if (binding instanceof PDOMBinding) { if (binding instanceof PDOMBinding) {
// there is no guarantee, that the binding is from the same PDOM object. // there is no guarantee, that the binding is from the same PDOM object.
PDOMBinding pdomBinding = (PDOMBinding) binding; PDOMBinding pdomBinding = (PDOMBinding) binding;
@ -516,17 +517,23 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} }
} }
PDOMNode parent = getAdaptedParent(binding, false, false); PDOMBinding result= (PDOMBinding) pdom.getCachedResult(inputBinding);
if (result != null) {
if (parent == this) { return result;
return CPPFindBinding.findBinding(getIndex(), this, binding);
} else if (parent instanceof IPDOMMemberOwner) {
return CPPFindBinding.findBinding(parent, this, binding);
} else if (parent instanceof PDOMCPPNamespace) {
return CPPFindBinding.findBinding(((PDOMCPPNamespace)parent).getIndex(), this, binding);
} }
return null; PDOMNode parent = getAdaptedParent(binding, false, false);
if (parent == this) {
result= CPPFindBinding.findBinding(getIndex(), this, binding);
} else if (parent instanceof IPDOMMemberOwner) {
result= CPPFindBinding.findBinding(parent, this, binding);
} else if (parent instanceof PDOMCPPNamespace) {
result= CPPFindBinding.findBinding(((PDOMCPPNamespace)parent).getIndex(), this, binding);
}
if (result != null) {
pdom.putCachedResult(inputBinding, result);
}
return result;
} }
public PDOMNode addType(PDOMNode parent, IType type) throws CoreException { public PDOMNode addType(PDOMNode parent, IType type) throws CoreException {

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.BTree;
@ -60,7 +61,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName
} }
public int getNodeType() { public int getNodeType() {
return PDOMCPPLinkage.CPPNAMESPACE; return IIndexCPPBindingConstants.CPPNAMESPACE;
} }
public BTree getIndex() throws CoreException { public BTree getIndex() throws CoreException {
@ -115,10 +116,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName
public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { public IBinding getBinding(IASTName name, boolean resolve) throws DOMException {
try { try {
BindingCollector visitor= new BindingCollector(getLinkageImpl(), name.toCharArray()); IBinding[] bindings= getBindingsViaCache(name.toCharArray());
getIndex().accept(visitor);
IBinding[] bindings= visitor.getBindings();
return CPPSemantics.resolveAmbiguities(name, bindings); return CPPSemantics.resolveAmbiguities(name, bindings);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -129,6 +127,9 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException {
IBinding[] result = null; IBinding[] result = null;
try { try {
if (!prefixLookup) {
return getBindingsViaCache(name.toCharArray());
}
BindingCollector visitor= new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup); BindingCollector visitor= new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup);
getIndex().accept(visitor); getIndex().accept(visitor);
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings()); result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings());
@ -138,6 +139,19 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, 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;
}
BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, null, false, true);
getIndex().accept(visitor);
result = visitor.getBindings();
pdom.putCachedResult(key, result);
return result;
}
public boolean isFullyCached() throws DOMException { public boolean isFullyCached() throws DOMException {
return true; return true;
} }