从零开始看WebKit源码——bmalloc[1]

最近有些空,准备看看浏览器相关的源码,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 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值