分类: LINUX
2011-10-08 16:07:42
解释到这里基本完成了size
inline void* do_malloc_pages(ThreadCache* heap, size_t size) {
void* result;
bool report_large;
Length num_pages = tcmalloc::pages(size);
size = num_pages << kPageShift;
if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {
result = DoSampledAllocation(size);
SpinLockHolder h(Static::pageheap_lock());
report_large = should_report_large(num_pages);
} else {
SpinLockHolder h(Static::pageheap_lock());
Span* span = Static::pageheap()->New(num_pages);
result = (span == NULL ? NULL : SpanToMallocResult(span));
report_large = should_report_large(num_pages);
}
if (report_large) {
ReportLargeAlloc(num_pages, result);
}
return result;
}
在非sample的情况下,首先获取pageheap的lock,然后通过调用Static::pageheap()->New出num_pages的空间。
DoSampledAllocation函数比较简单,主要是通过GetStackTrace获取一个StackTrace然后调用Static::pageheap()->New来分配内存,只是在最后将分配出来的span加入sampled_objects中。
static void* DoSampledAllocation(size_t size) {
// Grab the stack trace outside the heap lock
StackTrace tmp;
tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);
tmp.size = size;
SpinLockHolder h(Static::pageheap_lock());
// Allocate span
Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));
if (span == NULL) {
return NULL;
}
// Allocate stack trace
StackTrace *stack = Static::stacktrace_allocator()->New();
if (stack == NULL) {
// Sampling failed because of lack of memory
return span;
}
*stack = tmp;
span->sample = 1;
span->objects = stack;
tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
return SpanToMallocResult(span);
}