- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 676
Generalize runtime #1503
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
Generalize runtime #1503
Conversation
| New MM header New GC (full object) header  | 
| @willemneal can we check to see if this breaks aspect? | 
| Also, have me a chuckle. "minor changes." This looks like a really big deal. Thanks for the work. | 
| Speaking of breaking changes, this would be the beginning of multiple breaking changes in a row. This one breaks anything depending on memory layout or runtime APIs already (very likely also aspect), and replacing ARC with ITCM will remove  | 
| Regarding breaking changes. Just wondering why __alloc / __realloc changed to __new / __renew? | 
| These do different things now. For instance,  | 
| I see. It's just question about naming. What about use  | 
| We can add wrappers (or forwarding builtins) for  | 
| Could also be a builtin module maybe: // std/malloc.ts
export { __alloc as malloc, __realloc as realloc, __free as free };// assembly/index.ts
import { malloc, realloc, free } from "malloc"; | 
| I like convensions with  // gc stuffs
gc.alloc, gc.realloc, gc.collect
// memory stuffs
mm.alloc, mm.realloc, mm.free, mm.reset
// other memory utils
mm.fill, mm.copy, mm.repeat, mm.compare
// intrinsics (for compatibility with wasm)
memory.fill, memory.copy, memory.init etc | 
| What if we'd just rename 
 and make these available globally, but mark them  Other than that I think it's fine to hide the GC details (except  | 
| Also good variant. In this case it will be: // gc stuffs
gc.alloc, gc.realloc
// /memory stuffs
alloc, realloc, free, reset
// intrinsics
memory.fill, memory.copy, memory.initanother alternative use "heap" namespace: heap.alloc, heap.realloc, heap.free, heap.resetI think in any case better use "alloc" instead "malloc" | 
| I like the  | 
| also great advantage of "heap" namespace we could put into it  | 
| First, I really like these changes. Would it be possible to be tagged on these sorts of changes more pre-emptively? | 
| Looking at this more, it becomes apparent that we'll need some sort of shadow stack after all, albeit only for managed objects. A tracing GC will run incrementally with the program and needs to know what's currently on the stack so it doesn't prematurely free what the current function, for instance calling  function doSomethingManaged(): void {
  var S = __stacksave(8);
  S[-1] = __new(123);
  S[-2] = __new(234);
  gc.collect(); // must not free 123 and 234
  __stackrestore(S);
}So far it looks like the compiler will be able to tell statically how much stack space to reserve, and only needs to insert  | 
| One way to model a shadow stack like this could be: 
 Inside loops, the same stack slot is taken by the same allocation or function return within the loop, effectively keeping everything explicitly or implicitly kept alive by the function alive while the function is. Overhead is the memory for maintaining a stack, potentially with a well-predicted check that the stack isn't overflown, stores to the stack slots, and traversing the stack in addition to other roots when marking/sweeping. Overall doesn't look so bad. A typical function using managed objects might end up with say 10 stack slots for example, ~40 bytes stack space, and a solid maximum stack size might be one page (65536 bytes, ~1638 depth). | 
| Alternative: Only do GC work when the Wasm execution stack is fully unwound, i.e. when returning from a directly called export. // index.ts
var _depth = 0;
var _collect_called = false;
export function someExport(): void {
  ++_depth;
  // code of someExport
  if (!--_depth) {
    if (_collect_called) doFullGc();
    else doSomeGc();
  }
}Does not require a shadow stack, but also isn't as granularly incremental anymore. Much easier to implement however, at hardly any runtime cost. @MaxGraey Wdyt? | 
| It seems it will be most of time is fully collected (stop the world mode). Not sure we need incremental collector in this case at all. I think we should investigate our efforts to approximated liveness-assisted GC but it required finish our IR first | 
| Nothing of this is optimal, I agree, and it seems that the best we can do is to make a forward decision, ideally with Wasm GC in mind, so we are not blocked on this forever. Would everyone be OK with me making that decision and taking the blame for it, so that we can otherwise go on? | 
| Going to merge this patch even without tracing along #1513, combining multiple breaking changes into one version, likely 0.17. | 
| Okay. It looks like this will be affecting as-pect user installs. Will have to work on this soon. Thanks for the changes! | 
Minor changes.
__alloc,__reallocand__freenow essentially beingmalloc,reallocandfreein C__allocdoes not take anidargument anymore__allocfor GC objects is now__new(withidargument)__reallocfor GC objects is now__renew__reallocand__freeare now exposed by the full/stub runtimes__allocArrayis now__newArray__allocBufferis now__newBuffer__allocStringis now__newStringgc.autohas been removed due to unforeseen consequences with the execution stackheapnamespace providingalloc,realloc,freeandreset(stub only)