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