StoreBuffer-inl.h (3006B)
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_StoreBuffer_inl_h 8 #define gc_StoreBuffer_inl_h 9 10 #include "gc/StoreBuffer.h" 11 12 #include "gc/Heap-inl.h" 13 14 namespace js { 15 namespace gc { 16 17 inline /* static */ size_t ArenaCellSet::getCellIndex(const TenuredCell* cell) { 18 uintptr_t cellOffset = uintptr_t(cell) & ArenaMask; 19 MOZ_ASSERT(cellOffset % ArenaCellIndexBytes == 0); 20 return cellOffset / ArenaCellIndexBytes; 21 } 22 23 inline /* static */ void ArenaCellSet::getWordIndexAndMask(size_t cellIndex, 24 size_t* wordp, 25 uint32_t* maskp) { 26 BitArray<MaxArenaCellIndex>::getIndexAndMask(cellIndex, wordp, maskp); 27 } 28 29 inline bool ArenaCellSet::hasCell(size_t cellIndex) const { 30 MOZ_ASSERT(cellIndex < MaxArenaCellIndex); 31 return bits.get(cellIndex); 32 } 33 34 inline void ArenaCellSet::putCell(size_t cellIndex) { 35 MOZ_ASSERT(cellIndex < MaxArenaCellIndex); 36 MOZ_ASSERT(arena); 37 38 bits.set(cellIndex); 39 check(); 40 } 41 42 inline void ArenaCellSet::check() const { 43 #ifdef DEBUG 44 bool bitsZero = bits.isAllClear(); 45 MOZ_ASSERT(isEmpty() == bitsZero); 46 MOZ_ASSERT(isEmpty() == !arena); 47 if (!isEmpty()) { 48 MOZ_ASSERT(IsCellPointerValid(arena)); 49 JSRuntime* runtime = arena->zone()->runtimeFromMainThread(); 50 uint64_t minorGCCount = runtime->gc.minorGCCount(); 51 MOZ_ASSERT(minorGCCount == minorGCNumberAtCreation || 52 minorGCCount == minorGCNumberAtCreation + 1); 53 } 54 #endif 55 } 56 57 inline void StoreBuffer::WholeCellBuffer::put(const Cell* cell) { 58 if (cell != last_) { 59 putDontCheckLast(cell); 60 } 61 } 62 63 inline void StoreBuffer::WholeCellBuffer::putDontCheckLast(const Cell* cell) { 64 // This can still be called when |cell == last_| if the caller didn't check 65 // and that's OK. 66 67 MOZ_ASSERT(cell->isTenured()); 68 69 // BigInts don't have any children, so shouldn't show up here. 70 MOZ_ASSERT(cell->getTraceKind() != JS::TraceKind::BigInt); 71 72 Arena* arena = cell->asTenured().arena(); 73 ArenaCellSet* cells = arena->bufferedCells(); 74 if (cells->isEmpty()) { 75 cells = allocateCellSet(arena); 76 if (!cells) { 77 return; 78 } 79 } 80 81 cells->putCell(&cell->asTenured()); 82 cells->check(); 83 84 last_ = cell; 85 } 86 87 /* static */ 88 inline bool StoreBuffer::isInWholeCellBuffer(Cell* cell) { 89 TenuredCell* tenured = &cell->asTenured(); 90 gc::ArenaCellSet* cells = tenured->arena()->bufferedCells(); 91 return cells && cells->hasCell(tenured); 92 } 93 94 inline void StoreBuffer::putWholeCell(Cell* cell) { bufferWholeCell.put(cell); } 95 inline void StoreBuffer::putWholeCellDontCheckLast(Cell* cell) { 96 bufferWholeCell.putDontCheckLast(cell); 97 } 98 99 } // namespace gc 100 } // namespace js 101 102 #endif // gc_StoreBuffer_inl_h