From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- js/src/jsapi-tests/testGCHeapBarriers.cpp | 629 ++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 js/src/jsapi-tests/testGCHeapBarriers.cpp (limited to 'js/src/jsapi-tests/testGCHeapBarriers.cpp') diff --git a/js/src/jsapi-tests/testGCHeapBarriers.cpp b/js/src/jsapi-tests/testGCHeapBarriers.cpp new file mode 100644 index 0000000000..d1f1348872 --- /dev/null +++ b/js/src/jsapi-tests/testGCHeapBarriers.cpp @@ -0,0 +1,629 @@ +/* -*- 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 "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" + +#include "gc/GCRuntime.h" +#include "js/ArrayBuffer.h" // JS::NewArrayBuffer +#include "js/RootingAPI.h" +#include "jsapi-tests/tests.h" +#include "vm/Runtime.h" + +#include "vm/JSContext-inl.h" + +using namespace js; + +// A heap-allocated structure containing one of our barriered pointer wrappers +// to test. +template +struct TestStruct { + W wrapper; + + void trace(JSTracer* trc) { + TraceNullableEdge(trc, &wrapper, "TestStruct::wrapper"); + } + + TestStruct() {} + explicit TestStruct(T init) : wrapper(init) {} +}; + +template +static T* CreateNurseryGCThing(JSContext* cx) { + MOZ_CRASH(); + return nullptr; +} + +template <> +JSObject* CreateNurseryGCThing(JSContext* cx) { + JS::RootedObject obj(cx, JS_NewPlainObject(cx)); + if (!obj) { + return nullptr; + } + JS_DefineProperty(cx, obj, "x", 42, 0); + MOZ_ASSERT(IsInsideNursery(obj)); + return obj; +} + +template <> +JSFunction* CreateNurseryGCThing(JSContext* cx) { + /* + * We don't actually use the function as a function, so here we cheat and + * cast a JSObject. + */ + return static_cast(CreateNurseryGCThing(cx)); +} + +template +static T* CreateTenuredGCThing(JSContext* cx) { + MOZ_CRASH(); + return nullptr; +} + +template <> +JSObject* CreateTenuredGCThing(JSContext* cx) { + // Use ArrayBuffers because they have finalizers, which allows using them in + // TenuredHeap<> without awkward conversations about nursery allocatability. + // Note that at some point ArrayBuffers might become nursery allocated at + // which point this test will have to change. + JSObject* obj = JS::NewArrayBuffer(cx, 20); + MOZ_ASSERT(!IsInsideNursery(obj)); + MOZ_ASSERT(obj->getClass()->hasFinalize() && + !(obj->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE)); + return obj; +} + +static void MakeWhite(JSObject* obj) { + gc::TenuredCell* cell = &obj->asTenured(); + cell->unmark(); + MOZ_ASSERT(!obj->isMarkedAny()); +} + +static void MakeGray(JSObject* obj) { + gc::TenuredCell* cell = &obj->asTenured(); + cell->unmark(); + cell->markIfUnmarked(gc::MarkColor::Gray); + MOZ_ASSERT(obj->isMarkedGray()); +} + +// Test post-barrier implementation on wrapper types. The following wrapper +// types have post barriers: +// - JS::Heap +// - GCPtr +// - HeapPtr +// - WeakHeapPtr +BEGIN_TEST(testGCHeapPostBarriers) { +#ifdef JS_GC_ZEAL + AutoLeaveZeal nozeal(cx); +#endif /* JS_GC_ZEAL */ + + /* Sanity check - objects start in the nursery and then become tenured. */ + JS_GC(cx); + JS::RootedObject obj(cx, CreateNurseryGCThing(cx)); + CHECK(js::gc::IsInsideNursery(obj.get())); + JS_GC(cx); + CHECK(!js::gc::IsInsideNursery(obj.get())); + JS::RootedObject tenuredObject(cx, obj); + + /* JSObject and JSFunction objects are nursery allocated. */ + CHECK(TestHeapPostBarriersForType()); + CHECK(TestHeapPostBarriersForType()); + // Bug 1599378: Add string tests. + + return true; +} + +bool CanAccessObject(JSObject* obj) { + JS::RootedObject rootedObj(cx, obj); + JS::RootedValue value(cx); + CHECK(JS_GetProperty(cx, rootedObj, "x", &value)); + CHECK(value.isInt32()); + CHECK(value.toInt32() == 42); + return true; +} + +template +bool TestHeapPostBarriersForType() { + CHECK((TestHeapPostBarriersForWrapper())); + CHECK((TestHeapPostBarriersForMovableWrapper())); + CHECK((TestHeapPostBarriersForMovableWrapper())); + CHECK((TestHeapPostBarriersForMovableWrapper())); + return true; +} + +template