LCOV - app.info - js/src/builtin/TestingFunctions.cpp

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