Made some effort at reducing memory use. Implemented #54

This commit is contained in:
Hackerpilot 2013-10-13 23:23:31 +00:00
parent 41dbdaed4a
commit cc49cef4c7
6 changed files with 108 additions and 33 deletions

View File

@ -98,6 +98,23 @@ public:
return this.opCmp(other.name);
}
/**
* Gets all parts whose name matches the given string.
*/
const(ACSymbol)*[] getPartsByName(string name) const
{
return cast(typeof(return)) parts.filter!(a => a.name == name).array;
}
size_t estimateMemory(size_t runningTotal) const
{
runningTotal = runningTotal + name.length + callTip.length
+ ACSymbol.sizeof;
foreach (part; parts)
runningTotal = part.estimateMemory(runningTotal);
return runningTotal;
}
/**
* Symbols that compose this symbol, such as enum members, class variables,
* methods, etc.
@ -109,15 +126,25 @@ public:
*/
string name;
/**
* Calltip to display if this is a function
*/
string callTip;
/**
* Module containing the symbol.
*/
string symbolFile;
/**
* The symbol that represents the type.
*/
const(ACSymbol)* type;
/**
* Calltip to display if this is a function
* Symbol location
*/
string callTip;
size_t location;
/**
* The kind of symbol
@ -128,24 +155,6 @@ public:
* Symbol qualifier
*/
SymbolQualifier qualifier;
/**
* Symbol location
*/
size_t location;
/**
* Module containing the symbol.
*/
string symbolFile;
/**
* Gets all parts whose name matches the given string.
*/
const(ACSymbol)*[] getPartsByName(string name) const
{
return cast(typeof(return)) parts.filter!(a => a.name == name).array;
}
}
struct Scope
@ -318,6 +327,28 @@ static this()
builtinSymbols = [bool_, int_, long_, byte_, char_, dchar_, short_, ubyte_, uint_,
ulong_, ushort_, wchar_, cdouble_, cent_, cfloat_, creal_, double_,
float_, idouble_, ifloat_, ireal_, real_, ucent_, void_];
// _argptr has type void*
argptrType = new Type;
argptrType.type2 = new Type2;
argptrType.type2.builtinType = TokenType.void_;
TypeSuffix argptrTypeSuffix = new TypeSuffix;
argptrTypeSuffix.star = true;
argptrType.typeSuffixes ~= argptrTypeSuffix;
// _arguments has type TypeInfo[]
argumentsType = new Type;
argumentsType = new Type;
argumentsType.type2 = new Type2;
argumentsType.type2.symbol = new Symbol;
argumentsType.type2.symbol.identifierOrTemplateChain = new IdentifierOrTemplateChain;
IdentifierOrTemplateInstance i = new IdentifierOrTemplateInstance;
i.identifier.value = "TypeInfo";
i.identifier.type = TokenType.identifier;
argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances ~= i;
TypeSuffix argumentsTypeSuffix = new TypeSuffix;
argumentsTypeSuffix.array = true;
argumentsType.typeSuffixes ~= argptrTypeSuffix;
}
const(ACSymbol)*[] builtinSymbols;
@ -325,3 +356,5 @@ const(ACSymbol)*[] arraySymbols;
const(ACSymbol)*[] assocArraySymbols;
const(ACSymbol)*[] classSymbols;
const(ACSymbol)*[] structSymbols;
Type argptrType;
Type argumentsType;

View File

