1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=99 ft=cpp:
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 Mozilla SpiderMonkey JavaScript 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 the GNU General Public License Version 2 or later (the "GPL"), or
28 : * 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 js_utility_h__
41 : #define js_utility_h__
42 :
43 : #include "mozilla/Assertions.h"
44 :
45 : #include <stdlib.h>
46 : #include <string.h>
47 :
48 : #ifdef JS_OOM_DO_BACKTRACES
49 : #include <stdio.h>
50 : #include <execinfo.h>
51 : #endif
52 :
53 : #include "jstypes.h"
54 :
55 : #ifdef __cplusplus
56 :
57 : /* The public JS engine namespace. */
58 : namespace JS {}
59 :
60 : /* The mozilla-shared reusable template/utility namespace. */
61 : namespace mozilla {}
62 :
63 : /* The private JS engine namespace. */
64 : namespace js {
65 :
66 : /* The private namespace is a superset of the public/shared namespaces. */
67 : using namespace JS;
68 : using namespace mozilla;
69 :
70 : } /* namespace js */
71 : #endif /* __cplusplus */
72 :
73 : JS_BEGIN_EXTERN_C
74 :
75 : /*
76 : * Pattern used to overwrite freed memory. If you are accessing an object with
77 : * this pattern, you probably have a dangling pointer.
78 : */
79 : #define JS_FREE_PATTERN 0xDA
80 :
81 : #define JS_ASSERT(expr) MOZ_ASSERT(expr)
82 : #define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF(cond, expr)
83 : #define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason)
84 : #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr)
85 : #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr)
86 :
87 : #ifdef DEBUG
88 : # ifdef JS_THREADSAFE
89 : # define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr)
90 : # else
91 : # define JS_THREADSAFE_ASSERT(expr) ((void) 0)
92 : # endif
93 : #else
94 : # define JS_THREADSAFE_ASSERT(expr) ((void) 0)
95 : #endif
96 :
97 : #define JS_STATIC_ASSERT(cond) MOZ_STATIC_ASSERT(cond, "JS_STATIC_ASSERT")
98 : #define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF")
99 :
100 : /*
101 : * Abort the process in a non-graceful manner. This will cause a core file,
102 : * call to the debugger or other moral equivalent as well as causing the
103 : * entire process to stop.
104 : */
105 : extern JS_PUBLIC_API(void) JS_Abort(void);
106 :
107 : /*
108 : * Custom allocator support for SpiderMonkey
109 : */
110 : #if defined JS_USE_CUSTOM_ALLOCATOR
111 : # include "jscustomallocator.h"
112 : #else
113 : # ifdef DEBUG
114 : /*
115 : * In order to test OOM conditions, when the shell command-line option
116 : * |-A NUM| is passed, we fail continuously after the NUM'th allocation.
117 : */
118 : extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set from shell/js.cpp */
119 : extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */
120 :
121 : #ifdef JS_OOM_DO_BACKTRACES
122 : #define JS_OOM_BACKTRACE_SIZE 32
123 : static JS_ALWAYS_INLINE void
124 : PrintBacktrace()
125 : {
126 : void* OOM_trace[JS_OOM_BACKTRACE_SIZE];
127 : char** OOM_traceSymbols = NULL;
128 : int32_t OOM_traceSize = 0;
129 : int32_t OOM_traceIdx = 0;
130 : OOM_traceSize = backtrace(OOM_trace, JS_OOM_BACKTRACE_SIZE);
131 : OOM_traceSymbols = backtrace_symbols(OOM_trace, OOM_traceSize);
132 :
133 : if (!OOM_traceSymbols)
134 : return;
135 :
136 : for (OOM_traceIdx = 0; OOM_traceIdx < OOM_traceSize; ++OOM_traceIdx) {
137 : fprintf(stderr, "#%d %s\n", OOM_traceIdx, OOM_traceSymbols[OOM_traceIdx]);
138 : }
139 :
140 : free(OOM_traceSymbols);
141 : }
142 :
143 : #define JS_OOM_EMIT_BACKTRACE() \
144 : do {\
145 : fprintf(stderr, "Forcing artificial memory allocation function failure:\n");\
146 : PrintBacktrace();\
147 : } while (0)
148 : # else
149 : # define JS_OOM_EMIT_BACKTRACE() do {} while(0)
150 : #endif /* JS_OOM_DO_BACKTRACES */
151 :
152 : # define JS_OOM_POSSIBLY_FAIL() \
153 : do \
154 : { \
155 : if (++OOM_counter > OOM_maxAllocations) { \
156 : JS_OOM_EMIT_BACKTRACE();\
157 : return NULL; \
158 : } \
159 : } while (0)
160 :
161 : # else
162 : # define JS_OOM_POSSIBLY_FAIL() do {} while(0)
163 : # endif
164 :
165 : /*
166 : * SpiderMonkey code should not be calling these allocation functions directly.
167 : * Instead, all calls should go through JSRuntime, JSContext or OffTheBooks.
168 : * However, js_free() can be called directly.
169 : */
170 52567268 : static JS_INLINE void* js_malloc(size_t bytes)
171 : {
172 52567268 : JS_OOM_POSSIBLY_FAIL();
173 52567268 : return malloc(bytes);
174 : }
175 :
176 2831700 : static JS_INLINE void* js_calloc(size_t bytes)
177 : {
178 2831700 : JS_OOM_POSSIBLY_FAIL();
179 2831700 : return calloc(bytes, 1);
180 : }
181 :
182 7774069 : static JS_INLINE void* js_realloc(void* p, size_t bytes)
183 : {
184 7774069 : JS_OOM_POSSIBLY_FAIL();
185 7774069 : return realloc(p, bytes);
186 : }
187 :
188 70670004 : static JS_INLINE void js_free(void* p)
189 : {
190 70670004 : free(p);
191 70670004 : }
192 : #endif/* JS_USE_CUSTOM_ALLOCATOR */
193 :
194 : /*
195 : * Replace bit-scanning code sequences with CPU-specific instructions to
196 : * speedup calculations of ceiling/floor log2.
197 : *
198 : * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129.
199 : *
200 : * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856.
201 : */
202 : #if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
203 :
204 : unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);
205 : unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask);
206 : # pragma intrinsic(_BitScanForward,_BitScanReverse)
207 :
208 : __forceinline static int
209 : __BitScanForward32(unsigned int val)
210 : {
211 : unsigned long idx;
212 :
213 : _BitScanForward(&idx, (unsigned long)val);
214 : return (int)idx;
215 : }
216 : __forceinline static int
217 : __BitScanReverse32(unsigned int val)
218 : {
219 : unsigned long idx;
220 :
221 : _BitScanReverse(&idx, (unsigned long)val);
222 : return (int)(31-idx);
223 : }
224 : # define js_bitscan_ctz32(val) __BitScanForward32(val)
225 : # define js_bitscan_clz32(val) __BitScanReverse32(val)
226 : # define JS_HAS_BUILTIN_BITSCAN32
227 :
228 : #if defined(_M_AMD64) || defined(_M_X64)
229 : unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask);
230 : unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask);
231 : # pragma intrinsic(_BitScanForward64,_BitScanReverse64)
232 :
233 : __forceinline static int
234 : __BitScanForward64(unsigned __int64 val)
235 : {
236 : unsigned long idx;
237 :
238 : _BitScanForward64(&idx, val);
239 : return (int)idx;
240 : }
241 : __forceinline static int
242 : __BitScanReverse64(unsigned __int64 val)
243 : {
244 : unsigned long idx;
245 :
246 : _BitScanReverse64(&idx, val);
247 : return (int)(63-idx);
248 : }
249 : # define js_bitscan_ctz64(val) __BitScanForward64(val)
250 : # define js_bitscan_clz64(val) __BitScanReverse64(val)
251 : # define JS_HAS_BUILTIN_BITSCAN64
252 : #endif
253 : #elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
254 :
255 : # define js_bitscan_ctz32(val) __builtin_ctz(val)
256 : # define js_bitscan_clz32(val) __builtin_clz(val)
257 : # define JS_HAS_BUILTIN_BITSCAN32
258 : # if (JS_BYTES_PER_WORD == 8)
259 : # define js_bitscan_ctz64(val) __builtin_ctzll(val)
260 : # define js_bitscan_clz64(val) __builtin_clzll(val)
261 : # define JS_HAS_BUILTIN_BITSCAN64
262 : # endif
263 :
264 : #endif
265 :
266 : /*
267 : ** Macro version of JS_CeilingLog2: Compute the log of the least power of
268 : ** 2 greater than or equal to _n. The result is returned in _log2.
269 : */
270 : #ifdef JS_HAS_BUILTIN_BITSCAN32
271 : /*
272 : * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)).
273 : * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is
274 : * undefined.
275 : */
276 : # define JS_CEILING_LOG2(_log2,_n) \
277 : JS_BEGIN_MACRO \
278 : unsigned int j_ = (unsigned int)(_n); \
279 : (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \
280 : JS_END_MACRO
281 : #else
282 : # define JS_CEILING_LOG2(_log2,_n) \
283 : JS_BEGIN_MACRO \
284 : uint32_t j_ = (uint32_t)(_n); \
285 : (_log2) = 0; \
286 : if ((j_) & ((j_)-1)) \
287 : (_log2) += 1; \
288 : if ((j_) >> 16) \
289 : (_log2) += 16, (j_) >>= 16; \
290 : if ((j_) >> 8) \
291 : (_log2) += 8, (j_) >>= 8; \
292 : if ((j_) >> 4) \
293 : (_log2) += 4, (j_) >>= 4; \
294 : if ((j_) >> 2) \
295 : (_log2) += 2, (j_) >>= 2; \
296 : if ((j_) >> 1) \
297 : (_log2) += 1; \
298 : JS_END_MACRO
299 : #endif
300 :
301 : /*
302 : ** Macro version of JS_FloorLog2: Compute the log of the greatest power of
303 : ** 2 less than or equal to _n. The result is returned in _log2.
304 : **
305 : ** This is equivalent to finding the highest set bit in the word.
306 : */
307 : #ifdef JS_HAS_BUILTIN_BITSCAN32
308 : /*
309 : * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)).
310 : * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1
311 : * to ensure 0 result when _n == 0.
312 : */
313 : # define JS_FLOOR_LOG2(_log2,_n) \
314 : JS_BEGIN_MACRO \
315 : (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \
316 : JS_END_MACRO
317 : #else
318 : # define JS_FLOOR_LOG2(_log2,_n) \
319 : JS_BEGIN_MACRO \
320 : uint32_t j_ = (uint32_t)(_n); \
321 : (_log2) = 0; \
322 : if ((j_) >> 16) \
323 : (_log2) += 16, (j_) >>= 16; \
324 : if ((j_) >> 8) \
325 : (_log2) += 8, (j_) >>= 8; \
326 : if ((j_) >> 4) \
327 : (_log2) += 4, (j_) >>= 4; \
328 : if ((j_) >> 2) \
329 : (_log2) += 2, (j_) >>= 2; \
330 : if ((j_) >> 1) \
331 : (_log2) += 1; \
332 : JS_END_MACRO
333 : #endif
334 :
335 : /*
336 : * Internal function.
337 : * Compute the log of the least power of 2 greater than or equal to n. This is
338 : * a version of JS_CeilingLog2 that operates on unsigned integers with
339 : * CPU-dependant size.
340 : */
341 : #define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1))
342 :
343 : /*
344 : * Internal function.
345 : * Compute the log of the greatest power of 2 less than or equal to n.
346 : * This is a version of JS_FloorLog2 that operates on unsigned integers with
347 : * CPU-dependant size and requires that n != 0.
348 : */
349 : #define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n))
350 :
351 : #if JS_BYTES_PER_WORD == 4
352 : # ifdef JS_HAS_BUILTIN_BITSCAN32
353 : # define js_FloorLog2wImpl(n) \
354 : ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
355 : # else
356 : JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n);
357 : # endif
358 : #elif JS_BYTES_PER_WORD == 8
359 : # ifdef JS_HAS_BUILTIN_BITSCAN64
360 : # define js_FloorLog2wImpl(n) \
361 : ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
362 : # else
363 : JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n);
364 : # endif
365 : #else
366 : # error "NOT SUPPORTED"
367 : #endif
368 :
369 : JS_END_EXTERN_C
370 :
371 : #ifdef __cplusplus
372 : #include <new>
373 :
374 : /*
375 : * User guide to memory management within SpiderMonkey:
376 : *
377 : * Quick tips:
378 : *
379 : * Allocation:
380 : * - Prefer to allocate using JSContext:
381 : * cx->{malloc_,realloc_,calloc_,new_,array_new}
382 : *
383 : * - If no JSContext is available, use a JSRuntime:
384 : * rt->{malloc_,realloc_,calloc_,new_,array_new}
385 : *
386 : * - As a last resort, use unaccounted allocation ("OffTheBooks"):
387 : * js::OffTheBooks::{malloc_,realloc_,calloc_,new_,array_new}
388 : *
389 : * Deallocation:
390 : * - When the deallocation occurs on a slow path, use:
391 : * Foreground::{free_,delete_,array_delete}
392 : *
393 : * - Otherwise deallocate on a background thread using a JSContext:
394 : * cx->{free_,delete_,array_delete}
395 : *
396 : * - If no JSContext is available, use a JSRuntime:
397 : * rt->{free_,delete_,array_delete}
398 : *
399 : * - As a last resort, use UnwantedForeground deallocation:
400 : * js::UnwantedForeground::{free_,delete_,array_delete}
401 : *
402 : * General tips:
403 : *
404 : * - Mixing and matching these allocators is allowed (you may free memory
405 : * allocated by any allocator, with any deallocator).
406 : *
407 : * - Never, ever use normal C/C++ memory management:
408 : * malloc, free, new, new[], delete, operator new, etc.
409 : *
410 : * - Never, ever use low-level SpiderMonkey allocators:
411 : * js_malloc(), js_free(), js_calloc(), js_realloc()
412 : * Their use is reserved for the other memory managers.
413 : *
414 : * - Classes which have private constructors or destructors should have
415 : * JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR added to their
416 : * declaration.
417 : *
418 : * Details:
419 : *
420 : * Using vanilla new/new[] is unsafe in SpiderMonkey because they throw on
421 : * failure instead of returning NULL, which is what SpiderMonkey expects.
422 : * (Even overriding them is unsafe, as the system's C++ runtime library may
423 : * throw, which we do not support. We also can't just use the 'nothrow'
424 : * variant of new/new[], because we want to mediate *all* allocations
425 : * within SpiderMonkey, to satisfy any embedders using
426 : * JS_USE_CUSTOM_ALLOCATOR.)
427 : *
428 : * JSContexts and JSRuntimes keep track of memory allocated, and use this
429 : * accounting to schedule GC. OffTheBooks does not. We'd like to remove
430 : * OffTheBooks allocations as much as possible (bug 636558).
431 : *
432 : * On allocation failure, a JSContext correctly reports an error, which a
433 : * JSRuntime and OffTheBooks does not.
434 : *
435 : * A JSContext deallocates in a background thread. A JSRuntime might
436 : * deallocate in the background in the future, but does not now. Foreground
437 : * deallocation is preferable on slow paths. UnwantedForeground deallocations
438 : * occur where we have no JSContext or JSRuntime, and the deallocation is not
439 : * on a slow path. We want to remove UnwantedForeground deallocations (bug
440 : * 636561).
441 : *
442 : * JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR makes the allocation
443 : * classes friends with your class, giving them access to private
444 : * constructors and destructors.
445 : *
446 : * |make check| does a source level check on the number of uses OffTheBooks,
447 : * UnwantedForeground, js_malloc, js_free etc, to prevent regressions. If you
448 : * really must add one, update Makefile.in, and run |make check|.
449 : *
450 : * |make check| also statically prevents the use of vanilla new/new[].
451 : */
452 :
453 : #define JS_NEW_BODY(allocator, t, parms) \
454 : void *memory = allocator(sizeof(t)); \
455 : return memory ? new(memory) t parms : NULL;
456 :
457 : /*
458 : * Given a class which should provide new_() methods, add
459 : * JS_DECLARE_NEW_METHODS (see JSContext for a usage example). This
460 : * adds new_()s with up to 12 parameters. Add more versions of new_ below if
461 : * you need more than 12 parameters.
462 : *
463 : * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS,
464 : * or the build will break.
465 : */
466 : #define JS_DECLARE_NEW_METHODS(ALLOCATOR, QUALIFIERS)\
467 : template <class T>\
468 : QUALIFIERS T *new_() {\
469 : JS_NEW_BODY(ALLOCATOR, T, ())\
470 : }\
471 : \
472 : template <class T, class P1>\
473 : QUALIFIERS T *new_(P1 p1) {\
474 : JS_NEW_BODY(ALLOCATOR, T, (p1))\
475 : }\
476 : \
477 : template <class T, class P1, class P2>\
478 : QUALIFIERS T *new_(P1 p1, P2 p2) {\
479 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2))\
480 : }\
481 : \
482 : template <class T, class P1, class P2, class P3>\
483 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3) {\
484 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3))\
485 : }\
486 : \
487 : template <class T, class P1, class P2, class P3, class P4>\
488 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4) {\
489 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4))\
490 : }\
491 : \
492 : template <class T, class P1, class P2, class P3, class P4, class P5>\
493 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
494 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5))\
495 : }\
496 : \
497 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6>\
498 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
499 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6))\
500 : }\
501 : \
502 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>\
503 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
504 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7))\
505 : }\
506 : \
507 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>\
508 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
509 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8))\
510 : }\
511 : \
512 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>\
513 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
514 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9))\
515 : }\
516 : \
517 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>\
518 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
519 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))\
520 : }\
521 : \
522 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>\
523 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
524 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))\
525 : }\
526 : \
527 : template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>\
528 : QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
529 : JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))\
530 : }\
531 : static const int JSMinAlignment = 8;\
532 : template <class T>\
533 : QUALIFIERS T *array_new(size_t n) {\
534 : /* The length is stored just before the vector memory. */\
535 : uint64_t numBytes64 = uint64_t(JSMinAlignment) + uint64_t(sizeof(T)) * uint64_t(n);\
536 : size_t numBytes = size_t(numBytes64);\
537 : if (numBytes64 != numBytes) {\
538 : JS_ASSERT(0); /* we want to know if this happens in debug builds */\
539 : return NULL;\
540 : }\
541 : void *memory = ALLOCATOR(numBytes);\
542 : if (!memory)\
543 : return NULL;\
544 : *(size_t *)memory = n;\
545 : memory = (void*)(uintptr_t(memory) + JSMinAlignment);\
546 : return new(memory) T[n];\
547 : }\
548 :
549 :
550 : #define JS_DECLARE_DELETE_METHODS(DEALLOCATOR, QUALIFIERS)\
551 : template <class T>\
552 : QUALIFIERS void delete_(T *p) {\
553 : if (p) {\
554 : p->~T();\
555 : DEALLOCATOR(p);\
556 : }\
557 : }\
558 : \
559 : template <class T>\
560 : QUALIFIERS void array_delete(T *p) {\
561 : if (p) {\
562 : void* p0 = (void *)(uintptr_t(p) - js::OffTheBooks::JSMinAlignment);\
563 : size_t n = *(size_t *)p0;\
564 : for (size_t i = 0; i < n; i++)\
565 : (p + i)->~T();\
566 : DEALLOCATOR(p0);\
567 : }\
568 : }
569 :
570 :
571 : /*
572 : * In general, all allocations should go through a JSContext or JSRuntime, so
573 : * that the garbage collector knows how much memory has been allocated. In
574 : * cases where it is difficult to use a JSContext or JSRuntime, OffTheBooks can
575 : * be used, though this is undesirable.
576 : */
577 : namespace js {
578 :
579 : class OffTheBooks {
580 : public:
581 1983568 : JS_DECLARE_NEW_METHODS(::js_malloc, JS_ALWAYS_INLINE static)
582 :
583 2042291 : static JS_INLINE void* malloc_(size_t bytes) {
584 2042291 : return ::js_malloc(bytes);
585 : }
586 :
587 568160 : static JS_INLINE void* calloc_(size_t bytes) {
588 568160 : return ::js_calloc(bytes);
589 : }
590 :
591 5140818 : static JS_INLINE void* realloc_(void* p, size_t bytes) {
592 5140818 : return ::js_realloc(p, bytes);
593 : }
594 : };
595 :
596 : /*
597 : * We generally prefer deallocating using JSContext because it can happen in
598 : * the background. On slow paths, we may prefer foreground allocation.
599 : */
600 : class Foreground {
601 : public:
602 : /* See parentheses comment above. */
603 44246150 : static JS_ALWAYS_INLINE void free_(void* p) {
604 44246150 : ::js_free(p);
605 44246151 : }
606 :
607 1238681 : JS_DECLARE_DELETE_METHODS(::js_free, JS_ALWAYS_INLINE static)
608 : };
609 :
610 : class UnwantedForeground : public Foreground {
611 : };
612 :
613 : } /* namespace js */
614 :
615 : /*
616 : * Note lack of ; in JSRuntime below. This is intentional so "calling" this
617 : * looks "normal".
618 : */
619 : #define JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR \
620 : friend class js::OffTheBooks;\
621 : friend class js::Foreground;\
622 : friend class js::UnwantedForeground;\
623 : friend struct ::JSContext;\
624 : friend struct ::JSRuntime
625 :
626 : /*
627 : * The following classes are designed to cause assertions to detect
628 : * inadvertent use of guard objects as temporaries. In other words,
629 : * when we have a guard object whose only purpose is its constructor and
630 : * destructor (and is never otherwise referenced), the intended use
631 : * might be:
632 : * JSAutoTempValueRooter tvr(cx, 1, &val);
633 : * but is is easy to accidentally write:
634 : * JSAutoTempValueRooter(cx, 1, &val);
635 : * which compiles just fine, but runs the destructor well before the
636 : * intended time.
637 : *
638 : * They work by adding (#ifdef DEBUG) an additional parameter to the
639 : * guard object's constructor, with a default value, so that users of
640 : * the guard object's API do not need to do anything. The default value
641 : * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998),
642 : * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a
643 : * guarantee that temporaries are destroyed in the reverse of their
644 : * construction order, but I actually can't find a statement that that
645 : * is true in the general case (beyond the two specific cases mentioned
646 : * there). However, it seems to be true.
647 : *
648 : * These classes are intended to be used only via the macros immediately
649 : * below them:
650 : * JS_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member
651 : * variable, and should be put where a declaration of a private
652 : * member variable would be placed.
653 : * JS_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the
654 : * parameters to each constructor of the guard object; it declares
655 : * (ifdef DEBUG) an additional parameter.
656 : * JS_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each
657 : * constructor. It uses the parameter declared by
658 : * JS_GUARD_OBJECT_NOTIFIER_PARAM.
659 : */
660 : #ifdef DEBUG
661 : class JS_FRIEND_API(JSGuardObjectNotifier)
662 : {
663 : private:
664 : bool* mStatementDone;
665 : public:
666 876422621 : JSGuardObjectNotifier() : mStatementDone(NULL) {}
667 :
668 876422583 : ~JSGuardObjectNotifier() {
669 876422583 : *mStatementDone = true;
670 876422583 : }
671 :
672 876422590 : void setStatementDone(bool *aStatementDone) {
673 876422590 : mStatementDone = aStatementDone;
674 876422590 : }
675 : };
676 :
677 : class JS_FRIEND_API(JSGuardObjectNotificationReceiver)
678 : {
679 : private:
680 : bool mStatementDone;
681 : public:
682 876422596 : JSGuardObjectNotificationReceiver() : mStatementDone(false) {}
683 :
684 876422607 : ~JSGuardObjectNotificationReceiver() {
685 : /*
686 : * Assert that the guard object was not used as a temporary.
687 : * (Note that this assert might also fire if Init is not called
688 : * because the guard object's implementation is not using the
689 : * above macros correctly.)
690 : */
691 876422607 : JS_ASSERT(mStatementDone);
692 876422607 : }
693 :
694 876422604 : void Init(const JSGuardObjectNotifier &aNotifier) {
695 : /*
696 : * aNotifier is passed as a const reference so that we can pass a
697 : * temporary, but we really intend it as non-const
698 : */
699 : const_cast<JSGuardObjectNotifier&>(aNotifier).
700 876422604 : setStatementDone(&mStatementDone);
701 876422584 : }
702 : };
703 :
704 : #define JS_DECL_USE_GUARD_OBJECT_NOTIFIER \
705 : JSGuardObjectNotificationReceiver _mCheckNotUsedAsTemporary;
706 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM \
707 : , const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier()
708 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT \
709 : , const JSGuardObjectNotifier& _notifier
710 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM0 \
711 : const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier()
712 : #define JS_GUARD_OBJECT_NOTIFIER_INIT \
713 : JS_BEGIN_MACRO _mCheckNotUsedAsTemporary.Init(_notifier); JS_END_MACRO
714 :
715 : #else /* defined(DEBUG) */
716 :
717 : #define JS_DECL_USE_GUARD_OBJECT_NOTIFIER
718 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM
719 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT
720 : #define JS_GUARD_OBJECT_NOTIFIER_PARAM0
721 : #define JS_GUARD_OBJECT_NOTIFIER_INIT JS_BEGIN_MACRO JS_END_MACRO
722 :
723 : #endif /* !defined(DEBUG) */
724 :
725 : namespace js {
726 :
727 : /*
728 : * "Move" References
729 : *
730 : * Some types can be copied much more efficiently if we know the original's
731 : * value need not be preserved --- that is, if we are doing a "move", not a
732 : * "copy". For example, if we have:
733 : *
734 : * Vector<T> u;
735 : * Vector<T> v(u);
736 : *
737 : * the constructor for v must apply a copy constructor to each element of u ---
738 : * taking time linear in the length of u. However, if we know we will not need u
739 : * any more once v has been initialized, then we could initialize v very
740 : * efficiently simply by stealing u's dynamically allocated buffer and giving it
741 : * to v --- a constant-time operation, regardless of the size of u.
742 : *
743 : * Moves often appear in container implementations. For example, when we append
744 : * to a vector, we may need to resize its buffer. This entails moving each of
745 : * its extant elements from the old, smaller buffer to the new, larger buffer.
746 : * But once the elements have been migrated, we're just going to throw away the
747 : * old buffer; we don't care if they still have their values. So if the vector's
748 : * element type can implement "move" more efficiently than "copy", the vector
749 : * resizing should by all means use a "move" operation. Hash tables also need to
750 : * be resized.
751 : *
752 : * The details of the optimization, and whether it's worth applying, vary from
753 : * one type to the next. And while some constructor calls are moves, many really
754 : * are copies, and can't be optimized this way. So we need:
755 : *
756 : * 1) a way for a particular invocation of a copy constructor to say that it's
757 : * really a move, and that the value of the original isn't important
758 : * afterwards (althought it must still be safe to destroy); and
759 : *
760 : * 2) a way for a type (like Vector) to announce that it can be moved more
761 : * efficiently than it can be copied, and provide an implementation of that
762 : * move operation.
763 : *
764 : * The Move(T &) function takes a reference to a T, and returns an MoveRef<T>
765 : * referring to the same value; that's 1). An MoveRef<T> is simply a reference
766 : * to a T, annotated to say that a copy constructor applied to it may move that
767 : * T, instead of copying it. Finally, a constructor that accepts an MoveRef<T>
768 : * should perform a more efficient move, instead of a copy, providing 2).
769 : *
770 : * So, where we might define a copy constructor for a class C like this:
771 : *
772 : * C(const C &rhs) { ... copy rhs to this ... }
773 : *
774 : * we would declare a move constructor like this:
775 : *
776 : * C(MoveRef<C> rhs) { ... move rhs to this ... }
777 : *
778 : * And where we might perform a copy like this:
779 : *
780 : * C c2(c1);
781 : *
782 : * we would perform a move like this:
783 : *
784 : * C c2(Move(c1))
785 : *
786 : * Note that MoveRef<T> implicitly converts to T &, so you can pass an
787 : * MoveRef<T> to an ordinary copy constructor for a type that doesn't support a
788 : * special move constructor, and you'll just get a copy. This means that
789 : * templates can use Move whenever they know they won't use the original value
790 : * any more, even if they're not sure whether the type at hand has a specialized
791 : * move constructor. If it doesn't, the MoveRef<T> will just convert to a T &,
792 : * and the ordinary copy constructor will apply.
793 : *
794 : * A class with a move constructor can also provide a move assignment operator,
795 : * which runs this's destructor, and then applies the move constructor to
796 : * *this's memory. A typical definition:
797 : *
798 : * C &operator=(MoveRef<C> rhs) {
799 : * this->~C();
800 : * new(this) C(rhs);
801 : * return *this;
802 : * }
803 : *
804 : * With that in place, one can write move assignments like this:
805 : *
806 : * c2 = Move(c1);
807 : *
808 : * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but
809 : * destructible state.
810 : *
811 : * This header file defines MoveRef and Move in the js namespace. It's up to
812 : * individual containers to annotate moves as such, by calling Move; and it's up
813 : * to individual types to define move constructors.
814 : *
815 : * One hint: if you're writing a move constructor where the type has members
816 : * that should be moved themselves, it's much nicer to write this:
817 : *
818 : * C(MoveRef<C> c) : x(c->x), y(c->y) { }
819 : *
820 : * than the equivalent:
821 : *
822 : * C(MoveRef<C> c) { new(&x) X(c->x); new(&y) Y(c->y); }
823 : *
824 : * especially since GNU C++ fails to notice that this does indeed initialize x
825 : * and y, which may matter if they're const.
826 : */
827 : template<typename T>
828 : class MoveRef {
829 : public:
830 : typedef T Referent;
831 623848219 : explicit MoveRef(T &t) : pointer(&t) { }
832 : T &operator*() const { return *pointer; }
833 503115273 : T *operator->() const { return pointer; }
834 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
835 : /*
836 : * If MoveRef is used in a rvalue position (which is expected), we can
837 : * end up in a situation where, without this ifdef, we would try to pass
838 : * a T& to a move constructor, which fails. It is not clear if the compiler
839 : * should instead use the copy constructor, but for now this lets us build
840 : * with clang. See bug 689066 and llvm.org/pr11003 for the details.
841 : * Note: We can probably remove MoveRef completely once we are comfortable
842 : * using c++11.
843 : */
844 2625745 : operator T&& () const { return static_cast<T&&>(*pointer); }
845 : #else
846 420753712 : operator T& () const { return *pointer; }
847 : #endif
848 : private:
849 : T *pointer;
850 : };
851 :
852 : template<typename T>
853 572438269 : MoveRef<T> Move(T &t) { return MoveRef<T>(t); }
854 :
855 : template<typename T>
856 51409950 : MoveRef<T> Move(const T &t) { return MoveRef<T>(const_cast<T &>(t)); }
857 :
858 : /* Useful for implementing containers that assert non-reentrancy */
859 : class ReentrancyGuard
860 : {
861 : /* ReentrancyGuard is not copyable. */
862 : ReentrancyGuard(const ReentrancyGuard &);
863 : void operator=(const ReentrancyGuard &);
864 :
865 : #ifdef DEBUG
866 : bool &entered;
867 : #endif
868 : public:
869 : template <class T>
870 : #ifdef DEBUG
871 1658585216 : ReentrancyGuard(T &obj)
872 1658585216 : : entered(obj.entered)
873 : #else
874 : ReentrancyGuard(T &/*obj*/)
875 : #endif
876 : {
877 : #ifdef DEBUG
878 1658585216 : JS_ASSERT(!entered);
879 1658585216 : entered = true;
880 : #endif
881 1658585216 : }
882 1658585158 : ~ReentrancyGuard()
883 : {
884 : #ifdef DEBUG
885 1658585158 : entered = false;
886 : #endif
887 1658585158 : }
888 : };
889 :
890 : /*
891 : * Round x up to the nearest power of 2. This function assumes that the most
892 : * significant bit of x is not set, which would lead to overflow.
893 : */
894 : JS_ALWAYS_INLINE size_t
895 360136858 : RoundUpPow2(size_t x)
896 : {
897 360136858 : return size_t(1) << JS_CEILING_LOG2W(x);
898 : }
899 :
900 : } /* namespace js */
901 :
902 : #endif /* defined(__cplusplus) */
903 :
904 : /*
905 : * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|.
906 : */
907 : typedef size_t(*JSMallocSizeOfFun)(const void *p);
908 :
909 : /* sixgill annotation defines */
910 : #ifndef HAVE_STATIC_ANNOTATIONS
911 : # define HAVE_STATIC_ANNOTATIONS
912 : # ifdef XGILL_PLUGIN
913 : # define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
914 : # define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
915 : # define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
916 : # define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
917 : # define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
918 : # define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
919 : # define STATIC_PASTE2(X,Y) X ## Y
920 : # define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
921 : # define STATIC_ASSERT(COND) \
922 : JS_BEGIN_MACRO \
923 : __attribute__((assert_static(#COND), unused)) \
924 : int STATIC_PASTE1(assert_static_, __COUNTER__); \
925 : JS_END_MACRO
926 : # define STATIC_ASSUME(COND) \
927 : JS_BEGIN_MACRO \
928 : __attribute__((assume_static(#COND), unused)) \
929 : int STATIC_PASTE1(assume_static_, __COUNTER__); \
930 : JS_END_MACRO
931 : # define STATIC_ASSERT_RUNTIME(COND) \
932 : JS_BEGIN_MACRO \
933 : __attribute__((assert_static_runtime(#COND), unused)) \
934 : int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \
935 : JS_END_MACRO
936 : # else /* XGILL_PLUGIN */
937 : # define STATIC_PRECONDITION(COND) /* nothing */
938 : # define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
939 : # define STATIC_POSTCONDITION(COND) /* nothing */
940 : # define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
941 : # define STATIC_INVARIANT(COND) /* nothing */
942 : # define STATIC_INVARIANT_ASSUME(COND) /* nothing */
943 : # define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
944 : # define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
945 : # define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
946 : # endif /* XGILL_PLUGIN */
947 : # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
948 : #endif /* HAVE_STATIC_ANNOTATIONS */
949 :
950 : #endif /* js_utility_h__ */
|