|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=4 sw=4 et tw=79 ft=cpp: |
|
3 * |
|
4 * This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #ifndef gc_Nursery_inl_h |
|
9 #define gc_Nursery_inl_h |
|
10 |
|
11 #ifdef JSGC_GENERATIONAL |
|
12 |
|
13 #include "gc/Nursery.h" |
|
14 |
|
15 #include "gc/Heap.h" |
|
16 |
|
17 namespace js { |
|
18 namespace gc { |
|
19 |
|
20 /* |
|
21 * This structure overlays a Cell in the Nursery and re-purposes its memory |
|
22 * for managing the Nursery collection process. |
|
23 */ |
|
24 class RelocationOverlay |
|
25 { |
|
26 friend class MinorCollectionTracer; |
|
27 |
|
28 /* The low bit is set so this should never equal a normal pointer. */ |
|
29 static const uintptr_t Relocated = uintptr_t(0xbad0bad1); |
|
30 |
|
31 /* Set to Relocated when moved. */ |
|
32 uintptr_t magic_; |
|
33 |
|
34 /* The location |this| was moved to. */ |
|
35 Cell *newLocation_; |
|
36 |
|
37 /* A list entry to track all relocated things. */ |
|
38 RelocationOverlay *next_; |
|
39 |
|
40 public: |
|
41 static RelocationOverlay *fromCell(Cell *cell) { |
|
42 JS_ASSERT(!cell->isTenured()); |
|
43 return reinterpret_cast<RelocationOverlay *>(cell); |
|
44 } |
|
45 |
|
46 bool isForwarded() const { |
|
47 return magic_ == Relocated; |
|
48 } |
|
49 |
|
50 Cell *forwardingAddress() const { |
|
51 JS_ASSERT(isForwarded()); |
|
52 return newLocation_; |
|
53 } |
|
54 |
|
55 void forwardTo(Cell *cell) { |
|
56 JS_ASSERT(!isForwarded()); |
|
57 magic_ = Relocated; |
|
58 newLocation_ = cell; |
|
59 next_ = nullptr; |
|
60 } |
|
61 |
|
62 RelocationOverlay *next() const { |
|
63 return next_; |
|
64 } |
|
65 }; |
|
66 |
|
67 } /* namespace gc */ |
|
68 } /* namespace js */ |
|
69 |
|
70 template <typename T> |
|
71 MOZ_ALWAYS_INLINE bool |
|
72 js::Nursery::getForwardedPointer(T **ref) |
|
73 { |
|
74 JS_ASSERT(ref); |
|
75 JS_ASSERT(isInside(*ref)); |
|
76 const gc::RelocationOverlay *overlay = reinterpret_cast<const gc::RelocationOverlay *>(*ref); |
|
77 if (!overlay->isForwarded()) |
|
78 return false; |
|
79 /* This static cast from Cell* restricts T to valid (GC thing) types. */ |
|
80 *ref = static_cast<T *>(overlay->forwardingAddress()); |
|
81 return true; |
|
82 } |
|
83 |
|
84 #endif /* JSGC_GENERATIONAL */ |
|
85 |
|
86 #endif /* gc_Nursery_inl_h */ |