Made some effort at reducing memory use. Implemented #54
This commit is contained in:
parent
41dbdaed4a
commit
cc49cef4c7
73
actypes.d
73
actypes.d
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
4
build.sh
4
build.sh
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,11 +42,6 @@ public:
|
|||
acSymbol.symbolFile = symbolFile;
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
Log.trace(acSymbol.name, " destructor");
|
||||
}
|
||||
|
||||
void addChild(SemanticSymbol* child)
|
||||
{
|
||||
children ~= child;
|
||||
|
|
3
server.d
3
server.d
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue