1. We have async support but are still lacking some important parts (mainly interleaved GC) before complex, long-running performance benchmarks can be performed. I expect the performance to initially be relatively bad as we're missing important optimisations like shapes and inline caching.
2. The vector compacting is done so as to ensure that the heap allocated data does not fragment in memory. That being said, it's definitely possible that the heap vectors themselves slowly fragment to span disjoint memory areas instead of being all right next to each other. I don't think this will be a big problem though, as the vectors are still themselves densely packed.
I expect the heap design will definitely suffer some penalties in cases where old data is slowly trickling out from underneath a mass of newer but still live data: During a major GC in these circumstances, the majority of data gets copied to densely pack the vector again. That being said, this isn't too different from a half-space copying garbage collector, and I don't think those are particularly terrible.
I did consider a similar system ages ages ago for more easily embedding a JS engine into a C/C++ codebase, type-shapes would be allocated on a per page-basis so the runtime/GC wouldn't need any V-table pointers,etc on top of regular plain C object shapes to locate the type info but instead rely on an indirection per-page for those types shared with the C world. Ultimately felt a bit too complicated for something meant for embedding.
A tagged index gives you 7 bytes to use for payload: This for instance gives us the possibility of representing all but the most decimal heavy doubles on the stack (we drop the bottom byte from a double if it is all zeroes, and save the remaining data on the stack), but also allowing up to 7 byte strings on the stack! And all safe integers! And up to 56 bits worth of Bigints!
So, a tagged enum is pretty powerful :)
1) Performance in Real-World Scenarios: Have you benchmarked Nova against established engines like V8 or SpiderMonkey in scenarios involving complex, non-linear data access patterns? How does it perform under typical workloads like DOM manipulation or complex async operations?
2) Trade-offs in Garbage Collection: You mentioned the potential pitfalls with vector growth and compaction during GC. Could this design lead to significant memory fragmentation or performance bottlenecks in long-running applications? Are there scenarios where this approach shines or struggles compared to more traditional heap designs?
Looking forward to seeing how Nova evolves and the kind of applications it thrives in!