⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastmalloc.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Copyright (c) 2005, 2007, Google Inc.// All rights reserved.// Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.// // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:// //     * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.//     * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// ---// Author: Sanjay Ghemawat <opensource@google.com>//// A malloc that uses a per-thread cache to satisfy small malloc requests.// (The time for malloc/free of a small object drops from 300 ns to 50 ns.)//// See doc/tcmalloc.html for a high-level// description of how this malloc works.//// SYNCHRONIZATION//  1. The thread-specific lists are accessed without acquiring any locks.//     This is safe because each such list is only accessed by one thread.//  2. We have a lock per central free-list, and hold it while manipulating//     the central free list for a particular size.//  3. The central page allocator is protected by "pageheap_lock".//  4. The pagemap (which maps from page-number to descriptor),//     can be read without holding any locks, and written while holding//     the "pageheap_lock".//  5. To improve performance, a subset of the information one can get//     from the pagemap is cached in a data structure, pagemap_cache_,//     that atomically reads and writes its entries.  This cache can be//     read and written without locking.////     This multi-threaded access to the pagemap is safe for fairly//     subtle reasons.  We basically assume that when an object X is//     allocated by thread A and deallocated by thread B, there must//     have been appropriate synchronization in the handoff of object//     X from thread A to thread B.  The same logic applies to pagemap_cache_.//// THE PAGEID-TO-SIZECLASS CACHE// Hot PageID-to-sizeclass mappings are held by pagemap_cache_.  If this cache// returns 0 for a particular PageID then that means "no information," not that// the sizeclass is 0.  The cache may have stale information for pages that do// not hold the beginning of any free()'able object.  Staleness is eliminated// in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and// do_memalign() for all other relevant pages.//// TODO: Bias reclamation to larger addresses// TODO: implement mallinfo/mallopt// TODO: Better testing//// 9/28/2003 (new page-level allocator replaces ptmalloc2):// * malloc/free of small objects goes from ~300 ns to ~50 ns.// * allocation of a reasonably complicated struct//   goes from about 1100 ns to about 300 ns.#include "config.h"#include "FastMalloc.h"#include "Assertions.h"#if ENABLE(JSC_MULTIPLE_THREADS)#include <pthread.h>#endif#ifndef NO_TCMALLOC_SAMPLES#ifdef WTF_CHANGES#define NO_TCMALLOC_SAMPLES#endif#endif#if !defined(USE_SYSTEM_MALLOC) && defined(NDEBUG)#define FORCE_SYSTEM_MALLOC 0#else#define FORCE_SYSTEM_MALLOC 1#endif#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC))#ifndef NDEBUGnamespace WTF {#if ENABLE(JSC_MULTIPLE_THREADS)static pthread_key_t isForbiddenKey;static pthread_once_t isForbiddenKeyOnce = PTHREAD_ONCE_INIT;static void initializeIsForbiddenKey(){  pthread_key_create(&isForbiddenKey, 0);}static bool isForbidden(){    pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey);    return !!pthread_getspecific(isForbiddenKey);}void fastMallocForbid(){    pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey);    pthread_setspecific(isForbiddenKey, &isForbiddenKey);}void fastMallocAllow(){    pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey);    pthread_setspecific(isForbiddenKey, 0);}#elsestatic bool staticIsForbidden;static bool isForbidden(){    return staticIsForbidden;}void fastMallocForbid(){    staticIsForbidden = true;}void fastMallocAllow(){    staticIsForbidden = false;}#endif // ENABLE(JSC_MULTIPLE_THREADS)} // namespace WTF#endif // NDEBUG#include <string.h>namespace WTF {void* fastZeroedMalloc(size_t n) {    void* result = fastMalloc(n);    memset(result, 0, n);    return result;}    void* tryFastZeroedMalloc(size_t n) {    void* result = tryFastMalloc(n);    if (!result)        return 0;    memset(result, 0, n);    return result;}} // namespace WTF#if FORCE_SYSTEM_MALLOC#include <stdlib.h>#if !PLATFORM(WIN_OS)    #include <pthread.h>#else    #include "windows.h"#endifnamespace WTF {void* tryFastMalloc(size_t n) {    ASSERT(!isForbidden());    return malloc(n);}void* fastMalloc(size_t n) {    ASSERT(!isForbidden());    void* result = malloc(n);    if (!result)        CRASH();    return result;}void* tryFastCalloc(size_t n_elements, size_t element_size){    ASSERT(!isForbidden());    return calloc(n_elements, element_size);}void* fastCalloc(size_t n_elements, size_t element_size){    ASSERT(!isForbidden());    void* result = calloc(n_elements, element_size);    if (!result)        CRASH();    return result;}void fastFree(void* p){    ASSERT(!isForbidden());    free(p);}void* tryFastRealloc(void* p, size_t n){    ASSERT(!isForbidden());    return realloc(p, n);}void* fastRealloc(void* p, size_t n){    ASSERT(!isForbidden());    void* result = realloc(p, n);    if (!result)        CRASH();    return result;}void releaseFastMallocFreeMemory() { }    FastMallocStatistics fastMallocStatistics(){    FastMallocStatistics statistics = { 0, 0, 0, 0 };    return statistics;}} // namespace WTF#if PLATFORM(DARWIN)// This symbol is present in the JavaScriptCore exports file even when FastMalloc is disabled.// It will never be used in this case, so it's type and value are less interesting than its presence.extern "C" const int jscore_fastmalloc_introspection = 0;#endif#else // FORCE_SYSTEM_MALLOC#if HAVE(STDINT_H)#include <stdint.h>#elif HAVE(INTTYPES_H)#include <inttypes.h>#else#include <sys/types.h>#endif#include "AlwaysInline.h"#include "Assertions.h"#include "TCPackedCache.h"#include "TCPageMap.h"#include "TCSpinLock.h"#include "TCSystemAlloc.h"#include <algorithm>#include <errno.h>#include <new>#include <pthread.h>#include <stdarg.h>#include <stddef.h>#include <stdio.h>#if COMPILER(MSVC)#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN#endif#include <windows.h>#endif#if WTF_CHANGES#if PLATFORM(DARWIN)#include "MallocZoneSupport.h"#include <wtf/HashSet.h>#endif#ifndef PRIuS#define PRIuS "zu"#endif// Calling pthread_getspecific through a global function pointer is faster than a normal// call to the function on Mac OS X, and it's used in performance-critical code. So we// use a function pointer. But that's not necessarily faster on other platforms, and we had// problems with this technique on Windows, so we'll do this only on Mac OS X.#if PLATFORM(DARWIN)static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific;#define pthread_getspecific(key) pthread_getspecific_function_pointer(key)#endif#define DEFINE_VARIABLE(type, name, value, meaning) \  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \  type FLAGS_##name(value);                                \  char FLAGS_no##name;                                                        \  }                                                                           \  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name  #define DEFINE_int64(name, value, meaning) \  DEFINE_VARIABLE(int64_t, name, value, meaning)  #define DEFINE_double(name, value, meaning) \  DEFINE_VARIABLE(double, name, value, meaning)namespace WTF {#define malloc fastMalloc#define calloc fastCalloc#define free fastFree#define realloc fastRealloc#define MESSAGE LOG_ERROR#define CHECK_CONDITION ASSERT#if PLATFORM(DARWIN)class Span;class TCMalloc_Central_FreeListPadded;class TCMalloc_PageHeap;class TCMalloc_ThreadCache;template <typename T> class PageHeapAllocator;class FastMallocZone {public:    static void init();    static kern_return_t enumerate(task_t, void*, unsigned typeMmask, vm_address_t zoneAddress, memory_reader_t, vm_range_recorder_t);    static size_t goodSize(malloc_zone_t*, size_t size) { return size; }    static boolean_t check(malloc_zone_t*) { return true; }    static void  print(malloc_zone_t*, boolean_t) { }    static void log(malloc_zone_t*, void*) { }    static void forceLock(malloc_zone_t*) { }    static void forceUnlock(malloc_zone_t*) { }    static void statistics(malloc_zone_t*, malloc_statistics_t* stats) { memset(stats, 0, sizeof(malloc_statistics_t)); }private:    FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*, PageHeapAllocator<Span>*, PageHeapAllocator<TCMalloc_ThreadCache>*);    static size_t size(malloc_zone_t*, const void*);    static void* zoneMalloc(malloc_zone_t*, size_t);    static void* zoneCalloc(malloc_zone_t*, size_t numItems, size_t size);    static void zoneFree(malloc_zone_t*, void*);    static void* zoneRealloc(malloc_zone_t*, void*, size_t);    static void* zoneValloc(malloc_zone_t*, size_t) { LOG_ERROR("valloc is not supported"); return 0; }    static void zoneDestroy(malloc_zone_t*) { }    malloc_zone_t m_zone;    TCMalloc_PageHeap* m_pageHeap;    TCMalloc_ThreadCache** m_threadHeaps;    TCMalloc_Central_FreeListPadded* m_centralCaches;    PageHeapAllocator<Span>* m_spanAllocator;    PageHeapAllocator<TCMalloc_ThreadCache>* m_pageHeapAllocator;};#endif#endif#ifndef WTF_CHANGES// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if// you're porting to a system where you really can't get a stacktrace.#ifdef NO_TCMALLOC_SAMPLES// We use #define so code compiles even if you #include stacktrace.h somehow.# define GetStackTrace(stack, depth, skip)  (0)#else# include <google/stacktrace.h>#endif#endif// Even if we have support for thread-local storage in the compiler// and linker, the OS may not support it.  We need to check that at// runtime.  Right now, we have to keep a manual set of "bad" OSes.#if defined(HAVE_TLS)  static bool kernel_supports_tls = false;      // be conservative  static inline bool KernelSupportsTLS() {    return kernel_supports_tls;  }# if !HAVE_DECL_UNAME   // if too old for uname, probably too old for TLS    static void CheckIfKernelSupportsTLS() {      kernel_supports_tls = false;    }# else#   include <sys/utsname.h>    // DECL_UNAME checked for <sys/utsname.h> too    static void CheckIfKernelSupportsTLS() {      struct utsname buf;      if (uname(&buf) != 0) {   // should be impossible        MESSAGE("uname failed assuming no TLS support (errno=%d)\n", errno);        kernel_supports_tls = false;      } else if (strcasecmp(buf.sysname, "linux") == 0) {        // The linux case: the first kernel to support TLS was 2.6.0        if (buf.release[0] < '2' && buf.release[1] == '.')    // 0.x or 1.x          kernel_supports_tls = false;        else if (buf.release[0] == '2' && buf.release[1] == '.' &&                 buf.release[2] >= '0' && buf.release[2] < '6' &&                 buf.release[3] == '.')                       // 2.0 - 2.5          kernel_supports_tls = false;        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -