From a9b596be377ed6101ed813c8db740b7369b1c405 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 8 May 2007 14:07:00 +0000 Subject: [PATCH] See 180164, caching for binding-adaptation and scope-lookups in pdom. --- .../eclipse/cdt/internal/core/pdom/PDOM.java | 28 ++++++++++++ .../core/pdom/dom/c/PDOMCLinkage.java | 18 ++++++-- .../core/pdom/dom/c/PDOMCStructure.java | 22 +++++++--- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 43 +++++++++++++------ .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 31 +++++++------ .../core/pdom/dom/cpp/PDOMCPPNamespace.java | 24 ++++++++--- 6 files changed, 128 insertions(+), 38 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index c11676821a9..5bfb7a1fe8b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -514,6 +514,8 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { private long lastWriteAccess= 0; private long lastReadAccess= 0; + private HashMap fResultCache= new HashMap(); + public void acquireReadLock() throws InterruptedException { synchronized (mutex) { ++waitingReaders; @@ -529,12 +531,19 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { } public void releaseReadLock() { + boolean clearCache= false; synchronized (mutex) { assert lockCount > 0: "No lock to release"; //$NON-NLS-1$ lastReadAccess= System.currentTimeMillis(); if (lockCount > 0) --lockCount; 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) { + synchronized(fResultCache) { + fResultCache.clear(); + } try { db.setReadOnly(flush); } catch (CoreException e) { @@ -740,5 +752,21 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { public void flush() throws CoreException { 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(); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index 083df3ab287..fe6c38d616e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -147,7 +147,8 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { return 0; } - public PDOMBinding adaptBinding(IBinding binding) throws CoreException { + public PDOMBinding adaptBinding(final IBinding inputBinding) throws CoreException { + IBinding binding= inputBinding; if (binding instanceof PDOMBinding) { // there is no guarantee, that the binding is from the same PDOM object. PDOMBinding pdomBinding = (PDOMBinding) binding; @@ -163,15 +164,24 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { return null; } } + + PDOMBinding result= (PDOMBinding) pdom.getCachedResult(inputBinding); + if (result != null) { + return result; + } + PDOMNode parent = getAdaptedParent(binding, false, false); 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) { - 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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java index afa0644021d..30f1f15d186 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java @@ -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.index.IIndexBinding; 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.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; @@ -74,7 +75,7 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom } public int getNodeType() { - return PDOMCLinkage.CSTRUCTURE; + return IIndexCBindingConstants.CSTRUCTURE; } public Object clone() { @@ -136,19 +137,30 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom } 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 { - accept(field); + accept(visitor); // returned => not found return null; } catch (CoreException e) { - if (e.getStatus().equals(Status.OK_STATUS)) - return field.getField(); + if (e.getStatus().equals(Status.OK_STATUS)) { + result= visitor.getField(); + } else { CCorePlugin.log(e); return null; } } + if (result != null) { + pdom.putCachedResult(key, result); + } + return result; } public IScope getCompositeScope() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index d3a3dc375e9..db1cec0fe7d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -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.ICPPMethod; 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.dom.parser.ProblemBinding; 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.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; @@ -92,7 +92,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { } public int getNodeType() { - return PDOMCPPLinkage.CPPCLASSTYPE; + return IIndexCPPBindingConstants.CPPCLASSTYPE; } public PDOMCPPBase getFirstBase() throws CoreException { @@ -312,7 +312,8 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { try { - if (getDBName().equals(name.toCharArray())) { + final char[] nameChars = name.toCharArray(); + if (getDBName().equals(nameChars)) { if (CPPClassScope.isConstructorReference(name)){ return CPPSemantics.resolveAmbiguities(name, getConstructors()); } @@ -320,9 +321,8 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { return this; } - BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray()); - accept(visitor); - return CPPSemantics.resolveAmbiguities(name, visitor.getBindings()); + final IBinding[] candidates = getBindingsViaCache(nameChars); + return CPPSemantics.resolveAmbiguities(name, candidates); } catch (CoreException e) { CCorePlugin.log(e); } @@ -332,22 +332,41 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException { IBinding[] result = null; try { - if ((!prefixLookup && getDBName().compare(name.toCharArray(), true) == 0) - || (prefixLookup && getDBName().comparePrefix(name.toCharArray(), false) == 0)) { + final char[] nameChars = name.toCharArray(); + 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 // 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); - result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, visitor.getBindings()); + result= visitor.getBindings(); } catch (CoreException 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 { return CPPSemantics.findBindings( this, name, false ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index fc01830615b..9c0540b1464 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -496,10 +496,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { /** * Find the equivalent binding, or binding placeholder within this PDOM */ - public PDOMBinding adaptBinding(IBinding binding) throws CoreException { - if (binding == null || binding instanceof IProblemBinding) + public PDOMBinding adaptBinding(final IBinding inputBinding) throws CoreException { + if (inputBinding == null || inputBinding instanceof IProblemBinding) return null; + IBinding binding= inputBinding; if (binding instanceof PDOMBinding) { // there is no guarantee, that the binding is from the same PDOM object. PDOMBinding pdomBinding = (PDOMBinding) binding; @@ -515,18 +516,24 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return null; } } - - PDOMNode parent = getAdaptedParent(binding, false, false); - - if (parent == this) { - 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); + + PDOMBinding result= (PDOMBinding) pdom.getCachedResult(inputBinding); + if (result != null) { + return result; } - 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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java index ae97858cb72..7a8079b1542 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java @@ -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.parser.util.ArrayUtil; 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.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.BTree; @@ -60,7 +61,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName } public int getNodeType() { - return PDOMCPPLinkage.CPPNAMESPACE; + return IIndexCPPBindingConstants.CPPNAMESPACE; } 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 { try { - BindingCollector visitor= new BindingCollector(getLinkageImpl(), name.toCharArray()); - getIndex().accept(visitor); - - IBinding[] bindings= visitor.getBindings(); + IBinding[] bindings= getBindingsViaCache(name.toCharArray()); return CPPSemantics.resolveAmbiguities(name, bindings); } catch (CoreException 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 { IBinding[] result = null; try { + if (!prefixLookup) { + return getBindingsViaCache(name.toCharArray()); + } BindingCollector visitor= new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup); getIndex().accept(visitor); 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); } + 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 { return true; }