diff --git a/src/runtime/object.cpp b/src/runtime/object.cpp index 813bfef549..97794a7f09 100644 --- a/src/runtime/object.cpp +++ b/src/runtime/object.cpp @@ -293,11 +293,10 @@ static inline lean_object * get_next(lean_object * o) { static inline void set_next(lean_object * o, lean_object * n) { if (sizeof(void*) == 8) { - size_t new_header = (size_t)n; - LEAN_BYTE(new_header, 7) = o->m_tag; - LEAN_BYTE(new_header, 6) = o->m_other; - ((size_t*)o)[0] = new_header; - lean_assert(get_next(o) == n); + uint16_t hi; + memcpy(&hi, (char*)o + 6, 2); + size_t header = ((size_t)hi << 48) | (size_t)n; + memcpy(o, &header, 8); } else { // 32-bit version ((lean_object**)o)[0] = n; @@ -361,61 +360,65 @@ extern "C" LEAN_EXPORT lean_object * lean_alloc_object(size_t sz) { static void deactivate_task(lean_task_object * t); static void deactivate_promise(lean_promise_object * t); +static void lean_del_core_other(object * o, uint8 tag, object * & todo) { + switch (tag) { + case LeanClosure: { + object ** it = lean_closure_arg_cptr(o); + object ** end = it + lean_closure_num_fixed(o); + for (; it != end; ++it) dec(*it, todo); + lean_dealloc(o, lean_closure_byte_size(o)); + break; + } + case LeanArray: { + object ** it = lean_array_cptr(o); + object ** end = it + lean_array_size(o); + for (; it != end; ++it) dec(*it, todo); + lean_dealloc(o, lean_array_byte_size(o)); + break; + } + case LeanScalarArray: + lean_dealloc(o, lean_sarray_byte_size(o)); + break; + case LeanString: + lean_dealloc(o, lean_string_byte_size(o)); + break; + case LeanMPZ: + to_mpz(o)->m_value.~mpz(); + lean_free_small_object(o); + break; + case LeanThunk: + if (object * c = lean_to_thunk(o)->m_closure) dec(c, todo); + if (object * v = lean_to_thunk(o)->m_value) dec(v, todo); + lean_free_small_object(o); + break; + case LeanRef: + if (object * v = lean_to_ref(o)->m_value) dec(v, todo); + lean_free_small_object(o); + break; + case LeanTask: + deactivate_task(lean_to_task(o)); + break; + case LeanPromise: + deactivate_promise(lean_to_promise(o)); + break; + case LeanExternal: + lean_to_external(o)->m_class->m_finalize(lean_to_external(o)->m_data); + lean_free_small_object(o); + break; + default: + lean_unreachable(); + } +} + static void lean_del_core(object * o, object * & todo) { uint8 tag = lean_ptr_tag(o); - if (tag <= LeanMaxCtorTag) { + if (LEAN_LIKELY(tag <= LeanMaxCtorTag)) { object ** it = lean_ctor_obj_cptr(o); object ** end = it + lean_ctor_num_objs(o); for (; it != end; ++it) dec(*it, todo); lean_free_small_object(o); } else { - switch (tag) { - case LeanClosure: { - object ** it = lean_closure_arg_cptr(o); - object ** end = it + lean_closure_num_fixed(o); - for (; it != end; ++it) dec(*it, todo); - lean_dealloc(o, lean_closure_byte_size(o)); - break; - } - case LeanArray: { - object ** it = lean_array_cptr(o); - object ** end = it + lean_array_size(o); - for (; it != end; ++it) dec(*it, todo); - lean_dealloc(o, lean_array_byte_size(o)); - break; - } - case LeanScalarArray: - lean_dealloc(o, lean_sarray_byte_size(o)); - break; - case LeanString: - lean_dealloc(o, lean_string_byte_size(o)); - break; - case LeanMPZ: - to_mpz(o)->m_value.~mpz(); - lean_free_small_object(o); - break; - case LeanThunk: - if (object * c = lean_to_thunk(o)->m_closure) dec(c, todo); - if (object * v = lean_to_thunk(o)->m_value) dec(v, todo); - lean_free_small_object(o); - break; - case LeanRef: - if (object * v = lean_to_ref(o)->m_value) dec(v, todo); - lean_free_small_object(o); - break; - case LeanTask: - deactivate_task(lean_to_task(o)); - break; - case LeanPromise: - deactivate_promise(lean_to_promise(o)); - break; - case LeanExternal: - lean_to_external(o)->m_class->m_finalize(lean_to_external(o)->m_data); - lean_free_small_object(o); - break; - default: - lean_unreachable(); - } + lean_del_core_other(o, tag, todo); } }