1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
6 
7 #ifndef gc_Tenuring_h
8 #define gc_Tenuring_h
9 
10 #include "gc/AllocKind.h"
11 #include "js/TracingAPI.h"
12 
13 namespace js {
14 
15 class NativeObject;
16 class Nursery;
17 class PlainObject;
18 
19 namespace gc {
20 class RelocationOverlay;
21 class StringRelocationOverlay;
22 }  // namespace gc
23 
24 class TenuringTracer final : public GenericTracer {
25   Nursery& nursery_;
26 
27   // Amount of data moved to the tenured generation during collection.
28   size_t tenuredSize = 0;
29   // Number of cells moved to the tenured generation.
30   size_t tenuredCells = 0;
31 
32   // These lists are threaded through the Nursery using the space from
33   // already moved things. The lists are used to fix up the moved things and
34   // to find things held live by intra-Nursery pointers.
35   gc::RelocationOverlay* objHead = nullptr;
36   gc::StringRelocationOverlay* stringHead = nullptr;
37 
38   JSObject* onObjectEdge(JSObject* obj) override;
39   JSString* onStringEdge(JSString* str) override;
40   JS::Symbol* onSymbolEdge(JS::Symbol* sym) override;
41   JS::BigInt* onBigIntEdge(JS::BigInt* bi) override;
42   js::BaseScript* onScriptEdge(BaseScript* script) override;
43   js::Shape* onShapeEdge(Shape* shape) override;
44   js::RegExpShared* onRegExpSharedEdge(RegExpShared* shared) override;
45   js::BaseShape* onBaseShapeEdge(BaseShape* base) override;
46   js::GetterSetter* onGetterSetterEdge(GetterSetter* gs) override;
47   js::PropMap* onPropMapEdge(PropMap* map) override;
48   js::jit::JitCode* onJitCodeEdge(jit::JitCode* code) override;
49   js::Scope* onScopeEdge(Scope* scope) override;
50 
51  public:
52   TenuringTracer(JSRuntime* rt, Nursery* nursery);
53 
nursery()54   Nursery& nursery() { return nursery_; }
55 
56   // Move all objects and everything they can reach to the tenured heap. Called
57   // after all roots have been traced.
58   void collectToObjectFixedPoint();
59 
60   // Move all strings and all strings they can reach to the tenured heap, and
61   // additionally do any fixups for when strings are pointing into memory that
62   // was deduplicated. Called after collectToObjectFixedPoint().
63   void collectToStringFixedPoint();
64 
65   size_t getTenuredSize() const;
66   size_t getTenuredCells() const;
67 
68   void traverse(JS::Value* thingp);
69 
70   // The store buffers need to be able to call these directly.
71   void traceObject(JSObject* src);
72   void traceObjectSlots(NativeObject* nobj, uint32_t start, uint32_t end);
73   void traceSlots(JS::Value* vp, uint32_t nslots);
74   void traceString(JSString* src);
75   void traceBigInt(JS::BigInt* src);
76 
77  private:
78   // The dependent string chars needs to be relocated if the base which it's
79   // using chars from has been deduplicated.
80   template <typename CharT>
81   void relocateDependentStringChars(JSDependentString* tenuredDependentStr,
82                                     JSLinearString* baseOrRelocOverlay,
83                                     size_t* offset,
84                                     bool* rootBaseNotYetForwarded,
85                                     JSLinearString** rootBase);
86 
87   inline void insertIntoObjectFixupList(gc::RelocationOverlay* entry);
88   inline void insertIntoStringFixupList(gc::StringRelocationOverlay* entry);
89 
90   template <typename T>
91   inline T* allocTenured(JS::Zone* zone, gc::AllocKind kind);
92   JSString* allocTenuredString(JSString* src, JS::Zone* zone,
93                                gc::AllocKind dstKind);
94 
95   inline JSObject* movePlainObjectToTenured(PlainObject* src);
96   JSObject* moveToTenuredSlow(JSObject* src);
97   JSString* moveToTenured(JSString* src);
98   JS::BigInt* moveToTenured(JS::BigInt* src);
99 
100   size_t moveElementsToTenured(NativeObject* dst, NativeObject* src,
101                                gc::AllocKind dstKind);
102   size_t moveSlotsToTenured(NativeObject* dst, NativeObject* src);
103   size_t moveStringToTenured(JSString* dst, JSString* src,
104                              gc::AllocKind dstKind);
105   size_t moveBigIntToTenured(JS::BigInt* dst, JS::BigInt* src,
106                              gc::AllocKind dstKind);
107 
108   void traceSlots(JS::Value* vp, JS::Value* end);
109 };
110 
111 }  // namespace js
112 
113 #endif  // gc_Tenuring_h
114