Repository navigation
Conversation
2170cd0 to
c42c932
Compare
UncleGrumpy
left a comment
There was a problem hiding this comment.
We should also update UPDATING.md with the change in pruning behavior, since this could break some apps that expect module level pruning - especially where some functions from a module not called directly by the app are expected to be available for use as disterl rpc calls.
We way want to open an issue after this merges to automate the regeneration of src/packbeam_drivers.hrl from the AtomVM repo, so master stays in sync with AtomVM current release branch or main - which is something we will need to decide on since sometimes they diverge quite far.
c42c932 to
50aabee
Compare
Very true. And I realize that what I created didn't match the release branch. Let's use a CI script for this. |
f97d837 to
a2120f2
Compare
UncleGrumpy
left a comment
There was a problem hiding this comment.
Since this was a large and complicated PR, I had CodeRabbit do a review and a few things turned up, several of which may need to be checked for validity.
| Keep -> Keep; | ||
| More -> close_references(Fs, M, More) | ||
| end. | ||
| op_labels(Name, [A | _], Funs) when Name =:= make_fun2; Name =:= make_fun3 -> |
There was a problem hiding this comment.
A CodeRabbit review turned this up, which should be verified as accurate:
Include call_fun2 targets in the keep closure.
call_fun2 uses its first operand as a FunT index. trim/2 retains that row, but op_labels/3 does not retain its target label. If the target has no retained make_fun* instruction, rebuilding FunT can fail at maps:get(L, LM).
🐛 Suggested fix--- "a/src/packbeam_beam.erl"
+++ "b/src/packbeam_beam.erl"
@@ -124,7 +124,9 @@
Keep -> Keep;
More -> close_references(Fs, M, More)
end.
-op_labels(Name, [A | _], Funs) when Name =:= make_fun2; Name =:= make_fun3 ->
+op_labels(Name, [A | _], Funs) when
- Name =:= make_fun2; Name =:= make_fun3; Name =:= call_fun2
+->
{?COMPACT_LITERAL, I} = value(A),
[L || [_, _, L, _, _, ] <- [maps:get(I, Funs)]];
op_labels(, As, _) ->
| enc(T, V) when V < 2048 -> <<((V bsr 8) bsl 5 bor 8 bor T), (V band 255)>>; | ||
| enc(T, V) -> | ||
| B = binary:encode_unsigned(V), | ||
| N = byte_size(B), |
There was a problem hiding this comment.
This was another CodeRabbit suggestions that may or may not be accurate, I haven't spent enough time studying the internals of the beam compiler:
Preserve the sign byte when re-encoding large positive operands.
At V = 32768, binary:encode_unsigned/1 produces <<16#80, 0>>. This encoder writes those bytes without the leading zero used by the BEAM assembler for a positive compact operand. A pruned module with a relocated index or label at that boundary can therefore contain an invalid operand. Prefix a zero byte when the high bit is set.
| case maps:get(received, G) andalso lists:member({F, A}, ?SENDS) of | ||
| true -> 1 bsl (A - 1); | ||
| false -> 0 | ||
| end; |
There was a problem hiding this comment.
CodeRabbit also suggests:
Select the message operand by function, not by last position.
When a receive makes messages relevant, message_arg/2 selects the last argument for every function in ?SENDS. The message is argument 2 for erlang:send/3 and argument 3 for erlang:send_after/4 and erlang:start_timer/4; their last arguments are options. If a call’s result is unused, this pass can miss the message value that determines a later dynamic call target and prune that target. Select the documented message position for each function.
|
We also may want to broaden the test scope to cover any cases that would have failed before these requested changes to prevent any future regression. |
1f1f6a4 to
b211b79
Compare
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
b211b79 to
12d1cfe
Compare
Works better with atomvm/AtomVM#2404
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