xpcom/glue/tests/gtest/TestGCPostBarriers.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=8 et :
     3  */
     4 /* This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 /*
     9  * Tests that generational garbage collection post-barriers are correctly
    10  * implemented for nsTArrays that contain JavaScript Values.
    11  */
    13 #include "jsapi.h"
    14 #include "nsTArray.h"
    16 #include "gtest/gtest.h"
    18 #include "js/TracingAPI.h"
    19 #include "js/HeapAPI.h"
    21 #include "mozilla/CycleCollectedJSRuntime.h"
    23 using namespace JS;
    24 using namespace mozilla;
    26 template <class ArrayT>
    27 static void
    28 TraceArray(JSTracer* trc, void* data)
    29 {
    30   ArrayT* array = static_cast<ArrayT *>(data);
    31   for (unsigned i = 0; i < array->Length(); ++i)
    32     JS_CallHeapObjectTracer(trc, &array->ElementAt(i), "array-element");
    33 }
    35 /*
    36  * Use arrays with initial size much smaller than the final number of elements
    37  * to test that moving Heap<T> elements works correctly.
    38  */
    39 const size_t ElementCount = 100;
    40 const size_t InitialElements = ElementCount / 10;
    42 template <class ArrayT>
    43 static void
    44 RunTest(JSRuntime* rt, JSContext* cx, ArrayT* array)
    45 {
    46   JS_GC(rt);
    48   ASSERT_TRUE(array != nullptr);
    49   JS_AddExtraGCRootsTracer(rt, TraceArray<ArrayT>, array);
    51   /*
    52    * Create the array and fill it with new JS objects. With GGC these will be
    53    * allocated in the nursery.
    54    */
    55   RootedValue value(cx);
    56   const char* property = "foo";
    57   JS::shadow::Runtime* srt = reinterpret_cast<JS::shadow::Runtime*>(rt);
    58   for (size_t i = 0; i < ElementCount; ++i) {
    59     RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
    60 #ifdef JSGC_GENERATIONAL
    61     ASSERT_TRUE(js::gc::IsInsideNursery(srt, obj));
    62 #else
    63     ASSERT_FALSE(js::gc::IsInsideNursery(srt, obj));
    64 #endif
    65     value = Int32Value(i);
    66     ASSERT_TRUE(JS_SetProperty(cx, obj, property, value));
    67     array->AppendElement(obj);
    68   }
    70   /*
    71    * If postbarriers are not working, we will crash here when we try to mark
    72    * objects that have been moved to the tenured heap.
    73    */
    74   JS_GC(rt);
    76   /*
    77    * Sanity check that our array contains what we expect.
    78    */
    79   for (size_t i = 0; i < ElementCount; ++i) {
    80     RootedObject obj(cx, array->ElementAt(i));
    81     ASSERT_FALSE(js::gc::IsInsideNursery(srt, obj));
    82     ASSERT_TRUE(JS_GetProperty(cx, obj, property, &value));
    83     ASSERT_TRUE(value.isInt32());
    84     ASSERT_EQ(static_cast<int32_t>(i), value.toInt32());
    85   }
    87   JS_RemoveExtraGCRootsTracer(rt, TraceArray<ArrayT>, array);
    88 }
    90 static void
    91 CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx)
    92 {
    93   static const JSClass GlobalClass = {
    94     "global", JSCLASS_GLOBAL_FLAGS,
    95     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    96     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
    97     nullptr, nullptr, nullptr, nullptr,
    98     JS_GlobalObjectTraceHook
    99   };
   101   JS::CompartmentOptions options;
   102   options.setVersion(JSVERSION_LATEST);
   103   JS::PersistentRootedObject global(cx);
   104   global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
   105   ASSERT_TRUE(global != nullptr);
   107   JSCompartment *oldCompartment = JS_EnterCompartment(cx, global);
   109   typedef Heap<JSObject*> ElementT;
   111   {
   112     nsTArray<ElementT>* array = new nsTArray<ElementT>(InitialElements);
   113     RunTest(rt, cx, array);
   114     delete array;
   115   }
   117   {
   118     FallibleTArray<ElementT>* array = new FallibleTArray<ElementT>(InitialElements);
   119     RunTest(rt, cx, array);
   120     delete array;
   121   }
   123   {
   124     nsAutoTArray<ElementT, InitialElements> array;
   125     RunTest(rt, cx, &array);
   126   }
   128   {
   129     AutoFallibleTArray<ElementT, InitialElements> array;
   130     RunTest(rt, cx, &array);
   131   }
   133   JS_LeaveCompartment(cx, oldCompartment);
   134 }
   136 TEST(GCPostBarriers, nsTArray) {
   137   CycleCollectedJSRuntime* ccrt = CycleCollectedJSRuntime::Get();
   138   ASSERT_TRUE(ccrt != nullptr);
   139   JSRuntime* rt = ccrt->Runtime();
   140   ASSERT_TRUE(rt != nullptr);
   142   JSContext *cx = JS_NewContext(rt, 8192);
   143   ASSERT_TRUE(cx != nullptr);
   144   JS_BeginRequest(cx);
   146   CreateGlobalAndRunTest(rt, cx);
   148   JS_EndRequest(cx);
   149   JS_DestroyContext(cx);
   150 }

mercurial