diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /js/src/jsapi-tests/testGCHeapPostBarriers.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/jsapi-tests/testGCHeapPostBarriers.cpp')
-rw-r--r-- | js/src/jsapi-tests/testGCHeapPostBarriers.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testGCHeapPostBarriers.cpp b/js/src/jsapi-tests/testGCHeapPostBarriers.cpp new file mode 100644 index 000000000..74512a53f --- /dev/null +++ b/js/src/jsapi-tests/testGCHeapPostBarriers.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +* vim: set ts=8 sts=4 et sw=4 tw=99: +*/ +/* 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/UniquePtr.h" + +#include "js/RootingAPI.h" +#include "jsapi-tests/tests.h" +#include "vm/Runtime.h" + +template <typename T> +static T* CreateGCThing(JSContext* cx) +{ + MOZ_CRASH(); + return nullptr; +} + +template <> +JSObject* CreateGCThing(JSContext* cx) +{ + JS::RootedObject obj(cx, JS_NewPlainObject(cx)); + if (!obj) + return nullptr; + JS_DefineProperty(cx, obj, "x", 42, 0); + return obj; +} + +template <> +JSFunction* CreateGCThing(JSContext* cx) +{ + /* + * We don't actually use the function as a function, so here we cheat and + * cast a JSObject. + */ + return static_cast<JSFunction*>(CreateGCThing<JSObject>(cx)); +} + +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, CreateGCThing<JSObject>(cx)); + CHECK(js::gc::IsInsideNursery(obj.get())); + JS_GC(cx); + CHECK(!js::gc::IsInsideNursery(obj.get())); + JS::RootedObject tenuredObject(cx, obj); + + /* Currently JSObject and JSFunction objects are nursery allocated. */ + CHECK(TestHeapPostBarriersForType<JSObject>()); + CHECK(TestHeapPostBarriersForType<JSFunction>()); + + 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 <typename T> +bool +TestHeapPostBarriersForType() +{ + CHECK((TestHeapPostBarriersForWrapper<T, JS::Heap<T*>>())); + CHECK((TestHeapPostBarriersForWrapper<T, js::GCPtr<T*>>())); + CHECK((TestHeapPostBarriersForWrapper<T, js::HeapPtr<T*>>())); + return true; +} + +template <typename T, typename W> +bool +TestHeapPostBarriersForWrapper() +{ + CHECK((TestHeapPostBarrierUpdate<T, W>())); + CHECK((TestHeapPostBarrierInitFailure<T, W>())); + return true; +} + +template <typename T, typename W> +bool +TestHeapPostBarrierUpdate() +{ + // Normal case - allocate a heap object, write a nursery pointer into it and + // check that it gets updated on minor GC. + + T* initialObj = CreateGCThing<T>(cx); + CHECK(initialObj != nullptr); + CHECK(js::gc::IsInsideNursery(initialObj)); + uintptr_t initialObjAsInt = uintptr_t(initialObj); + + W* ptr = nullptr; + + { + auto heapPtr = cx->make_unique<W>(); + CHECK(heapPtr); + + W& wrapper = *heapPtr; + CHECK(wrapper.get() == nullptr); + wrapper = initialObj; + CHECK(wrapper == initialObj); + + ptr = heapPtr.release(); + } + + cx->minorGC(JS::gcreason::API); + + CHECK(uintptr_t(ptr->get()) != initialObjAsInt); + CHECK(!js::gc::IsInsideNursery(ptr->get())); + CHECK(CanAccessObject(ptr->get())); + + return true; +} + +template <typename T, typename W> +bool +TestHeapPostBarrierInitFailure() +{ + // Failure case - allocate a heap object, write a nursery pointer into it + // and fail to complete initialization. + + T* initialObj = CreateGCThing<T>(cx); + CHECK(initialObj != nullptr); + CHECK(js::gc::IsInsideNursery(initialObj)); + + { + auto heapPtr = cx->make_unique<W>(); + CHECK(heapPtr); + + W& wrapper = *heapPtr; + CHECK(wrapper.get() == nullptr); + wrapper = initialObj; + CHECK(wrapper == initialObj); + } + + cx->minorGC(JS::gcreason::API); + + return true; +} + +END_TEST(testGCHeapPostBarriers) |