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
17 * The Original Code is Mozilla Communicator client code, released
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.
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 ***** */
44 * JS execution context.
48 #include "jsarena.h" /* Added by JSIFY */
55 #include "jshashtable.h"
58 #include "jspropertycache.h"
59 #include "jspropertytree.h"
70 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
72 #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
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
{
89 # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt)
91 # define GSN_CACHE_METER(cache,cnt) /* nothing */
95 #define js_FinishGSNCache(cache) js_PurgeGSNCache(cache)
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. */
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 */
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. */
128 class FrameInfoCache
;
135 template<typename T
> class Queue
;
136 typedef Queue
<uint16
> SlotList
;
139 typedef nanojit::HashMap
<REHashKey
, REFragment
*, REHashFn
> REHashMap
;
141 #if defined(JS_JIT_SPEW) || defined(DEBUG)
143 typedef nanojit::HashMap
<uint32
, FragPI
, nanojit::DefaultHash
<uint32
> > FragStatsMap
;
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
157 ContextAllocPolicy(JSContext
*cx
) : cx(cx
) {}
158 JSContext
*context() const { return cx
; }
160 /* Inline definitions below. */
161 void *malloc(size_t bytes
);
163 void *realloc(void *p
, size_t bytes
);
164 void reportAllocOverflow() const;
167 /* Holds the execution state during trace execution. */
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
;
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.
198 // Used when calling natives from trace to root the vp vector.
202 TracerState(JSContext
*cx
, TraceMonitor
*tm
, TreeFragment
*ti
,
203 uintN
&inlineCallCountp
, VMSideExit
** innermostNestedGuardp
);
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. */
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).
247 /* The context to which this callstack belongs. */
251 /* If this callstack is suspended, the top of the callstack. */
252 JSStackFrame
*suspendedFrame
;
254 /* This callstack was suspended by JS_SaveFrameChain. */
257 /* Links members of the JSContext::currentCallStack list. */
260 /* The varobj on entry to initialFrame. */
261 JSObject
*initialVarObj
;
263 /* The first frame executed in this callstack. */
264 JSStackFrame
*initialFrame
;
267 CallStack(JSContext
*cx
)
272 suspendedFrame(NULL
), saved(false), previous(NULL
),
273 initialVarObj(NULL
), initialFrame(NULL
)
277 bool contains(JSStackFrame
*fp
);
280 void suspend(JSStackFrame
*fp
) {
281 JS_ASSERT(fp
&& !isSuspended() && contains(fp
));
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
) {
325 bool isSaved() const {
326 JS_ASSERT_IF(saved
, isSuspended());
331 /* Holds the number of recording attemps for an address. */
332 typedef HashMap
<jsbytecode
*,
334 DefaultHasher
<jsbytecode
*>,
335 SystemAllocPolicy
> RecordAttemptMap
;
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
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
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
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
383 * - reTempAlloc is just like tempAlloc, but is used for regexp
384 * compilation in RegExpNativeCompiler rather than normal compilation in
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
;
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.
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
428 TypeMap
* cachedTempTypeMap
;
431 /* Fields needed for fragment/guard profiling. */
432 nanojit::Seq
<nanojit::Fragment
*>* branches
;
435 * profAlloc has a lifetime which spans exactly from js_InitJIT to
438 VMAllocator
* profAlloc
;
439 FragStatsMap
* profTab
;
442 /* Flush the JIT cache. */
445 /* Mark all objects baked into native code in the code cache. */
446 void mark(JSTracer
*trc
);
448 bool outOfMemory() const;
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.
459 # define JS_ON_TRACE(cx) (JS_TRACE_MONITOR(cx).tracecx != NULL)
461 # define JS_ON_TRACE(cx) JS_FALSE
465 # define JS_EVAL_CACHE_METERING 1
466 # define JS_FUNCTION_METERING 1
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
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
);
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
);
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
{
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
533 * The GSN cache is per thread since even multi-cx-per-thread embeddings
534 * do not interleave js_GetSrcNote calls.
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
;
545 /* Trace-tree JIT recorder/interpreter state. */
546 js::TraceMonitor traceMonitor
;
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
;
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.
567 JSString
*s
; // if s==NULL, d and base are not valid
571 * Cache of reusable JSNativeEnumerators mapped by shape identifiers (as
572 * stored in scope->shape). This cache is nulled by the GC and protected
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
;
592 void mark(JSTracer
*trc
);
593 void purge(JSContext
*cx
);
594 void purgeGCFreeLists();
600 * Structure uniquely representing a thread. It holds thread-private data
601 * that can be accessed without a global lock.
604 /* Linked list of all contexts in use on this thread. */
607 /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */
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.
628 /* Factored out of JSThread for !JS_THREADSAFE embedding in JSRuntime. */
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
;
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.
655 js_InitContextThread(JSContext
*cx
);
658 * On entrance the GC lock must be held and it will be held on exit.
661 js_ClearContextThread(JSContext
*cx
);
663 #endif /* JS_THREADSAFE */
665 typedef enum JSDestroyContextMode
{
670 } JSDestroyContextMode
;
672 typedef enum JSRuntimeState
{
679 typedef enum JSBuiltinFunctionId
{
680 JSBUILTIN_ObjectToIterator
,
681 JSBUILTIN_CallIteratorNext
,
683 } JSBuiltinFunctionId
;
685 typedef struct JSPropertyTreeEntry
{
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
708 # define PROTO_CACHE_METER(cx, x) \
709 ((void) (JS_ATOMIC_INCREMENT(&(cx)->runtime->classProtoCacheStats.x)))
711 # define PROTO_CACHE_METER(cx, x) ((void) 0)
715 struct GlobalAndProto
{
720 GlobalAndProto entries
[JSProto_LIMIT
- JSProto_Object
];
723 # pragma GCC visibility push(default)
725 friend JSBool
js_GetClassPrototype(JSContext
*cx
, JSObject
*scope
,
726 JSProtoKey protoKey
, JSObject
**protop
,
729 # pragma GCC visibility pop
735 typedef Vector
<JSGCChunkInfo
*, 32, SystemAllocPolicy
> GCChunks
;
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
;
764 JSGCArena
*gcEmptyArenaList
;
766 JSGCArenaList gcArenaList
[FINALIZE_LIMIT
];
767 JSGCDoubleArenaList gcDoubleArenaList
;
768 JSDHashTable gcRootsHash
;
769 JSDHashTable gcLocksHash
;
770 jsrefcount gcKeepAtoms
;
774 size_t gcMaxMallocBytes
;
775 uint32 gcEmptyArenaPoolLifespan
;
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.
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
;
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
;
820 size_t gcMarkLaterCount
;
824 JSBackgroundThread gcHelperThread
;
828 * The trace operation and its data argument to trace embedding-specific
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. */
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. */
861 /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
862 JSDebugHooks globalDebugHooks
;
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
);
873 /* More debugging state, see jsdbgapi.c. */
875 JSCList watchPointList
;
877 /* Client opaque pointers */
881 /* These combine to interlock the GC and new requests. */
884 PRCondVar
*requestDone
;
888 /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
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)
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
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
;
957 PRLock
*scriptFilenameTableLock
;
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)
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
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)
1012 # define ENUM_CACHE_METER(name) ((void) 0)
1015 #ifdef JS_DUMP_LOOP_STATS
1016 /* Loop statistics, to trigger trace recording and compiling. */
1017 JSBasicStats loopStats
;
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
;
1050 double lengthSquaredSum
;
1051 double strdepLengthSum
;
1052 double strdepLengthSquaredSum
;
1054 /* Script instrumentation. */
1055 jsrefcount liveScripts
;
1056 jsrefcount totalScripts
;
1057 jsrefcount liveEmptyScripts
;
1058 jsrefcount totalEmptyScripts
;
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
1073 JSBasicStats hostenvScopeDepthStats
;
1074 JSBasicStats lexicalScopeDepthStats
;
1081 #ifdef JS_FUNCTION_METERING
1082 JSFunctionMeter functionMeter
;
1083 char lastScriptFilename
[1024];
1086 #ifdef JS_PROTO_CACHE_METERING
1087 JSClassProtoCache::Stats classProtoCacheStats
;
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
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++)
1129 # define EVAL_CACHE_METER(x) ((void) 0)
1133 # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which)
1134 # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which)
1136 # define JS_RUNTIME_METER(rt, which) /* nothing */
1137 # define JS_RUNTIME_UNMETER(rt, which) /* nothing */
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
1149 struct JSArgumentFormatMap
{
1152 JSArgumentFormatter formatter
;
1153 JSArgumentFormatMap
*next
;
1157 struct JSStackHeader
{
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
{
1175 typedef struct JSResolvingEntry
{
1176 JSDHashEntryHdr hdr
;
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 */
1191 struct JSRegExpStatics
{
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
);
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. */
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
;
1236 * Classic Algol "display" static link optimization.
1238 #define JS_DISPLAY_SIZE 16U
1240 JSStackFrame
*display
[JS_DISPLAY_SIZE
];
1242 /* Runtime version control identifier. */
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. */
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. */
1283 JSArenaPool stackPool
;
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. */
1311 jsbytecode
*tracePrevPc
;
1314 /* Per-context optional error reporter. */
1315 JSErrorReporter errorReporter
;
1317 /* Branch callback. */
1318 JSOperationCallback operationCallback
;
1320 /* Interpreter activation count. */
1323 /* Client opaque pointers. */
1329 # pragma GCC visibility push(default)
1331 friend void js_TraceContext(JSTracer
*, JSContext
*);
1333 # pragma GCC visibility pop
1336 /* Linked list of callstacks. See CallStack. */
1337 js::CallStack
*currentCallStack
;
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
) {
1349 currentCallStack
->suspend(fp
);
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()) {
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
);
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
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
1394 JSCList threadLinks
; /* JSThread contextList linkage */
1396 #define CX_FROM_THREAD_LINKS(tl) \
1397 ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
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. */
1418 /* Random number generator state, used by jsmath.cpp. */
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.)
1443 /* Caller must be holding runtime->gcLock. */
1444 void updateJITEnabled() {
1446 jitEnabled
= ((options
& JSOPTION_JIT
) &&
1447 (debugHooks
== &js_NullDebugHooks
||
1448 (debugHooks
== &runtime
->globalDebugHooks
&&
1449 !runtime
->debuggerInhibitsJIT())));
1453 JSClassProtoCache classProtoCache
;
1455 #ifdef JS_THREADSAFE
1457 * The sweep task for this context.
1459 js::BackgroundSweepTask
*gcSweepTask
;
1462 ptrdiff_t &getMallocCounter() {
1463 #ifdef JS_THREADSAFE
1464 return thread
->gcThreadMallocBytes
;
1466 return runtime
->gcMallocBytes
;
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
);
1492 * Use 1 as an arbitrary non-null pointer indicating successful
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
);
1506 inline void* mallocNoReport(size_t bytes
) {
1507 JS_ASSERT(bytes
!= 0);
1508 void *p
= runtime
->malloc(bytes
);
1511 updateMallocCounter(bytes
);
1515 inline void* calloc(size_t bytes
) {
1516 JS_ASSERT(bytes
!= 0);
1517 void *p
= runtime
->calloc(bytes
);
1518 updateMallocCounter(p
, bytes
);
1522 inline void* realloc(void* p
, size_t bytes
) {
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
);
1534 inline void free(void* p
) {
1535 #ifdef JS_THREADSAFE
1537 gcSweepTask
->freeLater(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)); \
1553 return new(memory) T parms;
1556 JS_ALWAYS_INLINE T
*create() {
1560 template <class T
, class P1
>
1561 JS_ALWAYS_INLINE T
*create(const P1
&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
))
1577 JS_ALWAYS_INLINE
void destroy(T
*p
) {
1582 bool isConstructing();
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)
1617 static inline JSAtom
**
1618 FrameAtomBase(JSContext
*cx
, JSStackFrame
*fp
)
1621 ? COMMON_ATOMS_START(&cx
->runtime
->atomState
)
1622 : fp
->script
->atomMap
.vector
;
1627 class AutoGCRooter
{
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;
1637 JS_ASSERT(this == context
->autoGCRooters
);
1638 context
->autoGCRooters
= down
;
1641 inline void trace(JSTracer
*trc
);
1644 # pragma GCC visibility push(default)
1646 friend void ::js_TraceContext(JSTracer
*trc
, JSContext
*acx
);
1648 # pragma GCC visibility pop
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.
1663 JSContext
* const context
;
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 */
1682 /* No copy or assignment semantics. */
1683 AutoGCRooter(AutoGCRooter
&ida
);
1684 void operator=(AutoGCRooter
&ida
);
1687 class AutoPreserveWeakRoots
: private AutoGCRooter
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
);
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
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
);
1740 val
= STRING_TO_JSVAL(str
);
1743 void setDouble(jsdouble
*dp
) {
1744 JS_ASSERT(tag
== JSVAL
);
1746 val
= DOUBLE_TO_JSVAL(dp
);
1749 jsval
value() const {
1750 JS_ASSERT(tag
== JSVAL
);
1755 JS_ASSERT(tag
== JSVAL
);
1759 friend void AutoGCRooter::trace(JSTracer
*trc
);
1763 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1766 class AutoObjectRooter
: private AutoGCRooter
{
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
) {
1779 JSObject
* object() const {
1783 JSObject
** addr() {
1787 friend void AutoGCRooter::trace(JSTracer
*trc
);
1791 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1794 class AutoArrayRooter
: private AutoGCRooter
{
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
);
1816 friend void AutoGCRooter::trace(JSTracer
*trc
);
1819 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1822 class AutoScopePropertyRooter
: private AutoGCRooter
{
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
);
1834 JSScopeProperty
* const sprop
;
1835 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1838 class AutoScriptRooter
: private AutoGCRooter
{
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
);
1855 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1858 class AutoIdRooter
: private AutoGCRooter
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
;
1876 friend void AutoGCRooter::trace(JSTracer
*trc
);
1880 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1883 class AutoIdArray
: private AutoGCRooter
{
1885 AutoIdArray(JSContext
*cx
, JSIdArray
*ida JS_GUARD_OBJECT_NOTIFIER_PARAM
)
1886 : AutoGCRooter(cx
, IDARRAY
), idArray(ida
)
1888 JS_GUARD_OBJECT_NOTIFIER_INIT
;
1892 JS_DestroyIdArray(context
, idArray
);
1895 return idArray
== NULL
;
1897 jsid
operator[](size_t i
) const {
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
);
1909 inline void trace(JSTracer
*trc
);
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
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
;
1932 ~AutoEnumStateRooter() {
1933 if (!JSVAL_IS_NULL(stateValue
)) {
1937 obj
->enumerate(context
, JSENUMERATE_DESTROY
, &stateValue
, 0);
1942 friend void AutoGCRooter::trace(JSTracer
*trc
);
1944 jsval
state() const { return stateValue
; }
1945 jsval
* addr() { return &stateValue
; }
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
;
1957 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
1960 #ifdef JS_HAS_XML_SUPPORT
1961 class AutoXMLRooter
: private AutoGCRooter
{
1963 AutoXMLRooter(JSContext
*cx
, JSXML
*xml
)
1964 : AutoGCRooter(cx
, XML
), xml(xml
)
1969 friend void AutoGCRooter::trace(JSTracer
*trc
);
1974 #endif /* JS_HAS_XML_SUPPORT */
1980 explicit AutoLockGC(JSRuntime
*rt
) : rt(rt
) { JS_LOCK_GC(rt
); }
1981 ~AutoLockGC() { JS_UNLOCK_GC(rt
); }
1984 class AutoUnlockGC
{
1988 explicit AutoUnlockGC(JSRuntime
*rt
) : rt(rt
) { JS_UNLOCK_GC(rt
); }
1989 ~AutoUnlockGC() { JS_LOCK_GC(rt
); }
1992 class AutoKeepAtoms
{
1995 explicit AutoKeepAtoms(JSRuntime
*rt
) : rt(rt
) { JS_KEEP_ATOMS(rt
); }
1996 ~AutoKeepAtoms() { JS_UNKEEP_ATOMS(rt
); }
1999 } /* namespace js */
2001 class JSAutoResolveFlags
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
; }
2015 JSContext
*mContext
;
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 & \
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
);
2069 js_InitThreads(JSRuntime
*rt
);
2072 js_FinishThreads(JSRuntime
*rt
);
2075 js_PurgeThreads(JSContext
*cx
);
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
2086 js_SyncOptionsToVersion(JSContext
*cx
);
2089 * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context
2090 * data that depends on version.
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.
2100 js_SetVersion(JSContext
*cx
, JSVersion version
);
2103 * Create and destroy functions for JSContext, which is manually allocated
2104 * and exclusively owned.
2107 js_NewContext(JSRuntime
*rt
, size_t stackChunkSize
);
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.
2117 js_ValidContextPointer(JSRuntime
*rt
, JSContext
*cx
);
2119 static JS_INLINE JSContext
*
2120 js_ContextFromLinkField(JSCList
*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.
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.
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.
2156 js_WaitForGC(JSRuntime
*rt
);
2158 #else /* !JS_THREADSAFE */
2160 # define js_WaitForGC(rt) ((void) 0)
2165 * JSClass.resolve and watchpoint recursion damping machinery.
2168 js_StartResolving(JSContext
*cx
, JSResolvingKey
*key
, uint32 flag
,
2169 JSResolvingEntry
**entryp
);
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
2184 js_EnterLocalRootScope(JSContext
*cx
);
2186 #define js_LeaveLocalRootScope(cx) \
2187 js_LeaveLocalRootScopeWithResult(cx, JSVAL_NULL)
2190 js_LeaveLocalRootScopeWithResult(JSContext
*cx
, jsval rval
);
2193 js_ForgetLocalRoot(JSContext
*cx
, jsval v
);
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) \
2210 extern JS_FRIEND_API(const JSErrorFormatString
*)
2211 js_GetErrorMessage(void *userRef
, const char *locale
, const uintN errorNumber
);
2215 js_ReportErrorVA(JSContext
*cx
, uintN flags
, const char *format
, va_list ap
);
2218 js_ReportErrorNumberVA(JSContext
*cx
, uintN flags
, JSErrorCallback callback
,
2219 void *userRef
, const uintN errorNumber
,
2220 JSBool charArgs
, va_list ap
);
2223 js_ExpandErrorArguments(JSContext
*cx
, JSErrorCallback callback
,
2224 void *userRef
, const uintN errorNumber
,
2225 char **message
, JSErrorReport
*reportp
,
2226 bool charArgs
, va_list ap
);
2230 js_ReportOutOfMemory(JSContext
*cx
);
2233 * Report that cx->scriptStackQuota is exhausted.
2236 js_ReportOutOfScriptQuota(JSContext
*cx
);
2239 js_ReportOverRecursed(JSContext
*cx
);
2242 js_ReportAllocationOverflow(JSContext
*cx
);
2244 #define JS_CHECK_RECURSION(cx, onerror) \
2248 if (!JS_CHECK_STACK_SIZE(cx, stackDummy_)) { \
2249 js_ReportOverRecursed(cx); \
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
);
2262 js_ReportIsNotDefined(JSContext
*cx
, const char *name
);
2265 * Report an attempt to access the property of a null or undefined value (v).
2268 js_ReportIsNullOrUndefined(JSContext
*cx
, intN spindex
, jsval v
,
2269 JSString
*fallback
);
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.
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)
2305 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit)
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
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.
2321 js_InvokeOperationCallback(JSContext
*cx
);
2323 #ifndef JS_THREADSAFE
2324 # define js_TriggerAllOperationCallbacks(rt, gcLocked) \
2325 js_TriggerAllOperationCallbacks (rt)
2329 js_TriggerAllOperationCallbacks(JSRuntime
*rt
, JSBool gcLocked
);
2331 extern JSStackFrame
*
2332 js_GetScriptedCaller(JSContext
*cx
, JSStackFrame
*fp
);
2335 js_GetCurrentBytecodePC(JSContext
* cx
);
2338 js_CurrentPCIsInImacro(JSContext
*cx
);
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
);
2354 static JS_FORCES_STACK JS_INLINE
void
2355 LeaveTrace(JSContext
*cx
)
2358 if (JS_ON_TRACE(cx
))
2363 static JS_INLINE
void
2364 LeaveTraceIfGlobalObject(JSContext
*cx
, JSObject
*obj
)
2366 if (!obj
->fslots
[JSSLOT_PARENT
])
2370 static JS_INLINE JSBool
2371 CanLeaveTrace(JSContext
*cx
)
2373 JS_ASSERT(JS_ON_TRACE(cx
));
2375 return cx
->bailExit
!= NULL
;
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
)
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
;
2422 ContextAllocPolicy::malloc(size_t bytes
)
2424 return cx
->malloc(bytes
);
2428 ContextAllocPolicy::free(void *p
)
2434 ContextAllocPolicy::realloc(void *p
, size_t bytes
)
2436 return cx
->realloc(p
, bytes
);
2440 ContextAllocPolicy::reportAllocOverflow() const
2442 js_ReportAllocationOverflow(cx
);
2445 class AutoValueVector
: private AutoGCRooter
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
))
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
);
2483 Vector
<jsval
, 8> vector
;
2484 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
2490 #pragma warning(pop)
2491 #pragma warning(pop)
2494 #endif /* jscntxt_h___ */