Skip to content

ICE when compiling smallvec::SmallVecData<[f64; 4]>::heap_mut #61

Description

@LDemetrios

Hi!

So, as promised, I tried to feed your compiler a big project. And here's a panic:

thread '<unnamed>' panicked at src/lib.rs:1649:9:
failed to lower OOMIR shard canonical-types-9 to JVM bytecode: Function smallvec/SmallVecData_f64Array4::heap_mut: Failed to translate function: VerificationError { context: "Function heap_mut, block bb0, OOMIR instruction 5", message: "Failed to translate InvokeVirtual { dest: Some(\"_1_deref_object\"), class_name: \"org/rustlang/runtime/Pointer\", method_name: \"getObjectAs\", method_ty: Signature { params: [(\"self\", Pointer(Class(\"smallvec/SmallVecData_f64Array4\"))), (\"target_class\", Class(\"java/lang/String\"))], ret: Class(\"java/lang/Object\"), is_static: false }, args: [Constant(String(\"smallvec/SmallVecData_f64Array4\"))], operand: Variable { name: \"_1\", ty: Pointer(Class(\"smallvec/SmallVecData_f64Array4\")) } }: VerificationError { context: \"Function heap_mut\", message: \"could not load deferred pointer for operation getObjectAs\" }" }
stack backtrace:
   0:        0x1094ec0d8 - <std[c8fa24e64d9cf078]::backtrace::Backtrace>::create
   1:        0x1070b6bc4 - std[c8fa24e64d9cf078]::panicking::update_hook::<alloc[211306b2149fe892]::boxed::Box<rustc_driver_impl[6ce72ed364af5ef8]::install_ice_hook::{closure#1}>>::{closure#0}
   2:        0x109500418 - std[c8fa24e64d9cf078]::panicking::panic_with_hook
   3:        0x1094e07d4 - std[c8fa24e64d9cf078]::panicking::panic_handler::{closure#0}
   4:        0x1094d8d50 - std[c8fa24e64d9cf078]::sys::backtrace::__rust_end_short_backtrace::<std[c8fa24e64d9cf078]::panicking::panic_handler::{closure#0}, !>
   5:        0x1094e2040 - __rustc[897652c62be20a70]::rust_begin_unwind
   6:        0x1095e5c78 - core[f1ce509e42dc19ff]::panicking::panic_fmt
   7:        0x10c4d4c58 - rustc_codegen_jvm[d89b58a70c509517]::emit_oomir_shard::{closure#0}
   8:        0x10c3a6274 - rustc_codegen_jvm[d89b58a70c509517]::emit_oomir_shard
   9:        0x10c33a144 - std[c8fa24e64d9cf078]::sys::backtrace::__rust_begin_short_backtrace::<<rustc_codegen_jvm[d89b58a70c509517]::MyBackend as rustc_codegen_ssa[603e0dcf5e1902f0]::traits::backend::CodegenBackend>::codegen_crate::{closure#2}::{closure#0}, ()>
  10:        0x10c3c85b4 - <std[c8fa24e64d9cf078]::thread::lifecycle::spawn_unchecked<<rustc_codegen_jvm[d89b58a70c509517]::MyBackend as rustc_codegen_ssa[603e0dcf5e1902f0]::traits::backend::CodegenBackend>::codegen_crate::{closure#2}::{closure#0}, ()>::{closure#1} as core[f1ce509e42dc19ff]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  11:        0x10950adb0 - <std[c8fa24e64d9cf078]::sys::thread::unix::Thread>::new::thread_start
  12:        0x1860d3c08 - __pthread_cond_wait


rustc version: 1.100.0-nightly (1303417c4 2026-09-21)
platform: aarch64-apple-darwinthread 'rustc' panicked at src/lib.rs:1812:30:
OOMIR shard worker stopped without a result: RecvError
stack backtrace:
   0:        0x1094ec0d8 - <std[c8fa24e64d9cf078]::backtrace::Backtrace>::create
   1:        0x1070b6bc4 - std[c8fa24e64d9cf078]::panicking::update_hook::<alloc[211306b2149fe892]::boxed::Box<rustc_driver_impl[6ce72ed364af5ef8]::install_ice_hook::{closure#1}>>::{closure#0}
   2:        0x109500418 - std[c8fa24e64d9cf078]::panicking::panic_with_hook
   3:        0x1094e07d4 - std[c8fa24e64d9cf078]::panicking::panic_handler::{closure#0}
   4:        0x1094d8d50 - std[c8fa24e64d9cf078]::sys::backtrace::__rust_end_short_backtrace::<std[c8fa24e64d9cf078]::panicking::panic_handler::{closure#0}, !>
   5:        0x1094e2040 - __rustc[897652c62be20a70]::rust_begin_unwind
   6:        0x1095e5c78 - core[f1ce509e42dc19ff]::panicking::panic_fmt
   7:        0x1095e59c4 - core[f1ce509e42dc19ff]::result::unwrap_failed
   8:        0x10c283194 - std[c8fa24e64d9cf078]::thread::scoped::scope::<<rustc_codegen_jvm[d89b58a70c509517]::MyBackend as rustc_codegen_ssa[603e0dcf5e1902f0]::traits::backend::CodegenBackend>::codegen_crate::{closure#2}, alloc[211306b2149fe892]::vec::Vec<(alloc[211306b2149fe892]::string::String, std[c8fa24e64d9cf078]::path::PathBuf)>>
   9:        0x10c3bec30 - <rustc_codegen_jvm[d89b58a70c509517]::MyBackend as rustc_codegen_ssa[603e0dcf5e1902f0]::traits::backend::CodegenBackend>::codegen_crate
  10:        0x107a1e36c - <rustc_interface[a9842193f593845c]::queries::Linker>::codegen_and_build_linker
  11:        0x107048ee0 - rustc_interface[a9842193f593845c]::passes::create_and_enter_global_ctxt::<core[f1ce509e42dc19ff]::option::Option<rustc_interface[a9842193f593845c]::queries::Linker>, rustc_driver_impl[6ce72ed364af5ef8]::run_compiler::{closure#0}::{closure#1}>
  12:        0x1070b5560 - rustc_interface[a9842193f593845c]::interface::run_compiler::<(), rustc_driver_impl[6ce72ed364af5ef8]::run_compiler::{closure#0}>::{closure#2}
  13:        0x1070a6b58 - std[c8fa24e64d9cf078]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[a9842193f593845c]::util::run_in_thread_with_globals<rustc_interface[a9842193f593845c]::util::run_in_thread_pool_with_globals<rustc_interface[a9842193f593845c]::interface::run_compiler<(), rustc_driver_impl[6ce72ed364af5ef8]::run_compiler::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  14:        0x1070ba144 - <std[c8fa24e64d9cf078]::thread::lifecycle::spawn_unchecked<rustc_interface[a9842193f593845c]::util::run_in_thread_with_globals<rustc_interface[a9842193f593845c]::util::run_in_thread_pool_with_globals<rustc_interface[a9842193f593845c]::interface::run_compiler<(), rustc_driver_impl[6ce72ed364af5ef8]::run_compiler::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[f1ce509e42dc19ff]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  15:        0x10950adb0 - <std[c8fa24e64d9cf078]::sys::thread::unix::Thread>::new::thread_start
  16:        0x1860d3c08 - __pthread_cond_wait

query stack during panic:
end of query stack

I couldn't understand what really have happened there, as to my understanding the error message isn't really helpful. Additionally, I found out that parking lot itself compiles cleanly, so it's how it used is the issue.

If you need, I tried compiling https://github.com/LDemetrios/typst-shared-library/tree/shared-lib-v2 . I probably will end up later substituting parking lot dependencies with proper JVM synchronization, but that's gonna be when I understand your compiler better xD

Activity

  1. LDemetrios commented on Sep 22, 2026

    @LDemetrios
    Author

    It seems that some issues can be avoided by patching the code of dependencies. I hope I can get to the bottom of it some time, then I'll share what I changed so you can see what caused the issue

  2. LDemetrios commented on Sep 22, 2026

    @LDemetrios
    Author

    It also seems that later on icu_collator it just freezes

  3. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    Thank you for trying it out and for the report! I'm taking a look at that crash now, it just looks like a small bug that should be easy to fix. It's happening when compiling smallvec::SmallVecData<[f64; 4]>::heap_mut. I'll look at the freeze after.

  4. added
    A-lower2Involving the 2nd lowering pass (OOMIR -> JVM)
    I-ICEIssues causing an ICE in the codegen backend
    C-BugFunctionality that is claimed to be supported isn't working correctly in certain circumstances.
    S-In DevelopmentIssue with a contributor actively working on the needed development.
    on Sep 22, 2026
  5. changed the title [-]Crash compiling project with parking_lot_core[/-] [+]ICE when compiling `smallvec::SmallVecData<[f64; 4]>::heap_mut`[/+] on Sep 22, 2026
  6. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    MRE (can probably be a bit smaller still, but it's just what I'm working with right now)

    use std::mem::{ManuallyDrop, MaybeUninit};
    use std::ptr::NonNull;
    
    trait Array {
        type Item;
    }
    impl Array for [f64; 4] {
        type Item = f64;
    }
    
    union Data<A: Array> {
        inline: ManuallyDrop<MaybeUninit<A>>,
        heap: (NonNull<A::Item>, usize),
    }
    
    impl<A: Array> Data<A> {
        unsafe fn heap_mut(&mut self) -> (NonNull<A::Item>, &mut usize) {
            let heap = unsafe { &mut self.heap };
            (heap.0, &mut heap.1)
        }
    
        unsafe fn inline_mut(&mut self) -> NonNull<A::Item> {
            unsafe { NonNull::new_unchecked(self.inline.as_mut_ptr() as *mut A::Item) }
        }
    }
    
    pub fn run() {
        let mut data = Data::<[f64; 4]> {
            inline: ManuallyDrop::new(MaybeUninit::new([1.0, 2.0, 3.0, 4.0])),
        };
        unsafe {
            let pointer = data.inline_mut();
            assert_eq!(*pointer.as_ptr().add(2), 3.0);
        }
        let mut heap = [5.0, 6.0, 7.0, 8.0, 9.0];
        data = Data {
            heap: (NonNull::new(heap.as_mut_ptr()).unwrap(), heap.len()),
        };
        unsafe {
            let (pointer, len) = data.heap_mut();
            assert_eq!(pointer.as_ptr(), heap.as_mut_ptr());
            *len -= 1;
            pointer.as_ptr().add(4).write(99.0);
            assert_eq!(data.heap.1, 4);
            assert_eq!(heap[4], 99.0);
        }
    }
  7. LDemetrios commented on Sep 22, 2026

    @LDemetrios
    Author

    Thank you for trying it out and for the report! I'm taking a look at that crash now, it just looks like a small bug that should be easy to fix. It's happening when compiling smallvec::SmallVecData<[f64; 4]>::heap_mut. I'll look at the freeze after.

    I actually think I found the freeze. It's in oomir::Function, specifically constant tables, which results in 34GB footprint for icu_* crates before the compiler crashes with OOM on my machine

  8. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    I actually think I found the freeze. It's in oomir::Function, specifically constant tables, which results in 34GB footprint for icu_* crates before the compiler crashes with OOM on my machine

    Oh perfect, thank you! Can you try it with the experimental branch? I cleaned up a bunch of memory usage there. It's here: #57

  9. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    But I will still look into that memory issue and make a fix for mainline, because experimental isn't ready to be released yet.

  10. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    The crash issue was a tiny fix, I made a very silly mistake sorry! Pushed here, will wait for CI to go green before calling it fixed. Can you also try pulling the change and confirming it fixes it on your end too?

    2435278

  11. IntegralPilot commented on Sep 22, 2026

    @IntegralPilot
    Owner

    OK CI's passed and I'm going to bed now but I'll look into how to fix the freeze on main tomorrow.

  12. LDemetrios commented on Sep 22, 2026

    @LDemetrios
    Author

    Oh, good night!
    I've been fixing some issues with my local rust setup and only now was able to start a new compilation with memory improvements, still waiting. Thanks for your fast responses!
    Well, I've encountered several issues after working around this one, not sure if they are all related or different, I'll be testing that later as well. For now not doing anything crazy, just trying to compile xD.

  13. LDemetrios commented on Sep 22, 2026

    @LDemetrios
    Author

    Yeah it seems that memory explosion doesn't happen on that experimental branch!
    UPD: or not... I don't get how cargo sorts crates for compilation, I think I saw it had compiled once, but now I'm back to that freeze, LLM reports it stuck in

    rustc_codegen_jvm::java_exports::lower_public_library_exports
      -> lower_mono_function
      -> emit
      -> repeating oomir::constant::Constant::clone
    

    (I'm not that cool to analyze running programs myself)

  14. IntegralPilot commented on Sep 25, 2026

    @IntegralPilot
    Owner

    Thank you for trying it! Sorry for the delay, I was working on getting runtime speed in the experimental branch to something acceptable so I could merge it and stop working on 2 different versions. I've done that and merged it now.

    I have now also fixed the problem leading to that freeze in the experimental branch, which just got merged in.

    Can you please test again with the latest main? Thanks again for helping make it better! :)

  15. LDemetrios commented on Sep 27, 2026

    @LDemetrios
    Author

    Sorry for a delayed response, I've been digging through a bunch of errors related to jvm-unknown-jvm being, well, an unknown target: such crates as tar, stacker and dirs rely on system libraries and thus refuse to compile for jvm. Luckily, those aren't reaaally required for initial testing, so for now I mostly plugged them with no-ops and called it a day.

    The build now progressed to another failure, I link the report here. rustc-ice-2026-09-27T13_03_22-86270.txt To be clear, this is also a not-so-required dependency, and I might switch from wasmi to much more jvmish chicory runtime later, but I think you might wanna know about this anyway.

    If it's helpful for debugging or something, I've put my current progress into cargo-jvm-experiment branch.

    Thank you for your time!

  16. IntegralPilot commented on Sep 28, 2026

    @IntegralPilot
    Owner

    No worries, I spent longer replying to you! :)

    Thank you for linking that failure. There's no need to switch dependencies, it was just a silly mistake by me and I fixed that up in b0813e4

    Thank you also for linking the branch, I had some free time today so I've just been working the whole day on eliminating all the issues in the compiler that came up one by one (it was so useful for finding edge cases, they were all mostly just little oversights that needed small fixes!).

    I'm happy to say now that Typst on JVM is now working (though, for more complex documents, there might still be issues). I got it to generate this "Hello world!" image below, using your branch + latest main of this compiler.

    Can you try it and check it works for you (you may have to bump the JVM stack size)? If you also have any problems that come up with more complex documents that would be really helpful as well. :)

    As I think Typst is really useful because it covers so much in getting a document to compile, I also added compiling a hello world Typst document (using Typst compiled to JVM from that branch) to the regression suite on CI: bd1f78f

    Image
  17. LDemetrios commented on Sep 28, 2026

    @LDemetrios
    Author

    Thanks, that's really cool!

    Compilation for some reason produces two jars, typst-shared.jar and typst_shared.jar, almost the same size, not sure what's that about. Also, while debug version seems to work, release one fails with:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/rustlang/alloc/mono/Mono_619
            at typst_shared.typst_shared.main(main.rs)
    Caused by: java.lang.ClassNotFoundException: org.rustlang.alloc.mono.Mono_619
            at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)
            at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:502)
            ... 1 more
    

    Anyway, debug is enough for me to start adapting libraries and fuzzing, so, Skeletor will probably return later with more news xD

  18. IntegralPilot commented on Sep 28, 2026

    @IntegralPilot
    Owner

    Thanks, more testing would be really helpful, I appreciate it!

    The two jars are expected, it's because the project defines both a binary and a library. typst-shared.jar is the executable from src/main.rs and then typst_shared.jar is the library from src/lib.rs, a cdylib. Though maybe I should make that clearer in documentation somewhere.

    Thank you also for finding the release bug. I looked into it and it was just that we didn't handle ThinLTO properly and it only needed a small fix. I've fixed it now and added Typst release to CI, see dc27718

    I also managed to get some more complex ones working (and integrated into CI in both debug and release). It just needed fixing a couple more tiny bugs in the codegen, I've attached some of them below. I pushed it just before you left your comment!

    Image Image Image Image
  19. IntegralPilot commented on Sep 28, 2026

    @IntegralPilot
    Owner

    Also, sorry for how slow the compiled version currently is. I'm playing around with JFR to figure out where the bottlenecks are and how to make faster. I guess that's one of the very useful benefits of targeting JVM that there is such good tooling.

  20. LDemetrios commented on Sep 28, 2026

    @LDemetrios
    Author

    Seems like the error changed, but isn't gone

    $ java -jar target/jvm-unknown-jvm/release/typst-shared.jar
    Exception in thread "main" java.lang.NoSuchMethodError: 'typst_utils$crate154066864e868daa$.version_.TypstVersion typst_utils$crate154066864e868daa$.version_.version()'
            at typst_library.foundations.sys.module(Unknown Source)
            at typst_library.foundations.define$relative(Unknown Source)
            at typst_library.foundations.define(Unknown Source)
            at typst_library.typst_library.global$relative(Unknown Source)
            at typst_library.typst_library.global(Unknown Source)
            at typst_library.typst_library.build$9f914d43e8dc8749(Unknown Source)
            at typst_shared.world.library.stdlib.stdlib(Unknown Source)
            at typst_shared.typst_shared.main(main.rs)
    
  21. LDemetrios commented on Sep 28, 2026

    @LDemetrios
    Author

    Also, sorry for how slow the compiled version currently is. I'm playing around with JFR to figure out where the bottlenecks are and how to make faster. I guess that's one of the very useful benefits of targeting JVM that there is such good tooling.

    < The first version of my response was irrelevant due to my inability to read lol, so I'm editing it >

    Sure, some decline in efficiency is expected. I will profile something as well on my own, perhaps I'll return with suggestions. For now, my concern is that Typst uses a lot of EcoStrings, SmallVecs and other stuff that's very optimized for native targets, but requires bytewise shenanigans on jvm which probably are less efficient than just using native java stuff like arrays, lists and strings. And I will take a great pleasure in forking them and optimizing for jvm backend :)

  22. LDemetrios commented on Sep 28, 2026

    @LDemetrios
    Author
    Exception in thread "main" java.lang.NoSuchMethodError: 'typst_utils$crate154066864e868daa$.version_.TypstVersion typst_utils$crate154066864e868daa$.version_.version()'
    

    On second thought, just changing version to be:

    pub fn version() -> TypstVersion {
        *crate::singleton!(TypstVersion, {
            return TypstVersion {
                major: 0,
                minor: 14,
                patch: 2,
                raw: "0.14.2",
                commit: None,
            };
        })
    }
    

    seems to have solved the issue, which means the issue is in the fact it asks for env variables to be set during compilation

  23. LDemetrios commented on Sep 28, 2026

    @LDemetrios
    Author

    Regarding speed, I didn't see mentions of this in readme, but from my understanding of the compiler code, &T, when it's not &dyn Trait, is mapped just as pointer, into the Pointer wrapper. But why? From my point of view, the less we use raw Pointers, the better for the efficiency on the jvm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lower2Involving the 2nd lowering pass (OOMIR -> JVM)C-BugFunctionality that is claimed to be supported isn't working correctly in certain circumstances.I-ICEIssues causing an ICE in the codegen backendS-In DevelopmentIssue with a contributor actively working on the needed development.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions