| 2476 | } |
| 2477 | |
| 2478 | JEMALLOC_ALWAYS_INLINE int |
| 2479 | imalloc_body(static_opts_t *sopts, dynamic_opts_t *dopts, tsd_t *tsd) { |
| 2480 | /* Where the actual allocated memory will live. */ |
| 2481 | void *allocation = NULL; |
| 2482 | /* Filled in by compute_size_with_overflow below. */ |
| 2483 | size_t size = 0; |
| 2484 | /* |
| 2485 | * The zero initialization for ind is actually dead store, in that its |
| 2486 | * value is reset before any branch on its value is taken. Sometimes |
| 2487 | * though, it's convenient to pass it as arguments before this point. |
| 2488 | * To avoid undefined behavior then, we initialize it with dummy stores. |
| 2489 | */ |
| 2490 | szind_t ind = 0; |
| 2491 | /* usize will always be properly initialized. */ |
| 2492 | size_t usize; |
| 2493 | |
| 2494 | /* Reentrancy is only checked on slow path. */ |
| 2495 | int8_t reentrancy_level; |
| 2496 | |
| 2497 | /* Compute the amount of memory the user wants. */ |
| 2498 | if (unlikely(compute_size_with_overflow(sopts->may_overflow, dopts, |
| 2499 | &size))) { |
| 2500 | goto label_oom; |
| 2501 | } |
| 2502 | |
| 2503 | if (unlikely(dopts->alignment < sopts->min_alignment |
| 2504 | || (dopts->alignment & (dopts->alignment - 1)) != 0)) { |
| 2505 | goto label_invalid_alignment; |
| 2506 | } |
| 2507 | |
| 2508 | /* This is the beginning of the "core" algorithm. */ |
| 2509 | dopts->zero = zero_get(dopts->zero, sopts->slow); |
| 2510 | if (aligned_usize_get(size, dopts->alignment, &usize, &ind, |
| 2511 | sopts->bump_empty_aligned_alloc)) { |
| 2512 | goto label_oom; |
| 2513 | } |
| 2514 | dopts->usize = usize; |
| 2515 | /* Validate the user input. */ |
| 2516 | if (sopts->assert_nonempty_alloc) { |
| 2517 | assert (size != 0); |
| 2518 | } |
| 2519 | |
| 2520 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 2521 | |
| 2522 | /* |
| 2523 | * If we need to handle reentrancy, we can do it out of a |
| 2524 | * known-initialized arena (i.e. arena 0). |
| 2525 | */ |
| 2526 | reentrancy_level = tsd_reentrancy_level_get(tsd); |
| 2527 | if (sopts->slow && unlikely(reentrancy_level > 0)) { |
| 2528 | /* |
| 2529 | * We should never specify particular arenas or tcaches from |
| 2530 | * within our internal allocations. |
| 2531 | */ |
| 2532 | assert(dopts->tcache_ind == TCACHE_IND_AUTOMATIC || |
| 2533 | dopts->tcache_ind == TCACHE_IND_NONE); |
| 2534 | assert(dopts->arena_ind == ARENA_IND_AUTOMATIC); |
| 2535 | dopts->tcache_ind = TCACHE_IND_NONE; |
no test coverage detected