最近有些空,准备看看浏览器相关的源码,chromium以前看了一部分,这次准备看看WebKit的一些代码,并码点字记录一下梳理的过程。
首先先从bmalloc开始,相关文件在Source/bmalloc/bmalloc下,我们从bmalloc.h文件开始。
// Returns null on failure.
BINLINE void* tryMalloc(size_t size, HeapKind kind = HeapKind::Primary)
{
#if BUSE(LIBPAS)
if (!isGigacage(kind))
return bmalloc_try_allocate_inline(size);
return bmalloc_try_allocate_auxiliary_inline(&heapForKind(gigacageKind(kind)), size);
#else
return Cache::tryAllocate(kind, size);
#endif
}
首先是tryMalloc函数,这个函数接受两个参数size和kind,size是申请空间的大小,kind是enum class HeapKind的其中一个:
enum class HeapKind {
Primary,
PrimitiveGigacage,
JSValueGigacage
};
我们先关注Cache::tryAllocate(kind, size),相关文件在Cache.h和Cache.cpp中。
inline void* Cache::tryAllocate(HeapKind heapKind, size_t size)
{
PerHeapKind<Cache>* caches = PerThread<PerHeapKind<Cache>>::getFastCase();
if (!caches)
return tryAllocateSlowCaseNullCache(heapKind, size);
return caches->at(mapToActiveHeapKindAfterEnsuringGigacage(heapKind)).allocator().tryAllocate(size);
}
template<typename T>
BINLINE T* PerThread<T>::getFastCase()
{
return static_cast<T*>(PerThreadStorage<T>::get());
}
首先会调用getFastCase来判断当前是否已经创建了相关的空间,getFastCase函数会调用PerThreadStorage的static函数get
template<typename T> struct PerThreadStorage {
static bool s_didInitialize;
static pthread_key_t s_key;
static std::once_flag s_onceFlag;
static void* get()
{
if (!s_didInitialize)
return nullptr;
return pthread_getspecific(s_key);
}
static void init(void* object, void (*destructor)(void*))
{
std::call_once(s_onceFlag, [destructor]() {
int error = pthread_key_create(&s_key, destructor);
if (error)
BCRASH();
s_didInitialize = true;
});
pthread_setspecific(s_key, object);
}
};
初始状态下s_didInitialize是false,当调用init函数进行初始化并成功创建pthread_key后,s_didInitialize会被置为true。
pthread_key_create函数位于pthread.h文件中,其介绍如下。
简单的说,pthread_key_create用于生成一个key,这个key可以绑定一个thread specific的object(通过pthread_setspecific()函数),并通过pthread_getspecific进行object获取。
当get函数返回nullptr后,Cache::tryAllocate中会调用tryAllocateSlowCaseNullCache函数。
BNO_INLINE void* Cache::tryAllocateSlowCaseNullCache(HeapKind heapKind, size_t size)
{
if (auto* debugHeap = DebugHeap::tryGet())
return debugHeap->malloc(size, FailureAction::ReturnNull);
return PerThread<PerHeapKind<Cache>>::getSlowCase()->at(mapToActiveHeapKind(heapKind)).allocator().tryAllocate(size);
}
DebugHeap* debugHeapCache {
nullptr };
BINLINE DebugHeap* DebugHeap::tryGet()
{
DebugHeap* result = debugHeapCache;
if (result == debugHeapDisabled())
return nullptr;
if (result)
return result;
return tryGetSlow();
}
BINLINE DebugHeap* debugHeapDisabled()
{
return reinterpret_cast<DebugHeap*>(static_cast<uintptr_t>(1));
}
初始时debugHeapCache是nullptr,因此将调用tryGetSlow函数进行debugHeapCache的赋值。
DebugHeap* DebugHeap::tryGetSlow()
{
DebugHeap* result;
if (Environment::get()->isDebugHeapEnabled()) {
debugHeapCache = DebugHeap::get();
result = debugHeapCache;
} else {
debugHeapCache = debugHeapDisabled();
result = nullptr;
}
RELEASE_BASSERT(debugHeapCache);
return result;
}
class Environment