Skip to content
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

Use jl_reinit_foreign_type if available #5224

Merged
merged 3 commits into from
Nov 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 65 additions & 52 deletions src/julia_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,29 +104,6 @@ static inline int lt_ptr(void * a, void * b)
return (uintptr_t)a < (uintptr_t)b;
}

#if 0
static inline int gt_ptr(void * a, void * b)
{
return (uintptr_t)a > (uintptr_t)b;
}

static inline void *max_ptr(void *a, void *b)
{
if ((uintptr_t) a > (uintptr_t) b)
return a;
else
return b;
}

static inline void *min_ptr(void *a, void *b)
{
if ((uintptr_t) a < (uintptr_t) b)
return a;
else
return b;
}
#endif

/* align pointer to full word if mis-aligned */
static inline void * align_ptr(void * p)
{
Expand Down Expand Up @@ -205,9 +182,9 @@ static void JFinalizer(jl_value_t * obj)
TabFreeFuncBags[tnum]((Bag)&contents);
}

static jl_datatype_t * datatype_mptr;
static jl_datatype_t * datatype_bag;
static jl_datatype_t * datatype_largebag;
static jl_datatype_t * DatatypeGapObj;
static jl_datatype_t * DatatypeSmallBag;
static jl_datatype_t * DatatypeLargeBag;
static Bag * GapStackBottom;
static jl_ptls_t JuliaTLS, SaveTLS;
static BOOL IsJuliaMultiThreaded;
Expand Down Expand Up @@ -259,10 +236,10 @@ static void * AllocateBagMemory(UInt type, UInt size)
// HOOK: return `size` bytes memory of TNUM `type`.
void * result;
if (size <= MaxPoolObjSize) {
result = (void *)jl_gc_alloc_typed(JuliaTLS, size, datatype_bag);
result = (void *)jl_gc_alloc_typed(JuliaTLS, size, DatatypeSmallBag);
}
else {
result = (void *)jl_gc_alloc_typed(JuliaTLS, size, datatype_largebag);
result = (void *)jl_gc_alloc_typed(JuliaTLS, size, DatatypeLargeBag);
}
memset(result, 0, size);
if (TabFreeFuncBags[type])
Expand Down Expand Up @@ -403,7 +380,7 @@ void MarkJuliaObj(void * obj)
static void TryMark(void * p)
{
jl_value_t * p2 = jl_gc_internal_obj_base_ptr(p);
if (p2 && jl_typeis(p2, datatype_mptr)) {
if (p2 && jl_typeis(p2, DatatypeGapObj)) {
#ifndef REQUIRE_PRECISE_MARKING
// Prepopulate the mark cache with references we know
// are valid and in current use.
Expand All @@ -423,7 +400,7 @@ static void FindLiveRangeReverse(PtrArray * arr, void * start, void * end)
while (!lt_ptr(q, p)) {
void * addr = *(void **)q;
if (addr && jl_gc_internal_obj_base_ptr(addr) == addr &&
jl_typeis(addr, datatype_mptr)) {
jl_typeis(addr, DatatypeGapObj)) {
PtrArrayAdd(arr, addr);
}
q -= C_STACK_ALIGN;
Expand Down Expand Up @@ -561,7 +538,7 @@ static NOINLINE void TryMarkRange(void * start, void * end)

BOOL IsGapObj(void * p)
{
return jl_typeis(p, datatype_mptr);
return jl_typeis(p, DatatypeGapObj);
}

void CHANGED_BAG(Bag bag)
Expand Down Expand Up @@ -724,7 +701,7 @@ static uintptr_t MPtrMarkFunc(jl_ptls_t ptls, jl_value_t * obj)
// the comments on conservative stack scanning for an in-depth
// explanation.
void * ty = jl_typeof(header);
if (ty != datatype_bag && ty != datatype_largebag)
if (ty != DatatypeSmallBag && ty != DatatypeLargeBag)
return 0;
if (JMark(header))
return 1;
Expand All @@ -743,6 +720,23 @@ static uintptr_t BagMarkFunc(jl_ptls_t ptls, jl_value_t * obj)
return YoungRef;
}

jl_datatype_t * GAP_DeclareGapObj(jl_sym_t * name,
jl_module_t * module,
jl_datatype_t * parent)
{
return jl_new_foreign_type(name, module, parent, MPtrMarkFunc, NULL, 1,
0);
}

jl_datatype_t * GAP_DeclareBag(jl_sym_t * name,
jl_module_t * module,
jl_datatype_t * parent,
int large)
{
return jl_new_foreign_type(name, module, parent, BagMarkFunc, JFinalizer,
1, large > 0);
}

// Initialize the integration with Julia's garbage collector; in particular,
// create Julia types for use in our allocations. The types will be stored
// in the given 'module', and the MPtr type will be a subtype of 'parent'.
Expand All @@ -752,6 +746,8 @@ static uintptr_t BagMarkFunc(jl_ptls_t ptls, jl_value_t * obj)
void GAP_InitJuliaMemoryInterface(jl_module_t * module,
jl_datatype_t * parent)
{
jl_sym_t * name;

// HOOK: initialization happens here.
for (UInt i = 0; i < NUM_TYPES; i++) {
TabMarkFuncBags[i] = MarkAllSubBagsDefault;
Expand Down Expand Up @@ -785,34 +781,51 @@ void GAP_InitJuliaMemoryInterface(jl_module_t * module,
parent = jl_any_type;
}

// Julia defines HAVE_JL_REINIT_FOREIGN_TYPE if `jl_reinit_foreign_type`
// is available.
#ifdef HAVE_JL_REINIT_FOREIGN_TYPE
if (jl_boundp(module, jl_symbol("GapObj"))) {
DatatypeGapObj =
(jl_datatype_t *)jl_get_global(module, jl_symbol("GapObj"));
jl_reinit_foreign_type(DatatypeGapObj, MPtrMarkFunc, NULL);

DatatypeSmallBag =
(jl_datatype_t *)jl_get_global(module, jl_symbol("SmallBag"));
jl_reinit_foreign_type(DatatypeSmallBag, BagMarkFunc, JFinalizer);

DatatypeLargeBag =
(jl_datatype_t *)jl_get_global(module, jl_symbol("LargeBag"));
jl_reinit_foreign_type(DatatypeLargeBag, BagMarkFunc, JFinalizer);

return;
}
#endif

// create and store data type for master pointers
datatype_mptr = jl_new_foreign_type(jl_symbol("GapObj"), module, parent,
MPtrMarkFunc, NULL, 1, 0);
GAP_ASSERT(jl_is_datatype(datatype_mptr));
jl_set_const(module, jl_symbol("GapObj"), (jl_value_t *)datatype_mptr);
name = jl_symbol("GapObj");
DatatypeGapObj = GAP_DeclareGapObj(name, module, parent);
GAP_ASSERT(jl_is_datatype(DatatypeGapObj));
jl_set_const(module, name, (jl_value_t *)DatatypeGapObj);

// create and store data type for small bags
datatype_bag = jl_new_foreign_type(jl_symbol("Bag"), module, jl_any_type,
BagMarkFunc, JFinalizer, 1, 0);
GAP_ASSERT(jl_is_datatype(datatype_bag));
jl_set_const(module, jl_symbol("Bag"), (jl_value_t *)datatype_bag);
name = jl_symbol("SmallBag");
DatatypeSmallBag = GAP_DeclareBag(name, module, jl_any_type, 0);
GAP_ASSERT(jl_is_datatype(DatatypeSmallBag));
jl_set_const(module, name, (jl_value_t *)DatatypeSmallBag);

// create and store data type for large bags
datatype_largebag =
jl_new_foreign_type(jl_symbol("LargeBag"), module, jl_any_type,
BagMarkFunc, JFinalizer, 1, 1);
GAP_ASSERT(jl_is_datatype(datatype_largebag));
jl_set_const(module, jl_symbol("LargeBag"),
(jl_value_t *)datatype_largebag);

name = jl_symbol("LargeBag");
DatatypeLargeBag = GAP_DeclareBag(name, module, jl_any_type, 1);
GAP_ASSERT(jl_is_datatype(DatatypeLargeBag));
jl_set_const(module, name, (jl_value_t *)DatatypeLargeBag);
}

void InitBags(UInt initial_size, Bag * stack_bottom)
{
GapStackBottom = stack_bottom;
TotalTime = 0;

if (!datatype_mptr) {
if (!DatatypeGapObj) {
GAP_InitJuliaMemoryInterface(0, 0);
}

Expand Down Expand Up @@ -901,7 +914,7 @@ Bag NewBag(UInt type, UInt size)

if (IsJuliaMultiThreaded)
SetJuliaTLS();
bag = jl_gc_alloc_typed(JuliaTLS, sizeof(void *), datatype_mptr);
bag = jl_gc_alloc_typed(JuliaTLS, sizeof(void *), DatatypeGapObj);
SET_PTR_BAG(bag, 0);

BagHeader * header = AllocateBagMemory(type, alloc_size);
Expand Down Expand Up @@ -1007,18 +1020,18 @@ inline void MarkBag(Bag bag)
// relies on Julia internals. It is functionally equivalent
// to:
//
// if (JMarkTyped(p, datatype_mptr)) YoungRef++;
// if (JMarkTyped(p, DatatypeGapObj)) YoungRef++;
//
switch (jl_astaggedvalue(p)->bits.gc) {
case 0:
if (JMarkTyped(p, datatype_mptr))
if (JMarkTyped(p, DatatypeGapObj))
YoungRef++;
break;
case 1:
YoungRef++;
break;
case 2:
JMarkTyped(p, datatype_mptr);
JMarkTyped(p, DatatypeGapObj);
break;
case 3:
break;
Expand Down