@ -62,6 +62,19 @@ final class FirstPass : ASTVisitor
void run()
{
visit(mod);
mod = null;
}
override void visit(Unittest u)
{
// Create a dummy symbol because we don't want unit test symbols leaking
// into the symbol they're declared in.
SemanticSymbol* s = new SemanticSymbol("*unittest*",
CompletionKind.dummy, null, 0);
s.parent = currentSymbol;
currentSymbol = s;
u.accept(this);
currentSymbol = s.parent;
}
override void visit(Constructor con)
@ -388,6 +401,20 @@ private:
symbol.addChild(parameter);
parameter.parent = symbol;
}
if (parameters.hasVarargs)
{
SemanticSymbol* argptr = new SemanticSymbol("_argptr",
CompletionKind.variableName, null, 0);
argptr.type = argptrType;
argptr.parent = symbol;
symbol.addChild(argptr);
SemanticSymbol* arguments = new SemanticSymbol("_arguments",
CompletionKind.variableName, null, 0);
arguments.type = argumentsType;
arguments.parent = symbol;
symbol.addChild(arguments);
}
}
symbol.acSymbol.callTip = formatCallTip(returnType, functionName,
parameters);
@ -695,22 +722,29 @@ const(ACSymbol)*[] convertAstToSymbols(Module m, string symbolFile)
{
FirstPass first = new FirstPass(m, symbolFile);
first.run();
SecondPass second = SecondPass(first.rootSymbol, first.moduleScope);
second.run();
ThirdPass third = ThirdPass(second.rootSymbol, second.moduleScope);
third.run();
return cast(typeof(return)) third.rootSymbol.acSymbol.parts;
}
const(Scope)* generateAutocompleteTrees(const(Token)[] tokens, string symbolFile)
{
Module m = parseModule(tokens, null);
FirstPass first = new FirstPass(m, symbolFile);
first.run();
SecondPass second = SecondPass(first.rootSymbol, first.currentScope);
second.run();
ThirdPass third = ThirdPass(second.rootSymbol, second.moduleScope);
third.run();
return cast(typeof(return)) third.moduleScope;
}
@ -731,7 +765,7 @@ string[] iotcToStringArray(const IdentifierOrTemplateChain iotc)
private static string convertChainToImportPath(IdentifierChain chain)
{
return to!string(chain.identifiers.map!(a => a.value.dup).join(dirSeparator).array) ~ ".d";
return to!string(chain.identifiers.map!(a => a.value).join(dirSeparator).array) ~ ".d";
}
version(unittest) Module parseTestCode(string code)

View File

@ -2,6 +2,10 @@ dmd -wi client.d\
messages.d\
msgpack-d/src/msgpack.d\
-Imsgpack-d/src\
-release\
-inline\
-noboundscheck\
-O\
-ofdcd-client
dmd \

View File

@ -60,6 +60,18 @@ struct ModuleCache
cache = cache.init;
}
static void estimateMemory()
{
size_t estimate = 0;
foreach (c; cache)
{
foreach (symbol; c.symbols)
estimate = symbol.estimateMemory(estimate);
}
double megabytes = estimate / (1024.0F * 1024.0F);
Log.info("Memory use estimated at ", megabytes, " megabytes");
}
/**
* Adds the given path to the list of directories checked for imports
*/
@ -78,7 +90,6 @@ struct ModuleCache
{
foreach (fileName; dirEntries(path, "*.{d,di}", SpanMode.depth))
{
Log.info("Loading and caching completions for ", fileName);
getSymbolsInModule(fileName);
}
}
@ -92,7 +103,7 @@ struct ModuleCache
*/
static const(ACSymbol)*[] getSymbolsInModule(string moduleName)
{
// Log.info("Getting symbols for module ", moduleName);
string location = resolveImportLoctation(moduleName);
if (location is null)
return [];
@ -104,6 +115,8 @@ struct ModuleCache
return [];
}
Log.info("Getting symbols for module ", moduleName);
recursionGuard[location] = true;
const(ACSymbol)*[] symbols;
@ -131,9 +144,6 @@ struct ModuleCache
CacheEntry c = CacheEntry(symbols, modification);
cache[location] = c;
recursionGuard[location] = false;
import core.memory;
GC.collect();
GC.minimize();
return symbols;
}

View File

@ -42,11 +42,6 @@ public:
acSymbol.symbolFile = symbolFile;
}
~this()
{
Log.trace(acSymbol.name, " destructor");
}
void addChild(SemanticSymbol* child)
{
children ~= child;

View File

@ -98,6 +98,7 @@ int main(string[] args)
sw.stop();
Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds");
ModuleCache.estimateMemory();
while (true)
{
@ -114,8 +115,6 @@ int main(string[] args)
continue;
}
// TODO: Only process connections from localhost
scope (exit)
{
s.shutdown(SocketShutdown.BOTH);