static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap) { union { Uint *up; ProcBin *pbp; ErlFunThing *efp; ExternalThing *etp; } ohe; Eterm* ptr = src; Eterm* end = ptr + src_sz; Eterm dummy_ref; Eterm* hp = *hpp; while (ptr != end) { Eterm val; ASSERT(ptr < end); val = *ptr; ASSERT(val != ERTS_HOLE_MARKER); if (is_header(val)) { ASSERT(ptr + header_arity(val) < end); ohe.up = hp; MOVE_BOXED(ptr, val, hp, &dummy_ref); switch (val & _HEADER_SUBTAG_MASK) { case REFC_BINARY_SUBTAG: ohe.pbp->next = off_heap->mso; off_heap->mso = ohe.pbp; break; case FUN_SUBTAG: ohe.efp->next = off_heap->funs; off_heap->funs = ohe.efp; break; case EXTERNAL_PID_SUBTAG: case EXTERNAL_PORT_SUBTAG: case EXTERNAL_REF_SUBTAG: ohe.etp->next = off_heap->externals; off_heap->externals = ohe.etp; break; } } else { /* must be a cons cell */ ASSERT(ptr+1 < end); MOVE_CONS(ptr, val, hp, &dummy_ref); ptr += 2; } } *hpp = hp; }
static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap) { Eterm* ptr = src; Eterm* end = ptr + src_sz; Eterm dummy_ref; Eterm* hp = *hpp; while (ptr != end) { Eterm val; ASSERT(ptr < end); val = *ptr; ASSERT(val != ERTS_HOLE_MARKER); if (is_header(val)) { struct erl_off_heap_header* hdr = (struct erl_off_heap_header*)hp; ASSERT(ptr + header_arity(val) < end); MOVE_BOXED(ptr, val, hp, &dummy_ref); switch (val & _HEADER_SUBTAG_MASK) { case REFC_BINARY_SUBTAG: case FUN_SUBTAG: case EXTERNAL_PID_SUBTAG: case EXTERNAL_PORT_SUBTAG: case EXTERNAL_REF_SUBTAG: hdr->next = off_heap->first; off_heap->first = hdr; break; } } else { /* must be a cons cell */ ASSERT(ptr+1 < end); MOVE_CONS(ptr, val, hp, &dummy_ref); ptr += 2; } } *hpp = hp; }