mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 517083 - TM: introduce a temp allocator for allocations during recording and compilation, r=gal.
This commit is contained in:
parent
21b35a3bac
commit
ccc6ad4904
@ -155,7 +155,7 @@ struct JSTraceMonitor {
|
||||
*/
|
||||
JSContext *tracecx;
|
||||
|
||||
CLS(VMAllocator) allocator; // A chunk allocator for LIR.
|
||||
CLS(VMAllocator) dataAlloc; // A chunk allocator for LIR.
|
||||
CLS(nanojit::CodeAlloc) codeAlloc; // A general allocator for native code.
|
||||
CLS(nanojit::Assembler) assembler;
|
||||
CLS(nanojit::LirBuffer) lirbuf;
|
||||
|
@ -2003,15 +2003,13 @@ CompileRegExpToAST(JSContext* cx, JSTokenStream* ts,
|
||||
#ifdef JS_TRACER
|
||||
typedef js::Vector<LIns *, 4, js::ContextAllocPolicy> LInsList;
|
||||
|
||||
static avmplus::AvmCore s_core = avmplus::AvmCore();
|
||||
|
||||
/* Return the cached fragment for the given regexp, or create one. */
|
||||
static Fragment*
|
||||
LookupNativeRegExp(JSContext* cx, uint16 re_flags,
|
||||
const jschar* re_chars, size_t re_length)
|
||||
{
|
||||
JSTraceMonitor *tm = &JS_TRACE_MONITOR(cx);
|
||||
VMAllocator &alloc = *tm->allocator;
|
||||
VMAllocator &alloc = *tm->dataAlloc;
|
||||
REHashMap &table = *tm->reFragments;
|
||||
|
||||
REHashKey k(re_length, re_flags, re_chars);
|
||||
@ -2272,6 +2270,7 @@ enumerateNextChars(JSContext *cx, RENode *node, CharSet &set)
|
||||
|
||||
class RegExpNativeCompiler {
|
||||
private:
|
||||
VMAllocator tempAlloc;
|
||||
JSContext* cx;
|
||||
JSRegExp* re;
|
||||
CompilerState* cs; /* RegExp to compile */
|
||||
@ -2288,6 +2287,10 @@ class RegExpNativeCompiler {
|
||||
LIns* state;
|
||||
LIns* cpend;
|
||||
|
||||
bool outOfMemory() {
|
||||
return tempAlloc.outOfMemory() || JS_TRACE_MONITOR(cx).dataAlloc->outOfMemory();
|
||||
}
|
||||
|
||||
JSBool isCaseInsensitive() const { return (cs->flags & JSREG_FOLD) != 0; }
|
||||
|
||||
void targetCurrentPoint(LIns *ins)
|
||||
@ -2478,7 +2481,6 @@ class RegExpNativeCompiler {
|
||||
|
||||
LIns* compileFlat(RENode *&node, LIns* pos, LInsList& fails)
|
||||
{
|
||||
VMAllocator *alloc = JS_TRACE_MONITOR(cx).allocator;
|
||||
#ifdef USE_DOUBLE_CHAR_MATCH
|
||||
if (node->u.flat.length == 1) {
|
||||
if (node->next && node->next->op == REOP_FLAT &&
|
||||
@ -2494,7 +2496,7 @@ class RegExpNativeCompiler {
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < node->u.flat.length - 1; i += 2) {
|
||||
if (alloc->outOfMemory())
|
||||
if (outOfMemory())
|
||||
return 0;
|
||||
pos = compileFlatDoubleChar(((jschar*) node->kid)[i],
|
||||
((jschar*) node->kid)[i+1],
|
||||
@ -2512,7 +2514,7 @@ class RegExpNativeCompiler {
|
||||
return compileFlatSingleChar(node->u.flat.chr, pos, fails);
|
||||
} else {
|
||||
for (size_t i = 0; i < node->u.flat.length; i++) {
|
||||
if (alloc->outOfMemory())
|
||||
if (outOfMemory())
|
||||
return 0;
|
||||
pos = compileFlatSingleChar(((jschar*) node->kid)[i], pos, fails);
|
||||
if (!pos)
|
||||
@ -2541,7 +2543,7 @@ class RegExpNativeCompiler {
|
||||
if (!charSet->converted && !ProcessCharSet(cx, re, charSet))
|
||||
return NULL;
|
||||
LIns* skip = lirBufWriter->insSkip(bitmapLen);
|
||||
if (JS_TRACE_MONITOR(cx).allocator->outOfMemory())
|
||||
if (outOfMemory())
|
||||
return NULL;
|
||||
void* bitmapData = skip->payload();
|
||||
memcpy(bitmapData, charSet->u.bits, bitmapLen);
|
||||
@ -2960,9 +2962,8 @@ class RegExpNativeCompiler {
|
||||
*/
|
||||
LIns *compileNode(RENode *node, LIns *pos, bool atEnd, LInsList &fails)
|
||||
{
|
||||
VMAllocator *alloc = JS_TRACE_MONITOR(cx).allocator;
|
||||
for (; pos && node; node = node->next) {
|
||||
if (alloc->outOfMemory())
|
||||
if (outOfMemory())
|
||||
return NULL;
|
||||
|
||||
bool childNextIsEnd = atEnd && !node->next;
|
||||
@ -3038,7 +3039,7 @@ class RegExpNativeCompiler {
|
||||
/* Failed to match on first character, so fail whole match. */
|
||||
lir->ins0(LIR_regfence);
|
||||
lir->ins1(LIR_ret, lir->insImm(0));
|
||||
return !JS_TRACE_MONITOR(cx).allocator->outOfMemory();
|
||||
return !outOfMemory();
|
||||
}
|
||||
|
||||
/* Compile normal regular expressions that can match starting at any char. */
|
||||
@ -3054,7 +3055,7 @@ class RegExpNativeCompiler {
|
||||
lir->insStorei(lir->ins2(LIR_piadd, start, lir->insImmWord(2)), state,
|
||||
offsetof(REGlobalData, skipped));
|
||||
|
||||
return !JS_TRACE_MONITOR(cx).allocator->outOfMemory();
|
||||
return !outOfMemory();
|
||||
}
|
||||
|
||||
inline LIns*
|
||||
@ -3099,10 +3100,10 @@ class RegExpNativeCompiler {
|
||||
}
|
||||
|
||||
public:
|
||||
RegExpNativeCompiler(JSRegExp* re, CompilerState* cs, Fragment* fragment)
|
||||
: re(re), cs(cs), fragment(fragment), lir(NULL), lirBufWriter(NULL) { }
|
||||
RegExpNativeCompiler(JSContext* cx, JSRegExp* re, CompilerState* cs, Fragment* fragment)
|
||||
: cx(cx), re(re), cs(cs), fragment(fragment), lir(NULL), lirBufWriter(NULL) { }
|
||||
|
||||
JSBool compile(JSContext* cx)
|
||||
JSBool compile()
|
||||
{
|
||||
GuardRecord* guard = NULL;
|
||||
LIns* pos;
|
||||
@ -3110,10 +3111,9 @@ class RegExpNativeCompiler {
|
||||
size_t re_length;
|
||||
JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx);
|
||||
Assembler *assm = tm->assembler;
|
||||
VMAllocator& alloc = *tm->allocator;
|
||||
LIns* loopLabel = NULL;
|
||||
|
||||
if (alloc.outOfMemory() || js_OverfullJITCache(tm))
|
||||
if (outOfMemory() || js_OverfullJITCache(tm))
|
||||
return JS_FALSE;
|
||||
|
||||
re->source->getCharsAndLength(re_chars, re_length);
|
||||
@ -3126,10 +3126,9 @@ class RegExpNativeCompiler {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
this->cx = cx;
|
||||
/* At this point we have an empty fragment. */
|
||||
LirBuffer* lirbuf = fragment->lirbuf;
|
||||
if (alloc.outOfMemory())
|
||||
if (outOfMemory())
|
||||
goto fail;
|
||||
/* FIXME Use bug 463260 smart pointer when available. */
|
||||
lir = lirBufWriter = new LirBufWriter(lirbuf);
|
||||
@ -3138,7 +3137,7 @@ class RegExpNativeCompiler {
|
||||
#ifdef NJ_VERBOSE
|
||||
debug_only_stmt(
|
||||
if (js_LogController.lcbits & LC_TMRegexp) {
|
||||
lir = verbose_filter = new VerboseWriter(alloc, lir, lirbuf->names,
|
||||
lir = verbose_filter = new VerboseWriter(tempAlloc, lir, lirbuf->names,
|
||||
&js_LogController);
|
||||
}
|
||||
)
|
||||
@ -3187,9 +3186,9 @@ class RegExpNativeCompiler {
|
||||
|
||||
guard = insertGuard(loopLabel, re_chars, re_length);
|
||||
|
||||
if (alloc.outOfMemory())
|
||||
if (outOfMemory())
|
||||
goto fail;
|
||||
::compile(assm, fragment, alloc verbose_only(, tm->labels));
|
||||
::compile(assm, fragment, tempAlloc verbose_only(, tm->labels));
|
||||
if (assm->error() != nanojit::None)
|
||||
goto fail;
|
||||
|
||||
@ -3203,7 +3202,7 @@ class RegExpNativeCompiler {
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
fail:
|
||||
if (alloc.outOfMemory() || js_OverfullJITCache(tm)) {
|
||||
if (outOfMemory() || js_OverfullJITCache(tm)) {
|
||||
delete lirBufWriter;
|
||||
// recover profiling data from expiring Fragments
|
||||
verbose_only(
|
||||
@ -3236,14 +3235,14 @@ CompileRegExpToNative(JSContext* cx, JSRegExp* re, Fragment* fragment)
|
||||
JSBool rv = JS_FALSE;
|
||||
void* mark;
|
||||
CompilerState state;
|
||||
RegExpNativeCompiler rc(re, &state, fragment);
|
||||
RegExpNativeCompiler rc(cx, re, &state, fragment);
|
||||
|
||||
JS_ASSERT(!fragment->code());
|
||||
mark = JS_ARENA_MARK(&cx->tempPool);
|
||||
if (!CompileRegExpToAST(cx, NULL, re->source, re->flags, state)) {
|
||||
goto out;
|
||||
}
|
||||
rv = rc.compile(cx);
|
||||
rv = rc.compile();
|
||||
out:
|
||||
JS_ARENA_RELEASE(&cx->tempPool, mark);
|
||||
return rv;
|
||||
|
@ -1292,7 +1292,7 @@ getAnchor(JSTraceMonitor* tm, const void *ip, JSObject* globalObj, uint32 global
|
||||
uint32_t profFragID = (js_LogController.lcbits & LC_FragProfile)
|
||||
? (++(tm->lastFragID)) : 0;
|
||||
)
|
||||
VMFragment *f = new (*tm->allocator) VMFragment(ip, globalObj, globalShape, argc
|
||||
VMFragment *f = new (*tm->dataAlloc) VMFragment(ip, globalObj, globalShape, argc
|
||||
verbose_only(, profFragID));
|
||||
JS_ASSERT(f);
|
||||
|
||||
@ -2140,8 +2140,8 @@ JS_REQUIRES_STACK
|
||||
TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* _anchor, Fragment* _fragment,
|
||||
TreeInfo* ti, unsigned stackSlots, unsigned ngslots, JSTraceType* typeMap,
|
||||
VMSideExit* innermostNestedGuard, jsbytecode* outer, uint32 outerArgc)
|
||||
: whichTreesToTrash(JS_TRACE_MONITOR(cx).allocator),
|
||||
cfgMerges(JS_TRACE_MONITOR(cx).allocator)
|
||||
: whichTreesToTrash(&tempAlloc),
|
||||
cfgMerges(&tempAlloc)
|
||||
{
|
||||
JS_ASSERT(!_fragment->vmprivate && ti && cx->fp->regs->pc == (jsbytecode*)_fragment->ip);
|
||||
/* Reset the fragment state we care about in case we got a recycled fragment.
|
||||
@ -2196,13 +2196,13 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* _anchor, Fragment* _frag
|
||||
debug_only_stmt(
|
||||
if (js_LogController.lcbits & LC_TMRecorder) {
|
||||
lir = verbose_filter
|
||||
= new VerboseWriter (*JS_TRACE_MONITOR(cx).allocator, lir, lirbuf->names,
|
||||
= new VerboseWriter (tempAlloc, lir, lirbuf->names,
|
||||
&js_LogController);
|
||||
}
|
||||
)
|
||||
if (nanojit::AvmCore::config.soft_float)
|
||||
lir = float_filter = new SoftFloatFilter(lir);
|
||||
lir = cse_filter = new CseFilter(lir, *JS_TRACE_MONITOR(cx).allocator);
|
||||
lir = cse_filter = new CseFilter(lir, tempAlloc);
|
||||
lir = expr_filter = new ExprFilter(lir);
|
||||
lir = func_filter = new FuncFilter(lir);
|
||||
#ifdef DEBUG
|
||||
@ -2304,6 +2304,12 @@ TraceRecorder::~TraceRecorder()
|
||||
delete lir_buf_writer;
|
||||
}
|
||||
|
||||
bool
|
||||
TraceRecorder::outOfMemory()
|
||||
{
|
||||
return traceMonitor->dataAlloc->outOfMemory() || tempAlloc.outOfMemory();
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::removeFragmentReferences()
|
||||
{
|
||||
@ -2593,14 +2599,14 @@ JSTraceMonitor::flush()
|
||||
js_FragProfiling_FragFinalizer(f->head, this);
|
||||
)
|
||||
|
||||
allocator->reset();
|
||||
dataAlloc->reset();
|
||||
codeAlloc->reset();
|
||||
|
||||
Allocator& alloc = *allocator;
|
||||
Allocator& alloc = *dataAlloc;
|
||||
|
||||
for (size_t i = 0; i < MONITOR_N_GLOBAL_STATES; ++i) {
|
||||
globalStates[i].globalShape = -1;
|
||||
globalStates[i].globalSlots = new (alloc) SlotList(allocator);
|
||||
globalStates[i].globalSlots = new (alloc) SlotList(&alloc);
|
||||
}
|
||||
|
||||
assembler = new (alloc) Assembler(*codeAlloc, alloc, core, &js_LogController);
|
||||
@ -4129,12 +4135,12 @@ TraceRecorder::compile(JSTraceMonitor* tm)
|
||||
}
|
||||
if (anchor && anchor->exitType != CASE_EXIT)
|
||||
++treeInfo->branchCount;
|
||||
if (tm->allocator->outOfMemory())
|
||||
if (outOfMemory())
|
||||
return;
|
||||
|
||||
Assembler *assm = tm->assembler;
|
||||
::compile(assm, fragment, *tm->allocator verbose_only(, tm->labels));
|
||||
if (tm->allocator->outOfMemory())
|
||||
::compile(assm, fragment, tempAlloc verbose_only(, tm->labels));
|
||||
if (outOfMemory())
|
||||
return;
|
||||
|
||||
if (assm->error() != nanojit::None) {
|
||||
@ -4491,7 +4497,7 @@ TraceRecorder::closeLoop(SlotMap& slotMap, VMSideExit* exit, TypeConsensus& cons
|
||||
debug_only_print0(LC_TMTracer,
|
||||
"Trace has unstable loop variable with no stable peer, "
|
||||
"compiling anyway.\n");
|
||||
UnstableExit* uexit = new (*traceMonitor->allocator) UnstableExit;
|
||||
UnstableExit* uexit = new (*traceMonitor->dataAlloc) UnstableExit;
|
||||
uexit->fragment = fragment;
|
||||
uexit->exit = exit;
|
||||
uexit->next = treeInfo->unstableExits;
|
||||
@ -5030,7 +5036,7 @@ DeleteRecorder(JSContext* cx)
|
||||
tm->recorder = NULL;
|
||||
|
||||
/* If we ran out of memory, flush the code cache. */
|
||||
if (tm->allocator->outOfMemory() ||
|
||||
if (tm->dataAlloc->outOfMemory() ||
|
||||
js_OverfullJITCache(tm)) {
|
||||
ResetJIT(cx, FR_OOM);
|
||||
return false;
|
||||
@ -5386,7 +5392,7 @@ RecordTree(JSContext* cx, JSTraceMonitor* tm, VMFragment* f, jsbytecode* outer,
|
||||
f->root = f;
|
||||
f->lirbuf = tm->lirbuf;
|
||||
|
||||
if (tm->allocator->outOfMemory() || js_OverfullJITCache(tm)) {
|
||||
if (tm->dataAlloc->outOfMemory() || js_OverfullJITCache(tm)) {
|
||||
Backoff(cx, (jsbytecode*) f->root->ip);
|
||||
ResetJIT(cx, FR_OOM);
|
||||
debug_only_print0(LC_TMTracer,
|
||||
@ -5397,7 +5403,7 @@ RecordTree(JSContext* cx, JSTraceMonitor* tm, VMFragment* f, jsbytecode* outer,
|
||||
JS_ASSERT(!f->code() && !f->vmprivate);
|
||||
|
||||
/* Set up the VM-private treeInfo structure for this fragment. */
|
||||
TreeInfo* ti = new (*tm->allocator) TreeInfo(tm->allocator, f, globalSlots);
|
||||
TreeInfo* ti = new (*tm->dataAlloc) TreeInfo(tm->dataAlloc, f, globalSlots);
|
||||
|
||||
/* Capture the coerced type of each active slot in the type map. */
|
||||
ti->typeMap.captureTypes(cx, globalObj, *globalSlots, 0 /* callDepth */);
|
||||
@ -5569,7 +5575,7 @@ AttemptToExtendTree(JSContext* cx, VMSideExit* anchor, VMSideExit* exitedFrom, j
|
||||
Fragment* c;
|
||||
if (!(c = anchor->target)) {
|
||||
JSTraceMonitor *tm = &JS_TRACE_MONITOR(cx);
|
||||
Allocator& alloc = *tm->allocator;
|
||||
Allocator& alloc = *tm->dataAlloc;
|
||||
verbose_only(
|
||||
uint32_t profFragID = (js_LogController.lcbits & LC_FragProfile)
|
||||
? (++(tm->lastFragID)) : 0;
|
||||
@ -6778,7 +6784,7 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op)
|
||||
return JSRS_STOP;
|
||||
}
|
||||
|
||||
if (tr->traceMonitor->allocator->outOfMemory() || js_OverfullJITCache(&JS_TRACE_MONITOR(cx))) {
|
||||
if (tr->outOfMemory() || js_OverfullJITCache(&JS_TRACE_MONITOR(cx))) {
|
||||
js_AbortRecording(cx, "no more memory");
|
||||
ResetJIT(cx, FR_OOM);
|
||||
return JSRS_STOP;
|
||||
@ -7118,7 +7124,7 @@ void
|
||||
js_SetMaxCodeCacheBytes(JSContext* cx, uint32 bytes)
|
||||
{
|
||||
JSTraceMonitor* tm = &JS_THREAD_DATA(cx)->traceMonitor;
|
||||
JS_ASSERT(tm->codeAlloc && tm->allocator);
|
||||
JS_ASSERT(tm->codeAlloc && tm->dataAlloc);
|
||||
if (bytes > 1 G)
|
||||
bytes = 1 G;
|
||||
if (bytes < 128 K)
|
||||
@ -7190,8 +7196,8 @@ js_InitJIT(JSTraceMonitor *tm)
|
||||
JS_DHASH_DEFAULT_CAPACITY(PC_HASH_COUNT));
|
||||
}
|
||||
|
||||
JS_ASSERT(!tm->allocator&& !tm->codeAlloc);
|
||||
tm->allocator = new VMAllocator();
|
||||
JS_ASSERT(!tm->dataAlloc && !tm->codeAlloc);
|
||||
tm->dataAlloc = new VMAllocator();
|
||||
tm->codeAlloc = new CodeAlloc();
|
||||
tm->flush();
|
||||
verbose_only( tm->branches = NULL; )
|
||||
@ -7305,9 +7311,9 @@ js_FinishJIT(JSTraceMonitor *tm)
|
||||
tm->codeAlloc = NULL;
|
||||
}
|
||||
|
||||
if (tm->allocator) {
|
||||
delete tm->allocator;
|
||||
tm->allocator = NULL;
|
||||
if (tm->dataAlloc) {
|
||||
delete tm->dataAlloc;
|
||||
tm->dataAlloc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7425,10 +7431,10 @@ js_OverfullJITCache(JSTraceMonitor* tm)
|
||||
*
|
||||
*/
|
||||
jsuint maxsz = tm->maxCodeCacheBytes;
|
||||
VMAllocator *allocator = tm->allocator;
|
||||
VMAllocator *dataAlloc = tm->dataAlloc;
|
||||
CodeAlloc *codeAlloc = tm->codeAlloc;
|
||||
|
||||
return (codeAlloc->size() + allocator->size() > maxsz);
|
||||
return (codeAlloc->size() + dataAlloc->size() > maxsz);
|
||||
}
|
||||
|
||||
JS_FORCES_STACK JS_FRIEND_API(void)
|
||||
@ -9358,8 +9364,7 @@ TraceRecorder::newArguments()
|
||||
? lir->ins2(LIR_piadd, lirbuf->sp,
|
||||
lir->insImmWord(-treeInfo->nativeStackBase + nativeStackOffset(&cx->fp->argv[0])))
|
||||
: INS_CONSTPTR((void *) 2);
|
||||
js_ArgsPrivateNative *apn = js_ArgsPrivateNative::create(*traceMonitor->allocator,
|
||||
cx->fp->argc);
|
||||
js_ArgsPrivateNative *apn = js_ArgsPrivateNative::create(*traceMonitor->dataAlloc, cx->fp->argc);
|
||||
for (uintN i = 0; i < cx->fp->argc; ++i) {
|
||||
apn->typemap()[i] = determineSlotType(&cx->fp->argv[i]);
|
||||
}
|
||||
@ -9789,8 +9794,7 @@ TraceRecorder::newArray(JSObject* ctor, uint32 argc, jsval* argv, jsval* rval)
|
||||
|
||||
// arr->dslots[i] = box_jsval(vp[i]); for i in 0..argc
|
||||
LIns *dslots_ins = NULL;
|
||||
VMAllocator *alloc = traceMonitor->allocator;
|
||||
for (uint32 i = 0; i < argc && !alloc->outOfMemory(); i++) {
|
||||
for (uint32 i = 0; i < argc && !outOfMemory(); i++) {
|
||||
LIns *elt_ins = box_jsval(argv[i], get(&argv[i]));
|
||||
stobj_set_dslot(arr_ins, i, dslots_ins, elt_ins);
|
||||
}
|
||||
@ -10175,7 +10179,6 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
||||
}
|
||||
lir->insStorei(this_ins, invokevp_ins, 1 * sizeof(jsval));
|
||||
|
||||
VMAllocator *alloc = traceMonitor->allocator;
|
||||
// Populate argv.
|
||||
for (uintN n = 2; n < 2 + argc; n++) {
|
||||
LIns* i = box_jsval(vp[n], get(&vp[n]));
|
||||
@ -10183,7 +10186,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
||||
|
||||
// For a very long argument list we might run out of LIR space, so
|
||||
// check inside the loop.
|
||||
if (alloc->outOfMemory())
|
||||
if (outOfMemory())
|
||||
ABORT_TRACE("out of memory in argument list");
|
||||
}
|
||||
|
||||
@ -10193,7 +10196,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
||||
for (uintN n = 2 + argc; n < vplen; n++) {
|
||||
lir->insStorei(undef_ins, invokevp_ins, n * sizeof(jsval));
|
||||
|
||||
if (alloc->outOfMemory())
|
||||
if (outOfMemory())
|
||||
ABORT_TRACE("out of memory in extra slots");
|
||||
}
|
||||
}
|
||||
|
@ -691,6 +691,7 @@ enum TypeConsensus
|
||||
};
|
||||
|
||||
class TraceRecorder {
|
||||
VMAllocator tempAlloc;
|
||||
JSContext* cx;
|
||||
JSTraceMonitor* traceMonitor;
|
||||
JSObject* globalObj;
|
||||
@ -1000,6 +1001,8 @@ public:
|
||||
uint32 outerArgc);
|
||||
~TraceRecorder();
|
||||
|
||||
bool outOfMemory();
|
||||
|
||||
static JS_REQUIRES_STACK JSRecordingStatus monitorRecording(JSContext* cx, TraceRecorder* tr,
|
||||
JSOp op);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user