js/src/jit/IonAllocPolicy.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef jit_IonAllocPolicy_h
     8 #define jit_IonAllocPolicy_h
    10 #include "mozilla/GuardObjects.h"
    11 #include "mozilla/TypeTraits.h"
    13 #include "jscntxt.h"
    15 #include "ds/LifoAlloc.h"
    16 #include "jit/InlineList.h"
    17 #include "jit/Ion.h"
    19 namespace js {
    20 namespace jit {
    22 class TempAllocator
    23 {
    24     LifoAllocScope lifoScope_;
    26     // Linked list of GCThings rooted by this allocator.
    27     CompilerRootNode *rootList_;
    29   public:
    30     TempAllocator(LifoAlloc *lifoAlloc)
    31       : lifoScope_(lifoAlloc),
    32         rootList_(nullptr)
    33     { }
    35     void *allocateOrCrash(size_t bytes)
    36     {
    37         void *p = lifoScope_.alloc().alloc(bytes);
    38         if (!p)
    39             js::CrashAtUnhandlableOOM("LifoAlloc::allocOrCrash");
    40         return p;
    41     }
    43     void *allocate(size_t bytes)
    44     {
    45         void *p = lifoScope_.alloc().alloc(bytes);
    46         if (!ensureBallast())
    47             return nullptr;
    48         return p;
    49     }
    51     template <size_t ElemSize>
    52     void *allocateArray(size_t n)
    53     {
    54         if (n & mozilla::tl::MulOverflowMask<ElemSize>::value)
    55             return nullptr;
    56         void *p = lifoScope_.alloc().alloc(n * ElemSize);
    57         if (!ensureBallast())
    58             return nullptr;
    59         return p;
    60     }
    62     LifoAlloc *lifoAlloc()
    63     {
    64         return &lifoScope_.alloc();
    65     }
    67     CompilerRootNode *&rootList()
    68     {
    69         return rootList_;
    70     }
    72     bool ensureBallast() {
    73         // Most infallible Ion allocations are small, so we use a ballast of
    74         // ~16K for now.
    75         return lifoScope_.alloc().ensureUnusedApproximate(16 * 1024);
    76     }
    77 };
    79 // Stack allocated rooter for all roots associated with a TempAllocator
    80 class AutoTempAllocatorRooter : private AutoGCRooter
    81 {
    82   public:
    83     explicit AutoTempAllocatorRooter(JSContext *cx, TempAllocator *temp
    84                                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    85       : AutoGCRooter(cx, IONALLOC), temp(temp)
    86     {
    87         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    88     }
    90     friend void AutoGCRooter::trace(JSTracer *trc);
    91     void trace(JSTracer *trc);
    93   private:
    94     TempAllocator *temp;
    95     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    96 };
    98 class IonAllocPolicy
    99 {
   100     TempAllocator &alloc_;
   102   public:
   103     IonAllocPolicy(TempAllocator &alloc)
   104       : alloc_(alloc)
   105     {}
   106     void *malloc_(size_t bytes) {
   107         return alloc_.allocate(bytes);
   108     }
   109     void *calloc_(size_t bytes) {
   110         void *p = alloc_.allocate(bytes);
   111         if (p)
   112             memset(p, 0, bytes);
   113         return p;
   114     }
   115     void *realloc_(void *p, size_t oldBytes, size_t bytes) {
   116         void *n = malloc_(bytes);
   117         if (!n)
   118             return n;
   119         memcpy(n, p, Min(oldBytes, bytes));
   120         return n;
   121     }
   122     void free_(void *p) {
   123     }
   124     void reportAllocOverflow() const {
   125     }
   126 };
   128 // Deprecated. Don't use this. Will be removed after everything has been
   129 // converted to IonAllocPolicy.
   130 class OldIonAllocPolicy
   131 {
   132   public:
   133     OldIonAllocPolicy()
   134     {}
   135     void *malloc_(size_t bytes) {
   136         return GetIonContext()->temp->allocate(bytes);
   137     }
   138     void *calloc_(size_t bytes) {
   139         void *p = GetIonContext()->temp->allocate(bytes);
   140         if (p)
   141             memset(p, 0, bytes);
   142         return p;
   143     }
   144     void *realloc_(void *p, size_t oldBytes, size_t bytes) {
   145         void *n = malloc_(bytes);
   146         if (!n)
   147             return n;
   148         memcpy(n, p, Min(oldBytes, bytes));
   149         return n;
   150     }
   151     void free_(void *p) {
   152     }
   153     void reportAllocOverflow() const {
   154     }
   155 };
   157 class AutoIonContextAlloc
   158 {
   159     TempAllocator tempAlloc_;
   160     IonContext *icx_;
   161     TempAllocator *prevAlloc_;
   163   public:
   164     explicit AutoIonContextAlloc(JSContext *cx)
   165       : tempAlloc_(&cx->tempLifoAlloc()),
   166         icx_(GetIonContext()),
   167         prevAlloc_(icx_->temp)
   168     {
   169         icx_->temp = &tempAlloc_;
   170     }
   172     ~AutoIonContextAlloc() {
   173         JS_ASSERT(icx_->temp == &tempAlloc_);
   174         icx_->temp = prevAlloc_;
   175     }
   176 };
   178 struct TempObject
   179 {
   180     inline void *operator new(size_t nbytes, TempAllocator &alloc) {
   181         return alloc.allocateOrCrash(nbytes);
   182     }
   183     template <class T>
   184     inline void *operator new(size_t nbytes, T *pos) {
   185         static_assert(mozilla::IsConvertible<T*, TempObject*>::value,
   186                       "Placement new argument type must inherit from TempObject");
   187         return pos;
   188     }
   189 };
   191 template <typename T>
   192 class TempObjectPool
   193 {
   194     TempAllocator *alloc_;
   195     InlineForwardList<T> freed_;
   197   public:
   198     TempObjectPool()
   199       : alloc_(nullptr)
   200     {}
   201     void setAllocator(TempAllocator &alloc) {
   202         JS_ASSERT(freed_.empty());
   203         alloc_ = &alloc;
   204     }
   205     T *allocate() {
   206         JS_ASSERT(alloc_);
   207         if (freed_.empty())
   208             return new(*alloc_) T();
   209         return freed_.popFront();
   210     }
   211     void free(T *obj) {
   212         freed_.pushFront(obj);
   213     }
   214     void clear() {
   215         freed_.clear();
   216     }
   217 };
   219 } // namespace jit
   220 } // namespace js
   222 #endif /* jit_IonAllocPolicy_h */

mercurial