js/src/gc/Nursery-inl.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/gc/Nursery-inl.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,86 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=4 sw=4 et tw=79 ft=cpp:
     1.6 + *
     1.7 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +#ifndef gc_Nursery_inl_h
    1.12 +#define gc_Nursery_inl_h
    1.13 +
    1.14 +#ifdef JSGC_GENERATIONAL
    1.15 +
    1.16 +#include "gc/Nursery.h"
    1.17 +
    1.18 +#include "gc/Heap.h"
    1.19 +
    1.20 +namespace js {
    1.21 +namespace gc {
    1.22 +
    1.23 +/*
    1.24 + * This structure overlays a Cell in the Nursery and re-purposes its memory
    1.25 + * for managing the Nursery collection process.
    1.26 + */
    1.27 +class RelocationOverlay
    1.28 +{
    1.29 +    friend class MinorCollectionTracer;
    1.30 +
    1.31 +    /* The low bit is set so this should never equal a normal pointer. */
    1.32 +    static const uintptr_t Relocated = uintptr_t(0xbad0bad1);
    1.33 +
    1.34 +    /* Set to Relocated when moved. */
    1.35 +    uintptr_t magic_;
    1.36 +
    1.37 +    /* The location |this| was moved to. */
    1.38 +    Cell *newLocation_;
    1.39 +
    1.40 +    /* A list entry to track all relocated things. */
    1.41 +    RelocationOverlay *next_;
    1.42 +
    1.43 +  public:
    1.44 +    static RelocationOverlay *fromCell(Cell *cell) {
    1.45 +        JS_ASSERT(!cell->isTenured());
    1.46 +        return reinterpret_cast<RelocationOverlay *>(cell);
    1.47 +    }
    1.48 +
    1.49 +    bool isForwarded() const {
    1.50 +        return magic_ == Relocated;
    1.51 +    }
    1.52 +
    1.53 +    Cell *forwardingAddress() const {
    1.54 +        JS_ASSERT(isForwarded());
    1.55 +        return newLocation_;
    1.56 +    }
    1.57 +
    1.58 +    void forwardTo(Cell *cell) {
    1.59 +        JS_ASSERT(!isForwarded());
    1.60 +        magic_ = Relocated;
    1.61 +        newLocation_ = cell;
    1.62 +        next_ = nullptr;
    1.63 +    }
    1.64 +
    1.65 +    RelocationOverlay *next() const {
    1.66 +        return next_;
    1.67 +    }
    1.68 +};
    1.69 +
    1.70 +} /* namespace gc */
    1.71 +} /* namespace js */
    1.72 +
    1.73 +template <typename T>
    1.74 +MOZ_ALWAYS_INLINE bool
    1.75 +js::Nursery::getForwardedPointer(T **ref)
    1.76 +{
    1.77 +    JS_ASSERT(ref);
    1.78 +    JS_ASSERT(isInside(*ref));
    1.79 +    const gc::RelocationOverlay *overlay = reinterpret_cast<const gc::RelocationOverlay *>(*ref);
    1.80 +    if (!overlay->isForwarded())
    1.81 +        return false;
    1.82 +    /* This static cast from Cell* restricts T to valid (GC thing) types. */
    1.83 +    *ref = static_cast<T *>(overlay->forwardingAddress());
    1.84 +    return true;
    1.85 +}
    1.86 +
    1.87 +#endif /* JSGC_GENERATIONAL */
    1.88 +
    1.89 +#endif /* gc_Nursery_inl_h */

mercurial