| 321 | } |
| 322 | |
| 323 | static void *slab_realloc(void *ptr, size_t new_size) { |
| 324 | if (!ptr) { |
| 325 | return slab_malloc(new_size); |
| 326 | } |
| 327 | if (new_size == 0) { |
| 328 | /* realloc(ptr, 0) = free + return NULL */ |
| 329 | slab_free(ptr); |
| 330 | return NULL; |
| 331 | } |
| 332 | |
| 333 | /* Case 1: ptr is in a slab page (≤64B block) */ |
| 334 | slab_page_t *page = slab_map_lookup((uintptr_t)ptr & SLAB_PAGE_MASK); |
| 335 | if (page) { |
| 336 | if (new_size <= SLAB_CHUNK_SIZE) { |
| 337 | /* Still fits in a slab chunk — reuse same slot */ |
| 338 | return ptr; |
| 339 | } |
| 340 | /* Promote slab → heap */ |
| 341 | void *new_ptr = malloc(new_size); |
| 342 | if (!new_ptr) { |
| 343 | return NULL; |
| 344 | } |
| 345 | memcpy(new_ptr, ptr, SLAB_CHUNK_SIZE); |
| 346 | slab_free(ptr); |
| 347 | return new_ptr; |
| 348 | } |
| 349 | |
| 350 | /* Case 2: heap pointer (from malloc) */ |
| 351 | return realloc(ptr, new_size); |
| 352 | } |
| 353 | |
| 354 | static void slab_free(void *ptr) { |
| 355 | if (!ptr) { |
no test coverage detected