1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/vm/MallocProvider.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,123 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* 1.11 + * Hierarchy of SpiderMonkey system memory allocators: 1.12 + * 1.13 + * - System {m,c,re}alloc/new/free: Overridden by jemalloc in most 1.14 + * environments. Do not use these functions directly. 1.15 + * 1.16 + * - js_{m,c,re}alloc/new/free: Wraps the system allocators and adds a 1.17 + * failure injection framework for use by the fuzzers as well as templated, 1.18 + * typesafe variants. See js/public/Utility.h. 1.19 + * 1.20 + * - AllocPolicy: An interface for the js allocators, for use with templates. 1.21 + * These allocators are for system memory whose lifetime is not associated 1.22 + * with a GC thing. See js/src/jsalloc.h. 1.23 + * 1.24 + * - SystemAllocPolicy: No extra functionality over bare allocators. 1.25 + * 1.26 + * - TempAllocPolicy: Adds automatic error reporting to the provided 1.27 + * Context when allocations fail. 1.28 + * 1.29 + * - MallocProvider. A mixin base class that handles automatically updating 1.30 + * the GC's state in response to allocations that are tied to a GC lifetime 1.31 + * or are for a particular GC purpose. These allocators must only be used 1.32 + * for memory that will be freed when a GC thing is swept. 1.33 + * 1.34 + * - gc::Zone: Automatically triggers zone GC. 1.35 + * - JSRuntime: Automatically triggers full GC. 1.36 + * - ThreadsafeContext > ExclusiveContext > JSContext: 1.37 + * Dispatches directly to the runtime. 1.38 + */ 1.39 + 1.40 +#ifndef vm_MallocProvider_h 1.41 +#define vm_MallocProvider_h 1.42 + 1.43 +#include "mozilla/Attributes.h" 1.44 +#include "mozilla/Likely.h" 1.45 + 1.46 +#include "js/Utility.h" 1.47 + 1.48 +namespace js { 1.49 + 1.50 +template<class Client> 1.51 +struct MallocProvider 1.52 +{ 1.53 + void *malloc_(size_t bytes) { 1.54 + Client *client = static_cast<Client *>(this); 1.55 + client->updateMallocCounter(bytes); 1.56 + void *p = js_malloc(bytes); 1.57 + return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(nullptr, bytes); 1.58 + } 1.59 + 1.60 + void *calloc_(size_t bytes) { 1.61 + Client *client = static_cast<Client *>(this); 1.62 + client->updateMallocCounter(bytes); 1.63 + void *p = js_calloc(bytes); 1.64 + return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(reinterpret_cast<void *>(1), bytes); 1.65 + } 1.66 + 1.67 + void *realloc_(void *p, size_t oldBytes, size_t newBytes) { 1.68 + Client *client = static_cast<Client *>(this); 1.69 + /* 1.70 + * For compatibility we do not account for realloc that decreases 1.71 + * previously allocated memory. 1.72 + */ 1.73 + if (newBytes > oldBytes) 1.74 + client->updateMallocCounter(newBytes - oldBytes); 1.75 + void *p2 = js_realloc(p, newBytes); 1.76 + return MOZ_LIKELY(!!p2) ? p2 : client->onOutOfMemory(p, newBytes); 1.77 + } 1.78 + 1.79 + void *realloc_(void *p, size_t bytes) { 1.80 + Client *client = static_cast<Client *>(this); 1.81 + /* 1.82 + * For compatibility we do not account for realloc that increases 1.83 + * previously allocated memory. 1.84 + */ 1.85 + if (!p) 1.86 + client->updateMallocCounter(bytes); 1.87 + void *p2 = js_realloc(p, bytes); 1.88 + return MOZ_LIKELY(!!p2) ? p2 : client->onOutOfMemory(p, bytes); 1.89 + } 1.90 + 1.91 + template <class T> 1.92 + T *pod_malloc() { 1.93 + return (T *)malloc_(sizeof(T)); 1.94 + } 1.95 + 1.96 + template <class T> 1.97 + T *pod_calloc() { 1.98 + return (T *)calloc_(sizeof(T)); 1.99 + } 1.100 + 1.101 + template <class T> 1.102 + T *pod_malloc(size_t numElems) { 1.103 + if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { 1.104 + Client *client = static_cast<Client *>(this); 1.105 + client->reportAllocationOverflow(); 1.106 + return nullptr; 1.107 + } 1.108 + return (T *)malloc_(numElems * sizeof(T)); 1.109 + } 1.110 + 1.111 + template <class T> 1.112 + T *pod_calloc(size_t numElems, JSCompartment *comp = nullptr, JSContext *cx = nullptr) { 1.113 + if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { 1.114 + Client *client = static_cast<Client *>(this); 1.115 + client->reportAllocationOverflow(); 1.116 + return nullptr; 1.117 + } 1.118 + return (T *)calloc_(numElems * sizeof(T)); 1.119 + } 1.120 + 1.121 + JS_DECLARE_NEW_METHODS(new_, malloc_, MOZ_ALWAYS_INLINE) 1.122 +}; 1.123 + 1.124 +} /* namespace js */ 1.125 + 1.126 +#endif /* vm_MallocProvider_h */