1
0
Fork 0
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:
Sergey Prigogin 2017-03-09 18:14:00 -08:00
parent f144cd407f
commit 8bdda7bd02
6 changed files with 49 additions and 22 deletions

View file

@ -58,6 +58,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
private IASTName fDefinition;
private IASTName fDeclarations[];
private IType fType;
private IValue fInitialValue = IntegralValue.NOT_INITIALIZED;
private boolean fAllResolved;
/**
@ -109,10 +110,12 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
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) {
fType = null;
}
// Initial value has to be recalculated.
fInitialValue = IntegralValue.NOT_INITIALIZED;
}
@Override
@ -238,6 +241,13 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
@Override
public IValue getInitialValue() {
if (fInitialValue == IntegralValue.NOT_INITIALIZED) {
fInitialValue = computeInitialValue();
}
return fInitialValue;
}
private IValue computeInitialValue() {
Set<CPPVariable> recursionProtectionSet = fInitialValueInProgress.get();
if (!recursionProtectionSet.add(this)) {
return IntegralValue.UNKNOWN;

View file

@ -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.ICPPVariableTemplate;
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;
public class CPPVariableTemplate extends CPPTemplateDefinition
implements ICPPVariableTemplate, ICPPInternalDeclaredVariable {
private IType fType;
private IValue fInitialValue = IntegralValue.NOT_INITIALIZED;
private boolean fAllResolved;
private ICPPPartialSpecialization[] partialSpecializations = ICPPPartialSpecialization.EMPTY_ARRAY;
@ -61,6 +63,13 @@ public class CPPVariableTemplate extends CPPTemplateDefinition
@Override
public IValue getInitialValue() {
if (fInitialValue == IntegralValue.NOT_INITIALIZED) {
fInitialValue = computeInitialValue();
}
return fInitialValue;
}
private IValue computeInitialValue() {
return VariableHelpers.getInitialValue((IASTName) getDefinition(), (IASTName[]) getDeclarations(), getType());
}

View file

@ -10,6 +10,9 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
/**
* A common interface for CPPVariable and CPPVariableTemplate.
*/
public interface ICPPInternalDeclaredVariable extends ICPPInternalVariable {
/**
* Informs the variable that all its declarations and definitions have already been added.

View file

@ -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.ICPPASTUsingDirective;
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.ICPPNamespace;
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.util.CharArrayUtils;
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.index.FileContentKey;
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) {
long start= System.currentTimeMillis();
List<ICPPInternalDeclaredVariable> variables = new ArrayList<>();
SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length);
for (FileInAST file : data.fSelectedFiles) {
Symbols symbols= data.fSymbolMap.get(file.includeStatement);
@ -367,10 +370,13 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
final IASTName[] na= j.next();
final IASTName name = na[0];
progress2.split(1);
if (name != null) { // should not be null, just be defensive.
Throwable th= null;
if (name != null) { // Should not be null, just be defensive.
try {
final IBinding binding = name.resolveBinding();
if (binding instanceof ICPPInternalDeclaredVariable) {
variables.add((ICPPInternalDeclaredVariable) binding);
}
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
(((IASTName) name.getParent()).getBinding() == binding ||
binding instanceof ICPPFunctionTemplate)) {
@ -401,15 +407,10 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
} else {
fStatistics.fDeclarationCount++;
}
} catch (RuntimeException e) {
th= e;
} catch (StackOverflowError e) {
th= e;
}
if (th != null) {
} catch (RuntimeException | StackOverflowError e) {
if (!reported) {
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;
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;
}

View file

@ -704,7 +704,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
} else if (binding instanceof ICPPField) {
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
if(binding instanceof ICPPFieldTemplate) {
if (binding instanceof ICPPFieldTemplate) {
pdomBinding = new PDOMCPPFieldTemplate(this, parent, (ICPPFieldTemplate) binding);
} else {
pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding, true);
@ -1064,11 +1064,6 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return 0;
}
@Override
protected boolean cannotAdapt(final IBinding inputBinding) throws CoreException {
return super.cannotAdapt(inputBinding);
}
@Override
public final PDOMBinding adaptBinding(final IBinding inputBinding, boolean includeLocal) throws CoreException {
return adaptBinding(null, inputBinding, includeLocal ? FILE_LOCAL_REC_DUMMY : null);

View file

@ -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.ICPPVariable;
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.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database;
@ -49,11 +48,6 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
Database db = getDB();
db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(variable));
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());
linkage.new ConfigureVariable(variable, this);
}