LCOV - code coverage report
Current view: directory - js/src - jscntxt.h (source / functions) Found Hit Coverage
Test: app.info Lines: 283 274 96.8 %
Date: 2012-06-02 Functions: 203 188 92.6 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=78:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla Communicator client code, released
      18                 :  * March 31, 1998.
      19                 :  *
      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.
      24                 :  *
      25                 :  * Contributor(s):
      26                 :  *
      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.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : /* JS execution context. */
      42                 : 
      43                 : #ifndef jscntxt_h___
      44                 : #define jscntxt_h___
      45                 : 
      46                 : #include "mozilla/Attributes.h"
      47                 : 
      48                 : #include <string.h>
      49                 : 
      50                 : #include "jsapi.h"
      51                 : #include "jsfriendapi.h"
      52                 : #include "jsprvtd.h"
      53                 : #include "jsatom.h"
      54                 : #include "jsclist.h"
      55                 : #include "jsdhash.h"
      56                 : #include "jsgc.h"
      57                 : #include "jspropertycache.h"
      58                 : #include "jspropertytree.h"
      59                 : #include "jsutil.h"
      60                 : #include "prmjtime.h"
      61                 : 
      62                 : #include "ds/LifoAlloc.h"
      63                 : #include "gc/Statistics.h"
      64                 : #include "js/HashTable.h"
      65                 : #include "js/Vector.h"
      66                 : #include "vm/Stack.h"
      67                 : 
      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
      74                 : 
      75                 : JS_BEGIN_EXTERN_C
      76                 : struct DtoaState;
      77                 : JS_END_EXTERN_C
      78                 : 
      79                 : struct JSSharpInfo {
      80                 :     bool hasGen;
      81                 :     bool isSharp;
      82                 : 
      83          874063 :     JSSharpInfo() : hasGen(false), isSharp(false) {}
      84                 : };
      85                 : 
      86                 : typedef js::HashMap<JSObject *, JSSharpInfo> JSSharpTable;
      87                 : 
      88           26228 : struct JSSharpObjectMap {
      89                 :     unsigned     depth;
      90                 :     uint32_t     sharpgen;
      91                 :     JSSharpTable table;
      92                 : 
      93           26231 :     JSSharpObjectMap(JSContext *cx) : depth(0), sharpgen(0), table(js::TempAllocPolicy(cx)) {
      94           26231 :         table.init();
      95           26231 :     }
      96                 : };
      97                 : 
      98                 : namespace js {
      99                 : 
     100                 : namespace mjit {
     101                 : class JaegerCompartment;
     102                 : }
     103                 : 
     104                 : class WeakMapBase;
     105                 : class InterpreterFrames;
     106                 : 
     107                 : class ScriptOpcodeCounts;
     108                 : struct ScriptOpcodeCountsPair;
     109                 : 
     110                 : /*
     111                 :  * GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
     112                 :  * given pc in a script. We use the script->code pointer to tag the cache,
     113                 :  * instead of the script address itself, so that source notes are always found
     114                 :  * by offset from the bytecode with which they were generated.
     115                 :  */
     116           19908 : struct GSNCache {
     117                 :     typedef HashMap<jsbytecode *,
     118                 :                     jssrcnote *,
     119                 :                     PointerHasher<jsbytecode *, 0>,
     120                 :                     SystemAllocPolicy> Map;
     121                 : 
     122                 :     jsbytecode      *code;
     123                 :     Map             map;
     124                 : 
     125           19910 :     GSNCache() : code(NULL) { }
     126                 : 
     127                 :     void purge();
     128                 : };
     129                 : 
     130                 : inline GSNCache *
     131                 : GetGSNCache(JSContext *cx);
     132                 : 
     133                 : struct PendingProxyOperation {
     134                 :     PendingProxyOperation   *next;
     135                 :     JSObject                *object;
     136                 : };
     137                 : 
     138                 : typedef Vector<ScriptOpcodeCountsPair, 0, SystemAllocPolicy> ScriptOpcodeCountsVector;
     139                 : 
     140                 : struct ConservativeGCData
     141                 : {
     142                 :     /*
     143                 :      * The GC scans conservatively between ThreadData::nativeStackBase and
     144                 :      * nativeStackTop unless the latter is NULL.
     145                 :      */
     146                 :     uintptr_t           *nativeStackTop;
     147                 : 
     148                 :     union {
     149                 :         jmp_buf         jmpbuf;
     150                 :         uintptr_t       words[JS_HOWMANY(sizeof(jmp_buf), sizeof(uintptr_t))];
     151                 :     } registerSnapshot;
     152                 : 
     153                 :     /*
     154                 :      * Cycle collector uses this to communicate that the native stack of the
     155                 :      * GC thread should be scanned only if the thread have more than the given
     156                 :      * threshold of requests.
     157                 :      */
     158                 :     unsigned requestThreshold;
     159                 : 
     160           19910 :     ConservativeGCData()
     161           19910 :       : nativeStackTop(NULL), requestThreshold(0)
     162           19910 :     {}
     163                 : 
     164           19908 :     ~ConservativeGCData() {
     165                 : #ifdef JS_THREADSAFE
     166                 :         /*
     167                 :          * The conservative GC scanner should be disabled when the thread leaves
     168                 :          * the last request.
     169                 :          */
     170           19908 :         JS_ASSERT(!hasStackToScan());
     171                 : #endif
     172           19908 :     }
     173                 : 
     174                 :     JS_NEVER_INLINE void recordStackTop();
     175                 : 
     176                 : #ifdef JS_THREADSAFE
     177          424548 :     void updateForRequestEnd(unsigned suspendCount) {
     178          424548 :         if (suspendCount)
     179          356267 :             recordStackTop();
     180                 :         else
     181           68281 :             nativeStackTop = NULL;
     182          424548 :     }
     183                 : #endif
     184                 : 
     185           53058 :     bool hasStackToScan() const {
     186           53058 :         return !!nativeStackTop;
     187                 :     }
     188                 : };
     189                 : 
     190                 : } /* namespace js */
     191                 : 
     192                 : struct JSRuntime : js::RuntimeFriendFields
     193                 : {
     194                 :     /* Default compartment. */
     195                 :     JSCompartment       *atomsCompartment;
     196                 : 
     197                 :     /* List of compartments (protected by the GC lock). */
     198                 :     js::CompartmentVector compartments;
     199                 : 
     200                 :     /* See comment for JS_AbortIfWrongThread in jsapi.h. */
     201                 : #ifdef JS_THREADSAFE
     202                 :   public:
     203        27226744 :     void *ownerThread() const { return ownerThread_; }
     204                 :     void clearOwnerThread();
     205                 :     void setOwnerThread();
     206                 :     JS_FRIEND_API(bool) onOwnerThread() const;
     207                 :   private:
     208                 :     void                *ownerThread_;
     209                 :   public:
     210                 : #else
     211                 :   public:
     212                 :     bool onOwnerThread() const { return true; }
     213                 : #endif
     214                 : 
     215                 :     /* Keeper of the contiguous stack used by all contexts in this thread. */
     216                 :     js::StackSpace stackSpace;
     217                 : 
     218                 :     /* Temporary arena pool used while compiling and decompiling. */
     219                 :     static const size_t TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
     220                 :     js::LifoAlloc tempLifoAlloc;
     221                 : 
     222                 :   private:
     223                 :     /*
     224                 :      * Both of these allocators are used for regular expression code which is shared at the
     225                 :      * thread-data level.
     226                 :      */
     227                 :     JSC::ExecutableAllocator *execAlloc_;
     228                 :     WTF::BumpPointerAllocator *bumpAlloc_;
     229                 : 
     230                 :     JSC::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
     231                 :     WTF::BumpPointerAllocator *createBumpPointerAllocator(JSContext *cx);
     232                 : 
     233                 :   public:
     234           58226 :     JSC::ExecutableAllocator *getExecutableAllocator(JSContext *cx) {
     235           58226 :         return execAlloc_ ? execAlloc_ : createExecutableAllocator(cx);
     236                 :     }
     237            2975 :     WTF::BumpPointerAllocator *getBumpPointerAllocator(JSContext *cx) {
     238            2975 :         return bumpAlloc_ ? bumpAlloc_ : createBumpPointerAllocator(cx);
     239                 :     }
     240                 : 
     241                 :     /* Base address of the native stack for the current thread. */
     242                 :     uintptr_t           nativeStackBase;
     243                 : 
     244                 :     /* The native stack size limit that runtime should not exceed. */
     245                 :     size_t              nativeStackQuota;
     246                 : 
     247                 :     /*
     248                 :      * Frames currently running in js::Interpret. See InterpreterFrames for
     249                 :      * details.
     250                 :      */
     251                 :     js::InterpreterFrames *interpreterFrames;
     252                 : 
     253                 :     /* Context create/destroy callback. */
     254                 :     JSContextCallback   cxCallback;
     255                 : 
     256                 :     /* Compartment create/destroy callback. */
     257                 :     JSCompartmentCallback compartmentCallback;
     258                 : 
     259                 :     js::ActivityCallback  activityCallback;
     260                 :     void                 *activityCallbackArg;
     261                 : 
     262                 : #ifdef JS_THREADSAFE
     263                 :     /* Number of JS_SuspendRequest calls withot JS_ResumeRequest. */
     264                 :     unsigned            suspendCount;
     265                 : 
     266                 :     /* The request depth for this thread. */
     267                 :     unsigned            requestDepth;
     268                 : 
     269                 : # ifdef DEBUG
     270                 :     unsigned            checkRequestDepth;
     271                 : # endif
     272                 : #endif
     273                 : 
     274                 :     /* Garbage collector state, used by jsgc.c. */
     275                 : 
     276                 :     /*
     277                 :      * Set of all GC chunks with at least one allocated thing. The
     278                 :      * conservative GC uses it to quickly check if a possible GC thing points
     279                 :      * into an allocated chunk.
     280                 :      */
     281                 :     js::GCChunkSet      gcChunkSet;
     282                 : 
     283                 :     /*
     284                 :      * Doubly-linked lists of chunks from user and system compartments. The GC
     285                 :      * allocates its arenas from the corresponding list and when all arenas
     286                 :      * in the list head are taken, then the chunk is removed from the list.
     287                 :      * During the GC when all arenas in a chunk become free, that chunk is
     288                 :      * removed from the list and scheduled for release.
     289                 :      */
     290                 :     js::gc::Chunk       *gcSystemAvailableChunkListHead;
     291                 :     js::gc::Chunk       *gcUserAvailableChunkListHead;
     292                 :     js::gc::ChunkPool   gcChunkPool;
     293                 : 
     294                 :     js::RootedValueMap  gcRootsHash;
     295                 :     js::GCLocks         gcLocksHash;
     296                 :     unsigned            gcKeepAtoms;
     297                 :     size_t              gcBytes;
     298                 :     size_t              gcMaxBytes;
     299                 :     size_t              gcMaxMallocBytes;
     300                 : 
     301                 :     /*
     302                 :      * Number of the committed arenas in all GC chunks including empty chunks.
     303                 :      * The counter is volatile as it is read without the GC lock, see comments
     304                 :      * in MaybeGC.
     305                 :      */
     306                 :     volatile uint32_t   gcNumArenasFreeCommitted;
     307                 :     js::GCMarker        gcMarker;
     308                 :     void                *gcVerifyData;
     309                 :     bool                gcChunkAllocationSinceLastGC;
     310                 :     int64_t             gcNextFullGCTime;
     311                 :     int64_t             gcJitReleaseTime;
     312                 :     JSGCMode            gcMode;
     313                 :     volatile uintptr_t  gcIsNeeded;
     314                 :     js::WeakMapBase     *gcWeakMapList;
     315                 :     js::gcstats::Statistics gcStats;
     316                 : 
     317                 :     /* Incremented on every GC slice. */
     318                 :     uint64_t            gcNumber;
     319                 : 
     320                 :     /* The gcNumber at the time of the most recent GC's first slice. */
     321                 :     uint64_t            gcStartNumber;
     322                 : 
     323                 :     /* The reason that an interrupt-triggered GC should be called. */
     324                 :     js::gcreason::Reason gcTriggerReason;
     325                 : 
     326                 :     /*
     327                 :      * Compartment that triggered GC. If more than one Compatment need GC,
     328                 :      * gcTriggerCompartment is reset to NULL and a global GC is performed.
     329                 :      */
     330                 :     JSCompartment       *gcTriggerCompartment;
     331                 : 
     332                 :     /* Compartment that is currently involved in per-compartment GC */
     333                 :     JSCompartment       *gcCurrentCompartment;
     334                 : 
     335                 :     /*
     336                 :      * If this is non-NULL, all marked objects must belong to this compartment.
     337                 :      * This is used to look for compartment bugs.
     338                 :      */
     339                 :     JSCompartment       *gcCheckCompartment;
     340                 : 
     341                 :     /*
     342                 :      * The current incremental GC phase. During non-incremental GC, this is
     343                 :      * always NO_INCREMENTAL.
     344                 :      */
     345                 :     js::gc::State       gcIncrementalState;
     346                 : 
     347                 :     /* Indicates that a new compartment was created during incremental GC. */
     348                 :     bool                gcCompartmentCreated;
     349                 : 
     350                 :     /* Indicates that the last incremental slice exhausted the mark stack. */
     351                 :     bool                gcLastMarkSlice;
     352                 : 
     353                 :     /*
     354                 :      * Indicates that a GC slice has taken place in the middle of an animation
     355                 :      * frame, rather than at the beginning. In this case, the next slice will be
     356                 :      * delayed so that we don't get back-to-back slices.
     357                 :      */
     358                 :     volatile uintptr_t  gcInterFrameGC;
     359                 : 
     360                 :     /* Default budget for incremental GC slice. See SliceBudget in jsgc.h. */
     361                 :     int64_t             gcSliceBudget;
     362                 : 
     363                 :     /*
     364                 :      * We disable incremental GC if we encounter a js::Class with a trace hook
     365                 :      * that does not implement write barriers.
     366                 :      */
     367                 :     bool                gcIncrementalEnabled;
     368                 : 
     369                 :     /* Compartment that is undergoing an incremental GC. */
     370                 :     JSCompartment       *gcIncrementalCompartment;
     371                 : 
     372                 :     /*
     373                 :      * We save all conservative scanned roots in this vector so that
     374                 :      * conservative scanning can be "replayed" deterministically. In DEBUG mode,
     375                 :      * this allows us to run a non-incremental GC after every incremental GC to
     376                 :      * ensure that no objects were missed.
     377                 :      */
     378                 : #ifdef DEBUG
     379          425210 :     struct SavedGCRoot {
     380                 :         void *thing;
     381                 :         JSGCTraceKind kind;
     382                 : 
     383          175857 :         SavedGCRoot(void *thing, JSGCTraceKind kind) : thing(thing), kind(kind) {}
     384                 :     };
     385                 :     js::Vector<SavedGCRoot, 0, js::SystemAllocPolicy> gcSavedRoots;
     386                 : #endif
     387                 : 
     388                 :     /*
     389                 :      * We can pack these flags as only the GC thread writes to them. Atomic
     390                 :      * updates to packed bytes are not guaranteed, so stores issued by one
     391                 :      * thread may be lost due to unsynchronized read-modify-write cycles on
     392                 :      * other threads.
     393                 :      */
     394                 :     bool                gcPoke;
     395                 :     bool                gcRunning;
     396                 : 
     397                 :     /*
     398                 :      * These options control the zealousness of the GC. The fundamental values
     399                 :      * are gcNextScheduled and gcDebugCompartmentGC. At every allocation,
     400                 :      * gcNextScheduled is decremented. When it reaches zero, we do either a
     401                 :      * full or a compartmental GC, based on gcDebugCompartmentGC.
     402                 :      *
     403                 :      * At this point, if gcZeal_ == 2 then gcNextScheduled is reset to the
     404                 :      * value of gcZealFrequency. Otherwise, no additional GCs take place.
     405                 :      *
     406                 :      * You can control these values in several ways:
     407                 :      *   - Pass the -Z flag to the shell (see the usage info for details)
     408                 :      *   - Call gczeal() or schedulegc() from inside shell-executed JS code
     409                 :      *     (see the help for details)
     410                 :      *
     411                 :      * If gzZeal_ == 1 then we perform GCs in select places (during MaybeGC and
     412                 :      * whenever a GC poke happens). This option is mainly useful to embedders.
     413                 :      *
     414                 :      * We use gcZeal_ == 4 to enable write barrier verification. See the comment
     415                 :      * in jsgc.cpp for more information about this.
     416                 :      */
     417                 : #ifdef JS_GC_ZEAL
     418                 :     int                 gcZeal_;
     419                 :     int                 gcZealFrequency;
     420                 :     int                 gcNextScheduled;
     421                 :     bool                gcDebugCompartmentGC;
     422                 :     bool                gcDeterministicOnly;
     423                 : 
     424     -1793318227 :     int gcZeal() { return gcZeal_; }
     425                 : 
     426       270394255 :     bool needZealousGC() {
     427       270394255 :         if (gcNextScheduled > 0 && --gcNextScheduled == 0) {
     428           10570 :             if (gcZeal() == js::gc::ZealAllocValue)
     429           10500 :                 gcNextScheduled = gcZealFrequency;
     430           10570 :             return true;
     431                 :         }
     432       270383685 :         return false;
     433                 :     }
     434                 : #else
     435                 :     int gcZeal() { return 0; }
     436                 :     bool needZealousGC() { return false; }
     437                 : #endif
     438                 : 
     439                 :     JSGCCallback        gcCallback;
     440                 :     js::GCSliceCallback gcSliceCallback;
     441                 :     JSFinalizeCallback  gcFinalizeCallback;
     442                 : 
     443                 :   private:
     444                 :     /*
     445                 :      * Malloc counter to measure memory pressure for GC scheduling. It runs
     446                 :      * from gcMaxMallocBytes down to zero.
     447                 :      */
     448                 :     volatile ptrdiff_t  gcMallocBytes;
     449                 : 
     450                 :   public:
     451                 :     /*
     452                 :      * The trace operations to trace embedding-specific GC roots. One is for
     453                 :      * tracing through black roots and the other is for tracing through gray
     454                 :      * roots. The black/gray distinction is only relevant to the cycle
     455                 :      * collector.
     456                 :      */
     457                 :     JSTraceDataOp       gcBlackRootsTraceOp;
     458                 :     void                *gcBlackRootsData;
     459                 :     JSTraceDataOp       gcGrayRootsTraceOp;
     460                 :     void                *gcGrayRootsData;
     461                 : 
     462                 :     /* Stack of thread-stack-allocated GC roots. */
     463                 :     js::AutoGCRooter   *autoGCRooters;
     464                 : 
     465                 :     /* Strong references on scripts held for PCCount profiling API. */
     466                 :     js::ScriptOpcodeCountsVector *scriptPCCounters;
     467                 : 
     468                 :     /* Well-known numbers held for use by this runtime's contexts. */
     469                 :     js::Value           NaNValue;
     470                 :     js::Value           negativeInfinityValue;
     471                 :     js::Value           positiveInfinityValue;
     472                 : 
     473                 :     JSAtom              *emptyString;
     474                 : 
     475                 :     /* List of active contexts sharing this runtime. */
     476                 :     JSCList             contextList;
     477                 : 
     478         1736329 :     bool hasContexts() const {
     479         1736329 :         return !JS_CLIST_IS_EMPTY(&contextList);
     480                 :     }
     481                 : 
     482                 :     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
     483                 :     JSDebugHooks        debugHooks;
     484                 : 
     485                 :     /* If true, new compartments are initially in debug mode. */
     486                 :     bool                debugMode;
     487                 : 
     488                 :     /* If true, new scripts must be created with PC counter information. */
     489                 :     bool                profilingScripts;
     490                 : 
     491                 :     /* Had an out-of-memory error which did not populate an exception. */
     492                 :     JSBool              hadOutOfMemory;
     493                 : 
     494                 :     /*
     495                 :      * Linked list of all js::Debugger objects. This may be accessed by the GC
     496                 :      * thread, if any, or a thread that is in a request and holds gcLock.
     497                 :      */
     498                 :     JSCList             debuggerList;
     499                 : 
     500                 :     /* Client opaque pointers */
     501                 :     void                *data;
     502                 : 
     503                 : #ifdef JS_THREADSAFE
     504                 :     /* These combine to interlock the GC and new requests. */
     505                 :     PRLock              *gcLock;
     506                 : 
     507                 :     js::GCHelperThread  gcHelperThread;
     508                 : #endif /* JS_THREADSAFE */
     509                 : 
     510                 :     uint32_t            debuggerMutations;
     511                 : 
     512                 :     const JSSecurityCallbacks *securityCallbacks;
     513                 :     JSDestroyPrincipalsOp destroyPrincipals;
     514                 : 
     515                 :     /* Structured data callbacks are runtime-wide. */
     516                 :     const JSStructuredCloneCallbacks *structuredCloneCallbacks;
     517                 : 
     518                 :     /* Call this to accumulate telemetry data. */
     519                 :     JSAccumulateTelemetryDataCallback telemetryCallback;
     520                 : 
     521                 :     /*
     522                 :      * The propertyRemovals counter is incremented for every JSObject::clear,
     523                 :      * and for each JSObject::remove method call that frees a slot in the given
     524                 :      * object. See js_NativeGet and js_NativeSet in jsobj.cpp.
     525                 :      */
     526                 :     int32_t             propertyRemovals;
     527                 : 
     528                 :     /* Number localization, used by jsnum.c */
     529                 :     const char          *thousandsSeparator;
     530                 :     const char          *decimalSeparator;
     531                 :     const char          *numGrouping;
     532                 : 
     533                 :     /*
     534                 :      * Weak references to lazily-created, well-known XML singletons.
     535                 :      *
     536                 :      * NB: Singleton objects must be carefully disconnected from the rest of
     537                 :      * the object graph usually associated with a JSContext's global object,
     538                 :      * including the set of standard class objects.  See jsxml.c for details.
     539                 :      */
     540                 :     JSObject            *anynameObject;
     541                 :     JSObject            *functionNamespaceObject;
     542                 : 
     543                 :     /*
     544                 :      * Flag indicating that we are waiving any soft limits on the GC heap
     545                 :      * because we want allocations to be infallible (except when we hit OOM).
     546                 :      */
     547                 :     bool                waiveGCQuota;
     548                 : 
     549                 :     /*
     550                 :      * The GSN cache is per thread since even multi-cx-per-thread embeddings
     551                 :      * do not interleave js_GetSrcNote calls.
     552                 :      */
     553                 :     js::GSNCache        gsnCache;
     554                 : 
     555                 :     /* Property cache for faster call/get/set invocation. */
     556                 :     js::PropertyCache   propertyCache;
     557                 : 
     558                 :     /* State used by jsdtoa.cpp. */
     559                 :     DtoaState           *dtoaState;
     560                 : 
     561                 :     /* List of currently pending operations on proxies. */
     562                 :     js::PendingProxyOperation *pendingProxyOperation;
     563                 : 
     564                 :     js::ConservativeGCData conservativeGC;
     565                 : 
     566                 :   private:
     567                 :     JSPrincipals        *trustedPrincipals_;
     568                 :   public:
     569           21214 :     void setTrustedPrincipals(JSPrincipals *p) { trustedPrincipals_ = p; }
     570         9481962 :     JSPrincipals *trustedPrincipals() const { return trustedPrincipals_; }
     571                 : 
     572                 :     /* Literal table maintained by jsatom.c functions. */
     573                 :     JSAtomState         atomState;
     574                 : 
     575                 :     /* Tables of strings that are pre-allocated in the atomsCompartment. */
     576                 :     js::StaticStrings   staticStrings;
     577                 : 
     578                 :     JSWrapObjectCallback wrapObjectCallback;
     579                 :     JSPreWrapCallback    preWrapObjectCallback;
     580                 :     js::PreserveWrapperCallback preserveWrapperCallback;
     581                 : 
     582                 : #ifdef DEBUG
     583                 :     size_t              noGCOrAllocationCheck;
     584                 : #endif
     585                 : 
     586                 :     /*
     587                 :      * To ensure that cx->malloc does not cause a GC, we set this flag during
     588                 :      * OOM reporting (in js_ReportOutOfMemory). If a GC is requested while
     589                 :      * reporting the OOM, we ignore it.
     590                 :      */
     591                 :     int32_t             inOOMReport;
     592                 : 
     593                 :     bool                jitHardening;
     594                 : 
     595                 :     JSRuntime();
     596                 :     ~JSRuntime();
     597                 : 
     598                 :     bool init(uint32_t maxbytes);
     599                 : 
     600           39820 :     JSRuntime *thisFromCtor() { return this; }
     601                 : 
     602                 :     /*
     603                 :      * Call the system malloc while checking for GC memory pressure and
     604                 :      * reporting OOM error when cx is not null. We will not GC from here.
     605                 :      */
     606        29049063 :     void* malloc_(size_t bytes, JSContext *cx = NULL) {
     607        29049063 :         updateMallocCounter(cx, bytes);
     608        29049063 :         void *p = ::js_malloc(bytes);
     609        29049063 :         return JS_LIKELY(!!p) ? p : onOutOfMemory(NULL, bytes, cx);
     610                 :     }
     611                 : 
     612                 :     /*
     613                 :      * Call the system calloc while checking for GC memory pressure and
     614                 :      * reporting OOM error when cx is not null. We will not GC from here.
     615                 :      */
     616         2263540 :     void* calloc_(size_t bytes, JSContext *cx = NULL) {
     617         2263540 :         updateMallocCounter(cx, bytes);
     618         2263540 :         void *p = ::js_calloc(bytes);
     619         2263540 :         return JS_LIKELY(!!p) ? p : onOutOfMemory(reinterpret_cast<void *>(1), bytes, cx);
     620                 :     }
     621                 : 
     622          907136 :     void* realloc_(void* p, size_t oldBytes, size_t newBytes, JSContext *cx = NULL) {
     623          907136 :         JS_ASSERT(oldBytes < newBytes);
     624          907136 :         updateMallocCounter(cx, newBytes - oldBytes);
     625          907136 :         void *p2 = ::js_realloc(p, newBytes);
     626          907136 :         return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, newBytes, cx);
     627                 :     }
     628                 : 
     629          274243 :     void* realloc_(void* p, size_t bytes, JSContext *cx = NULL) {
     630                 :         /*
     631                 :          * For compatibility we do not account for realloc that increases
     632                 :          * previously allocated memory.
     633                 :          */
     634          274243 :         if (!p)
     635              37 :             updateMallocCounter(cx, bytes);
     636          274243 :         void *p2 = ::js_realloc(p, bytes);
     637          274243 :         return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, bytes, cx);
     638                 :     }
     639                 : 
     640        38033960 :     inline void free_(void* p) {
     641                 :         /* FIXME: Making this free in the background is buggy. Can it work? */
     642        38033960 :         js::Foreground::free_(p);
     643        38033960 :     }
     644                 : 
     645          435261 :     JS_DECLARE_NEW_METHODS(malloc_, JS_ALWAYS_INLINE)
     646           42287 :     JS_DECLARE_DELETE_METHODS(free_, JS_ALWAYS_INLINE)
     647                 : 
     648                 :     bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; }
     649                 : 
     650           71052 :     void resetGCMallocBytes() { gcMallocBytes = ptrdiff_t(gcMaxMallocBytes); }
     651                 : 
     652           19960 :     void setGCMaxMallocBytes(size_t value) {
     653                 :         /*
     654                 :          * For compatibility treat any value that exceeds PTRDIFF_T_MAX to
     655                 :          * mean that value.
     656                 :          */
     657           19960 :         gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
     658           19960 :         resetGCMallocBytes();
     659           19960 :     }
     660                 : 
     661                 :     /*
     662                 :      * Call this after allocating memory held by GC things, to update memory
     663                 :      * pressure counters or report the OOM error if necessary. If oomError and
     664                 :      * cx is not null the function also reports OOM error.
     665                 :      *
     666                 :      * The function must be called outside the GC lock and in case of OOM error
     667                 :      * the caller must ensure that no deadlock possible during OOM reporting.
     668                 :      */
     669                 :     void updateMallocCounter(JSContext *cx, size_t nbytes);
     670                 : 
     671                 :     /*
     672                 :      * The function must be called outside the GC lock.
     673                 :      */
     674                 :     JS_FRIEND_API(void) onTooMuchMalloc();
     675                 : 
     676                 :     /*
     677                 :      * This should be called after system malloc/realloc returns NULL to try
     678                 :      * to recove some memory or to report an error. Failures in malloc and
     679                 :      * calloc are signaled by p == null and p == reinterpret_cast<void *>(1).
     680                 :      * Other values of p mean a realloc failure.
     681                 :      *
     682                 :      * The function must be called outside the GC lock.
     683                 :      */
     684                 :     JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx);
     685                 : 
     686                 :     void triggerOperationCallback();
     687                 : 
     688                 :     void setJitHardening(bool enabled);
     689         1775528 :     bool getJitHardening() const {
     690         1775528 :         return jitHardening;
     691                 :     }
     692                 : 
     693                 :     void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *normal, size_t *temporary,
     694                 :                              size_t *regexpCode, size_t *stackCommitted, size_t *gcMarker);
     695                 : };
     696                 : 
     697                 : /* Common macros to access thread-local caches in JSRuntime. */
     698                 : #define JS_PROPERTY_CACHE(cx)   (cx->runtime->propertyCache)
     699                 : 
     700                 : #define JS_KEEP_ATOMS(rt)   (rt)->gcKeepAtoms++;
     701                 : #define JS_UNKEEP_ATOMS(rt) (rt)->gcKeepAtoms--;
     702                 : 
     703                 : #ifdef JS_ARGUMENT_FORMATTER_DEFINED
     704                 : /*
     705                 :  * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
     706                 :  * formatter functions.  Elements are sorted in non-increasing format string
     707                 :  * length order.
     708                 :  */
     709                 : struct JSArgumentFormatMap {
     710                 :     const char          *format;
     711                 :     size_t              length;
     712                 :     JSArgumentFormatter formatter;
     713                 :     JSArgumentFormatMap *next;
     714                 : };
     715                 : #endif
     716                 : 
     717                 : namespace js {
     718                 : 
     719                 : template <typename T> class Root;
     720                 : class CheckRoot;
     721                 : 
     722                 : struct AutoResolving;
     723                 : 
     724                 : static inline bool
     725             972 : OptionsHasXML(uint32_t options)
     726                 : {
     727             972 :     return !!(options & JSOPTION_XML);
     728                 : }
     729                 : 
     730                 : static inline bool
     731                 : OptionsSameVersionFlags(uint32_t self, uint32_t other)
     732                 : {
     733                 :     static const uint32_t mask = JSOPTION_XML;
     734                 :     return !((self & mask) ^ (other & mask));
     735                 : }
     736                 : 
     737                 : /*
     738                 :  * Flags accompany script version data so that a) dynamically created scripts
     739                 :  * can inherit their caller's compile-time properties and b) scripts can be
     740                 :  * appropriately compared in the eval cache across global option changes. An
     741                 :  * example of the latter is enabling the top-level-anonymous-function-is-error
     742                 :  * option: subsequent evals of the same, previously-valid script text may have
     743                 :  * become invalid.
     744                 :  */
     745                 : namespace VersionFlags {
     746                 : static const unsigned MASK         = 0x0FFF; /* see JSVersion in jspubtd.h */
     747                 : static const unsigned HAS_XML      = 0x1000; /* flag induced by XML option */
     748                 : static const unsigned FULL_MASK    = 0x3FFF;
     749                 : }
     750                 : 
     751                 : static inline JSVersion
     752         7884730 : VersionNumber(JSVersion version)
     753                 : {
     754         7884730 :     return JSVersion(uint32_t(version) & VersionFlags::MASK);
     755                 : }
     756                 : 
     757                 : static inline bool
     758         5151897 : VersionHasXML(JSVersion version)
     759                 : {
     760         5151897 :     return !!(version & VersionFlags::HAS_XML);
     761                 : }
     762                 : 
     763                 : /* @warning This is a distinct condition from having the XML flag set. */
     764                 : static inline bool
     765            1880 : VersionShouldParseXML(JSVersion version)
     766                 : {
     767            1880 :     return VersionHasXML(version) || VersionNumber(version) >= JSVERSION_1_6;
     768                 : }
     769                 : 
     770                 : static inline JSVersion
     771           50870 : VersionExtractFlags(JSVersion version)
     772                 : {
     773           50870 :     return JSVersion(uint32_t(version) & ~VersionFlags::MASK);
     774                 : }
     775                 : 
     776                 : static inline void
     777           24833 : VersionCopyFlags(JSVersion *version, JSVersion from)
     778                 : {
     779           24833 :     *version = JSVersion(VersionNumber(*version) | VersionExtractFlags(from));
     780           24833 : }
     781                 : 
     782                 : static inline bool
     783           26037 : VersionHasFlags(JSVersion version)
     784                 : {
     785           26037 :     return !!VersionExtractFlags(version);
     786                 : }
     787                 : 
     788                 : static inline unsigned
     789         5011016 : VersionFlagsToOptions(JSVersion version)
     790                 : {
     791         5011016 :     unsigned copts = VersionHasXML(version) ? JSOPTION_XML : 0;
     792         5011016 :     JS_ASSERT((copts & JSCOMPILEOPTION_MASK) == copts);
     793         5011016 :     return copts;
     794                 : }
     795                 : 
     796                 : static inline JSVersion
     797             968 : OptionFlagsToVersion(unsigned options, JSVersion version)
     798                 : {
     799             968 :     return VersionSetXML(version, OptionsHasXML(options));
     800                 : }
     801                 : 
     802                 : static inline bool
     803           26037 : VersionIsKnown(JSVersion version)
     804                 : {
     805           26037 :     return VersionNumber(version) != JSVERSION_UNKNOWN;
     806                 : }
     807                 : 
     808                 : typedef HashSet<JSObject *,
     809                 :                 DefaultHasher<JSObject *>,
     810                 :                 SystemAllocPolicy> BusyArraysSet;
     811                 : 
     812                 : } /* namespace js */
     813                 : 
     814                 : struct JSContext : js::ContextFriendFields
     815                 : {
     816                 :     explicit JSContext(JSRuntime *rt);
     817           52462 :     JSContext *thisDuringConstruction() { return this; }
     818                 :     ~JSContext();
     819                 : 
     820                 :     /* JSRuntime contextList linkage. */
     821                 :     JSCList             link;
     822                 : 
     823                 :   private:
     824                 :     /* See JSContext::findVersion. */
     825                 :     JSVersion           defaultVersion;      /* script compilation version */
     826                 :     JSVersion           versionOverride;     /* supercedes defaultVersion when valid */
     827                 :     bool                hasVersionOverride;
     828                 : 
     829                 :     /* Exception state -- the exception member is a GC root by definition. */
     830                 :     JSBool              throwing;           /* is there a pending exception? */
     831                 :     js::Value           exception;          /* most-recently-thrown exception */
     832                 : 
     833                 :     /* Per-context run options. */
     834                 :     unsigned               runOptions;            /* see jsapi.h for JSOPTION_* */
     835                 : 
     836                 :   public:
     837                 :     int32_t             reportGranularity;  /* see jsprobes.h */
     838                 : 
     839                 :     /* Locale specific callbacks for string conversion. */
     840                 :     JSLocaleCallbacks   *localeCallbacks;
     841                 : 
     842                 :     js::AutoResolving   *resolvingList;
     843                 : 
     844                 :     /*
     845                 :      * True if generating an error, to prevent runaway recursion.
     846                 :      * NB: generatingError packs with throwing below.
     847                 :      */
     848                 :     bool        generatingError;
     849                 : 
     850                 :     /* GC heap compartment. */
     851                 :     JSCompartment       *compartment;
     852                 : 
     853                 :     inline void setCompartment(JSCompartment *compartment);
     854                 : 
     855                 :     /* Current execution stack. */
     856                 :     js::ContextStack    stack;
     857                 : 
     858                 :     /* ContextStack convenience functions */
     859      1856072004 :     inline bool hasfp() const               { return stack.hasfp(); }
     860      1045535751 :     inline js::StackFrame* fp() const       { return stack.fp(); }
     861         3625099 :     inline js::StackFrame* maybefp() const  { return stack.maybefp(); }
     862        55876901 :     inline js::FrameRegs& regs() const      { return stack.regs(); }
     863        63767098 :     inline js::FrameRegs* maybeRegs() const { return stack.maybeRegs(); }
     864                 : 
     865                 :     /* Set cx->compartment based on the current scope chain. */
     866                 :     void resetCompartment();
     867                 : 
     868                 :     /* Wrap cx->exception for the current compartment. */
     869                 :     void wrapPendingException();
     870                 : 
     871                 :   private:
     872                 :     /* Lazily initialized pool of maps used during parse/emit. */
     873                 :     js::ParseMapPool    *parseMapPool_;
     874                 : 
     875                 :   public:
     876                 :     /* Top-level object and pointer to top stack frame's scope chain. */
     877                 :     JSObject            *globalObject;
     878                 : 
     879                 :     /* State for object and array toSource conversion. */
     880                 :     JSSharpObjectMap    sharpObjectMap;
     881                 :     js::BusyArraysSet   busyArrays;
     882                 : 
     883                 :     /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
     884                 :     JSArgumentFormatMap *argumentFormatMap;
     885                 : 
     886                 :     /* Last message string and log file for debugging. */
     887                 :     char                *lastMessage;
     888                 : 
     889                 :     /* Per-context optional error reporter. */
     890                 :     JSErrorReporter     errorReporter;
     891                 : 
     892                 :     /* Branch callback. */
     893                 :     JSOperationCallback operationCallback;
     894                 : 
     895                 :     /* Client opaque pointers. */
     896                 :     void                *data;
     897                 :     void                *data2;
     898                 : 
     899                 :     inline js::RegExpStatics *regExpStatics();
     900                 : 
     901                 :   public:
     902         6872290 :     js::ParseMapPool &parseMapPool() {
     903         6872290 :         JS_ASSERT(parseMapPool_);
     904         6872290 :         return *parseMapPool_;
     905                 :     }
     906                 : 
     907                 :     inline bool ensureParseMapPool();
     908                 : 
     909                 :     /*
     910                 :      * The default script compilation version can be set iff there is no code running.
     911                 :      * This typically occurs via the JSAPI right after a context is constructed.
     912                 :      */
     913                 :     inline bool canSetDefaultVersion() const;
     914                 : 
     915                 :     /* Force a version for future script compilation. */
     916                 :     inline void overrideVersion(JSVersion newVersion);
     917                 : 
     918                 :     /* Set the default script compilation version. */
     919           73313 :     void setDefaultVersion(JSVersion version) {
     920           73313 :         defaultVersion = version;
     921           73313 :     }
     922                 : 
     923           47629 :     void clearVersionOverride() { hasVersionOverride = false; }
     924           23786 :     JSVersion getDefaultVersion() const { return defaultVersion; }
     925          267388 :     bool isVersionOverridden() const { return hasVersionOverride; }
     926                 : 
     927                 :     JSVersion getVersionOverride() const {
     928                 :         JS_ASSERT(isVersionOverridden());
     929                 :         return versionOverride;
     930                 :     }
     931                 : 
     932                 :     /*
     933                 :      * Set the default version if possible; otherwise, force the version.
     934                 :      * Return whether an override occurred.
     935                 :      */
     936                 :     inline bool maybeOverrideVersion(JSVersion newVersion);
     937                 : 
     938                 :     /*
     939                 :      * If there is no code on the stack, turn the override version into the
     940                 :      * default version.
     941                 :      */
     942          243593 :     void maybeMigrateVersionOverride() {
     943          243593 :         JS_ASSERT(stack.empty());
     944          243593 :         if (JS_UNLIKELY(isVersionOverridden())) {
     945              22 :             defaultVersion = versionOverride;
     946              22 :             clearVersionOverride();
     947                 :         }
     948          243593 :     }
     949                 : 
     950                 :     /*
     951                 :      * Return:
     952                 :      * - The override version, if there is an override version.
     953                 :      * - The newest scripted frame's version, if there is such a frame.
     954                 :      * - The default version.
     955                 :      *
     956                 :      * Note: if this ever shows up in a profile, just add caching!
     957                 :      */
     958                 :     inline JSVersion findVersion() const;
     959                 : 
     960         1329240 :     void setRunOptions(unsigned ropts) {
     961         1329240 :         JS_ASSERT((ropts & JSRUNOPTION_MASK) == ropts);
     962         1329240 :         runOptions = ropts;
     963         1329240 :     }
     964                 : 
     965                 :     /* Note: may override the version. */
     966                 :     inline void setCompileOptions(unsigned newcopts);
     967                 : 
     968         3609000 :     unsigned getRunOptions() const { return runOptions; }
     969                 :     inline unsigned getCompileOptions() const;
     970                 :     inline unsigned allOptions() const;
     971                 : 
     972        42050102 :     bool hasRunOption(unsigned ropt) const {
     973        42050102 :         JS_ASSERT((ropt & JSRUNOPTION_MASK) == ropt);
     974        42050102 :         return !!(runOptions & ropt);
     975                 :     }
     976                 : 
     977         8873992 :     bool hasStrictOption() const { return hasRunOption(JSOPTION_STRICT); }
     978            7337 :     bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); }
     979          637462 :     bool hasAtLineOption() const { return hasRunOption(JSOPTION_ATLINE); }
     980                 : 
     981        71322898 :     js::LifoAlloc &tempLifoAlloc() { return runtime->tempLifoAlloc; }
     982                 :     inline js::LifoAlloc &typeLifoAlloc();
     983                 : 
     984                 : #ifdef JS_THREADSAFE
     985                 :     unsigned            outstandingRequests;/* number of JS_BeginRequest calls
     986                 :                                                without the corresponding
     987                 :                                                JS_EndRequest. */
     988                 : #endif
     989                 : 
     990                 : 
     991                 : #ifdef JSGC_ROOT_ANALYSIS
     992                 : 
     993                 :     /*
     994                 :      * Stack allocated GC roots for stack GC heap pointers, which may be
     995                 :      * overwritten if moved during a GC.
     996                 :      */
     997                 :     js::Root<js::gc::Cell*> *thingGCRooters[js::THING_ROOT_COUNT];
     998                 : 
     999                 : #ifdef DEBUG
    1000                 :     /*
    1001                 :      * Stack allocated list of stack locations which hold non-relocatable
    1002                 :      * GC heap pointers (where the target is rooted somewhere else) or integer
    1003                 :      * values which may be confused for GC heap pointers. These are used to
    1004                 :      * suppress false positives which occur when a rooting analysis treats the
    1005                 :      * location as holding a relocatable pointer, but have no other effect on
    1006                 :      * GC behavior.
    1007                 :      */
    1008                 :     js::CheckRoot *checkGCRooters;
    1009                 : #endif
    1010                 : 
    1011                 : #endif /* JSGC_ROOT_ANALYSIS */
    1012                 : 
    1013                 :     /* Stored here to avoid passing it around as a parameter. */
    1014                 :     unsigned               resolveFlags;
    1015                 : 
    1016                 :     /* Random number generator state, used by jsmath.cpp. */
    1017                 :     int64_t             rngSeed;
    1018                 : 
    1019                 :     /* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
    1020                 :     js::Value           iterValue;
    1021                 : 
    1022                 : #ifdef JS_METHODJIT
    1023                 :     bool                 methodJitEnabled;
    1024                 : 
    1025                 :     inline js::mjit::JaegerCompartment *jaegerCompartment();
    1026                 : #endif
    1027                 : 
    1028                 :     bool                 inferenceEnabled;
    1029                 : 
    1030     -1378315075 :     bool typeInferenceEnabled() { return inferenceEnabled; }
    1031                 : 
    1032                 :     /* Caller must be holding runtime->gcLock. */
    1033                 :     void updateJITEnabled();
    1034                 : 
    1035                 : #ifdef MOZ_TRACE_JSCALLS
    1036                 :     /* Function entry/exit debugging callback. */
    1037                 :     JSFunctionCallback    functionCallback;
    1038                 : 
    1039                 :     void doFunctionCallback(const JSFunction *fun,
    1040                 :                             const JSScript *scr,
    1041                 :                             int entering) const
    1042                 :     {
    1043                 :         if (functionCallback)
    1044                 :             functionCallback(fun, scr, this, entering);
    1045                 :     }
    1046                 : #endif
    1047                 : 
    1048                 :     DSTOffsetCache dstOffsetCache;
    1049                 : 
    1050                 :     /* List of currently active non-escaping enumerators (for-in). */
    1051                 :     JSObject *enumerators;
    1052                 : 
    1053                 :   private:
    1054                 :     /*
    1055                 :      * To go from a live generator frame (on the stack) to its generator object
    1056                 :      * (see comment js_FloatingFrameIfGenerator), we maintain a stack of active
    1057                 :      * generators, pushing and popping when entering and leaving generator
    1058                 :      * frames, respectively.
    1059                 :      */
    1060                 :     js::Vector<JSGenerator *, 2, js::SystemAllocPolicy> genStack;
    1061                 : 
    1062                 :   public:
    1063                 :     /* Return the generator object for the given generator frame. */
    1064                 :     JSGenerator *generatorFor(js::StackFrame *fp) const;
    1065                 : 
    1066                 :     /* Early OOM-check. */
    1067                 :     inline bool ensureGeneratorStackSpace();
    1068                 : 
    1069           30834 :     bool enterGenerator(JSGenerator *gen) {
    1070           30834 :         return genStack.append(gen);
    1071                 :     }
    1072                 : 
    1073           30834 :     void leaveGenerator(JSGenerator *gen) {
    1074           30834 :         JS_ASSERT(genStack.back() == gen);
    1075           30834 :         genStack.popBack();
    1076           30834 :     }
    1077                 : 
    1078                 : #ifdef JS_THREADSAFE
    1079                 :     /*
    1080                 :      * When non-null JSContext::free_ delegates the job to the background
    1081                 :      * thread.
    1082                 :      */
    1083                 :     js::GCHelperThread *gcBackgroundFree;
    1084                 : #endif
    1085                 : 
    1086        28535192 :     inline void* malloc_(size_t bytes) {
    1087        28535192 :         return runtime->malloc_(bytes, this);
    1088                 :     }
    1089                 : 
    1090                 :     inline void* mallocNoReport(size_t bytes) {
    1091                 :         JS_ASSERT(bytes != 0);
    1092                 :         return runtime->malloc_(bytes, NULL);
    1093                 :     }
    1094                 : 
    1095         1911865 :     inline void* calloc_(size_t bytes) {
    1096         1911865 :         JS_ASSERT(bytes != 0);
    1097         1911865 :         return runtime->calloc_(bytes, this);
    1098                 :     }
    1099                 : 
    1100          274243 :     inline void* realloc_(void* p, size_t bytes) {
    1101          274243 :         return runtime->realloc_(p, bytes, this);
    1102                 :     }
    1103                 : 
    1104          907136 :     inline void* realloc_(void* p, size_t oldBytes, size_t newBytes) {
    1105          907136 :         return runtime->realloc_(p, oldBytes, newBytes, this);
    1106                 :     }
    1107                 : 
    1108        25240467 :     inline void free_(void* p) {
    1109                 : #ifdef JS_THREADSAFE
    1110        25240467 :         if (gcBackgroundFree) {
    1111         2829189 :             gcBackgroundFree->freeLater(p);
    1112         2829189 :             return;
    1113                 :         }
    1114                 : #endif
    1115        22411278 :         runtime->free_(p);
    1116                 :     }
    1117                 : 
    1118         1727382 :     JS_DECLARE_NEW_METHODS(malloc_, inline)
    1119         2896400 :     JS_DECLARE_DELETE_METHODS(free_, inline)
    1120                 : 
    1121                 :     void purge();
    1122                 : 
    1123                 :     /* For DEBUG. */
    1124                 :     inline void assertValidStackDepth(unsigned depth);
    1125                 : 
    1126        65510927 :     bool isExceptionPending() {
    1127        65510927 :         return throwing;
    1128                 :     }
    1129                 : 
    1130         2256122 :     js::Value getPendingException() {
    1131         2256122 :         JS_ASSERT(throwing);
    1132         2256122 :         return exception;
    1133                 :     }
    1134                 : 
    1135                 :     void setPendingException(js::Value v);
    1136                 : 
    1137         2901326 :     void clearPendingException() {
    1138         2901326 :         this->throwing = false;
    1139         2901326 :         this->exception.setUndefined();
    1140         2901326 :     }
    1141                 : 
    1142                 :     /*
    1143                 :      * Count of currently active compilations.
    1144                 :      * When there are compilations active for the context, the GC must not
    1145                 :      * purge the ParseMapPool.
    1146                 :      */
    1147                 :     unsigned activeCompilations;
    1148                 : 
    1149                 : #ifdef DEBUG
    1150                 :     /*
    1151                 :      * Controls whether a quadratic-complexity assertion is performed during
    1152                 :      * stack iteration, defaults to true.
    1153                 :      */
    1154                 :     bool stackIterAssertionEnabled;
    1155                 : #endif
    1156                 : 
    1157                 :     /*
    1158                 :      * See JS_SetTrustedPrincipals in jsapi.h.
    1159                 :      * Note: !cx->compartment is treated as trusted.
    1160                 :      */
    1161                 :     bool runningWithTrustedPrincipals() const;
    1162                 : 
    1163                 :     JS_FRIEND_API(size_t) sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const;
    1164                 : 
    1165          198404 :     static inline JSContext *fromLinkField(JSCList *link) {
    1166          198404 :         JS_ASSERT(link);
    1167          198404 :         return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, link));
    1168                 :     }
    1169                 : 
    1170                 :     void mark(JSTracer *trc);
    1171                 : 
    1172                 :   private:
    1173                 :     /*
    1174                 :      * The allocation code calls the function to indicate either OOM failure
    1175                 :      * when p is null or that a memory pressure counter has reached some
    1176                 :      * threshold when p is not null. The function takes the pointer and not
    1177                 :      * a boolean flag to minimize the amount of code in its inlined callers.
    1178                 :      */
    1179                 :     JS_FRIEND_API(void) checkMallocGCPressure(void *p);
    1180                 : }; /* struct JSContext */
    1181                 : 
    1182                 : namespace js {
    1183                 : 
    1184                 : struct AutoResolving {
    1185                 :   public:
    1186                 :     enum Kind {
    1187                 :         LOOKUP,
    1188                 :         WATCH
    1189                 :     };
    1190                 : 
    1191        10001934 :     AutoResolving(JSContext *cx, JSObject *obj, jsid id, Kind kind = LOOKUP
    1192                 :                   JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1193        10001934 :       : context(cx), object(obj), id(id), kind(kind), link(cx->resolvingList)
    1194                 :     {
    1195        10001934 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1196        10001934 :         JS_ASSERT(obj);
    1197        10001934 :         cx->resolvingList = this;
    1198        10001934 :     }
    1199                 : 
    1200        20003868 :     ~AutoResolving() {
    1201        10001934 :         JS_ASSERT(context->resolvingList == this);
    1202        10001934 :         context->resolvingList = link;
    1203        10001934 :     }
    1204                 : 
    1205        10001934 :     bool alreadyStarted() const {
    1206        10001934 :         return link && alreadyStartedSlow();
    1207                 :     }
    1208                 : 
    1209                 :   private:
    1210                 :     bool alreadyStartedSlow() const;
    1211                 : 
    1212                 :     JSContext           *const context;
    1213                 :     JSObject            *const object;
    1214                 :     jsid                const id;
    1215                 :     Kind                const kind;
    1216                 :     AutoResolving       *const link;
    1217                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1218                 : };
    1219                 : 
    1220                 : #ifdef JS_HAS_XML_SUPPORT
    1221            6733 : class AutoXMLRooter : private AutoGCRooter {
    1222                 :   public:
    1223            6733 :     AutoXMLRooter(JSContext *cx, JSXML *xml
    1224                 :                   JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1225            6733 :       : AutoGCRooter(cx, XML), xml(xml)
    1226                 :     {
    1227            6733 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1228            6733 :         JS_ASSERT(xml);
    1229            6733 :     }
    1230                 : 
    1231                 :     friend void AutoGCRooter::trace(JSTracer *trc);
    1232                 : 
    1233                 :   private:
    1234                 :     JSXML * const xml;
    1235                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1236                 : };
    1237                 : #endif /* JS_HAS_XML_SUPPORT */
    1238                 : 
    1239                 : #ifdef JS_THREADSAFE
    1240                 : # define JS_LOCK_GC(rt)    PR_Lock((rt)->gcLock)
    1241                 : # define JS_UNLOCK_GC(rt)  PR_Unlock((rt)->gcLock)
    1242                 : #else
    1243                 : # define JS_LOCK_GC(rt)
    1244                 : # define JS_UNLOCK_GC(rt)
    1245                 : #endif
    1246                 : 
    1247                 : class AutoLockGC
    1248                 : {
    1249                 :   public:
    1250         4810912 :     explicit AutoLockGC(JSRuntime *rt = NULL
    1251                 :                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    1252         4810912 :       : runtime(rt)
    1253                 :     {
    1254         4810885 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    1255                 :         // Avoid MSVC warning C4390 for non-threadsafe builds.
    1256                 : #ifdef JS_THREADSAFE
    1257         4810870 :         if (rt)
    1258          403673 :             JS_LOCK_GC(rt);
    1259                 : #endif
    1260         4810878 :     }
    1261                 : 
    1262         4810925 :     ~AutoLockGC()
    1263         4810924 :     {
    1264                 : #ifdef JS_THREADSAFE
    1265         4810925 :         if (runtime)
    1266         2910581 :             JS_UNLOCK_GC(runtime);
    1267                 : #endif
    1268         4810929 :     }
    1269                 : 
    1270         2047018 :     bool locked() const {
    1271         2047018 :         return !!runtime;
    1272                 :     }
    1273                 : 
    1274         2506901 :     void lock(JSRuntime *rt) {
    1275         2506901 :         JS_ASSERT(rt);
    1276         2506901 :         JS_ASSERT(!runtime);
    1277         2506901 :         runtime = rt;
    1278         2506901 :         JS_LOCK_GC(rt);
    1279         2506902 :     }
    1280                 : 
    1281                 :   private:
    1282                 :     JSRuntime *runtime;
    1283                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1284                 : };
    1285                 : 
    1286                 : class AutoUnlockGC {
    1287                 :   private:
    1288                 :     JSRuntime *rt;
    1289                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1290                 : 
    1291                 :   public:
    1292           92750 :     explicit AutoUnlockGC(JSRuntime *rt
    1293                 :                           JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1294           92750 :       : rt(rt)
    1295                 :     {
    1296           92750 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1297           92750 :         JS_UNLOCK_GC(rt);
    1298           92750 :     }
    1299           92750 :     ~AutoUnlockGC() { JS_LOCK_GC(rt); }
    1300                 : };
    1301                 : 
    1302                 : class AutoKeepAtoms {
    1303                 :     JSRuntime *rt;
    1304                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1305                 : 
    1306                 :   public:
    1307          353716 :     explicit AutoKeepAtoms(JSRuntime *rt
    1308                 :                            JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1309          353716 :       : rt(rt)
    1310                 :     {
    1311          353716 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1312          353716 :         JS_KEEP_ATOMS(rt);
    1313          353716 :     }
    1314          353716 :     ~AutoKeepAtoms() { JS_UNKEEP_ATOMS(rt); }
    1315                 : };
    1316                 : 
    1317                 : class AutoReleasePtr {
    1318                 :     JSContext   *cx;
    1319                 :     void        *ptr;
    1320                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1321                 : 
    1322                 :     AutoReleasePtr(const AutoReleasePtr &other) MOZ_DELETE;
    1323                 :     AutoReleasePtr operator=(const AutoReleasePtr &other) MOZ_DELETE;
    1324                 : 
    1325                 :   public:
    1326            4085 :     explicit AutoReleasePtr(JSContext *cx, void *ptr
    1327                 :                             JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1328            4085 :       : cx(cx), ptr(ptr)
    1329                 :     {
    1330            4085 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1331            4085 :     }
    1332            4085 :     ~AutoReleasePtr() { cx->free_(ptr); }
    1333                 : };
    1334                 : 
    1335                 : /*
    1336                 :  * FIXME: bug 602774: cleaner API for AutoReleaseNullablePtr
    1337                 :  */
    1338                 : class AutoReleaseNullablePtr {
    1339                 :     JSContext   *cx;
    1340                 :     void        *ptr;
    1341                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1342                 : 
    1343                 :     AutoReleaseNullablePtr(const AutoReleaseNullablePtr &other) MOZ_DELETE;
    1344                 :     AutoReleaseNullablePtr operator=(const AutoReleaseNullablePtr &other) MOZ_DELETE;
    1345                 : 
    1346                 :   public:
    1347            2278 :     explicit AutoReleaseNullablePtr(JSContext *cx, void *ptr
    1348                 :                                     JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1349            2278 :       : cx(cx), ptr(ptr)
    1350                 :     {
    1351            2278 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1352            2278 :     }
    1353               0 :     void reset(void *ptr2) {
    1354               0 :         if (ptr)
    1355               0 :             cx->free_(ptr);
    1356               0 :         ptr = ptr2;
    1357               0 :     }
    1358            2278 :     ~AutoReleaseNullablePtr() { if (ptr) cx->free_(ptr); }
    1359                 : };
    1360                 : 
    1361                 : } /* namespace js */
    1362                 : 
    1363                 : class JSAutoResolveFlags
    1364                 : {
    1365                 :   public:
    1366        53651317 :     JSAutoResolveFlags(JSContext *cx, unsigned flags
    1367                 :                        JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1368        53651317 :       : mContext(cx), mSaved(cx->resolveFlags)
    1369                 :     {
    1370        53651317 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1371        53651317 :         cx->resolveFlags = flags;
    1372        53651317 :     }
    1373                 : 
    1374        53651317 :     ~JSAutoResolveFlags() { mContext->resolveFlags = mSaved; }
    1375                 : 
    1376                 :   private:
    1377                 :     JSContext *mContext;
    1378                 :     unsigned mSaved;
    1379                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1380                 : };
    1381                 : 
    1382                 : namespace js {
    1383                 : 
    1384                 : /*
    1385                 :  * Enumerate all contexts in a runtime.
    1386                 :  */
    1387                 : class ContextIter {
    1388                 :     JSCList *begin;
    1389                 :     JSCList *end;
    1390                 : 
    1391                 : public:
    1392          118264 :     explicit ContextIter(JSRuntime *rt) {
    1393          118264 :         end = &rt->contextList;
    1394          118264 :         begin = end->next;
    1395          118264 :     }
    1396                 : 
    1397          479794 :     bool done() const {
    1398          479794 :         return begin == end;
    1399                 :     }
    1400                 : 
    1401          117454 :     void next() {
    1402          117454 :         JS_ASSERT(!done());
    1403          117454 :         begin = begin->next;
    1404          117454 :     }
    1405                 : 
    1406          126622 :     JSContext *get() const {
    1407          126622 :         JS_ASSERT(!done());
    1408          126622 :         return JSContext::fromLinkField(begin);
    1409                 :     }
    1410                 : 
    1411                 :     operator JSContext *() const {
    1412                 :         return get();
    1413                 :     }
    1414                 : 
    1415          126622 :     JSContext *operator ->() const {
    1416          126622 :         return get();
    1417                 :     }
    1418                 : };
    1419                 : 
    1420                 : } /* namespace js */
    1421                 : 
    1422                 : /*
    1423                 :  * Create and destroy functions for JSContext, which is manually allocated
    1424                 :  * and exclusively owned.
    1425                 :  */
    1426                 : extern JSContext *
    1427                 : js_NewContext(JSRuntime *rt, size_t stackChunkSize);
    1428                 : 
    1429                 : typedef enum JSDestroyContextMode {
    1430                 :     JSDCM_NO_GC,
    1431                 :     JSDCM_MAYBE_GC,
    1432                 :     JSDCM_FORCE_GC,
    1433                 :     JSDCM_NEW_FAILED
    1434                 : } JSDestroyContextMode;
    1435                 : 
    1436                 : extern void
    1437                 : js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
    1438                 : 
    1439                 : #ifdef va_start
    1440                 : extern JSBool
    1441                 : js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap);
    1442                 : 
    1443                 : extern JSBool
    1444                 : js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback,
    1445                 :                        void *userRef, const unsigned errorNumber,
    1446                 :                        JSBool charArgs, va_list ap);
    1447                 : 
    1448                 : extern JSBool
    1449                 : js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
    1450                 :                         void *userRef, const unsigned errorNumber,
    1451                 :                         char **message, JSErrorReport *reportp,
    1452                 :                         bool charArgs, va_list ap);
    1453                 : #endif
    1454                 : 
    1455                 : namespace js {
    1456                 : 
    1457                 : /* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
    1458                 : extern void
    1459                 : ReportUsageError(JSContext *cx, JSObject *callee, const char *msg);
    1460                 : 
    1461                 : } /* namespace js */
    1462                 : 
    1463                 : extern void
    1464                 : js_ReportOutOfMemory(JSContext *cx);
    1465                 : 
    1466                 : extern JS_FRIEND_API(void)
    1467                 : js_ReportAllocationOverflow(JSContext *cx);
    1468                 : 
    1469                 : /*
    1470                 :  * Report an exception using a previously composed JSErrorReport.
    1471                 :  * XXXbe remove from "friend" API
    1472                 :  */
    1473                 : extern JS_FRIEND_API(void)
    1474                 : js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
    1475                 : 
    1476                 : extern void
    1477                 : js_ReportIsNotDefined(JSContext *cx, const char *name);
    1478                 : 
    1479                 : /*
    1480                 :  * Report an attempt to access the property of a null or undefined value (v).
    1481                 :  */
    1482                 : extern JSBool
    1483                 : js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const js::Value &v,
    1484                 :                            JSString *fallback);
    1485                 : 
    1486                 : extern void
    1487                 : js_ReportMissingArg(JSContext *cx, const js::Value &v, unsigned arg);
    1488                 : 
    1489                 : /*
    1490                 :  * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
    1491                 :  * the first argument for the error message. If the error message has less
    1492                 :  * then 3 arguments, use null for arg1 or arg2.
    1493                 :  */
    1494                 : extern JSBool
    1495                 : js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumber,
    1496                 :                          int spindex, const js::Value &v, JSString *fallback,
    1497                 :                          const char *arg1, const char *arg2);
    1498                 : 
    1499                 : #define js_ReportValueError(cx,errorNumber,spindex,v,fallback)                \
    1500                 :     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
    1501                 :                                     spindex, v, fallback, NULL, NULL))
    1502                 : 
    1503                 : #define js_ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1)          \
    1504                 :     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
    1505                 :                                     spindex, v, fallback, arg1, NULL))
    1506                 : 
    1507                 : #define js_ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2)     \
    1508                 :     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
    1509                 :                                     spindex, v, fallback, arg1, arg2))
    1510                 : 
    1511                 : extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
    1512                 : 
    1513                 : #ifdef JS_THREADSAFE
    1514                 : # define JS_ASSERT_REQUEST_DEPTH(cx)  JS_ASSERT((cx)->runtime->requestDepth >= 1)
    1515                 : #else
    1516                 : # define JS_ASSERT_REQUEST_DEPTH(cx)  ((void) 0)
    1517                 : #endif
    1518                 : 
    1519                 : /*
    1520                 :  * If the operation callback flag was set, call the operation callback.
    1521                 :  * This macro can run the full GC. Return true if it is OK to continue and
    1522                 :  * false otherwise.
    1523                 :  */
    1524                 : #define JS_CHECK_OPERATION_LIMIT(cx)                                          \
    1525                 :     (JS_ASSERT_REQUEST_DEPTH(cx),                                             \
    1526                 :      (!cx->runtime->interrupt || js_InvokeOperationCallback(cx)))
    1527                 : 
    1528                 : /*
    1529                 :  * Invoke the operation callback and return false if the current execution
    1530                 :  * is to be terminated.
    1531                 :  */
    1532                 : extern JSBool
    1533                 : js_InvokeOperationCallback(JSContext *cx);
    1534                 : 
    1535                 : extern JSBool
    1536                 : js_HandleExecutionInterrupt(JSContext *cx);
    1537                 : 
    1538                 : extern jsbytecode*
    1539                 : js_GetCurrentBytecodePC(JSContext* cx);
    1540                 : 
    1541                 : extern JSScript *
    1542                 : js_GetCurrentScript(JSContext* cx);
    1543                 : 
    1544                 : namespace js {
    1545                 : 
    1546                 : #ifdef JS_METHODJIT
    1547                 : namespace mjit {
    1548                 :     void ExpandInlineFrames(JSCompartment *compartment);
    1549                 : }
    1550                 : #endif
    1551                 : 
    1552                 : } /* namespace js */
    1553                 : 
    1554                 : /* How much expansion of inlined frames to do when inspecting the stack. */
    1555                 : enum FrameExpandKind {
    1556                 :     FRAME_EXPAND_NONE = 0,
    1557                 :     FRAME_EXPAND_ALL = 1
    1558                 : };
    1559                 : 
    1560                 : namespace js {
    1561                 : 
    1562                 : /************************************************************************/
    1563                 : 
    1564                 : static JS_ALWAYS_INLINE void
    1565         6101043 : MakeRangeGCSafe(Value *vec, size_t len)
    1566                 : {
    1567         6101043 :     PodZero(vec, len);
    1568         6101043 : }
    1569                 : 
    1570                 : static JS_ALWAYS_INLINE void
    1571                 : MakeRangeGCSafe(Value *beg, Value *end)
    1572                 : {
    1573                 :     PodZero(beg, end - beg);
    1574                 : }
    1575                 : 
    1576                 : static JS_ALWAYS_INLINE void
    1577                 : MakeRangeGCSafe(jsid *beg, jsid *end)
    1578                 : {
    1579                 :     for (jsid *id = beg; id != end; ++id)
    1580                 :         *id = INT_TO_JSID(0);
    1581                 : }
    1582                 : 
    1583                 : static JS_ALWAYS_INLINE void
    1584                 : MakeRangeGCSafe(jsid *vec, size_t len)
    1585                 : {
    1586                 :     MakeRangeGCSafe(vec, vec + len);
    1587                 : }
    1588                 : 
    1589                 : static JS_ALWAYS_INLINE void
    1590                 : MakeRangeGCSafe(const Shape **beg, const Shape **end)
    1591                 : {
    1592                 :     PodZero(beg, end - beg);
    1593                 : }
    1594                 : 
    1595                 : static JS_ALWAYS_INLINE void
    1596                 : MakeRangeGCSafe(const Shape **vec, size_t len)
    1597                 : {
    1598                 :     PodZero(vec, len);
    1599                 : }
    1600                 : 
    1601                 : static JS_ALWAYS_INLINE void
    1602        30149853 : SetValueRangeToUndefined(Value *beg, Value *end)
    1603                 : {
    1604        57824728 :     for (Value *v = beg; v != end; ++v)
    1605        27674875 :         v->setUndefined();
    1606        30149853 : }
    1607                 : 
    1608                 : static JS_ALWAYS_INLINE void
    1609        29593882 : SetValueRangeToUndefined(Value *vec, size_t len)
    1610                 : {
    1611        29593882 :     SetValueRangeToUndefined(vec, vec + len);
    1612        29593882 : }
    1613                 : 
    1614                 : static JS_ALWAYS_INLINE void
    1615                 : SetValueRangeToNull(Value *beg, Value *end)
    1616                 : {
    1617                 :     for (Value *v = beg; v != end; ++v)
    1618                 :         v->setNull();
    1619                 : }
    1620                 : 
    1621                 : static JS_ALWAYS_INLINE void
    1622                 : SetValueRangeToNull(Value *vec, size_t len)
    1623                 : {
    1624                 :     SetValueRangeToNull(vec, vec + len);
    1625                 : }
    1626                 : 
    1627                 : class AutoObjectVector : public AutoVectorRooter<JSObject *>
    1628           33844 : {
    1629                 :   public:
    1630           33844 :     explicit AutoObjectVector(JSContext *cx
    1631                 :                               JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1632           33844 :         : AutoVectorRooter<JSObject *>(cx, OBJVECTOR)
    1633                 :     {
    1634           33844 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1635           33844 :     }
    1636                 : 
    1637                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1638                 : };
    1639                 : 
    1640                 : class AutoShapeVector : public AutoVectorRooter<const Shape *>
    1641         1456589 : {
    1642                 :   public:
    1643         1456589 :     explicit AutoShapeVector(JSContext *cx
    1644                 :                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1645         1456589 :         : AutoVectorRooter<const Shape *>(cx, SHAPEVECTOR)
    1646                 :     {
    1647         1456589 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1648         1456589 :     }
    1649                 : 
    1650                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1651                 : };
    1652                 : 
    1653                 : class AutoValueArray : public AutoGCRooter
    1654           10038 : {
    1655                 :     js::Value *start_;
    1656                 :     unsigned length_;
    1657                 : 
    1658                 :   public:
    1659           10038 :     AutoValueArray(JSContext *cx, js::Value *start, unsigned length
    1660                 :                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
    1661           10038 :         : AutoGCRooter(cx, VALARRAY), start_(start), length_(length)
    1662                 :     {
    1663           10038 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
    1664           10038 :     }
    1665                 : 
    1666               0 :     Value *start() { return start_; }
    1667               0 :     unsigned length() const { return length_; }
    1668                 : 
    1669                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
    1670                 : };
    1671                 : 
    1672                 : /*
    1673                 :  * Allocation policy that uses JSRuntime::malloc_ and friends, so that
    1674                 :  * memory pressure is properly accounted for. This is suitable for
    1675                 :  * long-lived objects owned by the JSRuntime.
    1676                 :  *
    1677                 :  * Since it doesn't hold a JSContext (those may not live long enough), it
    1678                 :  * can't report out-of-memory conditions itself; the caller must check for
    1679                 :  * OOM and take the appropriate action.
    1680                 :  *
    1681                 :  * FIXME bug 647103 - replace these *AllocPolicy names.
    1682                 :  */
    1683                 : class RuntimeAllocPolicy
    1684                 : {
    1685                 :     JSRuntime *const runtime;
    1686                 : 
    1687                 :   public:
    1688           47052 :     RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {}
    1689           17050 :     RuntimeAllocPolicy(JSContext *cx) : runtime(cx->runtime) {}
    1690           78610 :     void *malloc_(size_t bytes) { return runtime->malloc_(bytes); }
    1691                 :     void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
    1692           78605 :     void free_(void *p) { runtime->free_(p); }
    1693               0 :     void reportAllocOverflow() const {}
    1694                 : };
    1695                 : 
    1696                 : /*
    1697                 :  * FIXME bug 647103 - replace these *AllocPolicy names.
    1698                 :  */
    1699                 : class ContextAllocPolicy
    1700                 : {
    1701                 :     JSContext *const cx;
    1702                 : 
    1703                 :   public:
    1704          860701 :     ContextAllocPolicy(JSContext *cx) : cx(cx) {}
    1705         7662743 :     JSContext *context() const { return cx; }
    1706          272156 :     void *malloc_(size_t bytes) { return cx->malloc_(bytes); }
    1707           79350 :     void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx->realloc_(p, oldBytes, bytes); }
    1708             549 :     void free_(void *p) { cx->free_(p); }
    1709               0 :     void reportAllocOverflow() const { js_ReportAllocationOverflow(cx); }
    1710                 : };
    1711                 : 
    1712                 : } /* namespace js */
    1713                 : 
    1714                 : #ifdef _MSC_VER
    1715                 : #pragma warning(pop)
    1716                 : #pragma warning(pop)
    1717                 : #endif
    1718                 : 
    1719                 : #endif /* jscntxt_h___ */

Generated by: LCOV version 1.7