# HG changeset patch # User Jon Coppeard # Date 1603288237 0 # Wed Oct 21 13:50:37 2020 +0000 # Node ID 8a8d7fdc7038fb360d7c50f5943ccafd7f0bb829 # Parent 7e223284a9225c66b590aaad671c7448d1ff0b57 Bug 1670358 - Add test for shrinking nsTArrays of JS::Heap r=sg Depends on D93654 Differential Revision: https://phabricator.services.mozilla.com/D94270 diff -r 7e223284a922 -r 8a8d7fdc7038 xpcom/tests/gtest/TestGCPostBarriers.cpp --- a/xpcom/tests/gtest/TestGCPostBarriers.cpp Wed Oct 21 13:50:36 2020 +0000 +++ b/xpcom/tests/gtest/TestGCPostBarriers.cpp Wed Oct 21 13:50:37 2020 +0000 @@ -9,6 +9,8 @@ * implemented for nsTArrays that contain JavaScript Values. */ +#include "mozilla/UniquePtr.h" + #include "jsapi.h" #include "nsTArray.h" @@ -37,11 +39,13 @@ const size_t InitialElements = ElementCount / 10; template -static void RunTest(JSContext* cx, ArrayT* array) { +static void TestGrow(JSContext* cx) { JS_GC(cx); + auto array = MakeUnique(); ASSERT_TRUE(array != nullptr); - JS_AddExtraGCRootsTracer(cx, TraceArray, array); + + JS_AddExtraGCRootsTracer(cx, TraceArray, array.get()); /* * Create the array and fill it with new JS objects. With GGC these will be @@ -66,7 +70,8 @@ /* * Sanity check that our array contains what we expect. */ - for (size_t i = 0; i < ElementCount; ++i) { + ASSERT_EQ(array->Length(), ElementCount); + for (size_t i = 0; i < array->Length(); i++) { RootedObject obj(cx, array->ElementAt(i)); ASSERT_TRUE(JS::ObjectIsTenured(obj)); ASSERT_TRUE(JS_GetProperty(cx, obj, property, &value)); @@ -74,7 +79,54 @@ ASSERT_EQ(static_cast(i), value.toInt32()); } - JS_RemoveExtraGCRootsTracer(cx, TraceArray, array); + JS_RemoveExtraGCRootsTracer(cx, TraceArray, array.get()); +} + +template +static void TestShrink(JSContext* cx) { + JS_GC(cx); + + auto array = MakeUnique(); + ASSERT_TRUE(array != nullptr); + + JS_AddExtraGCRootsTracer(cx, TraceArray, array.get()); + + /* + * Create the array and fill it with new JS objects. With GGC these will be + * allocated in the nursery. + */ + RootedValue value(cx); + const char* property = "foo"; + for (size_t i = 0; i < ElementCount; ++i) { + RootedObject obj(cx, JS_NewPlainObject(cx)); + ASSERT_FALSE(JS::ObjectIsTenured(obj)); + value = Int32Value(i); + ASSERT_TRUE(JS_SetProperty(cx, obj, property, value)); + ASSERT_TRUE(array->AppendElement(obj, fallible)); + } + + /* Shrink and compact the array */ + array->RemoveElementsAt(InitialElements, ElementCount - InitialElements); + array->Compact(); + + JS_GC(cx); + + ASSERT_EQ(array->Length(), InitialElements); + for (size_t i = 0; i < array->Length(); i++) { + RootedObject obj(cx, array->ElementAt(i)); + ASSERT_TRUE(JS::ObjectIsTenured(obj)); + ASSERT_TRUE(JS_GetProperty(cx, obj, property, &value)); + ASSERT_TRUE(value.isInt32()); + ASSERT_EQ(static_cast(i), value.toInt32()); + } + + JS_RemoveExtraGCRootsTracer(cx, TraceArray, array.get()); +} + +template +static void TestArrayType(JSContext* cx) { + TestGrow(cx); + TestShrink(cx); } static void CreateGlobalAndRunTest(JSContext* cx) { @@ -89,25 +141,11 @@ JS::Realm* oldRealm = JS::EnterRealm(cx, global); - typedef Heap ElementT; - - { - nsTArray* array = new nsTArray(InitialElements); - RunTest(cx, array); - delete array; - } + using ElementT = Heap; - { - FallibleTArray* array = - new FallibleTArray(InitialElements); - RunTest(cx, array); - delete array; - } - - { - AutoTArray array; - RunTest(cx, &array); - } + TestArrayType>(cx); + TestArrayType>(cx); + TestArrayType>(cx); JS::LeaveRealm(cx, oldRealm); }