|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
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/. */ |
|
7 |
|
8 #ifdef JSGC_GENERATIONAL |
|
9 |
|
10 #include "gc/Barrier.h" |
|
11 #include "jsapi-tests/tests.h" |
|
12 |
|
13 using namespace JS; |
|
14 using namespace js; |
|
15 |
|
16 struct AutoIgnoreRootingHazards { |
|
17 // Force a nontrivial destructor so the compiler sees the whole RAII scope |
|
18 static volatile int depth; |
|
19 AutoIgnoreRootingHazards() { depth++; } |
|
20 ~AutoIgnoreRootingHazards() { depth--; } |
|
21 }; |
|
22 volatile int AutoIgnoreRootingHazards::depth = 0; |
|
23 |
|
24 BEGIN_TEST(testGCStoreBufferRemoval) |
|
25 { |
|
26 // Sanity check - objects start in the nursery and then become tenured. |
|
27 JS_GC(cx->runtime()); |
|
28 JS::RootedObject obj(cx, NurseryObject()); |
|
29 CHECK(js::gc::IsInsideNursery(rt, obj.get())); |
|
30 JS_GC(cx->runtime()); |
|
31 CHECK(!js::gc::IsInsideNursery(rt, obj.get())); |
|
32 JS::RootedObject tenuredObject(cx, obj); |
|
33 |
|
34 // Hide the horrors herein from the static rooting analysis. |
|
35 AutoIgnoreRootingHazards ignore; |
|
36 |
|
37 // Test removal of store buffer entries added by RelocatablePtr<T>. |
|
38 { |
|
39 JSObject *badObject = reinterpret_cast<JSObject*>(1); |
|
40 JSObject *punnedPtr = nullptr; |
|
41 RelocatablePtrObject* relocPtr = |
|
42 reinterpret_cast<RelocatablePtrObject*>(&punnedPtr); |
|
43 new (relocPtr) RelocatablePtrObject; |
|
44 *relocPtr = NurseryObject(); |
|
45 relocPtr->~RelocatablePtrObject(); |
|
46 punnedPtr = badObject; |
|
47 JS_GC(cx->runtime()); |
|
48 |
|
49 new (relocPtr) RelocatablePtrObject; |
|
50 *relocPtr = NurseryObject(); |
|
51 *relocPtr = tenuredObject; |
|
52 relocPtr->~RelocatablePtrObject(); |
|
53 punnedPtr = badObject; |
|
54 JS_GC(cx->runtime()); |
|
55 |
|
56 new (relocPtr) RelocatablePtrObject; |
|
57 *relocPtr = NurseryObject(); |
|
58 *relocPtr = nullptr; |
|
59 relocPtr->~RelocatablePtrObject(); |
|
60 punnedPtr = badObject; |
|
61 JS_GC(cx->runtime()); |
|
62 } |
|
63 |
|
64 // Test removal of store buffer entries added by RelocatableValue. |
|
65 { |
|
66 Value punnedValue; |
|
67 RelocatableValue *relocValue = reinterpret_cast<RelocatableValue*>(&punnedValue); |
|
68 new (relocValue) RelocatableValue; |
|
69 *relocValue = ObjectValue(*NurseryObject()); |
|
70 relocValue->~RelocatableValue(); |
|
71 punnedValue = ObjectValueCrashOnTouch(); |
|
72 JS_GC(cx->runtime()); |
|
73 |
|
74 new (relocValue) RelocatableValue; |
|
75 *relocValue = ObjectValue(*NurseryObject()); |
|
76 *relocValue = ObjectValue(*tenuredObject); |
|
77 relocValue->~RelocatableValue(); |
|
78 punnedValue = ObjectValueCrashOnTouch(); |
|
79 JS_GC(cx->runtime()); |
|
80 |
|
81 new (relocValue) RelocatableValue; |
|
82 *relocValue = ObjectValue(*NurseryObject()); |
|
83 *relocValue = NullValue(); |
|
84 relocValue->~RelocatableValue(); |
|
85 punnedValue = ObjectValueCrashOnTouch(); |
|
86 JS_GC(cx->runtime()); |
|
87 } |
|
88 |
|
89 // Test removal of store buffer entries added by Heap<T>. |
|
90 { |
|
91 JSObject *badObject = reinterpret_cast<JSObject*>(1); |
|
92 JSObject *punnedPtr = nullptr; |
|
93 Heap<JSObject*>* heapPtr = |
|
94 reinterpret_cast<Heap<JSObject*>*>(&punnedPtr); |
|
95 new (heapPtr) Heap<JSObject*>; |
|
96 *heapPtr = NurseryObject(); |
|
97 heapPtr->~Heap<JSObject*>(); |
|
98 punnedPtr = badObject; |
|
99 JS_GC(cx->runtime()); |
|
100 |
|
101 new (heapPtr) Heap<JSObject*>; |
|
102 *heapPtr = NurseryObject(); |
|
103 *heapPtr = tenuredObject; |
|
104 heapPtr->~Heap<JSObject*>(); |
|
105 punnedPtr = badObject; |
|
106 JS_GC(cx->runtime()); |
|
107 |
|
108 new (heapPtr) Heap<JSObject*>; |
|
109 *heapPtr = NurseryObject(); |
|
110 *heapPtr = nullptr; |
|
111 heapPtr->~Heap<JSObject*>(); |
|
112 punnedPtr = badObject; |
|
113 JS_GC(cx->runtime()); |
|
114 } |
|
115 |
|
116 return true; |
|
117 } |
|
118 |
|
119 JSObject *NurseryObject() |
|
120 { |
|
121 return JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()); |
|
122 } |
|
123 END_TEST(testGCStoreBufferRemoval) |
|
124 |
|
125 #endif |