Bug 551763: Fix deletion of arguments ident. (r=Waldo)
[mozilla-central.git] / js / src / jscntxt.h
blob900a1a89a549394842d683c4bab39623dc534c0f
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=78:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
17 * The Original Code is Mozilla Communicator client code, released
18 * March 31, 1998.
20 * The Initial Developer of the Original Code is
21 * Netscape Communications Corporation.
22 * Portions created by the Initial Developer are Copyright (C) 1998
23 * the Initial Developer. All Rights Reserved.
25 * Contributor(s):
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #ifndef jscntxt_h___
42 #define jscntxt_h___
44 * JS execution context.
46 #include <string.h>
48 #include "jsarena.h" /* Added by JSIFY */
49 #include "jsclist.h"
50 #include "jslong.h"
51 #include "jsatom.h"
52 #include "jsdhash.h"
53 #include "jsdtoa.h"
54 #include "jsgc.h"
55 #include "jshashtable.h"
56 #include "jsinterp.h"
57 #include "jsobj.h"
58 #include "jspropertycache.h"
59 #include "jspropertytree.h"
60 #include "jsprvtd.h"
61 #include "jspubtd.h"
62 #include "jsregexp.h"
63 #include "jsutil.h"
64 #include "jsarray.h"
65 #include "jstask.h"
66 #include "jsvector.h"
68 #ifdef _MSC_VER
69 #pragma warning(push)
70 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
71 #pragma warning(push)
72 #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
73 #endif
76 * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
77 * given pc in a script. We use the script->code pointer to tag the cache,
78 * instead of the script address itself, so that source notes are always found
79 * by offset from the bytecode with which they were generated.
81 typedef struct JSGSNCache {
82 jsbytecode *code;
83 JSDHashTable table;
84 #ifdef JS_GSNMETER
85 uint32 hits;
86 uint32 misses;
87 uint32 fills;
88 uint32 purges;
89 # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt)
90 #else
91 # define GSN_CACHE_METER(cache,cnt) /* nothing */
92 #endif
93 } JSGSNCache;
95 #define js_FinishGSNCache(cache) js_PurgeGSNCache(cache)
97 extern void
98 js_PurgeGSNCache(JSGSNCache *cache);
100 /* These helper macros take a cx as parameter and operate on its GSN cache. */
101 #define JS_PURGE_GSN_CACHE(cx) js_PurgeGSNCache(&JS_GSN_CACHE(cx))
102 #define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt)
104 /* Forward declarations of nanojit types. */
105 namespace nanojit {
107 class Assembler;
108 class CodeAlloc;
109 class Fragment;
110 template<typename K> struct DefaultHash;
111 template<typename K, typename V, typename H> class HashMap;
112 template<typename T> class Seq;
114 } /* namespace nanojit */
116 namespace js {
118 /* Tracer constants. */
119 static const size_t MONITOR_N_GLOBAL_STATES = 4;
120 static const size_t FRAGMENT_TABLE_SIZE = 512;
121 static const size_t MAX_NATIVE_STACK_SLOTS = 4096;
122 static const size_t MAX_CALL_STACK_ENTRIES = 500;
123 static const size_t MAX_GLOBAL_SLOTS = 4096;
124 static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1;
126 /* Forward declarations of tracer types. */
127 class VMAllocator;
128 class FrameInfoCache;
129 struct REHashFn;
130 struct REHashKey;
131 struct FrameInfo;
132 struct VMSideExit;
133 struct TreeFragment;
134 struct TracerState;
135 template<typename T> class Queue;
136 typedef Queue<uint16> SlotList;
137 class TypeMap;
138 struct REFragment;
139 typedef nanojit::HashMap<REHashKey, REFragment*, REHashFn> REHashMap;
141 #if defined(JS_JIT_SPEW) || defined(DEBUG)
142 struct FragPI;
143 typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > FragStatsMap;
144 #endif
147 * Allocation policy that calls JSContext memory functions and reports errors
148 * to the context. Since the JSContext given on construction is stored for
149 * the lifetime of the container, this policy may only be used for containers
150 * whose lifetime is a shorter than the given JSContext.
152 class ContextAllocPolicy
154 JSContext *cx;
156 public:
157 ContextAllocPolicy(JSContext *cx) : cx(cx) {}
158 JSContext *context() const { return cx; }
160 /* Inline definitions below. */
161 void *malloc(size_t bytes);
162 void free(void *p);
163 void *realloc(void *p, size_t bytes);
164 void reportAllocOverflow() const;
167 /* Holds the execution state during trace execution. */
168 struct TracerState
170 JSContext* cx; // current VM context handle
171 double* stackBase; // native stack base
172 double* sp; // native stack pointer, stack[0] is spbase[0]
173 double* eos; // first unusable word after the native stack / begin of globals
174 FrameInfo** callstackBase; // call stack base
175 void* sor; // start of rp stack
176 FrameInfo** rp; // call stack pointer
177 void* eor; // first unusable word after the call stack
178 VMSideExit* lastTreeExitGuard; // guard we exited on during a tree call
179 VMSideExit* lastTreeCallGuard; // guard we want to grow from if the tree
180 // call exit guard mismatched
181 void* rpAtLastTreeCall; // value of rp at innermost tree call guard
182 VMSideExit* outermostTreeExitGuard; // the last side exit returned by js_CallTree
183 TreeFragment* outermostTree; // the outermost tree we initially invoked
184 uintN* inlineCallCountp; // inline call count counter
185 VMSideExit** innermostNestedGuardp;
186 VMSideExit* innermost;
187 uint64 startTime;
188 TracerState* prev;
190 // Used by _FAIL builtins; see jsbuiltins.h. The builtin sets the
191 // JSBUILTIN_BAILED bit if it bails off trace and the JSBUILTIN_ERROR bit
192 // if an error or exception occurred.
193 uint32 builtinStatus;
195 // Used to communicate the location of the return value in case of a deep bail.
196 double* deepBailSp;
198 // Used when calling natives from trace to root the vp vector.
199 uintN nativeVpLen;
200 jsval* nativeVp;
202 TracerState(JSContext *cx, TraceMonitor *tm, TreeFragment *ti,
203 uintN &inlineCallCountp, VMSideExit** innermostNestedGuardp);
204 ~TracerState();
208 * Storage for the execution state and store during trace execution. Generated
209 * code depends on the fact that the globals begin |MAX_NATIVE_STACK_SLOTS|
210 * doubles after the stack begins. Thus, on trace, |TracerState::eos| holds a
211 * pointer to the first global.
213 struct TraceNativeStorage
215 double stack_global_buf[MAX_NATIVE_STACK_SLOTS + GLOBAL_SLOTS_BUFFER_SIZE];
216 FrameInfo *callstack_buf[MAX_CALL_STACK_ENTRIES];
218 double *stack() { return stack_global_buf; }
219 double *global() { return stack_global_buf + MAX_NATIVE_STACK_SLOTS; }
220 FrameInfo **callstack() { return callstack_buf; }
223 /* Holds data to track a single globa. */
224 struct GlobalState {
225 JSObject* globalObj;
226 uint32 globalShape;
227 SlotList* globalSlots;
231 * A callstack contains a set of stack frames linked by fp->down. A callstack
232 * is a member of a JSContext and all of a JSContext's callstacks are kept in a
233 * list starting at cx->currentCallStack. A callstack may be active or
234 * suspended. There are zero or one active callstacks for a context and any
235 * number of suspended contexts. If there is an active context, it is the first
236 * in the currentCallStack list, |cx->fp != NULL| and the callstack's newest
237 * (top) stack frame is |cx->fp|. For all other (suspended) callstacks, the
238 * newest frame is pointed to by suspendedFrame.
240 * While all frames in a callstack are down-linked, not all down-linked frames
241 * are in the same callstack (e.g., calling js_Execute with |down != cx->fp|
242 * will create a new frame in a new active callstack).
244 class CallStack
246 #ifdef DEBUG
247 /* The context to which this callstack belongs. */
248 JSContext *cx;
249 #endif
251 /* If this callstack is suspended, the top of the callstack. */
252 JSStackFrame *suspendedFrame;
254 /* This callstack was suspended by JS_SaveFrameChain. */
255 bool saved;
257 /* Links members of the JSContext::currentCallStack list. */
258 CallStack *previous;
260 /* The varobj on entry to initialFrame. */
261 JSObject *initialVarObj;
263 /* The first frame executed in this callstack. */
264 JSStackFrame *initialFrame;
266 public:
267 CallStack(JSContext *cx)
269 #ifdef DEBUG
270 cx(cx),
271 #endif
272 suspendedFrame(NULL), saved(false), previous(NULL),
273 initialVarObj(NULL), initialFrame(NULL)
276 #ifdef DEBUG
277 bool contains(JSStackFrame *fp);
278 #endif
280 void suspend(JSStackFrame *fp) {
281 JS_ASSERT(fp && !isSuspended() && contains(fp));
282 suspendedFrame = fp;
285 void resume() {
286 JS_ASSERT(suspendedFrame);
287 suspendedFrame = NULL;
290 JSStackFrame *getSuspendedFrame() const {
291 JS_ASSERT(suspendedFrame);
292 return suspendedFrame;
295 bool isSuspended() const { return !!suspendedFrame; }
297 void setPrevious(CallStack *cs) { previous = cs; }
298 CallStack *getPrevious() const { return previous; }
300 void setInitialVarObj(JSObject *o) { initialVarObj = o; }
301 JSObject *getInitialVarObj() const { return initialVarObj; }
303 void setInitialFrame(JSStackFrame *f) { initialFrame = f; }
304 JSStackFrame *getInitialFrame() const { return initialFrame; }
307 * Saving and restoring is a special case of suspending and resuming
308 * whereby the active callstack becomes suspended without pushing a new
309 * active callstack. This means that if a callstack c1 is pushed on top of a
310 * saved callstack c2, when c1 is popped, c2 must not be made active. In
311 * the normal case, where c2 is not saved, when c1 is popped, c2 is made
312 * active. This distinction is indicated by the |saved| flag.
315 void save(JSStackFrame *fp) {
316 suspend(fp);
317 saved = true;
320 void restore() {
321 saved = false;
322 resume();
325 bool isSaved() const {
326 JS_ASSERT_IF(saved, isSuspended());
327 return saved;
331 /* Holds the number of recording attemps for an address. */
332 typedef HashMap<jsbytecode*,
333 size_t,
334 DefaultHasher<jsbytecode*>,
335 SystemAllocPolicy> RecordAttemptMap;
337 class Oracle;
340 * Trace monitor. Every JSThread (if JS_THREADSAFE) or JSRuntime (if not
341 * JS_THREADSAFE) has an associated trace monitor that keeps track of loop
342 * frequencies for all JavaScript code loaded into that runtime.
344 struct TraceMonitor {
346 * The context currently executing JIT-compiled code on this thread, or
347 * NULL if none. Among other things, this can in certain cases prevent
348 * last-ditch GC and suppress calls to JS_ReportOutOfMemory.
350 * !tracecx && !recorder: not on trace
351 * !tracecx && recorder: recording
352 * tracecx && !recorder: executing a trace
353 * tracecx && recorder: executing inner loop, recording outer loop
355 JSContext *tracecx;
358 * Cached storage to use when executing on trace. While we may enter nested
359 * traces, we always reuse the outer trace's storage, so never need more
360 * than of these.
362 TraceNativeStorage *storage;
365 * There are 5 allocators here. This might seem like overkill, but they
366 * have different lifecycles, and by keeping them separate we keep the
367 * amount of retained memory down significantly. They are flushed (ie.
368 * all the allocated memory is freed) periodically.
370 * - dataAlloc has the lifecycle of the monitor. It's flushed only when
371 * the monitor is flushed. It's used for fragments.
373 * - traceAlloc has the same flush lifecycle as the dataAlloc, but it is
374 * also *marked* when a recording starts and rewinds to the mark point
375 * if recording aborts. So you can put things in it that are only
376 * reachable on a successful record/compile cycle like GuardRecords and
377 * SideExits.
379 * - tempAlloc is flushed after each recording, successful or not. It's
380 * used to store LIR code and for all other elements in the LIR
381 * pipeline.
383 * - reTempAlloc is just like tempAlloc, but is used for regexp
384 * compilation in RegExpNativeCompiler rather than normal compilation in
385 * TraceRecorder.
387 * - codeAlloc has the same lifetime as dataAlloc, but its API is
388 * different (CodeAlloc vs. VMAllocator). It's used for native code.
389 * It's also a good idea to keep code and data separate to avoid I-cache
390 * vs. D-cache issues.
392 VMAllocator* dataAlloc;
393 VMAllocator* traceAlloc;
394 VMAllocator* tempAlloc;
395 VMAllocator* reTempAlloc;
396 nanojit::CodeAlloc* codeAlloc;
397 nanojit::Assembler* assembler;
398 FrameInfoCache* frameCache;
400 Oracle* oracle;
401 TraceRecorder* recorder;
403 GlobalState globalStates[MONITOR_N_GLOBAL_STATES];
404 TreeFragment* vmfragments[FRAGMENT_TABLE_SIZE];
405 RecordAttemptMap* recordAttempts;
408 * Maximum size of the code cache before we start flushing. 1/16 of this
409 * size is used as threshold for the regular expression code cache.
411 uint32 maxCodeCacheBytes;
414 * If nonzero, do not flush the JIT cache after a deep bail. That would
415 * free JITted code pages that we will later return to. Instead, set the
416 * needFlush flag so that it can be flushed later.
418 JSBool needFlush;
421 * Fragment map for the regular expression compiler.
423 REHashMap* reFragments;
425 // Cached temporary typemap to avoid realloc'ing every time we create one.
426 // This must be used in only one place at a given time. It must be cleared
427 // before use.
428 TypeMap* cachedTempTypeMap;
430 #ifdef DEBUG
431 /* Fields needed for fragment/guard profiling. */
432 nanojit::Seq<nanojit::Fragment*>* branches;
433 uint32 lastFragID;
435 * profAlloc has a lifetime which spans exactly from js_InitJIT to
436 * js_FinishJIT.
438 VMAllocator* profAlloc;
439 FragStatsMap* profTab;
440 #endif
442 /* Flush the JIT cache. */
443 void flush();
445 /* Mark all objects baked into native code in the code cache. */
446 void mark(JSTracer *trc);
448 bool outOfMemory() const;
451 } /* namespace js */
454 * N.B. JS_ON_TRACE(cx) is true if JIT code is on the stack in the current
455 * thread, regardless of whether cx is the context in which that trace is
456 * executing. cx must be a context on the current thread.
458 #ifdef JS_TRACER
459 # define JS_ON_TRACE(cx) (JS_TRACE_MONITOR(cx).tracecx != NULL)
460 #else
461 # define JS_ON_TRACE(cx) JS_FALSE
462 #endif
464 #ifdef DEBUG_brendan
465 # define JS_EVAL_CACHE_METERING 1
466 # define JS_FUNCTION_METERING 1
467 #endif
469 /* Number of potentially reusable scriptsToGC to search for the eval cache. */
470 #ifndef JS_EVAL_CACHE_SHIFT
471 # define JS_EVAL_CACHE_SHIFT 6
472 #endif
473 #define JS_EVAL_CACHE_SIZE JS_BIT(JS_EVAL_CACHE_SHIFT)
475 #ifdef JS_EVAL_CACHE_METERING
476 # define EVAL_CACHE_METER_LIST(_) _(probe), _(hit), _(step), _(noscope)
477 # define identity(x) x
479 struct JSEvalCacheMeter {
480 uint64 EVAL_CACHE_METER_LIST(identity);
483 # undef identity
484 #endif
486 #ifdef JS_FUNCTION_METERING
487 # define FUNCTION_KIND_METER_LIST(_) \
488 _(allfun), _(heavy), _(nofreeupvar), _(onlyfreevar), \
489 _(display), _(flat), _(setupvar), _(badfunarg)
490 # define identity(x) x
492 struct JSFunctionMeter {
493 int32 FUNCTION_KIND_METER_LIST(identity);
496 # undef identity
497 #endif
499 struct JSLocalRootChunk;
501 #define JSLRS_CHUNK_SHIFT 8
502 #define JSLRS_CHUNK_SIZE JS_BIT(JSLRS_CHUNK_SHIFT)
503 #define JSLRS_CHUNK_MASK JS_BITMASK(JSLRS_CHUNK_SHIFT)
505 struct JSLocalRootChunk {
506 jsval roots[JSLRS_CHUNK_SIZE];
507 JSLocalRootChunk *down;
510 struct JSLocalRootStack {
511 uint32 scopeMark;
512 uint32 rootCount;
513 JSLocalRootChunk *topChunk;
514 JSLocalRootChunk firstChunk;
516 /* See comments in js_NewFinalizableGCThing. */
517 JSGCFreeLists gcFreeLists;
520 const uint32 JSLRS_NULL_MARK = uint32(-1);
522 struct JSThreadData {
523 JSGCFreeLists gcFreeLists;
526 * Flag indicating that we are waiving any soft limits on the GC heap
527 * because we want allocations to be infallible (except when we hit
528 * a hard quota).
530 bool waiveGCQuota;
533 * The GSN cache is per thread since even multi-cx-per-thread embeddings
534 * do not interleave js_GetSrcNote calls.
536 JSGSNCache gsnCache;
538 /* Property cache for faster call/get/set invocation. */
539 js::PropertyCache propertyCache;
541 /* Optional stack of heap-allocated scoped local GC roots. */
542 JSLocalRootStack *localRootStack;
544 #ifdef JS_TRACER
545 /* Trace-tree JIT recorder/interpreter state. */
546 js::TraceMonitor traceMonitor;
547 #endif
549 /* Lock-free hashed lists of scripts created by eval to garbage-collect. */
550 JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE];
552 #ifdef JS_EVAL_CACHE_METERING
553 JSEvalCacheMeter evalCacheMeter;
554 #endif
556 /* State used by dtoa.c. */
557 DtoaState *dtoaState;
560 * State used to cache some double-to-string conversions. A stupid
561 * optimization aimed directly at v8-splay.js, which stupidly converts
562 * many doubles multiple times in a row.
564 struct {
565 jsdouble d;
566 jsint base;
567 JSString *s; // if s==NULL, d and base are not valid
568 } dtoaCache;
571 * Cache of reusable JSNativeEnumerators mapped by shape identifiers (as
572 * stored in scope->shape). This cache is nulled by the GC and protected
573 * by gcLock.
575 #define NATIVE_ENUM_CACHE_LOG2 8
576 #define NATIVE_ENUM_CACHE_MASK JS_BITMASK(NATIVE_ENUM_CACHE_LOG2)
577 #define NATIVE_ENUM_CACHE_SIZE JS_BIT(NATIVE_ENUM_CACHE_LOG2)
579 #define NATIVE_ENUM_CACHE_HASH(shape) \
580 ((((shape) >> NATIVE_ENUM_CACHE_LOG2) ^ (shape)) & NATIVE_ENUM_CACHE_MASK)
582 jsuword nativeEnumCache[NATIVE_ENUM_CACHE_SIZE];
585 * One-entry deep cache of iterator objects. We deposit here the last
586 * iterator that was freed in JSOP_ENDITER.
588 JSObject *cachedIteratorObject;
590 bool init();
591 void finish();
592 void mark(JSTracer *trc);
593 void purge(JSContext *cx);
594 void purgeGCFreeLists();
597 #ifdef JS_THREADSAFE
600 * Structure uniquely representing a thread. It holds thread-private data
601 * that can be accessed without a global lock.
603 struct JSThread {
604 /* Linked list of all contexts in use on this thread. */
605 JSCList contextList;
607 /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */
608 jsword id;
610 /* Indicates that the thread is waiting in ClaimTitle from jslock.cpp. */
611 JSTitle *titleToShare;
614 * Thread-local version of JSRuntime.gcMallocBytes to avoid taking
615 * locks on each JS_malloc.
617 ptrdiff_t gcThreadMallocBytes;
620 * This thread is inside js_GC, either waiting until it can start GC, or
621 * waiting for GC to finish on another thread. This thread holds no locks;
622 * other threads may steal titles from it.
624 * Protected by rt->gcLock.
626 bool gcWaiting;
628 /* Factored out of JSThread for !JS_THREADSAFE embedding in JSRuntime. */
629 JSThreadData data;
633 * Only when JSThread::gcThreadMallocBytes exhausts the following limit we
634 * update JSRuntime::gcMallocBytes.
637 const size_t JS_GC_THREAD_MALLOC_LIMIT = 1 << 19;
639 #define JS_THREAD_DATA(cx) (&(cx)->thread->data)
641 struct JSThreadsHashEntry {
642 JSDHashEntryHdr base;
643 JSThread *thread;
646 extern JSThread *
647 js_CurrentThread(JSRuntime *rt);
650 * The function takes the GC lock and does not release in successful return.
651 * On error (out of memory) the function releases the lock but delegates
652 * the error reporting to the caller.
654 extern JSBool
655 js_InitContextThread(JSContext *cx);
658 * On entrance the GC lock must be held and it will be held on exit.
660 extern void
661 js_ClearContextThread(JSContext *cx);
663 #endif /* JS_THREADSAFE */
665 typedef enum JSDestroyContextMode {
666 JSDCM_NO_GC,
667 JSDCM_MAYBE_GC,
668 JSDCM_FORCE_GC,
669 JSDCM_NEW_FAILED
670 } JSDestroyContextMode;
672 typedef enum JSRuntimeState {
673 JSRTS_DOWN,
674 JSRTS_LAUNCHING,
675 JSRTS_UP,
676 JSRTS_LANDING
677 } JSRuntimeState;
679 typedef enum JSBuiltinFunctionId {
680 JSBUILTIN_ObjectToIterator,
681 JSBUILTIN_CallIteratorNext,
682 JSBUILTIN_LIMIT
683 } JSBuiltinFunctionId;
685 typedef struct JSPropertyTreeEntry {
686 JSDHashEntryHdr hdr;
687 JSScopeProperty *child;
688 } JSPropertyTreeEntry;
690 typedef struct JSSetSlotRequest JSSetSlotRequest;
692 struct JSSetSlotRequest {
693 JSObject *obj; /* object containing slot to set */
694 JSObject *pobj; /* new proto or parent reference */
695 uint16 slot; /* which to set, proto or parent */
696 JSPackedBool cycle; /* true if a cycle was detected */
697 JSSetSlotRequest *next; /* next request in GC worklist */
700 /* Caching Class.prototype lookups for the standard classes. */
701 struct JSClassProtoCache {
702 void purge() { js::PodArrayZero(entries); }
704 #ifdef JS_PROTO_CACHE_METERING
705 struct Stats {
706 int32 probe, hit;
708 # define PROTO_CACHE_METER(cx, x) \
709 ((void) (JS_ATOMIC_INCREMENT(&(cx)->runtime->classProtoCacheStats.x)))
710 #else
711 # define PROTO_CACHE_METER(cx, x) ((void) 0)
712 #endif
714 private:
715 struct GlobalAndProto {
716 JSObject *global;
717 JSObject *proto;
720 GlobalAndProto entries[JSProto_LIMIT - JSProto_Object];
722 #ifdef __GNUC__
723 # pragma GCC visibility push(default)
724 #endif
725 friend JSBool js_GetClassPrototype(JSContext *cx, JSObject *scope,
726 JSProtoKey protoKey, JSObject **protop,
727 JSClass *clasp);
728 #ifdef __GNUC__
729 # pragma GCC visibility pop
730 #endif
733 namespace js {
735 typedef Vector<JSGCChunkInfo *, 32, SystemAllocPolicy> GCChunks;
737 } /* namespace js */
739 struct JSRuntime {
740 /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
741 JSRuntimeState state;
743 /* Context create/destroy callback. */
744 JSContextCallback cxCallback;
747 * Shape regenerated whenever a prototype implicated by an "add property"
748 * property cache fill and induced trace guard has a readonly property or a
749 * setter defined on it. This number proxies for the shapes of all objects
750 * along the prototype chain of all objects in the runtime on which such an
751 * add-property result has been cached/traced.
753 * See bug 492355 for more details.
755 * This comes early in JSRuntime to minimize the immediate format used by
756 * trace-JITted code that reads it.
758 uint32 protoHazardShape;
760 /* Garbage collector state, used by jsgc.c. */
761 js::GCChunks gcChunks;
762 size_t gcChunkCursor;
763 #ifdef DEBUG
764 JSGCArena *gcEmptyArenaList;
765 #endif
766 JSGCArenaList gcArenaList[FINALIZE_LIMIT];
767 JSGCDoubleArenaList gcDoubleArenaList;
768 JSDHashTable gcRootsHash;
769 JSDHashTable gcLocksHash;
770 jsrefcount gcKeepAtoms;
771 size_t gcBytes;
772 size_t gcLastBytes;
773 size_t gcMaxBytes;
774 size_t gcMaxMallocBytes;
775 uint32 gcEmptyArenaPoolLifespan;
776 uint32 gcLevel;
777 uint32 gcNumber;
778 JSTracer *gcMarkingTracer;
779 uint32 gcTriggerFactor;
780 size_t gcTriggerBytes;
781 volatile JSBool gcIsNeeded;
782 volatile JSBool gcFlushCodeCaches;
785 * NB: do not pack another flag here by claiming gcPadding unless the new
786 * flag is written only by the GC thread. Atomic updates to packed bytes
787 * are not guaranteed, so stores issued by one thread may be lost due to
788 * unsynchronized read-modify-write cycles on other threads.
790 JSPackedBool gcPoke;
791 JSPackedBool gcRunning;
792 JSPackedBool gcRegenShapes;
795 * During gc, if rt->gcRegenShapes &&
796 * (scope->flags & JSScope::SHAPE_REGEN) == rt->gcRegenShapesScopeFlag,
797 * then the scope's shape has already been regenerated during this GC.
798 * To avoid having to sweep JSScopes, the bit's meaning toggles with each
799 * shape-regenerating GC.
801 * FIXME Once scopes are GC'd (bug 505004), this will be obsolete.
803 uint8 gcRegenShapesScopeFlag;
805 #ifdef JS_GC_ZEAL
806 jsrefcount gcZeal;
807 #endif
809 JSGCCallback gcCallback;
812 * Malloc counter to measure memory pressure for GC scheduling. It runs
813 * from gcMaxMallocBytes down to zero.
815 ptrdiff_t gcMallocBytes;
817 /* See comments before DelayMarkingChildren is jsgc.cpp. */
818 JSGCArena *gcUnmarkedArenaStackTop;
819 #ifdef DEBUG
820 size_t gcMarkLaterCount;
821 #endif
823 #ifdef JS_THREADSAFE
824 JSBackgroundThread gcHelperThread;
825 #endif
828 * The trace operation and its data argument to trace embedding-specific
829 * GC roots.
831 JSTraceDataOp gcExtraRootsTraceOp;
832 void *gcExtraRootsData;
835 * Used to serialize cycle checks when setting __proto__ by requesting the
836 * GC handle the required cycle detection. If the GC hasn't been poked, it
837 * won't scan for garbage. This member is protected by rt->gcLock.
839 JSSetSlotRequest *setSlotRequests;
841 /* Well-known numbers held for use by this runtime's contexts. */
842 jsval NaNValue;
843 jsval negativeInfinityValue;
844 jsval positiveInfinityValue;
846 js::DeflatedStringCache *deflatedStringCache;
848 JSString *emptyString;
851 * Builtin functions, lazily created and held for use by the trace recorder.
853 * This field would be #ifdef JS_TRACER, but XPConnect is compiled without
854 * -DJS_TRACER and includes this header.
856 JSObject *builtinFunctions[JSBUILTIN_LIMIT];
858 /* List of active contexts sharing this runtime; protected by gcLock. */
859 JSCList contextList;
861 /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
862 JSDebugHooks globalDebugHooks;
864 #ifdef JS_TRACER
865 /* True if any debug hooks not supported by the JIT are enabled. */
866 bool debuggerInhibitsJIT() const {
867 return (globalDebugHooks.interruptHook ||
868 globalDebugHooks.callHook ||
869 globalDebugHooks.objectHook);
871 #endif
873 /* More debugging state, see jsdbgapi.c. */
874 JSCList trapList;
875 JSCList watchPointList;
877 /* Client opaque pointers */
878 void *data;
880 #ifdef JS_THREADSAFE
881 /* These combine to interlock the GC and new requests. */
882 PRLock *gcLock;
883 PRCondVar *gcDone;
884 PRCondVar *requestDone;
885 uint32 requestCount;
886 JSThread *gcThread;
888 /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
889 PRLock *rtLock;
890 #ifdef DEBUG
891 jsword rtLockOwner;
892 #endif
894 /* Used to synchronize down/up state change; protected by gcLock. */
895 PRCondVar *stateChange;
898 * State for sharing single-threaded titles, once a second thread tries to
899 * lock a title. The titleSharingDone condvar is protected by rt->gcLock
900 * to minimize number of locks taken in JS_EndRequest.
902 * The titleSharingTodo linked list is likewise "global" per runtime, not
903 * one-list-per-context, to conserve space over all contexts, optimizing
904 * for the likely case that titles become shared rarely, and among a very
905 * small set of threads (contexts).
907 PRCondVar *titleSharingDone;
908 JSTitle *titleSharingTodo;
911 * Magic terminator for the rt->titleSharingTodo linked list, threaded through
912 * title->u.link. This hack allows us to test whether a title is on the list
913 * by asking whether title->u.link is non-null. We use a large, likely bogus
914 * pointer here to distinguish this value from any valid u.count (small int)
915 * value.
917 #define NO_TITLE_SHARING_TODO ((JSTitle *) 0xfeedbeef)
920 * Lock serializing trapList and watchPointList accesses, and count of all
921 * mutations to trapList and watchPointList made by debugger threads. To
922 * keep the code simple, we define debuggerMutations for the thread-unsafe
923 * case too.
925 PRLock *debuggerLock;
927 JSDHashTable threads;
928 #endif /* JS_THREADSAFE */
929 uint32 debuggerMutations;
932 * Security callbacks set on the runtime are used by each context unless
933 * an override is set on the context.
935 JSSecurityCallbacks *securityCallbacks;
938 * Shared scope property tree, and arena-pool for allocating its nodes.
939 * This really should be free of all locking overhead and allocated in
940 * thread-local storage, hence the JS_PROPERTY_TREE(cx) macro.
942 js::PropertyTree propertyTree;
944 #define JS_PROPERTY_TREE(cx) ((cx)->runtime->propertyTree)
947 * The propertyRemovals counter is incremented for every JSScope::clear,
948 * and for each JSScope::remove method call that frees a slot in an object.
949 * See js_NativeGet and js_NativeSet in jsobj.cpp.
951 int32 propertyRemovals;
953 /* Script filename table. */
954 struct JSHashTable *scriptFilenameTable;
955 JSCList scriptFilenamePrefixes;
956 #ifdef JS_THREADSAFE
957 PRLock *scriptFilenameTableLock;
958 #endif
960 /* Number localization, used by jsnum.c */
961 const char *thousandsSeparator;
962 const char *decimalSeparator;
963 const char *numGrouping;
966 * Weak references to lazily-created, well-known XML singletons.
968 * NB: Singleton objects must be carefully disconnected from the rest of
969 * the object graph usually associated with a JSContext's global object,
970 * including the set of standard class objects. See jsxml.c for details.
972 JSObject *anynameObject;
973 JSObject *functionNamespaceObject;
975 #ifndef JS_THREADSAFE
976 JSThreadData threadData;
978 #define JS_THREAD_DATA(cx) (&(cx)->runtime->threadData)
979 #endif
982 * Object shape (property cache structural type) identifier generator.
984 * Type 0 stands for the empty scope, and must not be regenerated due to
985 * uint32 wrap-around. Since js_GenerateShape (in jsinterp.cpp) uses
986 * atomic pre-increment, the initial value for the first typed non-empty
987 * scope will be 1.
989 * If this counter overflows into SHAPE_OVERFLOW_BIT (in jsinterp.h), the
990 * cache is disabled, to avoid aliasing two different types. It stays
991 * disabled until a triggered GC at some later moment compresses live
992 * types, minimizing rt->shapeGen in the process.
994 volatile uint32 shapeGen;
996 /* Literal table maintained by jsatom.c functions. */
997 JSAtomState atomState;
999 JSEmptyScope *emptyArgumentsScope;
1000 JSEmptyScope *emptyBlockScope;
1003 * Various metering fields are defined at the end of JSRuntime. In this
1004 * way there is no need to recompile all the code that refers to other
1005 * fields of JSRuntime after enabling the corresponding metering macro.
1007 #ifdef JS_DUMP_ENUM_CACHE_STATS
1008 int32 nativeEnumProbes;
1009 int32 nativeEnumMisses;
1010 # define ENUM_CACHE_METER(name) JS_ATOMIC_INCREMENT(&cx->runtime->name)
1011 #else
1012 # define ENUM_CACHE_METER(name) ((void) 0)
1013 #endif
1015 #ifdef JS_DUMP_LOOP_STATS
1016 /* Loop statistics, to trigger trace recording and compiling. */
1017 JSBasicStats loopStats;
1018 #endif
1020 #ifdef DEBUG
1021 /* Function invocation metering. */
1022 jsrefcount inlineCalls;
1023 jsrefcount nativeCalls;
1024 jsrefcount nonInlineCalls;
1025 jsrefcount constructs;
1027 /* Title lock and scope property metering. */
1028 jsrefcount claimAttempts;
1029 jsrefcount claimedTitles;
1030 jsrefcount deadContexts;
1031 jsrefcount deadlocksAvoided;
1032 jsrefcount liveScopes;
1033 jsrefcount sharedTitles;
1034 jsrefcount totalScopes;
1035 jsrefcount liveScopeProps;
1036 jsrefcount liveScopePropsPreSweep;
1037 jsrefcount totalScopeProps;
1038 jsrefcount livePropTreeNodes;
1039 jsrefcount duplicatePropTreeNodes;
1040 jsrefcount totalPropTreeNodes;
1041 jsrefcount propTreeKidsChunks;
1043 /* String instrumentation. */
1044 jsrefcount liveStrings;
1045 jsrefcount totalStrings;
1046 jsrefcount liveDependentStrings;
1047 jsrefcount totalDependentStrings;
1048 jsrefcount badUndependStrings;
1049 double lengthSum;
1050 double lengthSquaredSum;
1051 double strdepLengthSum;
1052 double strdepLengthSquaredSum;
1054 /* Script instrumentation. */
1055 jsrefcount liveScripts;
1056 jsrefcount totalScripts;
1057 jsrefcount liveEmptyScripts;
1058 jsrefcount totalEmptyScripts;
1059 #endif /* DEBUG */
1061 #ifdef JS_SCOPE_DEPTH_METER
1063 * Stats on runtime prototype chain lookups and scope chain depths, i.e.,
1064 * counts of objects traversed on a chain until the wanted id is found.
1066 JSBasicStats protoLookupDepthStats;
1067 JSBasicStats scopeSearchDepthStats;
1070 * Stats on compile-time host environment and lexical scope chain lengths
1071 * (maximum depths).
1073 JSBasicStats hostenvScopeDepthStats;
1074 JSBasicStats lexicalScopeDepthStats;
1075 #endif
1077 #ifdef JS_GCMETER
1078 JSGCStats gcStats;
1079 #endif
1081 #ifdef JS_FUNCTION_METERING
1082 JSFunctionMeter functionMeter;
1083 char lastScriptFilename[1024];
1084 #endif
1086 #ifdef JS_PROTO_CACHE_METERING
1087 JSClassProtoCache::Stats classProtoCacheStats;
1088 #endif
1090 JSRuntime();
1091 ~JSRuntime();
1093 bool init(uint32 maxbytes);
1095 void setGCTriggerFactor(uint32 factor);
1096 void setGCLastBytes(size_t lastBytes);
1098 void* malloc(size_t bytes) { return ::js_malloc(bytes); }
1100 void* calloc(size_t bytes) { return ::js_calloc(bytes); }
1102 void* realloc(void* p, size_t bytes) { return ::js_realloc(p, bytes); }
1104 void free(void* p) { ::js_free(p); }
1106 bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; }
1108 void resetGCMallocBytes() { gcMallocBytes = ptrdiff_t(gcMaxMallocBytes); }
1110 void setGCMaxMallocBytes(size_t value) {
1112 * For compatibility treat any value that exceeds PTRDIFF_T_MAX to
1113 * mean that value.
1115 gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
1116 resetGCMallocBytes();
1120 /* Common macros to access thread-local caches in JSThread or JSRuntime. */
1121 #define JS_GSN_CACHE(cx) (JS_THREAD_DATA(cx)->gsnCache)
1122 #define JS_PROPERTY_CACHE(cx) (JS_THREAD_DATA(cx)->propertyCache)
1123 #define JS_TRACE_MONITOR(cx) (JS_THREAD_DATA(cx)->traceMonitor)
1124 #define JS_SCRIPTS_TO_GC(cx) (JS_THREAD_DATA(cx)->scriptsToGC)
1126 #ifdef JS_EVAL_CACHE_METERING
1127 # define EVAL_CACHE_METER(x) (JS_THREAD_DATA(cx)->evalCacheMeter.x++)
1128 #else
1129 # define EVAL_CACHE_METER(x) ((void) 0)
1130 #endif
1132 #ifdef DEBUG
1133 # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which)
1134 # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which)
1135 #else
1136 # define JS_RUNTIME_METER(rt, which) /* nothing */
1137 # define JS_RUNTIME_UNMETER(rt, which) /* nothing */
1138 #endif
1140 #define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
1141 #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
1143 #ifdef JS_ARGUMENT_FORMATTER_DEFINED
1145 * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
1146 * formatter functions. Elements are sorted in non-increasing format string
1147 * length order.
1149 struct JSArgumentFormatMap {
1150 const char *format;
1151 size_t length;
1152 JSArgumentFormatter formatter;
1153 JSArgumentFormatMap *next;
1155 #endif
1157 struct JSStackHeader {
1158 uintN nslots;
1159 JSStackHeader *down;
1162 #define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2)
1165 * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
1166 * here because all consumers need to see these declarations (and not just the
1167 * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
1168 * declaration), along with cx->resolvingTable.
1170 typedef struct JSResolvingKey {
1171 JSObject *obj;
1172 jsid id;
1173 } JSResolvingKey;
1175 typedef struct JSResolvingEntry {
1176 JSDHashEntryHdr hdr;
1177 JSResolvingKey key;
1178 uint32 flags;
1179 } JSResolvingEntry;
1181 #define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */
1182 #define JSRESFLAG_WATCH 0x2 /* resolving id from watch */
1183 #define JSRESOLVE_INFER 0xffff /* infer bits from current bytecode */
1185 extern const JSDebugHooks js_NullDebugHooks; /* defined in jsdbgapi.cpp */
1187 namespace js {
1188 class AutoGCRooter;
1191 struct JSRegExpStatics {
1192 JSContext *cx;
1193 JSString *input; /* input string to match (perl $_, GC root) */
1194 JSBool multiline; /* whether input contains newlines (perl $*) */
1195 JSSubString lastMatch; /* last string matched (perl $&) */
1196 JSSubString lastParen; /* last paren matched (perl $+) */
1197 JSSubString leftContext; /* input to left of last match (perl $`) */
1198 JSSubString rightContext; /* input to right of last match (perl $') */
1199 js::Vector<JSSubString> parens; /* last set of parens matched (perl $1, $2) */
1201 JSRegExpStatics(JSContext *cx) : cx(cx), parens(cx) {}
1203 bool copy(const JSRegExpStatics& other);
1204 void clearRoots();
1205 void clear();
1208 struct JSContext
1210 explicit JSContext(JSRuntime *rt) :
1211 runtime(rt), regExpStatics(this), busyArrays(this) {}
1214 * If this flag is set, we were asked to call back the operation callback
1215 * as soon as possible.
1217 volatile jsint operationCallbackFlag;
1219 /* JSRuntime contextList linkage. */
1220 JSCList link;
1222 #if JS_HAS_XML_SUPPORT
1224 * Bit-set formed from binary exponentials of the XML_* tiny-ids defined
1225 * for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit. Together
1226 * these act as a cache of the boolean XML.ignore* and XML.prettyPrinting
1227 * property values associated with this context's global object.
1229 uint8 xmlSettingFlags;
1230 uint8 padding;
1231 #else
1232 uint16 padding;
1233 #endif
1236 * Classic Algol "display" static link optimization.
1238 #define JS_DISPLAY_SIZE 16U
1240 JSStackFrame *display[JS_DISPLAY_SIZE];
1242 /* Runtime version control identifier. */
1243 uint16 version;
1245 /* Per-context options. */
1246 uint32 options; /* see jsapi.h for JSOPTION_* */
1248 /* Locale specific callbacks for string conversion. */
1249 JSLocaleCallbacks *localeCallbacks;
1252 * cx->resolvingTable is non-null and non-empty if we are initializing
1253 * standard classes lazily, or if we are otherwise recursing indirectly
1254 * from js_LookupProperty through a JSClass.resolve hook. It is used to
1255 * limit runaway recursion (see jsapi.c and jsobj.c).
1257 JSDHashTable *resolvingTable;
1260 * True if generating an error, to prevent runaway recursion.
1261 * NB: generatingError packs with insideGCMarkCallback and throwing below.
1263 JSPackedBool generatingError;
1265 /* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). */
1266 JSPackedBool insideGCMarkCallback;
1268 /* Exception state -- the exception member is a GC root by definition. */
1269 JSPackedBool throwing; /* is there a pending exception? */
1270 jsval exception; /* most-recently-thrown exception */
1272 /* Limit pointer for checking native stack consumption during recursion. */
1273 jsuword stackLimit;
1275 /* Quota on the size of arenas used to compile and execute scripts. */
1276 size_t scriptStackQuota;
1278 /* Data shared by threads in an address space. */
1279 JSRuntime * const runtime;
1281 /* Stack arena pool and frame pointer register. */
1282 JS_REQUIRES_STACK
1283 JSArenaPool stackPool;
1285 JS_REQUIRES_STACK
1286 JSStackFrame *fp;
1288 /* Temporary arena pool used while compiling and decompiling. */
1289 JSArenaPool tempPool;
1291 /* Top-level object and pointer to top stack frame's scope chain. */
1292 JSObject *globalObject;
1294 /* Storage to root recently allocated GC things and script result. */
1295 JSWeakRoots weakRoots;
1297 /* Regular expression class statics. */
1298 JSRegExpStatics regExpStatics;
1300 /* State for object and array toSource conversion. */
1301 JSSharpObjectMap sharpObjectMap;
1302 js::HashSet<JSObject *> busyArrays;
1304 /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
1305 JSArgumentFormatMap *argumentFormatMap;
1307 /* Last message string and trace file for debugging. */
1308 char *lastMessage;
1309 #ifdef DEBUG
1310 void *tracefp;
1311 jsbytecode *tracePrevPc;
1312 #endif
1314 /* Per-context optional error reporter. */
1315 JSErrorReporter errorReporter;
1317 /* Branch callback. */
1318 JSOperationCallback operationCallback;
1320 /* Interpreter activation count. */
1321 uintN interpLevel;
1323 /* Client opaque pointers. */
1324 void *data;
1325 void *data2;
1327 private:
1328 #ifdef __GNUC__
1329 # pragma GCC visibility push(default)
1330 #endif
1331 friend void js_TraceContext(JSTracer *, JSContext *);
1332 #ifdef __GNUC__
1333 # pragma GCC visibility pop
1334 #endif
1336 /* Linked list of callstacks. See CallStack. */
1337 js::CallStack *currentCallStack;
1339 public:
1340 /* Assuming there is an active callstack, return it. */
1341 js::CallStack *activeCallStack() const {
1342 JS_ASSERT(currentCallStack && !currentCallStack->isSaved());
1343 return currentCallStack;
1346 /* Add the given callstack to the list as the new active callstack. */
1347 void pushCallStack(js::CallStack *newcs) {
1348 if (fp)
1349 currentCallStack->suspend(fp);
1350 else
1351 JS_ASSERT_IF(currentCallStack, currentCallStack->isSaved());
1352 newcs->setPrevious(currentCallStack);
1353 currentCallStack = newcs;
1354 JS_ASSERT(!newcs->isSuspended() && !newcs->isSaved());
1357 /* Remove the active callstack and make the next callstack active. */
1358 void popCallStack() {
1359 JS_ASSERT(!currentCallStack->isSuspended() && !currentCallStack->isSaved());
1360 currentCallStack = currentCallStack->getPrevious();
1361 if (currentCallStack && !currentCallStack->isSaved()) {
1362 JS_ASSERT(fp);
1363 currentCallStack->resume();
1367 /* Mark the top callstack as suspended, without pushing a new one. */
1368 void saveActiveCallStack() {
1369 JS_ASSERT(fp && currentCallStack && !currentCallStack->isSuspended());
1370 currentCallStack->save(fp);
1371 fp = NULL;
1374 /* Undoes calls to suspendTopCallStack. */
1375 void restoreCallStack() {
1376 JS_ASSERT(!fp && currentCallStack && currentCallStack->isSuspended());
1377 fp = currentCallStack->getSuspendedFrame();
1378 currentCallStack->restore();
1382 * Perform a linear search of all frames in all callstacks in the given context
1383 * for the given frame, returning the callstack, if found, and null otherwise.
1385 js::CallStack *containingCallStack(JSStackFrame *target);
1387 #ifdef JS_THREADSAFE
1388 JSThread *thread;
1389 jsrefcount requestDepth;
1390 /* Same as requestDepth but ignoring JS_SuspendRequest/JS_ResumeRequest */
1391 jsrefcount outstandingRequests;
1392 JSTitle *lockedSealedTitle; /* weak ref, for low-cost sealed
1393 title locking */
1394 JSCList threadLinks; /* JSThread contextList linkage */
1396 #define CX_FROM_THREAD_LINKS(tl) \
1397 ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
1398 #endif
1400 /* PDL of stack headers describing stack slots not rooted by argv, etc. */
1401 JSStackHeader *stackHeaders;
1403 /* Stack of thread-stack-allocated GC roots. */
1404 js::AutoGCRooter *autoGCRooters;
1406 /* Debug hooks associated with the current context. */
1407 const JSDebugHooks *debugHooks;
1409 /* Security callbacks that override any defined on the runtime. */
1410 JSSecurityCallbacks *securityCallbacks;
1412 /* Pinned regexp pool used for regular expressions. */
1413 JSArenaPool regexpPool;
1415 /* Stored here to avoid passing it around as a parameter. */
1416 uintN resolveFlags;
1418 /* Random number generator state, used by jsmath.cpp. */
1419 int64 rngSeed;
1421 #ifdef JS_TRACER
1423 * State for the current tree execution. bailExit is valid if the tree has
1424 * called back into native code via a _FAIL builtin and has not yet bailed,
1425 * else garbage (NULL in debug builds).
1427 js::TracerState *tracerState;
1428 js::VMSideExit *bailExit;
1431 * True if traces may be executed. Invariant: The value of jitEnabled is
1432 * always equal to the expression in updateJITEnabled below.
1434 * This flag and the fields accessed by updateJITEnabled are written only
1435 * in runtime->gcLock, to avoid race conditions that would leave the wrong
1436 * value in jitEnabled. (But the interpreter reads this without
1437 * locking. That can race against another thread setting debug hooks, but
1438 * we always read cx->debugHooks without locking anyway.)
1440 bool jitEnabled;
1441 #endif
1443 /* Caller must be holding runtime->gcLock. */
1444 void updateJITEnabled() {
1445 #ifdef JS_TRACER
1446 jitEnabled = ((options & JSOPTION_JIT) &&
1447 (debugHooks == &js_NullDebugHooks ||
1448 (debugHooks == &runtime->globalDebugHooks &&
1449 !runtime->debuggerInhibitsJIT())));
1450 #endif
1453 JSClassProtoCache classProtoCache;
1455 #ifdef JS_THREADSAFE
1457 * The sweep task for this context.
1459 js::BackgroundSweepTask *gcSweepTask;
1460 #endif
1462 ptrdiff_t &getMallocCounter() {
1463 #ifdef JS_THREADSAFE
1464 return thread->gcThreadMallocBytes;
1465 #else
1466 return runtime->gcMallocBytes;
1467 #endif
1471 * Call this after allocating memory held by GC things, to update memory
1472 * pressure counters or report the OOM error if necessary.
1474 inline void updateMallocCounter(void *p, size_t nbytes) {
1475 JS_ASSERT(ptrdiff_t(nbytes) >= 0);
1476 ptrdiff_t &counter = getMallocCounter();
1477 counter -= ptrdiff_t(nbytes);
1478 if (!p || counter <= 0)
1479 checkMallocGCPressure(p);
1483 * Call this after successfully allocating memory held by GC things, to
1484 * update memory pressure counters.
1486 inline void updateMallocCounter(size_t nbytes) {
1487 JS_ASSERT(ptrdiff_t(nbytes) >= 0);
1488 ptrdiff_t &counter = getMallocCounter();
1489 counter -= ptrdiff_t(nbytes);
1490 if (counter <= 0) {
1492 * Use 1 as an arbitrary non-null pointer indicating successful
1493 * allocation.
1495 checkMallocGCPressure(reinterpret_cast<void *>(jsuword(1)));
1499 inline void* malloc(size_t bytes) {
1500 JS_ASSERT(bytes != 0);
1501 void *p = runtime->malloc(bytes);
1502 updateMallocCounter(p, bytes);
1503 return p;
1506 inline void* mallocNoReport(size_t bytes) {
1507 JS_ASSERT(bytes != 0);
1508 void *p = runtime->malloc(bytes);
1509 if (!p)
1510 return NULL;
1511 updateMallocCounter(bytes);
1512 return p;
1515 inline void* calloc(size_t bytes) {
1516 JS_ASSERT(bytes != 0);
1517 void *p = runtime->calloc(bytes);
1518 updateMallocCounter(p, bytes);
1519 return p;
1522 inline void* realloc(void* p, size_t bytes) {
1523 void *orig = p;
1524 p = runtime->realloc(p, bytes);
1527 * For compatibility we do not account for realloc that increases
1528 * previously allocated memory.
1530 updateMallocCounter(p, orig ? 0 : bytes);
1531 return p;
1534 inline void free(void* p) {
1535 #ifdef JS_THREADSAFE
1536 if (gcSweepTask) {
1537 gcSweepTask->freeLater(p);
1538 return;
1540 #endif
1541 runtime->free(p);
1545 * In the common case that we'd like to allocate the memory for an object
1546 * with cx->malloc/free, we cannot use overloaded C++ operators (no
1547 * placement delete). Factor the common workaround into one place.
1549 #define CREATE_BODY(parms) \
1550 void *memory = this->malloc(sizeof(T)); \
1551 if (!memory) \
1552 return NULL; \
1553 return new(memory) T parms;
1555 template <class T>
1556 JS_ALWAYS_INLINE T *create() {
1557 CREATE_BODY(())
1560 template <class T, class P1>
1561 JS_ALWAYS_INLINE T *create(const P1 &p1) {
1562 CREATE_BODY((p1))
1565 template <class T, class P1, class P2>
1566 JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2) {
1567 CREATE_BODY((p1, p2))
1570 template <class T, class P1, class P2, class P3>
1571 JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2, const P3 &p3) {
1572 CREATE_BODY((p1, p2, p3))
1574 #undef CREATE_BODY
1576 template <class T>
1577 JS_ALWAYS_INLINE void destroy(T *p) {
1578 p->~T();
1579 this->free(p);
1582 bool isConstructing();
1584 void purge();
1586 private:
1589 * The allocation code calls the function to indicate either OOM failure
1590 * when p is null or that a memory pressure counter has reached some
1591 * threshold when p is not null. The function takes the pointer and not
1592 * a boolean flag to minimize the amount of code in its inlined callers.
1594 void checkMallocGCPressure(void *p);
1597 JS_ALWAYS_INLINE JSObject *
1598 JSStackFrame::varobj(js::CallStack *cs)
1600 JS_ASSERT(cs->contains(this));
1601 return fun ? callobj : cs->getInitialVarObj();
1604 JS_ALWAYS_INLINE JSObject *
1605 JSStackFrame::varobj(JSContext *cx)
1607 JS_ASSERT(cx->activeCallStack()->contains(this));
1608 return fun ? callobj : cx->activeCallStack()->getInitialVarObj();
1611 #ifdef JS_THREADSAFE
1612 # define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0)
1613 #endif
1615 #ifdef __cplusplus
1617 static inline JSAtom **
1618 FrameAtomBase(JSContext *cx, JSStackFrame *fp)
1620 return fp->imacpc
1621 ? COMMON_ATOMS_START(&cx->runtime->atomState)
1622 : fp->script->atomMap.vector;
1625 namespace js {
1627 class AutoGCRooter {
1628 public:
1629 AutoGCRooter(JSContext *cx, ptrdiff_t tag)
1630 : down(cx->autoGCRooters), tag(tag), context(cx)
1632 JS_ASSERT(this != cx->autoGCRooters);
1633 cx->autoGCRooters = this;
1636 ~AutoGCRooter() {
1637 JS_ASSERT(this == context->autoGCRooters);
1638 context->autoGCRooters = down;
1641 inline void trace(JSTracer *trc);
1643 #ifdef __GNUC__
1644 # pragma GCC visibility push(default)
1645 #endif
1646 friend void ::js_TraceContext(JSTracer *trc, JSContext *acx);
1647 #ifdef __GNUC__
1648 # pragma GCC visibility pop
1649 #endif
1651 protected:
1652 AutoGCRooter * const down;
1655 * Discriminates actual subclass of this being used. If non-negative, the
1656 * subclass roots an array of jsvals of the length stored in this field.
1657 * If negative, meaning is indicated by the corresponding value in the enum
1658 * below. Any other negative value indicates some deeper problem such as
1659 * memory corruption.
1661 ptrdiff_t tag;
1663 JSContext * const context;
1665 enum {
1666 JSVAL = -1, /* js::AutoValueRooter */
1667 SPROP = -2, /* js::AutoScopePropertyRooter */
1668 WEAKROOTS = -3, /* js::AutoSaveWeakRoots */
1669 PARSER = -4, /* js::Parser */
1670 SCRIPT = -5, /* js::AutoScriptRooter */
1671 ENUMERATOR = -6, /* js::AutoEnumStateRooter */
1672 IDARRAY = -7, /* js::AutoIdArray */
1673 DESCRIPTORS = -8, /* js::AutoDescriptorArray */
1674 NAMESPACES = -9, /* js::AutoNamespaceArray */
1675 XML = -10, /* js::AutoXMLRooter */
1676 OBJECT = -11, /* js::AutoObjectRooter */
1677 ID = -12, /* js::AutoIdRooter */
1678 VECTOR = -13 /* js::AutoValueVector */
1681 private:
1682 /* No copy or assignment semantics. */
1683 AutoGCRooter(AutoGCRooter &ida);
1684 void operator=(AutoGCRooter &ida);
1687 class AutoPreserveWeakRoots : private AutoGCRooter
1689 public:
1690 explicit AutoPreserveWeakRoots(JSContext *cx
1691 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1692 : AutoGCRooter(cx, WEAKROOTS), savedRoots(cx->weakRoots)
1694 JS_GUARD_OBJECT_NOTIFIER_INIT;
1697 ~AutoPreserveWeakRoots()
1699 context->weakRoots = savedRoots;
1702 friend void AutoGCRooter::trace(JSTracer *trc);
1704 private:
1705 JSWeakRoots savedRoots;
1706 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1709 /* FIXME(bug 332648): Move this into a public header. */
1710 class AutoValueRooter : private AutoGCRooter
1712 public:
1713 explicit AutoValueRooter(JSContext *cx, jsval v = JSVAL_NULL
1714 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1715 : AutoGCRooter(cx, JSVAL), val(v)
1717 JS_GUARD_OBJECT_NOTIFIER_INIT;
1719 AutoValueRooter(JSContext *cx, JSString *str
1720 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1721 : AutoGCRooter(cx, JSVAL), val(STRING_TO_JSVAL(str))
1723 JS_GUARD_OBJECT_NOTIFIER_INIT;
1725 AutoValueRooter(JSContext *cx, JSObject *obj
1726 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1727 : AutoGCRooter(cx, JSVAL), val(OBJECT_TO_JSVAL(obj))
1729 JS_GUARD_OBJECT_NOTIFIER_INIT;
1732 void setObject(JSObject *obj) {
1733 JS_ASSERT(tag == JSVAL);
1734 val = OBJECT_TO_JSVAL(obj);
1737 void setString(JSString *str) {
1738 JS_ASSERT(tag == JSVAL);
1739 JS_ASSERT(str);
1740 val = STRING_TO_JSVAL(str);
1743 void setDouble(jsdouble *dp) {
1744 JS_ASSERT(tag == JSVAL);
1745 JS_ASSERT(dp);
1746 val = DOUBLE_TO_JSVAL(dp);
1749 jsval value() const {
1750 JS_ASSERT(tag == JSVAL);
1751 return val;
1754 jsval *addr() {
1755 JS_ASSERT(tag == JSVAL);
1756 return &val;
1759 friend void AutoGCRooter::trace(JSTracer *trc);
1761 private:
1762 jsval val;
1763 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1766 class AutoObjectRooter : private AutoGCRooter {
1767 public:
1768 AutoObjectRooter(JSContext *cx, JSObject *obj = NULL
1769 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1770 : AutoGCRooter(cx, OBJECT), obj(obj)
1772 JS_GUARD_OBJECT_NOTIFIER_INIT;
1775 void setObject(JSObject *obj) {
1776 this->obj = obj;
1779 JSObject * object() const {
1780 return obj;
1783 JSObject ** addr() {
1784 return &obj;
1787 friend void AutoGCRooter::trace(JSTracer *trc);
1789 private:
1790 JSObject *obj;
1791 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1794 class AutoArrayRooter : private AutoGCRooter {
1795 public:
1796 AutoArrayRooter(JSContext *cx, size_t len, jsval *vec
1797 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1798 : AutoGCRooter(cx, len), array(vec)
1800 JS_GUARD_OBJECT_NOTIFIER_INIT;
1801 JS_ASSERT(tag >= 0);
1804 void changeLength(size_t newLength) {
1805 tag = ptrdiff_t(newLength);
1806 JS_ASSERT(tag >= 0);
1809 void changeArray(jsval *newArray, size_t newLength) {
1810 changeLength(newLength);
1811 array = newArray;
1814 jsval *array;
1816 friend void AutoGCRooter::trace(JSTracer *trc);
1818 private:
1819 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1822 class AutoScopePropertyRooter : private AutoGCRooter {
1823 public:
1824 AutoScopePropertyRooter(JSContext *cx, JSScopeProperty *sprop
1825 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1826 : AutoGCRooter(cx, SPROP), sprop(sprop)
1828 JS_GUARD_OBJECT_NOTIFIER_INIT;
1831 friend void AutoGCRooter::trace(JSTracer *trc);
1833 private:
1834 JSScopeProperty * const sprop;
1835 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1838 class AutoScriptRooter : private AutoGCRooter {
1839 public:
1840 AutoScriptRooter(JSContext *cx, JSScript *script
1841 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1842 : AutoGCRooter(cx, SCRIPT), script(script)
1844 JS_GUARD_OBJECT_NOTIFIER_INIT;
1847 void setScript(JSScript *script) {
1848 this->script = script;
1851 friend void AutoGCRooter::trace(JSTracer *trc);
1853 private:
1854 JSScript *script;
1855 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1858 class AutoIdRooter : private AutoGCRooter
1860 public:
1861 explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0)
1862 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1863 : AutoGCRooter(cx, ID), idval(id)
1865 JS_GUARD_OBJECT_NOTIFIER_INIT;
1868 jsid id() {
1869 return idval;
1872 jsid * addr() {
1873 return &idval;
1876 friend void AutoGCRooter::trace(JSTracer *trc);
1878 private:
1879 jsid idval;
1880 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1883 class AutoIdArray : private AutoGCRooter {
1884 public:
1885 AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM)
1886 : AutoGCRooter(cx, IDARRAY), idArray(ida)
1888 JS_GUARD_OBJECT_NOTIFIER_INIT;
1890 ~AutoIdArray() {
1891 if (idArray)
1892 JS_DestroyIdArray(context, idArray);
1894 bool operator!() {
1895 return idArray == NULL;
1897 jsid operator[](size_t i) const {
1898 JS_ASSERT(idArray);
1899 JS_ASSERT(i < size_t(idArray->length));
1900 return idArray->vector[i];
1902 size_t length() const {
1903 return idArray->length;
1906 friend void AutoGCRooter::trace(JSTracer *trc);
1908 protected:
1909 inline void trace(JSTracer *trc);
1911 private:
1912 JSIdArray * const idArray;
1913 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1915 /* No copy or assignment semantics. */
1916 AutoIdArray(AutoIdArray &ida);
1917 void operator=(AutoIdArray &ida);
1920 /* The auto-root for enumeration object and its state. */
1921 class AutoEnumStateRooter : private AutoGCRooter
1923 public:
1924 AutoEnumStateRooter(JSContext *cx, JSObject *obj
1925 JS_GUARD_OBJECT_NOTIFIER_PARAM)
1926 : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue(JSVAL_NULL)
1928 JS_GUARD_OBJECT_NOTIFIER_INIT;
1929 JS_ASSERT(obj);
1932 ~AutoEnumStateRooter() {
1933 if (!JSVAL_IS_NULL(stateValue)) {
1934 #ifdef DEBUG
1935 JSBool ok =
1936 #endif
1937 obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0);
1938 JS_ASSERT(ok);
1942 friend void AutoGCRooter::trace(JSTracer *trc);
1944 jsval state() const { return stateValue; }
1945 jsval * addr() { return &stateValue; }
1947 protected:
1948 void trace(JSTracer *trc) {
1949 JS_CALL_OBJECT_TRACER(trc, obj, "js::AutoEnumStateRooter.obj");
1950 js_MarkEnumeratorState(trc, obj, stateValue);
1953 JSObject * const obj;
1955 private:
1956 jsval stateValue;
1957 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1960 #ifdef JS_HAS_XML_SUPPORT
1961 class AutoXMLRooter : private AutoGCRooter {
1962 public:
1963 AutoXMLRooter(JSContext *cx, JSXML *xml)
1964 : AutoGCRooter(cx, XML), xml(xml)
1966 JS_ASSERT(xml);
1969 friend void AutoGCRooter::trace(JSTracer *trc);
1971 private:
1972 JSXML * const xml;
1974 #endif /* JS_HAS_XML_SUPPORT */
1976 class AutoLockGC {
1977 private:
1978 JSRuntime *rt;
1979 public:
1980 explicit AutoLockGC(JSRuntime *rt) : rt(rt) { JS_LOCK_GC(rt); }
1981 ~AutoLockGC() { JS_UNLOCK_GC(rt); }
1984 class AutoUnlockGC {
1985 private:
1986 JSRuntime *rt;
1987 public:
1988 explicit AutoUnlockGC(JSRuntime *rt) : rt(rt) { JS_UNLOCK_GC(rt); }
1989 ~AutoUnlockGC() { JS_LOCK_GC(rt); }
1992 class AutoKeepAtoms {
1993 JSRuntime *rt;
1994 public:
1995 explicit AutoKeepAtoms(JSRuntime *rt) : rt(rt) { JS_KEEP_ATOMS(rt); }
1996 ~AutoKeepAtoms() { JS_UNKEEP_ATOMS(rt); }
1999 } /* namespace js */
2001 class JSAutoResolveFlags
2003 public:
2004 JSAutoResolveFlags(JSContext *cx, uintN flags
2005 JS_GUARD_OBJECT_NOTIFIER_PARAM)
2006 : mContext(cx), mSaved(cx->resolveFlags)
2008 JS_GUARD_OBJECT_NOTIFIER_INIT;
2009 cx->resolveFlags = flags;
2012 ~JSAutoResolveFlags() { mContext->resolveFlags = mSaved; }
2014 private:
2015 JSContext *mContext;
2016 uintN mSaved;
2017 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
2020 #endif /* __cpluscplus */
2023 * Slightly more readable macros for testing per-context option settings (also
2024 * to hide bitset implementation detail).
2026 * JSOPTION_XML must be handled specially in order to propagate from compile-
2027 * to run-time (from cx->options to script->version/cx->version). To do that,
2028 * we copy JSOPTION_XML from cx->options into cx->version as JSVERSION_HAS_XML
2029 * whenever options are set, and preserve this XML flag across version number
2030 * changes done via the JS_SetVersion API.
2032 * But when executing a script or scripted function, the interpreter changes
2033 * cx->version, including the XML flag, to script->version. Thus JSOPTION_XML
2034 * is a compile-time option that causes a run-time version change during each
2035 * activation of the compiled script. That version change has the effect of
2036 * changing JS_HAS_XML_OPTION, so that any compiling done via eval enables XML
2037 * support. If an XML-enabled script or function calls a non-XML function,
2038 * the flag bit will be cleared during the callee's activation.
2040 * Note that JS_SetVersion API calls never pass JSVERSION_HAS_XML or'd into
2041 * that API's version parameter.
2043 * Note also that script->version must contain this XML option flag in order
2044 * for XDR'ed scripts to serialize and deserialize with that option preserved
2045 * for detection at run-time. We can't copy other compile-time options into
2046 * script->version because that would break backward compatibility (certain
2047 * other options, e.g. JSOPTION_VAROBJFIX, are analogous to JSOPTION_XML).
2049 #define JS_HAS_OPTION(cx,option) (((cx)->options & (option)) != 0)
2050 #define JS_HAS_STRICT_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_STRICT)
2051 #define JS_HAS_WERROR_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_WERROR)
2052 #define JS_HAS_COMPILE_N_GO_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO)
2053 #define JS_HAS_ATLINE_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_ATLINE)
2055 #define JSVERSION_MASK 0x0FFF /* see JSVersion in jspubtd.h */
2056 #define JSVERSION_HAS_XML 0x1000 /* flag induced by XML option */
2057 #define JSVERSION_ANONFUNFIX 0x2000 /* see jsapi.h, the comments
2058 for JSOPTION_ANONFUNFIX */
2060 #define JSVERSION_NUMBER(cx) ((JSVersion)((cx)->version & \
2061 JSVERSION_MASK))
2062 #define JS_HAS_XML_OPTION(cx) ((cx)->version & JSVERSION_HAS_XML || \
2063 JSVERSION_NUMBER(cx) >= JSVERSION_1_6)
2065 extern JSThreadData *
2066 js_CurrentThreadData(JSRuntime *rt);
2068 extern JSBool
2069 js_InitThreads(JSRuntime *rt);
2071 extern void
2072 js_FinishThreads(JSRuntime *rt);
2074 extern void
2075 js_PurgeThreads(JSContext *cx);
2077 extern void
2078 js_TraceThreads(JSRuntime *rt, JSTracer *trc);
2081 * Ensures the JSOPTION_XML and JSOPTION_ANONFUNFIX bits of cx->options are
2082 * reflected in cx->version, since each bit must travel with a script that has
2083 * it set.
2085 extern void
2086 js_SyncOptionsToVersion(JSContext *cx);
2089 * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context
2090 * data that depends on version.
2092 extern void
2093 js_OnVersionChange(JSContext *cx);
2096 * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and
2097 * any future non-version-number flags induced by compiler options.
2099 extern void
2100 js_SetVersion(JSContext *cx, JSVersion version);
2103 * Create and destroy functions for JSContext, which is manually allocated
2104 * and exclusively owned.
2106 extern JSContext *
2107 js_NewContext(JSRuntime *rt, size_t stackChunkSize);
2109 extern void
2110 js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
2113 * Return true if cx points to a context in rt->contextList, else return false.
2114 * NB: the caller (see jslock.c:ClaimTitle) must hold rt->gcLock.
2116 extern JSBool
2117 js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
2119 static JS_INLINE JSContext *
2120 js_ContextFromLinkField(JSCList *link)
2122 JS_ASSERT(link);
2123 return (JSContext *) ((uint8 *) link - offsetof(JSContext, link));
2127 * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
2128 * the caller must be holding rt->gcLock.
2130 extern JSContext *
2131 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
2134 * Iterate through contexts with active requests. The caller must be holding
2135 * rt->gcLock in case of a thread-safe build, or otherwise guarantee that the
2136 * context list is not alternated asynchroniously.
2138 extern JS_FRIEND_API(JSContext *)
2139 js_NextActiveContext(JSRuntime *, JSContext *);
2141 #ifdef JS_THREADSAFE
2144 * Count the number of contexts entered requests on the current thread.
2146 extern uint32
2147 js_CountThreadRequests(JSContext *cx);
2150 * This is a helper for code at can potentially run outside JS request to
2151 * ensure that the GC is not running when the function returns.
2153 * This function must be called with the GC lock held.
2155 extern void
2156 js_WaitForGC(JSRuntime *rt);
2158 #else /* !JS_THREADSAFE */
2160 # define js_WaitForGC(rt) ((void) 0)
2162 #endif
2165 * JSClass.resolve and watchpoint recursion damping machinery.
2167 extern JSBool
2168 js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
2169 JSResolvingEntry **entryp);
2171 extern void
2172 js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
2173 JSResolvingEntry *entry, uint32 generation);
2176 * Local root set management.
2178 * NB: the jsval parameters below may be properly tagged jsvals, or GC-thing
2179 * pointers cast to (jsval). This relies on JSObject's tag being zero, but
2180 * on the up side it lets us push int-jsval-encoded scopeMark values on the
2181 * local root stack.
2183 extern JSBool
2184 js_EnterLocalRootScope(JSContext *cx);
2186 #define js_LeaveLocalRootScope(cx) \
2187 js_LeaveLocalRootScopeWithResult(cx, JSVAL_NULL)
2189 extern void
2190 js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval);
2192 extern void
2193 js_ForgetLocalRoot(JSContext *cx, jsval v);
2195 extern int
2196 js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
2199 * Report an exception, which is currently realized as a printf-style format
2200 * string and its arguments.
2202 typedef enum JSErrNum {
2203 #define MSG_DEF(name, number, count, exception, format) \
2204 name = number,
2205 #include "js.msg"
2206 #undef MSG_DEF
2207 JSErr_Limit
2208 } JSErrNum;
2210 extern JS_FRIEND_API(const JSErrorFormatString *)
2211 js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
2213 #ifdef va_start
2214 extern JSBool
2215 js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
2217 extern JSBool
2218 js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
2219 void *userRef, const uintN errorNumber,
2220 JSBool charArgs, va_list ap);
2222 extern JSBool
2223 js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
2224 void *userRef, const uintN errorNumber,
2225 char **message, JSErrorReport *reportp,
2226 bool charArgs, va_list ap);
2227 #endif
2229 extern void
2230 js_ReportOutOfMemory(JSContext *cx);
2233 * Report that cx->scriptStackQuota is exhausted.
2235 extern void
2236 js_ReportOutOfScriptQuota(JSContext *cx);
2238 extern void
2239 js_ReportOverRecursed(JSContext *cx);
2241 extern void
2242 js_ReportAllocationOverflow(JSContext *cx);
2244 #define JS_CHECK_RECURSION(cx, onerror) \
2245 JS_BEGIN_MACRO \
2246 int stackDummy_; \
2248 if (!JS_CHECK_STACK_SIZE(cx, stackDummy_)) { \
2249 js_ReportOverRecursed(cx); \
2250 onerror; \
2252 JS_END_MACRO
2255 * Report an exception using a previously composed JSErrorReport.
2256 * XXXbe remove from "friend" API
2258 extern JS_FRIEND_API(void)
2259 js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
2261 extern void
2262 js_ReportIsNotDefined(JSContext *cx, const char *name);
2265 * Report an attempt to access the property of a null or undefined value (v).
2267 extern JSBool
2268 js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v,
2269 JSString *fallback);
2271 extern void
2272 js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg);
2275 * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
2276 * the first argument for the error message. If the error message has less
2277 * then 3 arguments, use null for arg1 or arg2.
2279 extern JSBool
2280 js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
2281 intN spindex, jsval v, JSString *fallback,
2282 const char *arg1, const char *arg2);
2284 #define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \
2285 ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \
2286 spindex, v, fallback, NULL, NULL))
2288 #define js_ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1) \
2289 ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \
2290 spindex, v, fallback, arg1, NULL))
2292 #define js_ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2) \
2293 ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \
2294 spindex, v, fallback, arg1, arg2))
2296 extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
2299 * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack
2300 * grows in the expected direction.
2302 #if JS_STACK_GROWTH_DIRECTION > 0
2303 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit)
2304 #else
2305 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit)
2306 #endif
2309 * If the operation callback flag was set, call the operation callback.
2310 * This macro can run the full GC. Return true if it is OK to continue and
2311 * false otherwise.
2313 #define JS_CHECK_OPERATION_LIMIT(cx) \
2314 (!(cx)->operationCallbackFlag || js_InvokeOperationCallback(cx))
2317 * Invoke the operation callback and return false if the current execution
2318 * is to be terminated.
2320 extern JSBool
2321 js_InvokeOperationCallback(JSContext *cx);
2323 #ifndef JS_THREADSAFE
2324 # define js_TriggerAllOperationCallbacks(rt, gcLocked) \
2325 js_TriggerAllOperationCallbacks (rt)
2326 #endif
2328 void
2329 js_TriggerAllOperationCallbacks(JSRuntime *rt, JSBool gcLocked);
2331 extern JSStackFrame *
2332 js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
2334 extern jsbytecode*
2335 js_GetCurrentBytecodePC(JSContext* cx);
2337 extern bool
2338 js_CurrentPCIsInImacro(JSContext *cx);
2340 namespace js {
2342 #ifdef JS_TRACER
2344 * Reconstruct the JS stack and clear cx->tracecx. We must be currently in a
2345 * _FAIL builtin from trace on cx or another context on the same thread. The
2346 * machine code for the trace remains on the C stack when js_DeepBail returns.
2348 * Implemented in jstracer.cpp.
2350 JS_FORCES_STACK JS_FRIEND_API(void)
2351 DeepBail(JSContext *cx);
2352 #endif
2354 static JS_FORCES_STACK JS_INLINE void
2355 LeaveTrace(JSContext *cx)
2357 #ifdef JS_TRACER
2358 if (JS_ON_TRACE(cx))
2359 DeepBail(cx);
2360 #endif
2363 static JS_INLINE void
2364 LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj)
2366 if (!obj->fslots[JSSLOT_PARENT])
2367 LeaveTrace(cx);
2370 static JS_INLINE JSBool
2371 CanLeaveTrace(JSContext *cx)
2373 JS_ASSERT(JS_ON_TRACE(cx));
2374 #ifdef JS_TRACER
2375 return cx->bailExit != NULL;
2376 #else
2377 return JS_FALSE;
2378 #endif
2381 } /* namespace js */
2384 * Get the current cx->fp, first lazily instantiating stack frames if needed.
2385 * (Do not access cx->fp directly except in JS_REQUIRES_STACK code.)
2387 * Defined in jstracer.cpp if JS_TRACER is defined.
2389 static JS_FORCES_STACK JS_INLINE JSStackFrame *
2390 js_GetTopStackFrame(JSContext *cx)
2392 js::LeaveTrace(cx);
2393 return cx->fp;
2396 static JS_INLINE JSBool
2397 js_IsPropertyCacheDisabled(JSContext *cx)
2399 return cx->runtime->shapeGen >= js::SHAPE_OVERFLOW_BIT;
2402 static JS_INLINE uint32
2403 js_RegenerateShapeForGC(JSContext *cx)
2405 JS_ASSERT(cx->runtime->gcRunning);
2406 JS_ASSERT(cx->runtime->gcRegenShapes);
2409 * Under the GC, compared with js_GenerateShape, we don't need to use
2410 * atomic increments but we still must make sure that after an overflow
2411 * the shape stays such.
2413 uint32 shape = cx->runtime->shapeGen;
2414 shape = (shape + 1) | (shape & js::SHAPE_OVERFLOW_BIT);
2415 cx->runtime->shapeGen = shape;
2416 return shape;
2419 namespace js {
2421 inline void *
2422 ContextAllocPolicy::malloc(size_t bytes)
2424 return cx->malloc(bytes);
2427 inline void
2428 ContextAllocPolicy::free(void *p)
2430 cx->free(p);
2433 inline void *
2434 ContextAllocPolicy::realloc(void *p, size_t bytes)
2436 return cx->realloc(p, bytes);
2439 inline void
2440 ContextAllocPolicy::reportAllocOverflow() const
2442 js_ReportAllocationOverflow(cx);
2445 class AutoValueVector : private AutoGCRooter
2447 public:
2448 explicit AutoValueVector(JSContext *cx
2449 JS_GUARD_OBJECT_NOTIFIER_PARAM)
2450 : AutoGCRooter(cx, VECTOR), vector(cx)
2452 JS_GUARD_OBJECT_NOTIFIER_INIT;
2455 size_t length() const { return vector.length(); }
2457 bool push(jsval v) { return vector.append(v); }
2458 bool push(JSString *str) { return push(STRING_TO_JSVAL(str)); }
2459 bool push(JSObject *obj) { return push(OBJECT_TO_JSVAL(obj)); }
2460 bool push(jsdouble *dp) { return push(DOUBLE_TO_JSVAL(dp)); }
2462 void pop() { vector.popBack(); }
2464 bool resize(size_t newLength) {
2465 if (!vector.resize(newLength))
2466 return false;
2467 return true;
2470 bool reserve(size_t newLength) {
2471 return vector.reserve(newLength);
2474 jsval &operator[](size_t i) { return vector[i]; }
2475 jsval operator[](size_t i) const { return vector[i]; }
2477 const jsval *buffer() const { return vector.begin(); }
2478 jsval *buffer() { return vector.begin(); }
2480 friend void AutoGCRooter::trace(JSTracer *trc);
2482 private:
2483 Vector<jsval, 8> vector;
2484 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
2489 #ifdef _MSC_VER
2490 #pragma warning(pop)
2491 #pragma warning(pop)
2492 #endif
2494 #endif /* jscntxt_h___ */