昨天大概講一下什麼是 TCACHE 和他具體增加的結構和函數是什麼
那這邊為昨天先做個結尾就是
TCACHE 是一個優化機制,只要你 malloc()
和 free()
的大小符合 (fastbin, smallbin)
他就會改用 tcache_get()
和 tcache_put
,那我們這邊簡單看一下 source code:
/* Caller must ensure that we know tc_idx is valid and there's room
for more chunks. */
static void
tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
}
/* Caller must ensure that we know tc_idx is valid and there's
available chunks to remove. */
static void *
tcache_get (size_t tc_idx)
{
tcache_entry *e = tcache->entries[tc_idx];
assert (tc_idx entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
return (void *) e;
}
這兩個的程式碼大概意思就如昨天說的,其實就是 malloc
和 free
,但這邊可以看到註解
就是他有說,他並不會去檢查你丟進去的 tc_idx
,是否合法啦、有沒有問題等
所以簡單講就是他本身是不帶安全保護的。
然後這邊可以回來看 malloc()
和 free()
的程式碼
malloc() 呼叫時,裡面具體是呼叫 __libc_malloc
:
void *__libc_malloc (size_t bytes)
{
mstate ar_ptr;
void *victim;
#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 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);
return victim;
}
這邊可以看到他在一開始會先判斷可不可以使用 tcache ,可以的話就直接呼叫 tcache_get()
然後這邊就直接 return 而不會往下走了,而在以前沒有 tcache 的話
實際上會走到 _int_malloc()
裡面,然後那些安全機制基本也都是寫在這裡面
所以就變成如果使用 tcache ,那連舊有保護也沒再用了
free()
也是一樣的情況,這邊就不貼程式碼解釋了
總之,我們可以知道如果走 tcache ,他的保護會少超多(基本沒有)
所以我們現在要來看哪時會用到 tcache ,分兩個情況:
明天就講上面的兩個情況@@