namespace; include rt; // allocation inside a compiled o3 region. on the x86-64 jit a constant-size // new(T) pops its size-class list inline and a leaf's free pushes it back // inline; anything the inline code can't serve (an empty list, a mismatch) // takes the ordinary rt.new_k / rt.recycle_leaf call. every line must print the // same with ZYNOFASTALLOC=1, under ZYO3INTERP=1 and on the other backends. struct point { int x, y; }; // 2 words: class 3 struct wide { int a, b, c, d, e, f, g, h, i, j; }; // 10 words: class 4, eleven zeroed words struct cell { cell* next; int v; }; // has a pointer field: not a leaf // a block freed at the end of a pass comes back on the next: the sums show the // payload was zeroed every time o3 int churn(int n) { int total = 0, i = 0; while (i < n) { point* p = rt.new(point); total = total + p.x + p.y; p.x = i; p.y = 7; i++; } return total; } o3 int churn_wide(int n) { int total = 0, i = 0; while (i < n) { wide* w = rt.new(wide); total = total + w.a + w.e + w.j; w.a = 1; w.e = 2; w.j = 3; i++; } return total; } // the second new gets the block the first one freed o3 int addr(point* p) { int a = 0; unchecked { a = p; } return a; } o3 int reuse() { int a = 0, b = 0, z = 0; { point* p = rt.new(point); a = addr(p); p.x = 41; p.y = 42; } { point* q = rt.new(point); b = addr(q); z = q.x + q.y; } if (a == b && z == 0) return 1; return 0; } // more blocks than the class list holds: the list runs empty and new falls back // to the general allocator, then the whole chain goes back o3 cell*.u build(int n) { cell* c = rt.new(cell); c.v = n; if (n > 0) c.next = build(n - 1); return u*c; } o3 int sum(cell* c) { if (!c.next) return c.v; return c.v + sum(c.next); } o3 int chain(int n) { cell* head = build(n); int s = sum(head); rt.free(d*head); return s; } // a header the free can't vouch for: n words of untyped new have no type stamp, // so this free is the general recycle, and a typed new after it still works o3 int mixed(int n) { int i = 0, s = 0; while (i < n) { point* p = rt.new(point); int* w = rt.new(2); p.x = i; w[0] = i; w[1] = 1; s = s + p.x - w[0] + w[1]; i++; } return s; } int main() { rt.put_n(churn(1000)); rt.put_c(' '); rt.put_n(churn_wide(1000)); rt.put_c(' '); rt.put_n(reuse()); rt.put_c(' '); rt.put_n(chain(5000)); rt.put_c(' '); rt.put_n(mixed(500)); rt.put_c(' '); rt.put_n(churn(1000) + reuse()); rt.put_c(10); return 0; }