-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternate GC hooking into Julia GC. #2092
Conversation
Thanks @rbehrends ! Would you please consider rebasing this PR, to get rid of those merges? That'd make it a tad easier to look at this on a per-commit level. |
I can do that. There's a certain irony to the fact that I had used merges to add structure to the changes, but I agree that as GitHub does not deal with merges well, that may have inadvertently resulted in the opposite effect. |
To be honest, I don't see how the two merges in your PR add structure in a meaningful way... Anyway, so far this PR is pretty small, I think we are fine rebasing it. |
Codecov Report
@@ Coverage Diff @@
## master #2092 +/- ##
==========================================
- Coverage 75.41% 75.41% -0.01%
==========================================
Files 478 478
Lines 241578 241578
==========================================
- Hits 182192 182190 -2
- Misses 59386 59388 +2
|
Rebased and squashed version is here: https://github.com/fingolfin/gap/tree/mh/alt-gc |
src/alt_gc.c
Outdated
@@ -0,0 +1,329 @@ | |||
/**************************************************************************** | |||
** | |||
*W boehm_gc.c |
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.
Should be alt_gc.c
Though I don't quite see why we need the file alt_c.c
in the first place?
src/julia_gc.c
Outdated
@@ -0,0 +1,641 @@ | |||
/**************************************************************************** | |||
** | |||
*W boehm_gc.c |
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.
Should be julia_gc.c
; and the next few lines should be adjusted, too.
src/julia_gc.c
Outdated
|
||
enum { | ||
NTYPES = 256 | ||
}; |
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.
Perhaps we should resurrect #1700 to get this constant (but with a better name) into a header file, so all GCs can share it.
src/julia_gc.c
Outdated
NTYPES = 256 | ||
}; | ||
|
||
TNumInfoBags InfoBags [ NTYPES ]; |
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.
InfoBags
is another function which all GCs will share, so this, too, is something we can perhaps move into a shared header. I've thought about calling that bags.h
, and moving a considerable part of gasman.h
into that. Thoughts?
src/julia_gc.c
Outdated
void InitFreeFuncBag(UInt type, TNumFreeFuncBags finalizer_func) | ||
{ | ||
TabFreeFuncBags[type] = finalizer_func; | ||
} |
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.
TabFreeFuncBags
and InitFreeFuncBag
is also something that perhaps all GCs want to share (in theory, some memory manager might want to customize it; but if that happens, we can still think about a scheme to make it possible; no need to duplicate code until then, I'd say...)
src/julia_gc.c
Outdated
InfoBags[old_type].sizeAll -= size; | ||
InfoBags[new_type].sizeAll += size; | ||
} | ||
#endif |
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.
Note to self: factor out the above statistics code, too
src/julia_gc.c
Outdated
// Master pointers require one word of memory. | ||
void *result = (void *) jl_gc_alloc(JuliaTLS, | ||
sizeof(void *), datatype_mptr); | ||
return result; |
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 wondering whether it would make more sense for Boehm and Julia GC to store at lest the type and flags (but possibly also the size) inside the master point instead? This way, querying the type of an object requires on indirection less.
src/julia_gc.c
Outdated
*/ | ||
if (size == 0) | ||
alloc_size++; | ||
/* While we use the Boehm GC without the "all interior pointers" |
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 comment seems to be Boehm GC specific...
src/julia_gc.c
Outdated
/* get type and old size of the bag */ | ||
type = header->type; | ||
flags = header->flags; | ||
old_size = header->size; |
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.
Does Julia GC offer a function similar to GC_size
? If no, perhaps one could/should add one? (Small allocations seem to come from pools, where the allocation size should thus be known; big allocations seem to store the size in struct bigval_t
-- but of course I only scratched the surface of that code, so what I just said may very well be just nonsense)
src/julia_gc.c
Outdated
|
||
/***************************************************************************** | ||
** The following functions are not required respectively supported, so empty | ||
** implementations are provided |
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's just no true ... :-)
src/julia_gc.c
Outdated
@@ -456,6 +456,7 @@ UInt CollectBags ( | |||
UInt full ) | |||
{ | |||
// HOOK: perform a full collection | |||
jl_gc_collect(1); |
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 not jl_gc_collect(full);
?
FYI, we just updated this PR branch with a force push, so if anybody here was/is using that, you may need to take care when updating that branch. News: it was rebased, history was squashed, |
cddeeeb
to
912be10
Compare
src/boehm_gc.c
Outdated
} | ||
else if (new_size < old_size) { | ||
memset(DATA(header) + new_size, 0, old_size - new_size); | ||
} |
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 is a tiny improvement for Boehm which we could port over to master
right away.
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.
Indeed, see PR #2455
src/julia_gc.c
Outdated
#include "julia.h" | ||
#include "gcext.h" | ||
|
||
extern jl_value_t *(jl_gc_alloc)(jl_ptls_t ptls, size_t sz, void * ty); |
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 is from julia_internal.h
-- if this is internal, it probably is so for a good reason. So I guess we must ask them to make it public; or add a gcext
specific wrapper for it; or find a way to avoid it?
src/julia_gc.c
Outdated
bagContents2 = ((char *)bagContents) + sizeof(BagHeader); | ||
bag = (Bag)&bagContents2; | ||
TabFreeFuncBags[TNUM_BAG(bag)](bag); | ||
} |
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 function is not used. Are there plans to do so?
src/julia_gc.c
Outdated
** | ||
** Allocate memory for a new bag. | ||
** | ||
** 'AllocateBagMemory' is an auxiliary routine for the Boehm GC 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.
Should replace or remove Boehm GC
here.
src/julia_gc.c
Outdated
** Allocate memory for a new bag. | ||
** | ||
** 'AllocateBagMemory' is an auxiliary routine for the Boehm GC that | ||
** allocates memory from the appropriate pool. 'gc_type' is -1 if all words |
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.
gc_type == type
? Uhh, but below, it seems to actually be a TNUM?!
src/julia_gc.c
Outdated
static void * JCache; | ||
static void * JSp; | ||
static size_t max_pool_obj_size; | ||
static size_t bigval_startoffset; |
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.
Please consistently use CamelCase
for global vars, as that makes it easier to recognize them at a glance .
src/julia_gc.c
Outdated
|
||
// copy data and update the masterpointer | ||
src = PTR_BAG(bag); | ||
memcpy(DATA(header), src, old_size < new_size ? old_size : new_size); |
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.
even simpler would be to copy *everything, including the BagHeader
, and then only update header->size
src/julia_gc.c
Outdated
// Master pointers require one word of memory. | ||
void * result = | ||
(void *)jl_gc_alloc(JuliaTLS, sizeof(void *), datatype_mptr); | ||
memset(result, 0, sizeof(void *)); |
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 memset call is not necessary here. And at this point, perhaps we should just merge this function into `NewBag?
src/julia_gc.c
Outdated
UInt CollectBags(UInt size, UInt full) | ||
{ | ||
// HOOK: perform a full collection | ||
jl_gc_collect(1); |
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 not jl_gc_collect(full);
?
src/julia_gc.c
Outdated
datatype_bag = jl_new_foreign_type(jl_symbol("BagInner"), Module, | ||
jl_any_type, JMarkBag, NULL, 1, 0); | ||
datatype_largebag = jl_new_foreign_type( | ||
jl_symbol("BagInner"), Module, jl_any_type, JMarkBag, NULL, 1, 1); |
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.
Hmm, so two datatypes both use BagInner
as their name. Perhaps this second one should be BagLargeInner
?
Or perhaps it should be MasterPointer
(or MPtr
), Bag
, LargeBag
, matching the C variable names?
I recently wondered why we need the treap code, and it seems we don't: rbehrends#9 removes it, and seems to work just fine (at least in the GAP test suite). If you know of reasons why having it is beneficial, let's discuss it on that PR. |
db0a319
to
3e49fb9
Compare
5622c24
to
b2312c4
Compare
During a video conference call today, we seemed to agree that we this could be merged right away (and apparently, doing so would be helpful for @frankluebeck and @ThomasBreuer). I am fine with this, although I'd like to rebase and squash this one last time before that, i.e.: I would like to perform the merge. However, in the meantime, perhaps those people who want this in can at least formally "approve" this PR; and all others could at least briefly have a look at it, to make sure there is nothing immediately upsetting in this PR. |
BTW, right now, the Julia GC is not supported together with HPC-GAP. But this could be changed -- it just wasn't a priority for now. I think it would be useful to work towards that, but first, we should wait for the Julia changes to land there; then adapt our code here to match; and only afterwards, start looking more into HPC-GAP integration. |
src/weakptr.c
Outdated
len = LoadUInt(); | ||
STORE_LEN_WPOBJ(wpobj, len); | ||
for (i = 1; i <= len; i++) | ||
{ | ||
#ifdef USE_JULIA_GC | ||
SET_ELM_WPOBJ(wpobj, i, LoadSubObj()); | ||
#else |
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.
Very minor suggestion, I think we could just use the Julia codepath here -- it would be valid for GASMAN (I'm 99% sure). It might be slightly less efficient, but would save code seperation.
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.
Fine by me, will change it.
This is not a suggested change for this PR. Reading the weak pointer file, the main difference between the Julia and GASMAN implementation seems to be GASMAN has to handle DEAD_WEAK_BAGS. I think if we made GASMAN's ELM_WPOBJ return 0 if a bag for DEAD_WEAK_BAGs (and most code in weakptr.c doesn't care about the difference between 0 and a DEAD_WEAK_BAG), then I think the Julia weakpointer code (which uses cfunction calls rather than reading through bags with raw C pointers) could be used for both gasman and JuliaGC removing the code differences and cleaning things up. |
I have merged this branch into the master branch some days ago. Together with @rbehrends' corresponding branch of julia this seemed to work without problems on the GAP side. Merging this into the master branch now would simplify the task to install a combination of GAP/Julia that can be used for further development. I cannot see any problem for people who want to use GAP but not the new feature provided by this pull request. |
@@ -868,6 +960,9 @@ static Int InitKernel ( | |||
InitMarkFuncBags ( T_WPOBJ +COPYING, MarkWeakPointerObj ); |
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.
Completely unrelated stupid question (which does not need to be addressed for merging): why is it possible to have USE_GASMAN
and USE_THREADSAFE_COPYING
?
#define MARK_HASH(x) (FibHash((x), MARK_CACHE_BITS)) | ||
|
||
// #define STAT_MARK_CACHE | ||
|
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.
Will this become a compile-time option?
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.
Good question. It's also not clear to me how useful that cache really is. Which reminds me: I asked @rbehrends before to add more comments to this file, I'll prod him again about it once this is merged, and/or add some more comments myself.
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.
Actually, I also just discovered that MarkCache
doesn't actually seem to do anything! I.e. we never use it to prevent any computation. @rbehrends did we loose some code there, or what?
Use `--with-gc=julia` to switch to this alternative garbage collector. There is also a new `--with-julia=` option which can be used to point GAP at the correct Julia version (which currently still needs some patches to add APIs we need). The main work is in the new file src/julia_gc.c
This is the GAP side aspects of the work for making the Julia GC work with GAP.
The modified version of Julia with conservative stack scanning lives in the
rb/gc-extensions
branch at https://github.com/rbehrends/julia and is tracked via this pull request.To do list for the integration:
Checklist
Subgoals:
bigval_t
struct.bigval_t
allocation hooks.src/gc.{h,c}
.jl_value_from_interior_ptr(void *p)
directly?the API.
Subgoals:
through interior pointers.
jl_gc_wb_back()).
jl_task_root_scanner_hook
JuliaTLS
; ...)Building the system:
Build Julia from the
rb/gc-extensions
branch as usual, say in directory/julia/root/dir
. Then build GAP from this PR (resp. thealt-gc
branch) as follows (don't forget the finalusr
in the path passed to--with-julia
):Now you should be able to start GAP. Be warned, garbage collections are currently suppressed, and if one happens anyway, it'll crash. This is now being worked on.