mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 10:46:02 +02:00
Bug 513345 - A lot of time during indexing is spent inside
CompositeValue.create Added caching of initial values in CPPVariable and CPPVariableTemplate. Change-Id: Id56dc273d1b27a972a30021bb8f26ce57443d208
This commit is contained in:
parent
f144cd407f
commit
8bdda7bd02
6 changed files with 49 additions and 22 deletions
|
@ -58,6 +58,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
|
||||||
private IASTName fDefinition;
|
private IASTName fDefinition;
|
||||||
private IASTName fDeclarations[];
|
private IASTName fDeclarations[];
|
||||||
private IType fType;
|
private IType fType;
|
||||||
|
private IValue fInitialValue = IntegralValue.NOT_INITIALIZED;
|
||||||
private boolean fAllResolved;
|
private boolean fAllResolved;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,10 +110,12 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
|
||||||
fDeclarations = ArrayUtil.append(IASTName.class, fDeclarations, name);
|
fDeclarations = ArrayUtil.append(IASTName.class, fDeclarations, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Array types may be incomplete.
|
// An array type may be incomplete and needs to be recalculated.
|
||||||
if (fType instanceof IArrayType) {
|
if (fType instanceof IArrayType) {
|
||||||
fType = null;
|
fType = null;
|
||||||
}
|
}
|
||||||
|
// Initial value has to be recalculated.
|
||||||
|
fInitialValue = IntegralValue.NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -238,6 +241,13 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IValue getInitialValue() {
|
public IValue getInitialValue() {
|
||||||
|
if (fInitialValue == IntegralValue.NOT_INITIALIZED) {
|
||||||
|
fInitialValue = computeInitialValue();
|
||||||
|
}
|
||||||
|
return fInitialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IValue computeInitialValue() {
|
||||||
Set<CPPVariable> recursionProtectionSet = fInitialValueInProgress.get();
|
Set<CPPVariable> recursionProtectionSet = fInitialValueInProgress.get();
|
||||||
if (!recursionProtectionSet.add(this)) {
|
if (!recursionProtectionSet.add(this)) {
|
||||||
return IntegralValue.UNKNOWN;
|
return IntegralValue.UNKNOWN;
|
||||||
|
|
|
@ -19,11 +19,13 @@ import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
|
||||||
public class CPPVariableTemplate extends CPPTemplateDefinition
|
public class CPPVariableTemplate extends CPPTemplateDefinition
|
||||||
implements ICPPVariableTemplate, ICPPInternalDeclaredVariable {
|
implements ICPPVariableTemplate, ICPPInternalDeclaredVariable {
|
||||||
private IType fType;
|
private IType fType;
|
||||||
|
private IValue fInitialValue = IntegralValue.NOT_INITIALIZED;
|
||||||
private boolean fAllResolved;
|
private boolean fAllResolved;
|
||||||
private ICPPPartialSpecialization[] partialSpecializations = ICPPPartialSpecialization.EMPTY_ARRAY;
|
private ICPPPartialSpecialization[] partialSpecializations = ICPPPartialSpecialization.EMPTY_ARRAY;
|
||||||
|
|
||||||
|
@ -61,6 +63,13 @@ public class CPPVariableTemplate extends CPPTemplateDefinition
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IValue getInitialValue() {
|
public IValue getInitialValue() {
|
||||||
|
if (fInitialValue == IntegralValue.NOT_INITIALIZED) {
|
||||||
|
fInitialValue = computeInitialValue();
|
||||||
|
}
|
||||||
|
return fInitialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IValue computeInitialValue() {
|
||||||
return VariableHelpers.getInitialValue((IASTName) getDefinition(), (IASTName[]) getDeclarations(), getType());
|
return VariableHelpers.getInitialValue((IASTName) getDefinition(), (IASTName[]) getDeclarations(), getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common interface for CPPVariable and CPPVariableTemplate.
|
||||||
|
*/
|
||||||
public interface ICPPInternalDeclaredVariable extends ICPPInternalVariable {
|
public interface ICPPInternalDeclaredVariable extends ICPPInternalVariable {
|
||||||
/**
|
/**
|
||||||
* Informs the variable that all its declarations and definitions have already been added.
|
* Informs the variable that all its declarations and definitions have already been added.
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||||
|
@ -59,6 +60,7 @@ import org.eclipse.cdt.core.parser.IProblem;
|
||||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalDeclaredVariable;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||||
|
@ -356,6 +358,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
||||||
|
|
||||||
private void resolveNames(Data data, IProgressMonitor monitor) {
|
private void resolveNames(Data data, IProgressMonitor monitor) {
|
||||||
long start= System.currentTimeMillis();
|
long start= System.currentTimeMillis();
|
||||||
|
List<ICPPInternalDeclaredVariable> variables = new ArrayList<>();
|
||||||
SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length);
|
SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length);
|
||||||
for (FileInAST file : data.fSelectedFiles) {
|
for (FileInAST file : data.fSelectedFiles) {
|
||||||
Symbols symbols= data.fSymbolMap.get(file.includeStatement);
|
Symbols symbols= data.fSymbolMap.get(file.includeStatement);
|
||||||
|
@ -367,10 +370,13 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
||||||
final IASTName[] na= j.next();
|
final IASTName[] na= j.next();
|
||||||
final IASTName name = na[0];
|
final IASTName name = na[0];
|
||||||
progress2.split(1);
|
progress2.split(1);
|
||||||
if (name != null) { // should not be null, just be defensive.
|
if (name != null) { // Should not be null, just be defensive.
|
||||||
Throwable th= null;
|
|
||||||
try {
|
try {
|
||||||
final IBinding binding = name.resolveBinding();
|
final IBinding binding = name.resolveBinding();
|
||||||
|
if (binding instanceof ICPPInternalDeclaredVariable) {
|
||||||
|
variables.add((ICPPInternalDeclaredVariable) binding);
|
||||||
|
}
|
||||||
|
|
||||||
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
|
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
|
||||||
(((IASTName) name.getParent()).getBinding() == binding ||
|
(((IASTName) name.getParent()).getBinding() == binding ||
|
||||||
binding instanceof ICPPFunctionTemplate)) {
|
binding instanceof ICPPFunctionTemplate)) {
|
||||||
|
@ -401,15 +407,10 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
||||||
} else {
|
} else {
|
||||||
fStatistics.fDeclarationCount++;
|
fStatistics.fDeclarationCount++;
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException | StackOverflowError e) {
|
||||||
th= e;
|
|
||||||
} catch (StackOverflowError e) {
|
|
||||||
th= e;
|
|
||||||
}
|
|
||||||
if (th != null) {
|
|
||||||
if (!reported) {
|
if (!reported) {
|
||||||
data.fStatuses.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName,
|
data.fStatuses.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName,
|
||||||
name.toString(), file.fileContentKey.getLocation().getURI().getPath()), th));
|
name.toString(), file.fileContentKey.getLocation().getURI().getPath()), e));
|
||||||
}
|
}
|
||||||
reported= true;
|
reported= true;
|
||||||
j.remove();
|
j.remove();
|
||||||
|
@ -417,6 +418,21 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Precalculate types and initial values of all fields to avoid doing it later when writing
|
||||||
|
// to the index.
|
||||||
|
for (ICPPInternalDeclaredVariable variable : variables) {
|
||||||
|
variable.allDeclarationsDefinitionsAdded();
|
||||||
|
// TODO(sprigogin): It would be beneficial to precalculate types and initial values of all
|
||||||
|
// indexed variables not just fields. It should be done carefully to avoid
|
||||||
|
// unnecesssary overhead of doing it for variables that are not being indexed.
|
||||||
|
if (variable instanceof ICPPField) {
|
||||||
|
// Type and initial value will be cached by the variable.
|
||||||
|
variable.getType();
|
||||||
|
variable.getInitialValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fStatistics.fResolutionTime += System.currentTimeMillis() - start;
|
fStatistics.fResolutionTime += System.currentTimeMillis() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -704,7 +704,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
}
|
}
|
||||||
} else if (binding instanceof ICPPField) {
|
} else if (binding instanceof ICPPField) {
|
||||||
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
|
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
|
||||||
if(binding instanceof ICPPFieldTemplate) {
|
if (binding instanceof ICPPFieldTemplate) {
|
||||||
pdomBinding = new PDOMCPPFieldTemplate(this, parent, (ICPPFieldTemplate) binding);
|
pdomBinding = new PDOMCPPFieldTemplate(this, parent, (ICPPFieldTemplate) binding);
|
||||||
} else {
|
} else {
|
||||||
pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding, true);
|
pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding, true);
|
||||||
|
@ -1064,11 +1064,6 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean cannotAdapt(final IBinding inputBinding) throws CoreException {
|
|
||||||
return super.cannotAdapt(inputBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final PDOMBinding adaptBinding(final IBinding inputBinding, boolean includeLocal) throws CoreException {
|
public final PDOMBinding adaptBinding(final IBinding inputBinding, boolean includeLocal) throws CoreException {
|
||||||
return adaptBinding(null, inputBinding, includeLocal ? FILE_LOCAL_REC_DUMMY : null);
|
return adaptBinding(null, inputBinding, includeLocal ? FILE_LOCAL_REC_DUMMY : null);
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalDeclaredVariable;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||||
|
@ -49,11 +48,6 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
||||||
Database db = getDB();
|
Database db = getDB();
|
||||||
db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(variable));
|
db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(variable));
|
||||||
if (setTypeAndValue) {
|
if (setTypeAndValue) {
|
||||||
if (variable instanceof ICPPInternalDeclaredVariable) {
|
|
||||||
// By the time PDOMCPPVariable is created all declarations and definitions have already been
|
|
||||||
// added to the variable.
|
|
||||||
((ICPPInternalDeclaredVariable) variable).allDeclarationsDefinitionsAdded();
|
|
||||||
}
|
|
||||||
setType(parent.getLinkage(), variable.getType());
|
setType(parent.getLinkage(), variable.getType());
|
||||||
linkage.new ConfigureVariable(variable, this);
|
linkage.new ConfigureVariable(variable, this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue