Conversation
| } | ||
|
|
||
| // Initialize the identifier pool | ||
| shared static this() nothrow |
There was a problem hiding this comment.
????
Modules constructors for this type of work, shouldn't exist, outside of a single central one.
Otherwise things will get missed over time.
There was a problem hiding this comment.
True, moved it into Id.initialize()/Id.deinitialize(), and dropped module constructor.
There was a problem hiding this comment.
Wait, that ctor is pre existing, I was only extracting them so they can be repopulated between runs.
If you can think of a better place for them, please let me know, I can't find where a central way would fit, there is some issues right now with how dmd expects things to init due to how unittests are called.
Lines 595 to 605 in 278dce2
| */ | ||
| static IntegerExp createBool(bool b) | ||
| { | ||
| __gshared IntegerExp trueExp, falseExp; |
There was a problem hiding this comment.
you can in theory do this for true/false as done here
| */ | ||
| static IntegerExp literal(int v)() | ||
| { | ||
| __gshared IntegerExp theConstant; |
There was a problem hiding this comment.
but not this, because it is inside a template.
There was a problem hiding this comment.
though git grep \.literal\! shows only hits for IntegerExp.literal!0 and IntegerExp.literal!1
thewilsonator
left a comment
There was a problem hiding this comment.
I would try to split this up into separate PRs, much easier to review.
| /*********************************************************** | ||
| */ | ||
| // Auto-incremented package tag; reset between sessions. | ||
| private __gshared uint packageTag; |
There was a problem hiding this comment.
make this a static private member of Package
rainers
left a comment
There was a problem hiding this comment.
Although Visual D's semantic server tries to work incrementally to some extend (keep syntax-tree of parsing, don't ever release identifiers from the identifier pool, keep types that never change), keeping memory consumption low and free from false pointers is also a considerable advantage. Not sure how well this works for some parts of the semantic server that can currently still run in parallel.
It would be nice if you could split this into a couple of PRs
- make local
__gsharedvariables resettable - remove phobos from frontend.d (not used by Visual D). I suspect some of the reimplemented functions are also available in root/filename.d.
- add the scratch allocator: not sure if we should add another allocator. Maybe it is easy to add free/realloc support for explicit calls in the exisiting bump-allocator. Note that D array allocation is used and is performed by the (usually disabled) conservative GC to allow requesting array metadata.
|
|
||
| static void* xmalloc_noscan(size_t size) pure nothrow | ||
| { | ||
| if (isArenaEnabled) |
There was a problem hiding this comment.
Instead of testing isArenaEnabled it seems you can also just enable the GC and initialize arenaBit to zero or non-zero. That way the normal path does not receive an additional if.
| if (pred(sv)) | ||
| { | ||
| // Clear the value so the GC-scanned pool doesn't keep it reachable. | ||
| sv.value = T.init; |
There was a problem hiding this comment.
I don't think this works good enough, because the chain of used entries with hash collisions is interrupted. You need a separate marker for "deleted", see https://github.com/rainers/dmd/blob/dmdserver/compiler/src/dmd/root/stringtable.d#L217
| import dmd.dtemplate : TemplateDeclaration; | ||
|
|
||
| // Cache for object._arrayOp; hoisted so deinitialize can reset it. | ||
| private __gshared TemplateDeclaration arrayOpTemplate; |
There was a problem hiding this comment.
Your extracted variables seem very much in line with what Visual D does, though it abuses the mangling to access them, see https://github.com/rainers/visuald/blob/master/vdc/dmdserver/dmdinit.d#L68
Getting rid of these would be nice.
There are a couple of recursion checks using static nested or similar, though, which might also not get reset on fatal errors.
| } | ||
|
|
||
| /// Reset the module's global state between analyses. | ||
| void deinitialize() nothrow |
There was a problem hiding this comment.
Although precedent for deinitialize exists, I'd rather call these methods reset or resetState. Otherwise I would expect to have to call some initialize function on reuse.
Maybe too disruptive for existing methods, though, and inconsistent if only used for new ones.
This PR enables the frontend to be run in the same process without leaking memory & state between runs.
No behavior change for normal one shot compilation.
Each commit is independently reviewable.
Disclaimer: This is done with the help of a LLM.