Skip to content

Commit 39d797b

Browse files
committed
Reland: Allow re-initialization and caching of foreign types (#47407)
1 parent a7603f3 commit 39d797b

File tree

16 files changed

+238
-5
lines changed

16 files changed

+238
-5
lines changed

src/datatype.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu
7272
jl_atomic_store_relaxed(&tn->cache, jl_emptysvec);
7373
jl_atomic_store_relaxed(&tn->linearcache, jl_emptysvec);
7474
tn->names = NULL;
75-
tn->hash = bitmix(bitmix(module ? module->build_id : 0, name->hash), 0xa1ada1da);
75+
tn->hash = bitmix(bitmix(module ? module->build_id.lo : 0, name->hash), 0xa1ada1da);
7676
tn->_reserved = 0;
7777
tn->abstract = abstract;
7878
tn->mutabl = mutabl;
@@ -826,6 +826,22 @@ JL_DLLEXPORT jl_datatype_t * jl_new_foreign_type(jl_sym_t *name,
826826
return bt;
827827
}
828828

829+
JL_DLLEXPORT int jl_reinit_foreign_type(jl_datatype_t *dt,
830+
jl_markfunc_t markfunc,
831+
jl_sweepfunc_t sweepfunc)
832+
{
833+
if (!jl_is_foreign_type(dt))
834+
return 0;
835+
const jl_datatype_layout_t *layout = dt->layout;
836+
jl_fielddescdyn_t * desc =
837+
(jl_fielddescdyn_t *) ((char *)layout + sizeof(*layout));
838+
assert(!desc->markfunc);
839+
assert(!desc->sweepfunc);
840+
desc->markfunc = markfunc;
841+
desc->sweepfunc = sweepfunc;
842+
return 1;
843+
}
844+
829845
JL_DLLEXPORT int jl_is_foreign_type(jl_datatype_t *dt)
830846
{
831847
return jl_is_datatype(dt) && dt->layout && dt->layout->fielddesc_type == 3;

src/jl_exported_funcs.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@
343343
XX(jl_new_code_info_uninit) \
344344
XX(jl_new_datatype) \
345345
XX(jl_new_foreign_type) \
346+
XX(jl_reinit_foreign_type) \
346347
XX(jl_new_method_instance_uninit) \
347348
XX(jl_new_method_table) \
348349
XX(jl_new_method_uninit) \

src/julia_gcext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ JL_DLLEXPORT jl_datatype_t *jl_new_foreign_type(
4949
int haspointers,
5050
int large);
5151

52+
53+
#define HAVE_JL_REINIT_FOREIGN_TYPE 1
54+
JL_DLLEXPORT int jl_reinit_foreign_type(
55+
jl_datatype_t *dt,
56+
jl_markfunc_t markfunc,
57+
jl_sweepfunc_t sweepfunc);
58+
5259
JL_DLLEXPORT int jl_is_foreign_type(jl_datatype_t *dt);
5360

5461
JL_DLLEXPORT size_t jl_gc_max_internal_obj_size(void);

test/gcext/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/gcext
22
/gcext-debug
3+
/Foreign/deps
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.8.3"
4+
manifest_format = "2.0"
5+
project_hash = "e7199d961a5f4ebad68a3deaf5beaa7406a0afcb"
6+
7+
[[deps.Foreign]]
8+
deps = ["Libdl"]
9+
path = "../Foreign"
10+
uuid = "de1f6f7a-d7b3-400f-91c2-33f248ee89c4"
11+
version = "0.1.0"
12+
13+
[[deps.Libdl]]
14+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name = "DependsOnForeign"
2+
uuid = "4b0716e0-dfb5-4e00-8b44-e2685a41517f"
3+
version = "0.1.0"
4+
5+
[deps]
6+
Foreign = "de1f6f7a-d7b3-400f-91c2-33f248ee89c4"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module DependsOnForeign
2+
3+
using Foreign
4+
5+
f(obj::FObj) = Base.pointer_from_objref(obj)
6+
precompile(f, (FObj,))
7+
8+
const FObjRef = Ref{FObj}()
9+
10+
function __init__()
11+
FObjRef[] = FObj()
12+
end
13+
14+
end # module DependsOnForeign

test/gcext/Foreign/Manifest.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.9.0-DEV"
4+
manifest_format = "2.0"
5+
project_hash = "7b70172a2edbdc772ed789e79d4411d7528eae86"
6+
7+
[[deps.Libdl]]
8+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

test/gcext/Foreign/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name = "Foreign"
2+
uuid = "de1f6f7a-d7b3-400f-91c2-33f248ee89c4"
3+
version = "0.1.0"
4+
5+
[deps]
6+
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
#include "julia.h"
4+
#include "julia_gcext.h"
5+
6+
// TODO make these atomics
7+
int nmarks = 0;
8+
int nsweeps = 0;
9+
10+
uintptr_t mark(jl_ptls_t ptls, jl_value_t *p)
11+
{
12+
nmarks += 1;
13+
return 0;
14+
}
15+
16+
void sweep(jl_value_t *p)
17+
{
18+
nsweeps++;
19+
}
20+
21+
JL_DLLEXPORT jl_datatype_t *declare_foreign(jl_sym_t* name, jl_module_t *module, jl_datatype_t *parent)
22+
{
23+
return jl_new_foreign_type(name, module, parent, mark, sweep, 1, 0);
24+
}
25+
26+
// #define GC_MAX_SZCLASS (2032 - sizeof(void *))
27+
28+
JL_DLLEXPORT int reinit_foreign(jl_datatype_t *dt)
29+
{
30+
int ret = jl_reinit_foreign_type(dt, mark, sweep);
31+
nmarks = nsweeps = 0;
32+
if (ret == 0)
33+
return 0;
34+
if (dt->layout->npointers != 1)
35+
return -1;
36+
if (dt->layout->size != 0)
37+
return -2;
38+
return ret;
39+
}
40+
41+
JL_DLLEXPORT jl_value_t *allocate_foreign(jl_ptls_t ptls, size_t sz, jl_datatype_t *dt)
42+
{
43+
jl_value_t* obj = jl_gc_alloc_typed(ptls, sz, dt);
44+
jl_gc_schedule_foreign_sweepfunc(ptls, obj);
45+
return obj;
46+
}
47+
48+
JL_DLLEXPORT int nmark_counter()
49+
{
50+
return nmarks;
51+
}
52+
53+
JL_DLLEXPORT int nsweep_counter()
54+
{
55+
return nsweeps;
56+
}

0 commit comments

Comments
 (0)