전체 코드는 아래 더보기
더보기
void *
__libc_malloc (size_t bytes)
{
mstate ar_ptr;
void *victim;
void *(*hook) (size_t, const void *)
= atomic_forced_read (__malloc_hook);
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes = request2size (bytes);
size_t tc_idx = csize2tidx (tbytes);
MAYBE_INIT_TCACHE ();
DIAG_PUSH_NEEDS_COMMENT;
if (tc_idx < mp_.tcache_bins
/*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */
&& tcache
&& tcache->entries[tc_idx] != NULL)
{
return tcache_get (tc_idx);
}
DIAG_POP_NEEDS_COMMENT;
#endif
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
/* Retry with another arena only if we were able to find a usable arena
before. */
if (!victim && ar_ptr != NULL)
{
LIBC_PROBE (memory_malloc_retry, 1, bytes);
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
__libc_lock_unlock (ar_ptr->mutex);
assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
ar_ptr == arena_for_chunk (mem2chunk (victim)));
return victim;
}
libc_hidden_def (__libc_malloc)
glibc 2.23에서는 없었던 tcache에 관련한 코드만을 주로 정리한다 (malloc 할당 과정은 (glibc 2.23) _int_malloc 글 참고)
tcache와 관련된 코드를 제외하곤 glibc 2.23과 동일하다
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes = request2size (bytes);
size_t tc_idx = csize2tidx (tbytes);
MAYBE_INIT_TCACHE ();
DIAG_PUSH_NEEDS_COMMENT;
if (tc_idx < mp_.tcache_bins
/*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */
&& tcache
&& tcache->entries[tc_idx] != NULL)
{
return tcache_get (tc_idx);
}
DIAG_POP_NEEDS_COMMENT;
#endif
glibc 2.23에서는 없어던 tcache관련 처리 코드가 hook과 arena_get함수 사이에 추가되었다
tcache로 재할당이 가능하면 재할당해주는 코드이다
변수 선언
tcache_init을 호출하기 전에 변수 초기화해준다 (초기화 되는 변수를 아래와 같음)
- tbytes : request2size(bytes)의 반환 값을 저장 (가공된 할당 받을 크기 )
- tc_idx : tbytes의 인덱스를 구해 저장
tcache_init
#define MAYBE_INIT_TCACHE() \
if (__glibc_unlikely (tcache == NULL)) \
tcache_init();
변수 초기화 이후에 tcache가 NULL이면 tcache_init을 호출한다
tcache_init에서는 tcache_perthread_struct 크기의 힙을 할당 받는다
tcache_get
DIAG_PUSH_NEEDS_COMMENT;
if (tc_idx < mp_.tcache_bins
/*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */
&& tcache
&& tcache->entries[tc_idx] != NULL)
{
return tcache_get (tc_idx);
}
DIAG_POP_NEEDS_COMMENT;
- 할당 받을 크기가 tcache 범위내에 존재하는지
- tcache_perthread_struct가 할당되어있는지
- 할당 받을 크기의 freed chunk가 cache에 있는지
위의 검사를 한 뒤 tcache_get함수를 호출한다
tcache_get함수에서는 tcache에서 재할당알 청크를 반환한다 (tcache_get 링크글)
이후에 glibc 2.23과 동일하다
'Heap analysis > glibc 2.26' 카테고리의 다른 글
(glibc 2.26) _int_free (0) | 2022.05.02 |
---|---|
(glibc 2.26) _int_malloc (0) | 2022.05.01 |
(glibc 2.26) tcache_put (0) | 2022.05.01 |
(glibc 2.26) tcache_get (0) | 2022.05.01 |
(glibc 2.26) tcache_init (0) | 2022.05.01 |