Barrier.cpp (4532B)
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 #include "gc/Barrier.h" 8 9 #include "gc/Marking.h" 10 #include "jit/JitContext.h" 11 #include "js/HashTable.h" 12 #include "js/shadow/Zone.h" // JS::shadow::Zone 13 #include "js/Value.h" 14 #include "vm/BigIntType.h" // JS::BigInt 15 #include "vm/EnvironmentObject.h" 16 #include "vm/GeneratorObject.h" 17 #include "vm/JSObject.h" 18 #include "vm/PropMap.h" 19 #include "wasm/WasmJS.h" 20 21 #include "gc/StableCellHasher-inl.h" 22 23 namespace js { 24 25 bool RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone* shadowZone) { 26 MOZ_ASSERT( 27 CurrentThreadCanAccessRuntime(shadowZone->runtimeFromMainThread())); 28 return JS::RuntimeHeapIsMajorCollecting(); 29 } 30 31 #ifdef DEBUG 32 33 bool IsMarkedBlack(JSObject* obj) { return obj->isMarkedBlack(); } 34 35 bool HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, 36 uint32_t slot) const { 37 if (kind == Slot) { 38 return &owner->getSlotRef(slot) == this; 39 } 40 41 uint32_t numShifted = owner->getElementsHeader()->numShiftedElements(); 42 MOZ_ASSERT(slot >= numShifted); 43 return &owner->getDenseElement(slot - numShifted) == (const Value*)this; 44 } 45 46 void HeapSlot::assertPreconditionForPostWriteBarrier( 47 NativeObject* obj, Kind kind, uint32_t slot, const Value& target) const { 48 if (kind == Slot) { 49 MOZ_ASSERT(obj->getSlotAddressUnchecked(slot)->get() == target); 50 } else { 51 uint32_t numShifted = obj->getElementsHeader()->numShiftedElements(); 52 MOZ_ASSERT(slot >= numShifted); 53 MOZ_ASSERT( 54 static_cast<HeapSlot*>(obj->getDenseElements() + (slot - numShifted)) 55 ->get() == target); 56 } 57 58 if (!obj->zone()->isGCPreparing()) { 59 AssertTargetIsNotGray(obj); 60 } 61 } 62 63 bool CurrentThreadIsBaselineCompiling() { 64 jit::JitContext* jcx = jit::MaybeGetJitContext(); 65 return jcx && jcx->inBaselineBackend(); 66 } 67 68 bool CurrentThreadIsIonCompiling() { 69 jit::JitContext* jcx = jit::MaybeGetJitContext(); 70 return jcx && jcx->inIonBackend(); 71 } 72 73 bool CurrentThreadIsOffThreadCompiling() { 74 return CurrentThreadIsBaselineCompiling() || CurrentThreadIsIonCompiling(); 75 } 76 77 #endif // DEBUG 78 79 #if !MOZ_IS_GCC 80 template struct JS_PUBLIC_API StableCellHasher<JSObject*>; 81 template struct JS_PUBLIC_API StableCellHasher<JSScript*>; 82 #endif 83 84 } // namespace js 85 86 JS_PUBLIC_API void JS::HeapObjectPostWriteBarrier(JSObject** objp, 87 JSObject* prev, 88 JSObject* next) { 89 MOZ_ASSERT(objp); 90 js::InternalBarrierMethods<JSObject*>::postBarrier(objp, prev, next); 91 } 92 93 // Combined pre- and post-write barriers, used by the C++ Heap<T> 94 // implementation. 95 96 JS_PUBLIC_API void JS::HeapObjectWriteBarriers(JSObject** objp, JSObject* prev, 97 JSObject* next) { 98 MOZ_ASSERT(objp); 99 js::InternalBarrierMethods<JSObject*>::preBarrier(prev); 100 js::InternalBarrierMethods<JSObject*>::postBarrier(objp, prev, next); 101 } 102 103 JS_PUBLIC_API void JS::HeapStringWriteBarriers(JSString** strp, JSString* prev, 104 JSString* next) { 105 MOZ_ASSERT(strp); 106 js::InternalBarrierMethods<JSString*>::preBarrier(prev); 107 js::InternalBarrierMethods<JSString*>::postBarrier(strp, prev, next); 108 } 109 110 JS_PUBLIC_API void JS::HeapBigIntWriteBarriers(JS::BigInt** bip, 111 JS::BigInt* prev, 112 JS::BigInt* next) { 113 MOZ_ASSERT(bip); 114 js::InternalBarrierMethods<JS::BigInt*>::preBarrier(prev); 115 js::InternalBarrierMethods<JS::BigInt*>::postBarrier(bip, prev, next); 116 } 117 118 JS_PUBLIC_API void JS::HeapScriptWriteBarriers(JSScript** scriptp, 119 JSScript* prev, JSScript* next) { 120 MOZ_ASSERT(scriptp); 121 js::InternalBarrierMethods<JSScript*>::preBarrier(prev); 122 js::InternalBarrierMethods<JSScript*>::postBarrier(scriptp, prev, next); 123 } 124 125 JS_PUBLIC_API void JS::HeapValueWriteBarriers(JS::Value* valuep, 126 const Value& prev, 127 const Value& next) { 128 MOZ_ASSERT(valuep); 129 js::InternalBarrierMethods<JS::Value>::preBarrier(prev); 130 js::InternalBarrierMethods<JS::Value>::postBarrier(valuep, prev, next); 131 }