michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=4 sw=4 et tw=79 ft=cpp: michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef gc_Nursery_inl_h michael@0: #define gc_Nursery_inl_h michael@0: michael@0: #ifdef JSGC_GENERATIONAL michael@0: michael@0: #include "gc/Nursery.h" michael@0: michael@0: #include "gc/Heap.h" michael@0: michael@0: namespace js { michael@0: namespace gc { michael@0: michael@0: /* michael@0: * This structure overlays a Cell in the Nursery and re-purposes its memory michael@0: * for managing the Nursery collection process. michael@0: */ michael@0: class RelocationOverlay michael@0: { michael@0: friend class MinorCollectionTracer; michael@0: michael@0: /* The low bit is set so this should never equal a normal pointer. */ michael@0: static const uintptr_t Relocated = uintptr_t(0xbad0bad1); michael@0: michael@0: /* Set to Relocated when moved. */ michael@0: uintptr_t magic_; michael@0: michael@0: /* The location |this| was moved to. */ michael@0: Cell *newLocation_; michael@0: michael@0: /* A list entry to track all relocated things. */ michael@0: RelocationOverlay *next_; michael@0: michael@0: public: michael@0: static RelocationOverlay *fromCell(Cell *cell) { michael@0: JS_ASSERT(!cell->isTenured()); michael@0: return reinterpret_cast(cell); michael@0: } michael@0: michael@0: bool isForwarded() const { michael@0: return magic_ == Relocated; michael@0: } michael@0: michael@0: Cell *forwardingAddress() const { michael@0: JS_ASSERT(isForwarded()); michael@0: return newLocation_; michael@0: } michael@0: michael@0: void forwardTo(Cell *cell) { michael@0: JS_ASSERT(!isForwarded()); michael@0: magic_ = Relocated; michael@0: newLocation_ = cell; michael@0: next_ = nullptr; michael@0: } michael@0: michael@0: RelocationOverlay *next() const { michael@0: return next_; michael@0: } michael@0: }; michael@0: michael@0: } /* namespace gc */ michael@0: } /* namespace js */ michael@0: michael@0: template michael@0: MOZ_ALWAYS_INLINE bool michael@0: js::Nursery::getForwardedPointer(T **ref) michael@0: { michael@0: JS_ASSERT(ref); michael@0: JS_ASSERT(isInside(*ref)); michael@0: const gc::RelocationOverlay *overlay = reinterpret_cast(*ref); michael@0: if (!overlay->isForwarded()) michael@0: return false; michael@0: /* This static cast from Cell* restricts T to valid (GC thing) types. */ michael@0: *ref = static_cast(overlay->forwardingAddress()); michael@0: return true; michael@0: } michael@0: michael@0: #endif /* JSGC_GENERATIONAL */ michael@0: michael@0: #endif /* gc_Nursery_inl_h */