LCOV - code coverage report
Current view: directory - js/src/builtin - TestingFunctions.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 245 164 66.9 %
Date: 2012-04-07 Functions: 20 18 90.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* This Source Code Form is subject to the terms of the Mozilla Public
       3                 :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       4                 :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       5                 : 
       6                 : #include "jsapi.h"
       7                 : #include "jsbool.h"
       8                 : #include "jscntxt.h"
       9                 : #include "jscompartment.h"
      10                 : #include "jsfriendapi.h"
      11                 : #include "jsgc.h"
      12                 : #include "jsobj.h"
      13                 : #include "jsprf.h"
      14                 : #include "jswrapper.h"
      15                 : 
      16                 : #include "methodjit/MethodJIT.h"
      17                 : 
      18                 : using namespace js;
      19                 : using namespace JS;
      20                 : 
      21                 : static JSBool
      22            8732 : GC(JSContext *cx, unsigned argc, jsval *vp)
      23                 : {
      24                 :     /*
      25                 :      * If the first argument is 'compartment', we collect any compartments
      26                 :      * previously scheduled for GC via schedulegc. If the first argument is an
      27                 :      * object, we collect the object's compartment (any any other compartments
      28                 :      * scheduled for GC). Otherwise, we collect call compartments.
      29                 :      */
      30            8732 :     JSBool compartment = false;
      31            8732 :     if (argc == 1) {
      32             117 :         Value arg = vp[2];
      33             117 :         if (arg.isString()) {
      34               9 :             if (!JS_StringEqualsAscii(cx, arg.toString(), "compartment", &compartment))
      35               0 :                 return false;
      36             108 :         } else if (arg.isObject()) {
      37             108 :             PrepareCompartmentForGC(UnwrapObject(&arg.toObject())->compartment());
      38             108 :             compartment = true;
      39                 :         }
      40                 :     }
      41                 : 
      42                 : #ifndef JS_MORE_DETERMINISTIC
      43            8732 :     size_t preBytes = cx->runtime->gcBytes;
      44                 : #endif
      45                 : 
      46            8732 :     if (compartment)
      47             117 :         PrepareForDebugGC(cx->runtime);
      48                 :     else
      49            8615 :         PrepareForFullGC(cx->runtime);
      50            8732 :     GCForReason(cx, gcreason::API);
      51                 : 
      52            8732 :     char buf[256] = { '\0' };
      53                 : #ifndef JS_MORE_DETERMINISTIC
      54                 :     JS_snprintf(buf, sizeof(buf), "before %lu, after %lu\n",
      55            8732 :                 (unsigned long)preBytes, (unsigned long)cx->runtime->gcBytes);
      56                 : #endif
      57            8732 :     JSString *str = JS_NewStringCopyZ(cx, buf);
      58            8732 :     if (!str)
      59               0 :         return false;
      60            8732 :     *vp = STRING_TO_JSVAL(str);
      61            8732 :     return true;
      62                 : }
      63                 : 
      64                 : static const struct ParamPair {
      65                 :     const char      *name;
      66                 :     JSGCParamKey    param;
      67                 : } paramMap[] = {
      68                 :     {"maxBytes",            JSGC_MAX_BYTES },
      69                 :     {"maxMallocBytes",      JSGC_MAX_MALLOC_BYTES},
      70                 :     {"gcBytes",             JSGC_BYTES},
      71                 :     {"gcNumber",            JSGC_NUMBER},
      72                 :     {"sliceTimeBudget",     JSGC_SLICE_TIME_BUDGET}
      73                 : };
      74                 : 
      75                 : static JSBool
      76              18 : GCParameter(JSContext *cx, unsigned argc, jsval *vp)
      77                 : {
      78                 :     JSString *str;
      79              18 :     if (argc == 0) {
      80               0 :         str = JS_ValueToString(cx, JSVAL_VOID);
      81               0 :         JS_ASSERT(str);
      82                 :     } else {
      83              18 :         str = JS_ValueToString(cx, vp[2]);
      84              18 :         if (!str)
      85               0 :             return JS_FALSE;
      86              18 :         vp[2] = STRING_TO_JSVAL(str);
      87                 :     }
      88                 : 
      89              18 :     JSFlatString *flatStr = JS_FlattenString(cx, str);
      90              18 :     if (!flatStr)
      91               0 :         return false;
      92                 : 
      93              18 :     size_t paramIndex = 0;
      94              18 :     for (;; paramIndex++) {
      95              36 :         if (paramIndex == ArrayLength(paramMap)) {
      96                 :             JS_ReportError(cx,
      97                 :                            "the first argument argument must be maxBytes, "
      98                 :                            "maxMallocBytes, gcStackpoolLifespan, gcBytes or "
      99               0 :                            "gcNumber");
     100               0 :             return false;
     101                 :         }
     102              36 :         if (JS_FlatStringEqualsAscii(flatStr, paramMap[paramIndex].name))
     103                 :             break;
     104                 :     }
     105              18 :     JSGCParamKey param = paramMap[paramIndex].param;
     106                 : 
     107              18 :     if (argc == 1) {
     108               9 :         uint32_t value = JS_GetGCParameter(cx->runtime, param);
     109               9 :         return JS_NewNumberValue(cx, value, &vp[0]);
     110                 :     }
     111                 : 
     112               9 :     if (param == JSGC_NUMBER ||
     113                 :         param == JSGC_BYTES) {
     114                 :         JS_ReportError(cx, "Attempt to change read-only parameter %s",
     115               0 :                        paramMap[paramIndex].name);
     116               0 :         return false;
     117                 :     }
     118                 : 
     119                 :     uint32_t value;
     120               9 :     if (!JS_ValueToECMAUint32(cx, vp[3], &value)) {
     121                 :         JS_ReportError(cx,
     122                 :                        "the second argument must be convertable to uint32_t "
     123               0 :                        "with non-zero value");
     124               0 :         return false;
     125                 :     }
     126                 : 
     127               9 :     if (param == JSGC_MAX_BYTES) {
     128               9 :         uint32_t gcBytes = JS_GetGCParameter(cx->runtime, JSGC_BYTES);
     129               9 :         if (value < gcBytes) {
     130                 :             JS_ReportError(cx,
     131                 :                            "attempt to set maxBytes to the value less than the current "
     132                 :                            "gcBytes (%u)",
     133               0 :                            gcBytes);
     134               0 :             return false;
     135                 :         }
     136                 :     }
     137                 : 
     138               9 :     JS_SetGCParameter(cx->runtime, param, value);
     139               9 :     *vp = JSVAL_VOID;
     140               9 :     return true;
     141                 : }
     142                 : 
     143                 : static JSBool
     144               9 : InternalConst(JSContext *cx, unsigned argc, jsval *vp)
     145                 : {
     146               9 :     if (argc != 1) {
     147               0 :         JS_ReportError(cx, "the function takes exactly one argument");
     148               0 :         return false;
     149                 :     }
     150                 : 
     151               9 :     JSString *str = JS_ValueToString(cx, vp[2]);
     152               9 :     if (!str)
     153               0 :         return false;
     154               9 :     JSFlatString *flat = JS_FlattenString(cx, str);
     155               9 :     if (!flat)
     156               0 :         return false;
     157                 : 
     158               9 :     if (JS_FlatStringEqualsAscii(flat, "MARK_STACK_LENGTH")) {
     159               9 :         vp[0] = UINT_TO_JSVAL(js::MARK_STACK_LENGTH);
     160                 :     } else {
     161               0 :         JS_ReportError(cx, "unknown const name");
     162               0 :         return false;
     163                 :     }
     164               9 :     return true;
     165                 : }
     166                 : 
     167                 : #ifdef JS_GC_ZEAL
     168                 : static JSBool
     169            1647 : GCZeal(JSContext *cx, unsigned argc, jsval *vp)
     170                 : {
     171            1647 :     uint32_t zeal, frequency = JS_DEFAULT_ZEAL_FREQ;
     172                 : 
     173            1647 :     if (argc > 2) {
     174               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
     175               0 :         return JS_FALSE;
     176                 :     }
     177            1647 :     if (!JS_ValueToECMAUint32(cx, argc < 1 ? JSVAL_VOID : vp[2], &zeal))
     178               0 :         return JS_FALSE;
     179            1647 :     if (argc >= 2)
     180              54 :         if (!JS_ValueToECMAUint32(cx, vp[3], &frequency))
     181               0 :             return JS_FALSE;
     182                 : 
     183            1647 :     JS_SetGCZeal(cx, (uint8_t)zeal, frequency);
     184            1647 :     *vp = JSVAL_VOID;
     185            1647 :     return JS_TRUE;
     186                 : }
     187                 : 
     188                 : static JSBool
     189             117 : ScheduleGC(JSContext *cx, unsigned argc, jsval *vp)
     190                 : {
     191             117 :     if (argc != 1) {
     192               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
     193               0 :         return JS_FALSE;
     194                 :     }
     195                 : 
     196             117 :     Value arg(vp[2]);
     197             117 :     if (arg.isInt32()) {
     198                 :         /* Schedule a GC to happen after |arg| allocations. */
     199              54 :         JS_ScheduleGC(cx, arg.toInt32());
     200              63 :     } else if (arg.isObject()) {
     201                 :         /* Ensure that |comp| is collected during the next GC. */
     202              54 :         JSCompartment *comp = UnwrapObject(&arg.toObject())->compartment();
     203              54 :         PrepareCompartmentForGC(comp);
     204               9 :     } else if (arg.isString()) {
     205                 :         /* This allows us to schedule atomsCompartment for GC. */
     206               9 :         PrepareCompartmentForGC(arg.toString()->compartment());
     207                 :     }
     208                 : 
     209             117 :     *vp = JSVAL_VOID;
     210             117 :     return JS_TRUE;
     211                 : }
     212                 : 
     213                 : static JSBool
     214               9 : SelectForGC(JSContext *cx, unsigned argc, jsval *vp)
     215                 : {
     216               9 :     JSRuntime *rt = cx->runtime;
     217                 : 
     218              18 :     for (unsigned i = 0; i < argc; i++) {
     219               9 :         Value arg(JS_ARGV(cx, vp)[i]);
     220               9 :         if (arg.isObject()) {
     221               9 :             if (!rt->gcSelectedForMarking.append(&arg.toObject()))
     222               0 :                 return false;
     223                 :         }
     224                 :     }
     225                 : 
     226               9 :     *vp = JSVAL_VOID;
     227               9 :     return true;
     228                 : }
     229                 : 
     230                 : static JSBool
     231              18 : VerifyBarriers(JSContext *cx, unsigned argc, jsval *vp)
     232                 : {
     233              18 :     if (argc) {
     234               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
     235               0 :         return JS_FALSE;
     236                 :     }
     237              18 :     gc::VerifyBarriers(cx);
     238              18 :     *vp = JSVAL_VOID;
     239              18 :     return JS_TRUE;
     240                 : }
     241                 : 
     242                 : static JSBool
     243              81 : GCSlice(JSContext *cx, unsigned argc, jsval *vp)
     244                 : {
     245              81 :     bool limit = true;
     246              81 :     uint32_t budget = 0;
     247                 : 
     248              81 :     if (argc > 1) {
     249               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
     250               0 :         return JS_FALSE;
     251                 :     }
     252                 : 
     253              81 :     if (argc == 1) {
     254              54 :         if (!JS_ValueToECMAUint32(cx, vp[2], &budget))
     255               0 :             return false;
     256                 :     } else {
     257              27 :         limit = false;
     258                 :     }
     259                 : 
     260              81 :     GCDebugSlice(cx, limit, budget);
     261              81 :     *vp = JSVAL_VOID;
     262              81 :     return JS_TRUE;
     263                 : }
     264                 : 
     265                 : static JSBool
     266               0 : DeterministicGC(JSContext *cx, unsigned argc, jsval *vp)
     267                 : {
     268               0 :     if (argc != 1) {
     269               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
     270               0 :         return JS_FALSE;
     271                 :     }
     272                 : 
     273               0 :     gc::SetDeterministicGC(cx, js_ValueToBoolean(vp[2]));
     274               0 :     *vp = JSVAL_VOID;
     275               0 :     return JS_TRUE;
     276                 : }
     277                 : #endif /* JS_GC_ZEAL */
     278                 : 
     279                 : struct JSCountHeapNode {
     280                 :     void                *thing;
     281                 :     JSGCTraceKind       kind;
     282                 :     JSCountHeapNode     *next;
     283                 : };
     284                 : 
     285                 : typedef HashSet<void *, PointerHasher<void *, 3>, SystemAllocPolicy> VisitedSet;
     286                 : 
     287              18 : typedef struct JSCountHeapTracer {
     288                 :     JSTracer            base;
     289                 :     VisitedSet          visited;
     290                 :     JSCountHeapNode     *traceList;
     291                 :     JSCountHeapNode     *recycleList;
     292                 :     bool                ok;
     293                 : } JSCountHeapTracer;
     294                 : 
     295                 : static void
     296           77589 : CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
     297                 : {
     298           77589 :     JS_ASSERT(trc->callback == CountHeapNotify);
     299                 : 
     300           77589 :     JSCountHeapTracer *countTracer = (JSCountHeapTracer *)trc;
     301           77589 :     void *thing = *thingp;
     302                 : 
     303           77589 :     if (!countTracer->ok)
     304               0 :         return;
     305                 : 
     306          155178 :     VisitedSet::AddPtr p = countTracer->visited.lookupForAdd(thing);
     307           77589 :     if (p)
     308                 :         return;
     309                 : 
     310           57562 :     if (!countTracer->visited.add(p, thing)) {
     311               0 :         countTracer->ok = false;
     312                 :         return;
     313                 :     }
     314                 : 
     315           57562 :     JSCountHeapNode *node = countTracer->recycleList;
     316           57562 :     if (node) {
     317           14573 :         countTracer->recycleList = node->next;
     318                 :     } else {
     319           42989 :         node = (JSCountHeapNode *) js_malloc(sizeof *node);
     320           42989 :         if (!node) {
     321               0 :             countTracer->ok = false;
     322                 :             return;
     323                 :         }
     324                 :     }
     325           57562 :     node->thing = thing;
     326           57562 :     node->kind = kind;
     327           57562 :     node->next = countTracer->traceList;
     328           57562 :     countTracer->traceList = node;
     329                 : }
     330                 : 
     331                 : static const struct TraceKindPair {
     332                 :     const char       *name;
     333                 :     int32_t           kind;
     334                 : } traceKindNames[] = {
     335                 :     { "all",        -1                  },
     336                 :     { "object",     JSTRACE_OBJECT      },
     337                 :     { "string",     JSTRACE_STRING      },
     338                 : #if JS_HAS_XML_SUPPORT
     339                 :     { "xml",        JSTRACE_XML         },
     340                 : #endif
     341                 : };
     342                 : 
     343                 : static JSBool
     344               9 : CountHeap(JSContext *cx, unsigned argc, jsval *vp)
     345                 : {
     346                 :     void* startThing;
     347                 :     JSGCTraceKind startTraceKind;
     348                 :     jsval v;
     349                 :     int32_t traceKind;
     350                 :     JSString *str;
     351              18 :     JSCountHeapTracer countTracer;
     352                 :     JSCountHeapNode *node;
     353                 :     size_t counter;
     354                 : 
     355               9 :     startThing = NULL;
     356               9 :     startTraceKind = JSTRACE_OBJECT;
     357               9 :     if (argc > 0) {
     358               0 :         v = JS_ARGV(cx, vp)[0];
     359               0 :         if (JSVAL_IS_TRACEABLE(v)) {
     360               0 :             startThing = JSVAL_TO_TRACEABLE(v);
     361               0 :             startTraceKind = JSVAL_TRACE_KIND(v);
     362               0 :         } else if (!JSVAL_IS_NULL(v)) {
     363                 :             JS_ReportError(cx,
     364                 :                            "the first argument is not null or a heap-allocated "
     365               0 :                            "thing");
     366               0 :             return JS_FALSE;
     367                 :         }
     368                 :     }
     369                 : 
     370               9 :     traceKind = -1;
     371               9 :     if (argc > 1) {
     372               0 :         str = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
     373               0 :         if (!str)
     374               0 :             return JS_FALSE;
     375               0 :         JSFlatString *flatStr = JS_FlattenString(cx, str);
     376               0 :         if (!flatStr)
     377               0 :             return JS_FALSE;
     378               0 :         for (size_t i = 0; ;) {
     379               0 :             if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
     380               0 :                 traceKind = traceKindNames[i].kind;
     381                 :                 break;
     382                 :             }
     383               0 :             if (++i == ArrayLength(traceKindNames)) {
     384               0 :                 JSAutoByteString bytes(cx, str);
     385               0 :                 if (!!bytes)
     386               0 :                     JS_ReportError(cx, "trace kind name '%s' is unknown", bytes.ptr());
     387               0 :                 return JS_FALSE;
     388                 :             }
     389                 :         }
     390                 :     }
     391                 : 
     392               9 :     JS_TracerInit(&countTracer.base, JS_GetRuntime(cx), CountHeapNotify);
     393               9 :     if (!countTracer.visited.init()) {
     394               0 :         JS_ReportOutOfMemory(cx);
     395               0 :         return JS_FALSE;
     396                 :     }
     397               9 :     countTracer.ok = true;
     398               9 :     countTracer.traceList = NULL;
     399               9 :     countTracer.recycleList = NULL;
     400                 : 
     401               9 :     if (!startThing) {
     402               9 :         JS_TraceRuntime(&countTracer.base);
     403                 :     } else {
     404               0 :         JS_SET_TRACING_NAME(&countTracer.base, "root");
     405               0 :         JS_CallTracer(&countTracer.base, startThing, startTraceKind);
     406                 :     }
     407                 : 
     408               9 :     counter = 0;
     409           57580 :     while ((node = countTracer.traceList) != NULL) {
     410           57562 :         if (traceKind == -1 || node->kind == traceKind)
     411           57562 :             counter++;
     412           57562 :         countTracer.traceList = node->next;
     413           57562 :         node->next = countTracer.recycleList;
     414           57562 :         countTracer.recycleList = node;
     415           57562 :         JS_TraceChildren(&countTracer.base, node->thing, node->kind);
     416                 :     }
     417           43007 :     while ((node = countTracer.recycleList) != NULL) {
     418           42989 :         countTracer.recycleList = node->next;
     419           42989 :         js_free(node);
     420                 :     }
     421               9 :     if (!countTracer.ok) {
     422               0 :         JS_ReportOutOfMemory(cx);
     423               0 :         return false;
     424                 :     }
     425                 : 
     426               9 :     return JS_NewNumberValue(cx, (double) counter, vp);
     427                 : }
     428                 : 
     429                 : static unsigned finalizeCount = 0;
     430                 : 
     431                 : static void
     432              90 : finalize_counter_finalize(JSFreeOp *fop, JSObject *obj)
     433                 : {
     434              90 :     JS_ATOMIC_INCREMENT(&finalizeCount);
     435              90 : }
     436                 : 
     437                 : static JSClass FinalizeCounterClass = {
     438                 :     "FinalizeCounter", JSCLASS_IS_ANONYMOUS,
     439                 :     JS_PropertyStub,       /* addProperty */
     440                 :     JS_PropertyStub,       /* delProperty */
     441                 :     JS_PropertyStub,       /* getProperty */
     442                 :     JS_StrictPropertyStub, /* setProperty */
     443                 :     JS_EnumerateStub,
     444                 :     JS_ResolveStub,
     445                 :     JS_ConvertStub,
     446                 :     finalize_counter_finalize
     447                 : };
     448                 : 
     449                 : static JSBool
     450              90 : MakeFinalizeObserver(JSContext *cx, unsigned argc, jsval *vp)
     451                 : {
     452                 :     JSObject *obj = JS_NewObjectWithGivenProto(cx, &FinalizeCounterClass, NULL,
     453              90 :                                                JS_GetGlobalObject(cx));
     454              90 :     if (!obj)
     455               0 :         return false;
     456              90 :     *vp = OBJECT_TO_JSVAL(obj);
     457              90 :     return true;
     458                 : }
     459                 : 
     460                 : static JSBool
     461              27 : FinalizeCount(JSContext *cx, unsigned argc, jsval *vp)
     462                 : {
     463              27 :     *vp = INT_TO_JSVAL(finalizeCount);
     464              27 :     return true;
     465                 : }
     466                 : 
     467                 : JSBool
     468               0 : MJitCodeStats(JSContext *cx, unsigned argc, jsval *vp)
     469                 : {
     470                 : #ifdef JS_METHODJIT
     471               0 :     JSRuntime *rt = cx->runtime;
     472               0 :     AutoLockGC lock(rt);
     473               0 :     size_t n = 0;
     474               0 :     for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
     475               0 :         n += (*c)->sizeOfMjitCode();
     476                 :     }
     477               0 :     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(n));
     478                 : #else
     479                 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     480                 : #endif
     481               0 :     return true;
     482                 : }
     483                 : 
     484                 : JSBool
     485              27 : MJitChunkLimit(JSContext *cx, unsigned argc, jsval *vp)
     486                 : {
     487              27 :     if (argc != 1) {
     488               0 :         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
     489               0 :         return JS_FALSE;
     490                 :     }
     491                 : 
     492                 :     double t;
     493              27 :     if (!JS_ValueToNumber(cx, JS_ARGV(cx, vp)[0], &t))
     494               0 :         return JS_FALSE;
     495                 : 
     496                 : #ifdef JS_METHODJIT
     497              27 :     mjit::SetChunkLimit((uint32_t) t);
     498                 : #endif
     499                 : 
     500                 :     // Clear out analysis information which might refer to code compiled with
     501                 :     // the previous chunk limit.
     502              27 :     JS_GC(cx);
     503                 : 
     504              27 :     vp->setUndefined();
     505              27 :     return true;
     506                 : }
     507                 : 
     508                 : static JSBool
     509              27 : Terminate(JSContext *cx, unsigned arg, jsval *vp)
     510                 : {
     511              27 :     JS_ClearPendingException(cx);
     512              27 :     return JS_FALSE;
     513                 : }
     514                 : 
     515                 : static JSFunctionSpecWithHelp TestingFunctions[] = {
     516                 :     JS_FN_HELP("gc", ::GC, 0, 0,
     517                 : "gc([obj] | 'compartment')",
     518                 : "  Run the garbage collector. When obj is given, GC only its compartment.\n"
     519                 : "  If 'compartment' is given, GC any compartments that were scheduled for\n"
     520                 : "  GC via schedulegc."),
     521                 : 
     522                 :     JS_FN_HELP("gcparam", GCParameter, 2, 0,
     523                 : "gcparam(name [, value])",
     524                 : "  Wrapper for JS_[GS]etGCParameter. The name is either maxBytes,\n"
     525                 : "  maxMallocBytes, gcBytes, gcNumber, or sliceTimeBudget."),
     526                 : 
     527                 :     JS_FN_HELP("countHeap", CountHeap, 0, 0,
     528                 : "countHeap([start[, kind]])",
     529                 : "  Count the number of live GC things in the heap or things reachable from\n"
     530                 : "  start when it is given and is not null. kind is either 'all' (default) to\n"
     531                 : "  count all things or one of 'object', 'double', 'string', 'function',\n"
     532                 : "  'qname', 'namespace', 'xml' to count only things of that kind."),
     533                 : 
     534                 :     JS_FN_HELP("makeFinalizeObserver", MakeFinalizeObserver, 0, 0,
     535                 : "makeFinalizeObserver()",
     536                 : "  Get a special object whose finalization increases the counter returned\n"
     537                 : "  by the finalizeCount function."),
     538                 : 
     539                 :     JS_FN_HELP("finalizeCount", FinalizeCount, 0, 0,
     540                 : "finalizeCount()",
     541                 : "  Return the current value of the finalization counter that is incremented\n"
     542                 : "  each time an object returned by the makeFinalizeObserver is finalized."),
     543                 : 
     544                 : #ifdef JS_GC_ZEAL
     545                 :     JS_FN_HELP("gczeal", GCZeal, 2, 0,
     546                 : "gczeal(level, [period])",
     547                 : "  Specifies how zealous the garbage collector should be. Values for level:\n"
     548                 : "    0: Normal amount of collection\n"
     549                 : "    1: Collect when roots are added or removed\n"
     550                 : "    2: Collect when memory is allocated\n"
     551                 : "    3: Collect when the window paints (browser only)\n"
     552                 : "    4: Verify write barriers between instructions\n"
     553                 : "    5: Verify write barriers between paints\n"
     554                 : "  Period specifies that collection happens every n allocations.\n"),
     555                 : 
     556                 :     JS_FN_HELP("schedulegc", ScheduleGC, 1, 0,
     557                 : "schedulegc(num | obj)",
     558                 : "  If num is given, schedule a GC after num allocations.\n"
     559                 : "  If obj is given, schedule a GC of obj's compartment."),
     560                 : 
     561                 :     JS_FN_HELP("selectforgc", SelectForGC, 0, 0,
     562                 : "selectforgc(obj1, obj2, ...)",
     563                 : "  Schedule the given objects to be marked in the next GC slice."),
     564                 : 
     565                 :     JS_FN_HELP("verifybarriers", VerifyBarriers, 0, 0,
     566                 : "verifybarriers()",
     567                 : "  Start or end a run of the write barrier verifier."),
     568                 : 
     569                 :     JS_FN_HELP("gcslice", GCSlice, 1, 0,
     570                 : "gcslice(n)",
     571                 : "  Run an incremental GC slice that marks about n objects."),
     572                 : 
     573                 :     JS_FN_HELP("deterministicgc", DeterministicGC, 1, 0,
     574                 : "deterministicgc(true|false)",
     575                 : "  If true, only allow determinstic GCs to run."),
     576                 : #endif
     577                 : 
     578                 :     JS_FN_HELP("internalConst", InternalConst, 1, 0,
     579                 : "internalConst(name)",
     580                 : "  Query an internal constant for the engine. See InternalConst source for\n"
     581                 : "  the list of constant names."),
     582                 : 
     583                 : #ifdef JS_METHODJIT
     584                 :     JS_FN_HELP("mjitcodestats", MJitCodeStats, 0, 0,
     585                 : "mjitcodestats()",
     586                 : "Return stats on mjit code memory usage."),
     587                 : #endif
     588                 : 
     589                 :     JS_FN_HELP("mjitChunkLimit", MJitChunkLimit, 1, 0,
     590                 : "mjitChunkLimit(N)",
     591                 : "  Specify limit on compiled chunk size during mjit compilation."),
     592                 : 
     593                 :     JS_FN_HELP("terminate", Terminate, 0, 0,
     594                 : "terminate()",
     595                 : "  Terminate JavaScript execution, as if we had run out of\n"
     596                 : "  memory or been terminated by the slow script dialog."),
     597                 : 
     598                 :     JS_FS_END
     599                 : };
     600                 : 
     601                 : namespace js {
     602                 : 
     603                 : bool
     604           23328 : DefineTestingFunctions(JSContext *cx, JSObject *obj)
     605                 : {
     606           23328 :     return JS_DefineFunctionsWithHelp(cx, obj, TestingFunctions);
     607                 : }
     608                 : 
     609                 : } /* namespace js */

Generated by: LCOV version 1.7