1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=78:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is SpiderMonkey global object code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * the Mozilla Foundation.
21 : * Portions created by the Initial Developer are Copyright (C) 2011
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "jsgcmark.h"
41 :
42 : #include "gc/Barrier.h"
43 :
44 : #ifndef jsgc_barrier_inl_h___
45 : #define jsgc_barrier_inl_h___
46 :
47 : namespace js {
48 :
49 : inline void
50 184839298 : EncapsulatedValue::writeBarrierPre(const Value &value)
51 : {
52 : #ifdef JSGC_INCREMENTAL
53 184839298 : if (value.isMarkable()) {
54 9221097 : js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
55 9221097 : writeBarrierPre(cell->compartment(), value);
56 : }
57 : #endif
58 184839298 : }
59 :
60 : inline void
61 15707929 : EncapsulatedValue::writeBarrierPre(JSCompartment *comp, const Value &value)
62 : {
63 : #ifdef JSGC_INCREMENTAL
64 15707929 : if (comp->needsBarrier()) {
65 436 : Value tmp(value);
66 436 : js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
67 436 : JS_ASSERT(tmp == value);
68 : }
69 : #endif
70 15707929 : }
71 :
72 : inline void
73 184839298 : EncapsulatedValue::pre()
74 : {
75 184839298 : writeBarrierPre(value);
76 184839298 : }
77 :
78 : inline void
79 6486832 : EncapsulatedValue::pre(JSCompartment *comp)
80 : {
81 6486832 : writeBarrierPre(comp, value);
82 6486832 : }
83 :
84 : inline
85 2395098 : HeapValue::HeapValue()
86 2395098 : : EncapsulatedValue(UndefinedValue())
87 : {
88 2395098 : post();
89 2395098 : }
90 :
91 : inline
92 7149647 : HeapValue::HeapValue(const Value &v)
93 7149647 : : EncapsulatedValue(v)
94 : {
95 7149647 : JS_ASSERT(!IsPoisonedValue(v));
96 7149647 : post();
97 7149647 : }
98 :
99 : inline
100 6750 : HeapValue::HeapValue(const HeapValue &v)
101 6750 : : EncapsulatedValue(v.value)
102 : {
103 6750 : JS_ASSERT(!IsPoisonedValue(v.value));
104 6750 : post();
105 6750 : }
106 :
107 : inline
108 19102990 : HeapValue::~HeapValue()
109 : {
110 9551495 : pre();
111 9551495 : }
112 :
113 : inline void
114 9719501 : HeapValue::init(const Value &v)
115 : {
116 9719501 : JS_ASSERT(!IsPoisonedValue(v));
117 9719501 : value = v;
118 9719501 : post();
119 9719501 : }
120 :
121 : inline void
122 5322670 : HeapValue::init(JSCompartment *comp, const Value &v)
123 : {
124 5322670 : value = v;
125 5322670 : post(comp);
126 5322670 : }
127 :
128 : inline HeapValue &
129 8182436 : HeapValue::operator=(const Value &v)
130 : {
131 8182436 : pre();
132 8182436 : JS_ASSERT(!IsPoisonedValue(v));
133 8182436 : value = v;
134 8182436 : post();
135 8182436 : return *this;
136 : }
137 :
138 : inline HeapValue &
139 3845372 : HeapValue::operator=(const HeapValue &v)
140 : {
141 3845372 : pre();
142 3845372 : JS_ASSERT(!IsPoisonedValue(v.value));
143 3845372 : value = v.value;
144 3845372 : post();
145 3845372 : return *this;
146 : }
147 :
148 : inline void
149 1814156 : HeapValue::set(JSCompartment *comp, const Value &v)
150 : {
151 : #ifdef DEBUG
152 1814156 : if (value.isMarkable()) {
153 0 : js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
154 0 : JS_ASSERT(cell->compartment() == comp ||
155 0 : cell->compartment() == comp->rt->atomsCompartment);
156 : }
157 : #endif
158 :
159 1814156 : pre(comp);
160 1814156 : JS_ASSERT(!IsPoisonedValue(v));
161 1814156 : value = v;
162 1814156 : post(comp);
163 1814156 : }
164 :
165 : inline void
166 29191 : HeapValue::writeBarrierPost(const Value &value, void *addr)
167 : {
168 29191 : }
169 :
170 : inline void
171 : HeapValue::writeBarrierPost(JSCompartment *comp, const Value &value, void *addr)
172 : {
173 : }
174 :
175 : inline void
176 31298804 : HeapValue::post()
177 : {
178 31298804 : }
179 :
180 : inline void
181 7136826 : HeapValue::post(JSCompartment *comp)
182 : {
183 7136826 : }
184 :
185 : inline
186 : HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const Value &v)
187 : : EncapsulatedValue(v)
188 : {
189 : JS_ASSERT(!IsPoisonedValue(v));
190 : post(obj, slot);
191 : }
192 :
193 : inline
194 : HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const HeapSlot &s)
195 : : EncapsulatedValue(s.value)
196 : {
197 : JS_ASSERT(!IsPoisonedValue(s.value));
198 : post(obj, slot);
199 : }
200 :
201 : inline
202 3669654 : HeapSlot::~HeapSlot()
203 : {
204 1834827 : pre();
205 1834827 : }
206 :
207 : inline void
208 35388261 : HeapSlot::init(JSObject *obj, uint32_t slot, const Value &v)
209 : {
210 35388261 : value = v;
211 35388261 : post(obj, slot);
212 35388261 : }
213 :
214 : inline void
215 65902617 : HeapSlot::init(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
216 : {
217 65902617 : value = v;
218 65902617 : post(comp, obj, slot);
219 65902617 : }
220 :
221 : inline void
222 161425168 : HeapSlot::set(JSObject *obj, uint32_t slot, const Value &v)
223 : {
224 161425168 : JS_ASSERT_IF(!obj->isArray(), &obj->getSlotRef(slot) == this);
225 161425168 : JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
226 :
227 161425168 : pre();
228 161425168 : JS_ASSERT(!IsPoisonedValue(v));
229 161425168 : value = v;
230 161425168 : post(obj, slot);
231 161425168 : }
232 :
233 : inline void
234 4672676 : HeapSlot::set(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
235 : {
236 4672676 : JS_ASSERT_IF(!obj->isArray(), &const_cast<JSObject *>(obj)->getSlotRef(slot) == this);
237 4672676 : JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
238 4672676 : JS_ASSERT(obj->compartment() == comp);
239 :
240 4672676 : pre(comp);
241 4672676 : JS_ASSERT(!IsPoisonedValue(v));
242 4672676 : value = v;
243 4672676 : post(comp, obj, slot);
244 4672676 : }
245 :
246 : inline void
247 196813429 : HeapSlot::writeBarrierPost(JSObject *obj, uint32_t slot)
248 : {
249 196813429 : }
250 :
251 : inline void
252 70575293 : HeapSlot::writeBarrierPost(JSCompartment *comp, JSObject *obj, uint32_t slotno)
253 : {
254 70575293 : }
255 :
256 : inline void
257 196813429 : HeapSlot::post(JSObject *owner, uint32_t slot)
258 : {
259 196813429 : HeapSlot::writeBarrierPost(owner, slot);
260 196813429 : }
261 :
262 : inline void
263 70575293 : HeapSlot::post(JSCompartment *comp, JSObject *owner, uint32_t slot)
264 : {
265 70575293 : HeapSlot::writeBarrierPost(comp, owner, slot);
266 70575293 : }
267 :
268 : inline
269 33906486 : HeapId::HeapId(jsid id)
270 33906486 : : value(id)
271 : {
272 33906486 : JS_ASSERT(!IsPoisonedId(id));
273 33906486 : post();
274 33906486 : }
275 :
276 : inline
277 42315 : HeapId::~HeapId()
278 : {
279 42315 : pre();
280 42315 : }
281 :
282 : inline void
283 2890 : HeapId::init(jsid id)
284 : {
285 2890 : JS_ASSERT(!IsPoisonedId(id));
286 2890 : value = id;
287 2890 : post();
288 2890 : }
289 :
290 : inline void
291 58927 : HeapId::pre()
292 : {
293 : #ifdef JSGC_INCREMENTAL
294 58927 : if (JS_UNLIKELY(JSID_IS_OBJECT(value))) {
295 0 : JSObject *obj = JSID_TO_OBJECT(value);
296 0 : JSCompartment *comp = obj->compartment();
297 0 : if (comp->needsBarrier()) {
298 0 : js::gc::MarkObjectUnbarriered(comp->barrierTracer(), &obj, "write barrier");
299 0 : JS_ASSERT(obj == JSID_TO_OBJECT(value));
300 : }
301 : }
302 : #endif
303 58927 : }
304 :
305 : inline void
306 33925988 : HeapId::post()
307 : {
308 33925988 : }
309 :
310 : inline HeapId &
311 : HeapId::operator=(jsid id)
312 : {
313 : pre();
314 : JS_ASSERT(!IsPoisonedId(id));
315 : value = id;
316 : post();
317 : return *this;
318 : }
319 :
320 : inline HeapId &
321 16612 : HeapId::operator=(const HeapId &v)
322 : {
323 16612 : pre();
324 16612 : JS_ASSERT(!IsPoisonedId(v.value));
325 16612 : value = v.value;
326 16612 : post();
327 16612 : return *this;
328 : }
329 :
330 : inline const Value &
331 105171 : ReadBarrieredValue::get() const
332 : {
333 105171 : if (value.isObject())
334 90965 : JSObject::readBarrier(&value.toObject());
335 14206 : else if (value.isString())
336 14206 : JSString::readBarrier(value.toString());
337 : else
338 0 : JS_ASSERT(!value.isMarkable());
339 :
340 105171 : return value;
341 : }
342 :
343 : inline
344 105170 : ReadBarrieredValue::operator const Value &() const
345 : {
346 105170 : return get();
347 : }
348 :
349 : inline JSObject &
350 1 : ReadBarrieredValue::toObject() const
351 : {
352 1 : return get().toObject();
353 : }
354 :
355 : } /* namespace js */
356 :
357 : #endif /* jsgc_barrier_inl_h___ */
|