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 : #ifndef jsgc_barrier_inl_h___
41 : #define jsgc_barrier_inl_h___
42 :
43 : #include "jsgcmark.h"
44 :
45 : #include "gc/Barrier.h"
46 :
47 : #include "vm/ObjectImpl-inl.h"
48 : #include "vm/String-inl.h"
49 :
50 : namespace js {
51 :
52 : inline void
53 103734896 : EncapsulatedValue::writeBarrierPre(const Value &value)
54 : {
55 : #ifdef JSGC_INCREMENTAL
56 103734896 : if (value.isMarkable()) {
57 6873805 : js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
58 6873805 : writeBarrierPre(cell->compartment(), value);
59 : }
60 : #endif
61 103734896 : }
62 :
63 : inline void
64 9382186 : EncapsulatedValue::writeBarrierPre(JSCompartment *comp, const Value &value)
65 : {
66 : #ifdef JSGC_INCREMENTAL
67 9382186 : if (comp->needsBarrier()) {
68 427 : Value tmp(value);
69 427 : js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
70 427 : JS_ASSERT(tmp == value);
71 : }
72 : #endif
73 9382186 : }
74 :
75 : inline void
76 103734896 : EncapsulatedValue::pre()
77 : {
78 103734896 : writeBarrierPre(value);
79 103734896 : }
80 :
81 : inline void
82 2508381 : EncapsulatedValue::pre(JSCompartment *comp)
83 : {
84 2508381 : writeBarrierPre(comp, value);
85 2508381 : }
86 :
87 : inline
88 2392830 : HeapValue::HeapValue()
89 2392830 : : EncapsulatedValue(UndefinedValue())
90 : {
91 2392830 : post();
92 2392830 : }
93 :
94 : inline
95 7149629 : HeapValue::HeapValue(const Value &v)
96 7149629 : : EncapsulatedValue(v)
97 : {
98 7149629 : JS_ASSERT(!IsPoisonedValue(v));
99 7149629 : post();
100 7149629 : }
101 :
102 : inline
103 6750 : HeapValue::HeapValue(const HeapValue &v)
104 6750 : : EncapsulatedValue(v.value)
105 : {
106 6750 : JS_ASSERT(!IsPoisonedValue(v.value));
107 6750 : post();
108 6750 : }
109 :
110 : inline
111 19098418 : HeapValue::~HeapValue()
112 : {
113 9549209 : pre();
114 9549209 : }
115 :
116 : inline void
117 2780087 : HeapValue::init(const Value &v)
118 : {
119 2780087 : JS_ASSERT(!IsPoisonedValue(v));
120 2780087 : value = v;
121 2780087 : post();
122 2780087 : }
123 :
124 : inline void
125 5349190 : HeapValue::init(JSCompartment *comp, const Value &v)
126 : {
127 5349190 : value = v;
128 5349190 : post(comp);
129 5349190 : }
130 :
131 : inline HeapValue &
132 3702436 : HeapValue::operator=(const Value &v)
133 : {
134 3702436 : pre();
135 3702436 : JS_ASSERT(!IsPoisonedValue(v));
136 3702436 : value = v;
137 3702436 : post();
138 3702436 : return *this;
139 : }
140 :
141 : inline HeapValue &
142 3845358 : HeapValue::operator=(const HeapValue &v)
143 : {
144 3845358 : pre();
145 3845358 : JS_ASSERT(!IsPoisonedValue(v.value));
146 3845358 : value = v.value;
147 3845358 : post();
148 3845358 : return *this;
149 : }
150 :
151 : inline void
152 1170928 : HeapValue::set(JSCompartment *comp, const Value &v)
153 : {
154 : #ifdef DEBUG
155 1170928 : if (value.isMarkable()) {
156 0 : js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
157 0 : JS_ASSERT(cell->compartment() == comp ||
158 0 : cell->compartment() == comp->rt->atomsCompartment);
159 : }
160 : #endif
161 :
162 1170928 : pre(comp);
163 1170928 : JS_ASSERT(!IsPoisonedValue(v));
164 1170928 : value = v;
165 1170928 : post(comp);
166 1170928 : }
167 :
168 : inline void
169 19066 : HeapValue::writeBarrierPost(const Value &value, void *addr)
170 : {
171 19066 : }
172 :
173 : inline void
174 : HeapValue::writeBarrierPost(JSCompartment *comp, const Value &value, void *addr)
175 : {
176 : }
177 :
178 : inline void
179 19877090 : HeapValue::post()
180 : {
181 19877090 : }
182 :
183 : inline void
184 6520118 : HeapValue::post(JSCompartment *comp)
185 : {
186 6520118 : }
187 :
188 : inline
189 : HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const Value &v)
190 : : EncapsulatedValue(v)
191 : {
192 : JS_ASSERT(!IsPoisonedValue(v));
193 : post(obj, slot);
194 : }
195 :
196 : inline
197 : HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const HeapSlot &s)
198 : : EncapsulatedValue(s.value)
199 : {
200 : JS_ASSERT(!IsPoisonedValue(s.value));
201 : post(obj, slot);
202 : }
203 :
204 : inline
205 139596 : HeapSlot::~HeapSlot()
206 : {
207 69798 : pre();
208 69798 : }
209 :
210 : inline void
211 21992660 : HeapSlot::init(JSObject *obj, uint32_t slot, const Value &v)
212 : {
213 21992660 : value = v;
214 21992660 : post(obj, slot);
215 21992660 : }
216 :
217 : inline void
218 29746888 : HeapSlot::init(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
219 : {
220 29746888 : value = v;
221 29746888 : post(comp, obj, slot);
222 29746888 : }
223 :
224 : inline void
225 86568095 : HeapSlot::set(JSObject *obj, uint32_t slot, const Value &v)
226 : {
227 86568095 : JS_ASSERT_IF(!obj->isArray(), &obj->getSlotRef(slot) == this);
228 86568095 : JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
229 :
230 86568095 : pre();
231 86568095 : JS_ASSERT(!IsPoisonedValue(v));
232 86568095 : value = v;
233 86568095 : post(obj, slot);
234 86568095 : }
235 :
236 : inline void
237 1337453 : HeapSlot::set(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
238 : {
239 1337453 : JS_ASSERT_IF(!obj->isArray(), &const_cast<JSObject *>(obj)->getSlotRef(slot) == this);
240 1337453 : JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
241 1337453 : JS_ASSERT(obj->compartment() == comp);
242 :
243 1337453 : pre(comp);
244 1337453 : JS_ASSERT(!IsPoisonedValue(v));
245 1337453 : value = v;
246 1337453 : post(comp, obj, slot);
247 1337453 : }
248 :
249 : inline void
250 108560755 : HeapSlot::writeBarrierPost(JSObject *obj, uint32_t slot)
251 : {
252 108560755 : }
253 :
254 : inline void
255 31084341 : HeapSlot::writeBarrierPost(JSCompartment *comp, JSObject *obj, uint32_t slotno)
256 : {
257 31084341 : }
258 :
259 : inline void
260 108560755 : HeapSlot::post(JSObject *owner, uint32_t slot)
261 : {
262 108560755 : HeapSlot::writeBarrierPost(owner, slot);
263 108560755 : }
264 :
265 : inline void
266 31084341 : HeapSlot::post(JSCompartment *comp, JSObject *owner, uint32_t slot)
267 : {
268 31084341 : HeapSlot::writeBarrierPost(comp, owner, slot);
269 31084341 : }
270 :
271 : inline
272 20700681 : HeapId::HeapId(jsid id)
273 20700681 : : value(id)
274 : {
275 20700681 : JS_ASSERT(!IsPoisonedId(id));
276 20700681 : post();
277 20700681 : }
278 :
279 : inline
280 48428 : HeapId::~HeapId()
281 : {
282 48428 : pre();
283 48428 : }
284 :
285 : inline void
286 27045 : HeapId::init(jsid id)
287 : {
288 27045 : JS_ASSERT(!IsPoisonedId(id));
289 27045 : value = id;
290 27045 : post();
291 27045 : }
292 :
293 : inline void
294 57692 : HeapId::pre()
295 : {
296 : #ifdef JSGC_INCREMENTAL
297 57692 : if (JSID_IS_OBJECT(value)) {
298 0 : JSObject *obj = JSID_TO_OBJECT(value);
299 0 : JSCompartment *comp = obj->compartment();
300 0 : if (comp->needsBarrier()) {
301 0 : js::gc::MarkObjectUnbarriered(comp->barrierTracer(), &obj, "write barrier");
302 0 : JS_ASSERT(obj == JSID_TO_OBJECT(value));
303 : }
304 57692 : } else if (JSID_IS_STRING(value)) {
305 26483 : JSString *str = JSID_TO_STRING(value);
306 26483 : JSCompartment *comp = str->compartment();
307 26483 : if (comp->needsBarrier()) {
308 0 : js::gc::MarkStringUnbarriered(comp->barrierTracer(), &str, "write barrier");
309 0 : JS_ASSERT(str == JSID_TO_STRING(value));
310 : }
311 : }
312 : #endif
313 57692 : }
314 :
315 : inline void
316 20744380 : HeapId::post()
317 : {
318 20744380 : }
319 :
320 : inline HeapId &
321 : HeapId::operator=(jsid id)
322 : {
323 : if (id != value)
324 : pre();
325 : JS_ASSERT(!IsPoisonedId(id));
326 : value = id;
327 : post();
328 : return *this;
329 : }
330 :
331 : inline HeapId &
332 16654 : HeapId::operator=(const HeapId &v)
333 : {
334 16654 : if (v.value != value)
335 9264 : pre();
336 16654 : JS_ASSERT(!IsPoisonedId(v.value));
337 16654 : value = v.value;
338 16654 : post();
339 16654 : return *this;
340 : }
341 :
342 : inline const Value &
343 122026 : ReadBarrieredValue::get() const
344 : {
345 122026 : if (value.isObject())
346 108666 : JSObject::readBarrier(&value.toObject());
347 13360 : else if (value.isString())
348 13360 : JSString::readBarrier(value.toString());
349 : else
350 0 : JS_ASSERT(!value.isMarkable());
351 :
352 122026 : return value;
353 : }
354 :
355 : inline
356 122025 : ReadBarrieredValue::operator const Value &() const
357 : {
358 122025 : return get();
359 : }
360 :
361 : inline JSObject &
362 1 : ReadBarrieredValue::toObject() const
363 : {
364 1 : return get().toObject();
365 : }
366 :
367 : } /* namespace js */
368 :
369 : #endif /* jsgc_barrier_inl_h___ */
|