-
-
Notifications
You must be signed in to change notification settings - Fork 421
Conversation
MartinNowak
commented
Sep 29, 2017
- allows to add new GCs at link time
Thanks for your pull request, @MartinNowak! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + druntime#1924" |
781ab8e
to
377a33b
Compare
src/gc/config.d
Outdated
@@ -40,6 +42,8 @@ struct Config | |||
{ | |||
import core.internal.traits : externDFunc; | |||
|
|||
__gshared linkDummy = &_dummy_ref_to_link_gc_register_constructor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be simpler to just call _d_register_conservative_gc()
and _d_register_manual_gc()
explicitely. You can still override these symbols in the executable if you don't want to register them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The C object file wouldn't be referenced and doesn't get linked into the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What C object file? Just call _d_register_conservative_gc() and _d_register_manual_gc() right here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed yesterday that you can also reimplement gc_init in the executable registering the desired or new GCs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That wouldn't allow configuring by application users. Think of how Java GC's are often selected/optimized according to specific loads.
Wouldn't work with druntime as DLL or with hidden symbols in shared libraries.
Also many programmers hardly have an idea how linkers work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, replacing gc_init is a bit blunt and doesn't allow adding to existing GCs. It's currently the only way to remove a GC from the binary.
The current of _dummy_ref_to_link_gc_register_constructor
seems gratuitious, though. Just registering the GCs here should be fine.
src/gc/impl/conservative/gc.d
Outdated
@@ -332,6 +323,7 @@ class ConservativeGC : GC | |||
cstdlib.free(gcx); | |||
gcx = null; | |||
} | |||
cstdlib.free(cast(void*) this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Freeing this
in a public method is a bit dangerous because an invariant might crash. One possible solution might be to pass the finalize function to the registry, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, not so nice.
In fact just using a static buffer instead of the C heap might work as well.
Think the best alternative is to convert Dtor to a real destructor which doesn't have the invariant problem.
src/gc/impl/manual/gc.d
Outdated
class ManualGC : GC | ||
{ | ||
__gshared Array!Root roots; | ||
__gshared Array!Range ranges; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's been this way before, but it doesn't really make sense to make these members __gshared
.
__attribute__((constructor)) static void xxx_ctor() | ||
{ | ||
register_mygc(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration still needs a solution on Windows (though something similar is possible). I'd prefer if we would not have to rely on C, though.
Some time ago, I tried implementing pragma(dataSeg, "segment-name")
, would be pretty helpful for this, too. I think it's badly needed in a system programming language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping for the _STI/_STD mechanism to work (to be recognized by the linker), but must have misremembered that it works.
There is https://issues.dlang.org/show_bug.cgi?id=16300 and we've recently worked on constructor/destructor functions dlang/dmd#6956 that could be added as pragma(constructor) and pragma(destructor). Not sure what gdc or ldc are doing with regards to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/attributes.d#L229 in LDC, with the addition of pragma(crt_constructor)
and friends, perhaps we should add that?
The nits aside, this approach is much better for registering and selecting the GC than the current one. |
Think it would make sense to work on |
The registered factory should also be |
@@ -0,0 +1,87 @@ | |||
/** | |||
* Contains a registry for GC factories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm slightly confused by the terminology here: I would have expected the "registry" to be the "factory" and a GC is registered by adding a "factory method" to the factory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, yes it's a registry for factory methods.
@MartinNowak I wonder if we should explore dropping the notion of GC as a class, which allows replacing it during runtime (not really used or useful). This will cause some breakage but it would be a design improvement. What do you think? |
The opposite, let's allow to implement GCs as dub packages (#1924). There is still are still a lot of improvement potentials in the GC domain, but we (as core team) will hardly invest in this area in the next 1 or 2 years. |
Also I'd like this to be the last work on the GC for a while, people still get confused that our community keeps talking about GC improvements. |
f28f492
to
9c4d5b3
Compare
Rebased and replaced the C registration with pragma(crt_constructor). Might need dlang/dmd#9132 |
9c4d5b3
to
e191af9
Compare
119acd8
to
54b60c1
Compare
|
a265773
to
05503bd
Compare
posix.mak
Outdated
@@ -229,6 +229,10 @@ $(ROOT)/threadasm.o : src/core/threadasm.S | |||
@mkdir -p $(dir $@) | |||
$(CC) -c $(CFLAGS) $< -o$@ | |||
|
|||
$(ROOT)/gc/%.o : src/gc/%.c | |||
@mkdir -p $(dir $@) | |||
$(CC) -c $(CFLAGS) $< -o$@ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this? (I don't see any C files that have been added)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has remained from the initial version that used C files instead of pragma(crt_constructor). I'll remove it.
FYI the master -> stable branch-off will happen in ~ 3 days. So it would be nice to have this as part of 2.085. Anything blocking this? |
Good to go AFAICT. I guess a changelog entry and an update to the documentation are recommended. |
3c5e5ed
to
c864fed
Compare
c864fed
to
11f81f3
Compare
changelog/gc_registry.dd
Outdated
|
||
GC createMyGC() | ||
{ | ||
__gshared ubyte[__traits(classInstanceSize, MyGC)] buf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably good to add an alignment here see e.g. #2411
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, classInstanceAlignment doesn't seem good enough (and isn't yet available), so I opted for aligning to pointer size.
I also used core.lifetime.emplace now.
I've added a changelog entry, but noticed one gotcha: when writing a new GC you will have to import modules from the gc package, but that isn't available in the standard import folders. You always needed to add the src folder to the import paths somehow, not sure we should bother now. |
98403a8
to
4f3d2ac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhm, looks like we need to move the user-exposed bits to core.gc?
changelog/gc_registry.dd
Outdated
--- | ||
extern (C) pragma(crt_constructor) void registerMyGC() | ||
{ | ||
registerGCFactory("mygc", &createMyGC); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this need an import?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does (import gc.registry, gc.gcinterface;
), but they are not easily accessible right now
I'd rather add the necessary modules to the import folder as is. |
Wouldn't that be a potentially breaking change as we add a new top-level module? |
It is already there, just hidden. If you create a module with the same module name, you will get symbol conflicts at link time.
Might be an issue, but most of the time it should be ok to just recompile the module again, the linker just picks one. I'm also ok with not making them public. If you work on replacing the GC, adding an import path should not scare you. Maybe the changelog text is already too detailed, most of it might be better in the documentation. |
4f3d2ac
to
ee0c82c
Compare
I moved most of the changelog text to the documentation dlang/dlang.org#2577 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should still expose the methods to the user, s.t. dub packages have an easy way to provide a nice out-of-the-box experience for their custom GCs, but this can happen in another PR.
Hmm, currently all the user-exposed GC-related methods are in https://dlang.org/phobos/core_memory.html#.GC How about moving the public interfaces to this module or as a |