Skip to content

Merge #1814 after JIT changes#1864

Merged
bettio merged 1 commit intoatomvm:mainfrom
bettio:integrate-1814-pr-after-jit
Apr 4, 2026
Merged

Merge #1814 after JIT changes#1864
bettio merged 1 commit intoatomvm:mainfrom
bettio:integrate-1814-pr-after-jit

Conversation

@bettio
Copy link
Copy Markdown
Collaborator

@bettio bettio commented Oct 2, 2025

PR #1814 fails after JIT changes, apply fix before merging it to main.
Also some other improvements have been done.

Closes #1814

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

Comment thread tests/test.c Outdated

TEST_CASE(test_code_all_available_loaded),
TEST_CASE_EXPECTED(test_code_load_binary, 24),
#ifndef AVM_NO_JIT
Copy link
Copy Markdown
Collaborator Author

@bettio bettio Oct 2, 2025

Choose a reason for hiding this comment

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

@pguyot This is my best try at fixing build error with build-and-test (macos-15-intel, 28, -DAVM_DISABLE_JIT=OFF). Can we do anything better than just skipping the test?

The relevant error is:

test_code_get_object_code:
Unable to open export_test_module.beam
Unable to open export_test_module.beam
CRASH 
======
pid: <0.1.0>

Stacktrace:
[{test_code_get_object_code,undefined,0,[]},{test_code_get_object_code,start,0,[{file,"/Users/runner/work/AtomVM/AtomVM/tests/erlang_tests/test_code_get_object_code.erl"},{line,28}]}]

cp: #CP<module: 0, label: 13, offset: 756>

x[0]: error
x[1]: undef
x[2]: {2,1,81,1,[{0,268},{0,0}],error}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The test should follow the same pattern as test_code_load_binary to make sure we load the binary with precompiled native code. We will need to update it for every jit target, so maybe we should factorize the hrl at some point.

diff --git a/tests/erlang_tests/test_code_get_object_code.erl b/tests/erlang_tests/test_code_get_object_code.erl
index f411441b7..80f68711f 100644
--- a/tests/erlang_tests/test_code_get_object_code.erl
+++ b/tests/erlang_tests/test_code_get_object_code.erl
@@ -22,8 +22,18 @@
 
 -export([start/0, get_object_wrong_argument/1]).
 
+-ifdef(AVM_DISABLE_JIT).
 -include("code_load/export_test_module_data.hrl").
 
+export_test_module_data() ->
+    ?EXPORT_TEST_MODULE_DATA.
+-else.
+-include("code_load/export_test_module_data_x86_64.hrl").
+
+export_test_module_data() ->
+    ?EXPORT_TEST_MODULE_DATA_x86_64.
+-endif.
+
 start() ->
     ok = get_object_from_export_test_module(),
     ok = get_object_from_already_loaded_test_module(),
@@ -43,7 +53,7 @@ get_object_from_already_loaded_test_module() ->
     ok.
 
 get_object_from_export_test_module() ->
-    Bin = ?EXPORT_TEST_MODULE_DATA,
+    Bin = export_test_module_data(),
     error = code:get_object_code(export_test_module),
     {module, export_test_module} = code:load_binary(
         export_test_module, "export_test_module.beam", Bin

However, when I do that, I have a crash with the external calls:

ok = ?MODULE:get_object_wrong_argument("a string"),

There are other external calls in these tests and they don't crash. I don't know why this one does crash, though. I have yet to investigate this.

The following two versions don't crash.

start() ->
    hello = ?MODULE:id(hello),
    ok = ?MODULE:get_object_wrong_argument("a string"),
    ok = ?MODULE:get_object_wrong_argument(123),
    ok = ?MODULE:get_object_wrong_argument({1, "a"}),
    ok = ?MODULE:get_object_wrong_argument([1, b, 3]),
    ok = get_object_from_export_test_module(),
    ok = get_object_from_already_loaded_test_module(),
    ok = get_object_from_non_existing_module(),
    ok = get_object_wrong_argument("a string"),
    ok = get_object_wrong_argument(123),
    ok = get_object_wrong_argument({1, "a"}),
    ok = get_object_wrong_argument([1, b, 3]),
    0.
start() ->
    hello = ?MODULE:id(hello),
    ok = ?MODULE:get_object_wrong_argument("a string"),
    ok = ?MODULE:get_object_wrong_argument(123),
    ok = ?MODULE:get_object_wrong_argument({1, "a"}),
    ok = ?MODULE:get_object_wrong_argument([1, b, 3]),
    ok = get_object_from_export_test_module(),
    ok = get_object_from_already_loaded_test_module(),
    ok = get_object_from_non_existing_module(),
    ok = ?MODULE:get_object_wrong_argument("a string"),
    ok = ?MODULE:get_object_wrong_argument(123),
    ok = ?MODULE:get_object_wrong_argument({1, "a"}),
    ok = ?MODULE:get_object_wrong_argument([1, b, 3]),
    0.

I don't know if it's related to this nif.
Also I don't like this warning:

Warning, dangling refc binary, ref_count = 1
test_code_get_object_code:       OK
Success.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is the bug: https://github.com/atomvm/AtomVM/pull/1814/files#r2399909494

Additionally, maybe JIT is not very tolerant to hot code reloading on macOS (the mmap didn't have the proper flags), but it's not like we support hot code reloading yet.

@bettio bettio added the popcorn label Mar 13, 2026
@bettio bettio added this to the v0.7.0 milestone Mar 13, 2026
This function works with a caveat, unlike on the BEAM, it returns a
valid result even for modules loaded with `code:load_binary/3`.
Fixing this right now, would mean making bigger changes.

Co-authored-by: Davide Bettio <davide@uninstall.it>
Signed-off-by: Davide Bettio <davide@uninstall.it>
@bettio bettio force-pushed the integrate-1814-pr-after-jit branch from 57b5ae6 to 46c2827 Compare March 31, 2026 11:45
Comment thread src/libAtomVM/module.c
mod->fun_table = beam_file + offsets[FUNT];
mod->str_table = beam_file + offsets[STRT];
mod->str_table_len = sizes[STRT];
mod->binary = beam_file;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We could conditionally set this if module is loaded from file or from a binary and thus solve the (main) incompatibility with BEAM

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

That is an option, but either means changing all module_new_from_iff_binary calls or manually adding that change to different places in all platforms, that sounds messy.

Actually we need a refactor, that separates: finding a beam file in .avm or filesystem, from loading it and from parsing it and creating a new Module struct. That is something I wouldn't do right now.

A proper code:get_object_code would require implementing find + load to binary, not parsing the module and everything else.

@bettio bettio merged commit 36f1c90 into atomvm:main Apr 4, 2026
218 of 224 checks passed
bettio added a commit that referenced this pull request Apr 4, 2026
Merge fixes, features, and optimizations from release-0.7, including:
- Add json module for estdlib and exavmlib (#2247)
- Add timer:send_after/2,3 and apply_after/4 (#2228)
- Add erlang:display_string/1,2 (#2251)
- Add trim and list patterns to binary:split/2,3 (#2253)
- Implement code:get_object_code/1 (#1864)
- Add SPI support to RP2 platform (#2120)
- JIT: add ARM32 backend (#2248)
- JIT: add Thumb-2 variant for ARMv6-M backend (#2250)
- Fix erlang:raise/3 assert with built stacktrace (#2252)
- Fix test_json failure on single-precision float32 (#2257)
- ESP32: Increase Erlang boot.avm partition to 512KB (#2254)
- CI: Bump to OTP 28 and rebar3 3.25.1 (#2255)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants