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

Only add symbols that are explicit entrypoints when building juliac image #56681

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

gbaraldi
Copy link
Member

This currently just does a linear search over the items. We might want to change this datastructure to a hash table at some point, but given that I don't think libraries have too too many entrypoints this linear search should be fast enough.

Comment on lines +377 to +378
for (size_t i = 0; i < jl_entrypoint_mis->len ; i++) {
mi = (jl_method_instance_t*)jl_entrypoint_mis->items[i];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One worry I have here is that there is the potential to break user-code that depends on this behavior.
That code may be rare, but I have seen it in the wild.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just affects trimmed binaries, so I'm slightly less worried.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it's worth considering a policy change and making the flag --ignore-ccallable, rather than ignoring @ccallable by default unless you pass --compile-ccallable

But that's orthogonal versus this fix, which at least properly implements the current policy correctly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should stick to default-exclude for everything with trimming; it will keep it easier to use.

jl_method_instance_t* mi = (jl_method_instance_t*)jl_entrypoint_mis->items[i];
assert(jl_is_method_instance(mi));
jl_method_t *ccallable = mi->def.method;
if (ccallable == m) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a corner case here where the MI != the @ccallable signature, which would still lead to a crash I think.

Can we check for that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a comment that mentions that though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where that's asserted there - Can you spell it out for me?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static void *jl_precompile_trimmed(size_t world)
{
    // array of MethodInstances and ccallable aliases to include in the output
    jl_array_t *m = jl_alloc_vec_any(0);
    jl_value_t *ccallable = NULL;
    JL_GC_PUSH2(&m, &ccallable);
    jl_method_instance_t *mi;
    for (size_t i = 0; i < jl_entrypoint_mis->len ; i++) {
        mi = (jl_method_instance_t*)jl_entrypoint_mis->items[i];
        if (mi == NULL)
            break;
        assert(jl_is_method_instance(mi));

        jl_array_ptr_1d_push(m, (jl_value_t*)mi);
        ccallable = (jl_value_t *)mi->def.method->ccallable; // If the method passed into jl_entrypoint has ccallable we always compile it. 
        if (ccallable)
            jl_array_ptr_1d_push(m, ccallable);
    }
    jl_cgparams_t params = jl_default_cgparams;
    params.trim = jl_options.trim;
    void *native_code = jl_create_native(m, NULL, &params, 0, /* imaging */ 1, 0,
                                         world, NULL);
    JL_GC_POP();
    return native_code;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does that assert that the entrypoint MI == the ccallable signature?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means if we are compiling the entrypoint and if the method of that entrypoint has a ccallable defined on it, we will add both the entrypoint MI and the ccallable signature (it's an svec). We can maybe compare ccallables instead of methods.

Copy link
Member

@topolarity topolarity Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine, but we shouldn't be imprecise about checking the entrypoint just because we happen to enqueue the ccallables in that way right now

It makes it buggy if we ever try to add entrypoints without the corresponding ccallable in the future

@topolarity topolarity linked an issue Dec 6, 2024 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segfault with @ccallable functions and juliac
4 participants