// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- // // Check what's going on with the temp allocator: // Is it really the responsible for these paths? // It seems that the next beta (after 0.1.055b) compiler allows us to check this pretty easily. // // // An example that uses several different allocators, then asks them all // who owns which memory. // // Note that this is probably not the kind of thing you want to do at runtime // in the steady state, as it may not be very fast, but it could be a very helpful // debugging facility. // #import "Basic"; #import "Pool"; #import "Flat_Pool"; #import "rpmalloc"; main :: () { pool: Pool; flat: Flat_Pool; a := context.default_allocator; b := Allocator.{pool_allocator_proc, *pool}; c := Allocator.{flat_pool_allocator_proc, *flat}; d := Allocator.{rpmalloc_allocator_proc, null}; d.proc(.STARTUP, 0, 0, null, null); // rpmalloc needs explicit init right now, but others don't. ma := alloc(1000, allocator=a); mb := alloc(1000, allocator=b); mc := alloc(1000, allocator=c); md := alloc(1000, allocator=d); report_who_owns(ma, a, b, c, d); report_who_owns(mb, a, b, c, d); report_who_owns(mc, a, b, c, d); report_who_owns(md, a, b, c, d); } report_who_owns :: (memory: *void, allocators: .. Allocator) { someone_owns_this := false; print("Querying all allocators for address: %\n", memory); for allocators { caps, name := get_capabilities(it); assert((caps & .IS_THIS_YOURS) != 0); // It had better be claiming to support this! yours := cast(bool) it.proc(.IS_THIS_YOURS, 0, 0, memory, it.data); print("[%] says \"%\"\n", yours, name); someone_owns_this ||= yours; } assert(someone_owns_this); } // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- // checked_add :: (a: $T, b: T) -> result: T, overflow: bool #modify { if T.type == .INTEGER return; T = null; } { overflow: bool; result: T = a + b; info := type_info(T); if info.signed { // (+A) + (+B) = −C // (−A) + (−B) = +C if ((a > 0) && (b > 0) && (result < 0)) || ((a < 0) && (b < 0) && (result > 0)) { overflow = true; } } else { if result < a { overflow = true; } } return result, overflow; } checked_sub :: (a: $T, b: T) -> result: T, overflow: bool #modify { if T.type == .INTEGER return; T = null; } { overflow: bool; result: T = a - b; info := type_info(T); if info.signed { // (+A) − (−B) = −C // (−A) − (+B) = +C if ((a > 0) && (b < 0) && (result < 0)) || ((a < 0) && (b > 0) && (result > 0)) { overflow = true; } } else { if result > a { overflow = true; } } return result, overflow; }