-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Simplify GROWABLE_HEAP transform #24295
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
Simplify GROWABLE_HEAP transform #24295
Conversation
sbc100
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
d2c16fe to
767a4eb
Compare
This comment was marked as outdated.
This comment was marked as outdated.
02aa81c to
3f1ecd4
Compare
|
Converted to draft because I thought of some cases where this change can be problematic without further work, even though those cases are not yet covered by tests. SAFE_HEAP one should be still good to go. |
Converted to ready for review because turns out it's not a regression, the edge case I was thinking of (memory growth + ASAN/SAFE_HEAP) is already not working as expected and will be addressed separately in #24309. |
3f1ecd4 to
ede14eb
Compare
|
I want to do a bit more testing here just in case, so holding off merging for now. |
|
Yessss. After investigating #24309, I realised another issue with this refactoring, and I knew this should be failing in some cases, but couldn't make it break any tests. Turns out, it's tricky to trigger that edge case due to pthreads involved and due to Emscripten accessing the heap in a lot of functions (and, thus, updating it even before it's actually needed), but finally managed to craft a test that breaks after this transform. One of those rare feelings when things work but they really shouldn't 😅 I'll submit a new test either in this PR or separately. |
0534aec to
1e24d3c
Compare
|
Ok the tests look pretty different now because majority of Emscripten APIs that are implemented in JS touch HEAP in one way or another, and so even logging via I had to drop all the way down to @kripken @sbc100 I'm waiting for the CI to see if this uncovered anything else, but otherwise should be ready for another look. |
I don't understand why you can't use use the return value of
|
Arguments are evaluated before the function itself, which is what I was trying to demonstrate & catch with the updated tests. If you do let gotHeap = GROWABLE_HEAP(HEAP8);then it's equivalent to let gotHeap = (function GROWABLE_HEAP(arr) {
// inside GROWABLE_HEAP:
HEAP8 = new Uint8Array(...);
HEAP16 = ...;
...;
return arr;
})(HEAP8);which in turn is like let arr = HEAP8;
HEAP8 = new Uint8Array(...);
HEAP16 = ...;
...;
let gotHeap = arr; // the old value of HEAP8, not the one from assignment aboveMeanwhile, doing let gotHeap = (GROWABLE_HEAP(), HEAP8);is like HEAP8 = new Uint8Array(...);
HEAP16 = ...;
...;
let gotHeap = HEAP8;which is exactly what we want. |
|
I see. In that case perhaps we can rename |
Yeah, either is fine by me. I was thinking of |
I'll just do this, especially since this function is no longer exposed as runtime symbol and doesn't need to have the uppercase name. |
|
Yeah I guess there is no reason to do with all caps here. |
|
Since this symbol will appear a lot in unminified output is it worth picking a short-ish name? Maybe not? |
|
Eh, personally I'd prioritise debuggability over code size for unminified JS. |
|
FWIW I'll probably merge / rename those functions a bit more as part of fixing #24309 anyway. |
|
CI looks good and I feel more confident in this change now 🤞 |
1c450c2 to
54031be
Compare
|
FAIL [0.002s]: test_async_hello_v8 (test_core.instance) looks like a broken test on main branch. |
|
Trying to read the changes since my last review, I have a problem that I've seen in @sbc100 's PRs as well with force-pushes... how can I see only the last changes? The last "compare" button shows what appears to be a merge commit from main, and nothing else, and otherwise I see 13 force-pushed commits but I can't tell which are different from before and which (if any) are new compared to before. In general I think using normal merge commits, not force-pushes, avoids such problems. Is there another way to read the diff here? |
It looks like he did squash the commits so if you want to do an incremental review you could just look at the later commits. Obviously its not ideal because (a) you have to trust the earlier commits are not updated and (b) you need to keep track or remember which commit you last reviewed. But as somehow a very much a rebase workflow person, I'm hesitant to force folks into a merge workflow. |
|
Personally I always like to review the whole change each time, just to remind myself what its doing as a whole. |
|
Ok, thanks, last commit looks good. |
Similar to emscripten-core#24291, but for the transform handling `-pthread` + `-sALLOW_MEMORY_GROWTH`. In the first commit I added a codesize variation to commit current sizes, and in the second you can see that this transform actually saves the total size in addition to making acorn-optimizer simpler.
Memory views are automatically and lazily updated by the HEAPxx[...] transform, so this unconditional transform is not necessary.
54031be to
bdee9d8
Compare
While working on #24295, I noticed I could accidentally prevent ASan and SAFE_HEAP from finding any `HEAPxx[n]` accesses from JS when `ALLOW_MEMORY_GROWTH` is enabled, and no tests would catch it, because no tests verify that acorn-optimizer passes which change `HEAPxx[n]` into something else can work in conjunction with each other. After adding the test, I found that an existing `SUPPORT_BIG_ENDIAN` feature was already broken in the same way, because it transforms `HEAPxx[n]` accesses into DataView methods, and since it was running before ASan and SAFE_HEAP, those latter transforms became no-ops. I fixed that in the same PR by moving the big-endian transform to the end. In the future we might want to consolidate those transforms in a more reliable way (e.g. only run a single code transform that does `HEAPxx[n]` -> `__loadHeap`/`__storeHeap` where those functions do all the work using `#if`s), but at least for now this PR fixes an immediate problem and catches potential future regressions.
) While working on #24295, I noticed I could accidentally prevent ASan and SAFE_HEAP from finding any `HEAPxx[n]` accesses from JS when `ALLOW_MEMORY_GROWTH` is enabled, and no tests would catch it, because no tests verify that acorn-optimizer passes which change `HEAPxx[n]` into something else can work in conjunction with each other. After adding the test, I found that an existing `SUPPORT_BIG_ENDIAN` feature was already broken in the same way, because it transforms `HEAPxx[n]` accesses into DataView methods, and since it was running before ASan and SAFE_HEAP, those latter transforms became no-ops. I fixed that in the same PR by moving the big-endian transform to the end. In the future we might want to consolidate those transforms in a more reliable way (e.g. only run a single code transform that does `HEAPxx[n]` -> `__loadHeap`/`__storeHeap` where those functions do all the work using `#if`s), but at least for now this PR fixes an immediate problem and catches potential future regressions.
…cripten-core#24309) While working on emscripten-core#24295, I noticed I could accidentally prevent ASan and SAFE_HEAP from finding any `HEAPxx[n]` accesses from JS when `ALLOW_MEMORY_GROWTH` is enabled, and no tests would catch it, because no tests verify that acorn-optimizer passes which change `HEAPxx[n]` into something else can work in conjunction with each other. After adding the test, I found that an existing `SUPPORT_BIG_ENDIAN` feature was already broken in the same way, because it transforms `HEAPxx[n]` accesses into DataView methods, and since it was running before ASan and SAFE_HEAP, those latter transforms became no-ops. I fixed that in the same PR by moving the big-endian transform to the end. In the future we might want to consolidate those transforms in a more reliable way (e.g. only run a single code transform that does `HEAPxx[n]` -> `__loadHeap`/`__storeHeap` where those functions do all the work using `#if`s), but at least for now this PR fixes an immediate problem and catches potential future regressions.
This PR fixes issues with big endian support introduced in the following PRs: - #24295 - The change did not consider the `littleEndianHeap` transform implications, - #24283 - The new LE_HEAP* functions were not added to link.py, causing runtime failure on BE system. The `littleEndianHeap` transform code is simplified and updated to detect the code introduced by `growableHeap` pass. A new test was added to verify the combined transformation generates working code.
Similar to #24291, but for the transform handling
-pthread+-sALLOW_MEMORY_GROWTH.In the first commit I added a codesize variation to commit current sizes, and in the second you can see that this transform actually saves the total size in addition to making acorn-optimizer simpler.