-static struct Block_byref *_Block_byref_copy(const void *arg) {
- struct Block_byref *src = (struct Block_byref *)arg;
-
- if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {
- // src points to stack
- struct Block_byref *copy = (struct Block_byref *)malloc(src->size);
- copy->isa = NULL;
- // byref value 4 is logical refcount of 2: one for caller, one for stack
- copy->flags = src->flags | BLOCK_BYREF_NEEDS_FREE | 4;
- copy->forwarding = copy; // patch heap copy to point to itself
- src->forwarding = copy; // patch stack to point to heap copy
- copy->size = src->size;
-
- if (src->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
- // Trust copy helper to copy everything of interest
- // If more than one field shows up in a byref block this is wrong XXX
- struct Block_byref_2 *src2 = (struct Block_byref_2 *)(src+1);
- struct Block_byref_2 *copy2 = (struct Block_byref_2 *)(copy+1);
- copy2->byref_keep = src2->byref_keep;
- copy2->byref_destroy = src2->byref_destroy;
-
- if (src->flags & BLOCK_BYREF_LAYOUT_EXTENDED) {
- struct Block_byref_3 *src3 = (struct Block_byref_3 *)(src2+1);
- struct Block_byref_3 *copy3 = (struct Block_byref_3*)(copy2+1);
- copy3->layout = src3->layout;
- }
-
- (*src2->byref_keep)(copy, src);
- }
- else {
- // Bitwise copy.
- // This copy includes Block_byref_3, if any.
- memmove(copy+1, src+1, src->size - sizeof(*src));
- }
- }
- // already copied to heap
- else if ((src->forwarding->flags & BLOCK_BYREF_NEEDS_FREE) == BLOCK_BYREF_NEEDS_FREE) {
- latching_incr_int(&src->forwarding->flags);
- }
-
- return src->forwarding;
-}
-
-static void _Block_byref_release(const void *arg) {
- struct Block_byref *byref = (struct Block_byref *)arg;
-
- // dereference the forwarding pointer since the compiler isn't doing this anymore (ever?)
- byref = byref->forwarding;
-
- if (byref->flags & BLOCK_BYREF_NEEDS_FREE) {
- __assert_only int32_t refcount = byref->flags & BLOCK_REFCOUNT_MASK;
- os_assert(refcount);
- if (latching_decr_int_should_deallocate(&byref->flags)) {
- if (byref->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
- struct Block_byref_2 *byref2 = (struct Block_byref_2 *)(byref+1);
- (*byref2->byref_destroy)(byref);
- }
- free(byref);
- }
- }
+static struct Block_byref *
+_Block_byref_copy(const void *arg)
+{
+ struct Block_byref *src = (struct Block_byref *)arg;
+
+ if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {
+ // src points to stack
+ struct Block_byref *copy = (struct Block_byref *)malloc(src->size);
+ copy->isa = NULL;
+ // byref value 4 is logical refcount of 2: one for caller, one for stack
+ copy->flags = src->flags | BLOCK_BYREF_NEEDS_FREE | 4;
+ copy->forwarding = copy; // patch heap copy to point to itself
+ src->forwarding = copy; // patch stack to point to heap copy
+ copy->size = src->size;
+
+ if (src->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
+ // Trust copy helper to copy everything of interest
+ // If more than one field shows up in a byref block this is wrong XXX
+ struct Block_byref_2 *src2 = (struct Block_byref_2 *)(src + 1);
+ struct Block_byref_2 *copy2 = (struct Block_byref_2 *)(copy + 1);
+ copy2->byref_keep = src2->byref_keep;
+ copy2->byref_destroy = src2->byref_destroy;
+
+ if (src->flags & BLOCK_BYREF_LAYOUT_EXTENDED) {
+ struct Block_byref_3 *src3 = (struct Block_byref_3 *)(src2 + 1);
+ struct Block_byref_3 *copy3 = (struct Block_byref_3*)(copy2 + 1);
+ copy3->layout = src3->layout;
+ }
+
+ (*src2->byref_keep)(copy, src);
+ } else {
+ // Bitwise copy.
+ // This copy includes Block_byref_3, if any.
+ memmove(copy + 1, src + 1, src->size - sizeof(*src));
+ }
+ }
+ // already copied to heap
+ else if ((src->forwarding->flags & BLOCK_BYREF_NEEDS_FREE) == BLOCK_BYREF_NEEDS_FREE) {
+ latching_incr_int(&src->forwarding->flags);
+ }
+
+ return src->forwarding;
+}
+
+static void
+_Block_byref_release(const void *arg)
+{
+ struct Block_byref *byref = (struct Block_byref *)arg;
+
+ // dereference the forwarding pointer since the compiler isn't doing this anymore (ever?)
+ byref = byref->forwarding;
+
+ if (byref->flags & BLOCK_BYREF_NEEDS_FREE) {
+ __assert_only int32_t refcount = byref->flags & BLOCK_REFCOUNT_MASK;
+ os_assert(refcount);
+ if (latching_decr_int_should_deallocate(&byref->flags)) {
+ if (byref->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
+ struct Block_byref_2 *byref2 = (struct Block_byref_2 *)(byref + 1);
+ (*byref2->byref_destroy)(byref);
+ }
+ free(byref);
+ }
+ }