LCOV - code coverage report
Current view: directory - js/src/builtin - TestingFunctions.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 230 140 60.9 %
Date: 2012-06-02 Functions: 17 14 82.4 %

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

Generated by: LCOV version 1.7