/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gc/Barrier.h" #include "gc/Marking.h" #include "jit/JitContext.h" #include "js/HashTable.h" #include "js/shadow/Zone.h" // JS::shadow::Zone #include "js/Value.h" #include "vm/BigIntType.h" // JS::BigInt #include "vm/EnvironmentObject.h" #include "vm/GeneratorObject.h" #include "vm/JSObject.h" #include "vm/PropMap.h" #include "wasm/WasmJS.h" #include "gc/StableCellHasher-inl.h" namespace js { bool RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone* shadowZone) { MOZ_ASSERT( CurrentThreadCanAccessRuntime(shadowZone->runtimeFromMainThread())); return JS::RuntimeHeapIsMajorCollecting(); } #ifdef DEBUG bool IsMarkedBlack(JSObject* obj) { return obj->isMarkedBlack(); } bool HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot) const { if (kind == Slot) { return &owner->getSlotRef(slot) == this; } uint32_t numShifted = owner->getElementsHeader()->numShiftedElements(); MOZ_ASSERT(slot >= numShifted); return &owner->getDenseElement(slot - numShifted) == (const Value*)this; } void HeapSlot::assertPreconditionForPostWriteBarrier( NativeObject* obj, Kind kind, uint32_t slot, const Value& target) const { if (kind == Slot) { MOZ_ASSERT(obj->getSlotAddressUnchecked(slot)->get() == target); } else { uint32_t numShifted = obj->getElementsHeader()->numShiftedElements(); MOZ_ASSERT(slot >= numShifted); MOZ_ASSERT( static_cast(obj->getDenseElements() + (slot - numShifted)) ->get() == target); } if (!obj->zone()->isGCPreparing()) { AssertTargetIsNotGray(obj); } } bool CurrentThreadIsIonCompiling() { jit::JitContext* jcx = jit::MaybeGetJitContext(); return jcx && jcx->inIonBackend(); } #endif // DEBUG #if !MOZ_IS_GCC template struct JS_PUBLIC_API StableCellHasher; #endif } // namespace js // Post-write barrier, used by the C++ Heap implementation. JS_PUBLIC_API void JS::HeapObjectPostWriteBarrier(JSObject** objp, JSObject* prev, JSObject* next) { MOZ_ASSERT(objp); js::InternalBarrierMethods::postBarrier(objp, prev, next); } JS_PUBLIC_API void JS::HeapStringPostWriteBarrier(JSString** strp, JSString* prev, JSString* next) { MOZ_ASSERT(strp); js::InternalBarrierMethods::postBarrier(strp, prev, next); } JS_PUBLIC_API void JS::HeapBigIntPostWriteBarrier(JS::BigInt** bip, JS::BigInt* prev, JS::BigInt* next) { MOZ_ASSERT(bip); js::InternalBarrierMethods::postBarrier(bip, prev, next); } JS_PUBLIC_API void JS::HeapValuePostWriteBarrier(JS::Value* valuep, const Value& prev, const Value& next) { MOZ_ASSERT(valuep); js::InternalBarrierMethods::postBarrier(valuep, prev, next); } // Combined pre- and post-write barriers, used by the rust Heap // implementation. JS_PUBLIC_API void JS::HeapObjectWriteBarriers(JSObject** objp, JSObject* prev, JSObject* next) { MOZ_ASSERT(objp); js::InternalBarrierMethods::preBarrier(prev); js::InternalBarrierMethods::postBarrier(objp, prev, next); } JS_PUBLIC_API void JS::HeapStringWriteBarriers(JSString** strp, JSString* prev, JSString* next) { MOZ_ASSERT(strp); js::InternalBarrierMethods::preBarrier(prev); js::InternalBarrierMethods::postBarrier(strp, prev, next); } JS_PUBLIC_API void JS::HeapBigIntWriteBarriers(JS::BigInt** bip, JS::BigInt* prev, JS::BigInt* next) { MOZ_ASSERT(bip); js::InternalBarrierMethods::preBarrier(prev); js::InternalBarrierMethods::postBarrier(bip, prev, next); } JS_PUBLIC_API void JS::HeapScriptWriteBarriers(JSScript** scriptp, JSScript* prev, JSScript* next) { MOZ_ASSERT(scriptp); js::InternalBarrierMethods::preBarrier(prev); js::InternalBarrierMethods::postBarrier(scriptp, prev, next); } JS_PUBLIC_API void JS::HeapValueWriteBarriers(JS::Value* valuep, const Value& prev, const Value& next) { MOZ_ASSERT(valuep); js::InternalBarrierMethods::preBarrier(prev); js::InternalBarrierMethods::postBarrier(valuep, prev, next); }