Bug 890784 (part 1) - Create a new vm/Runtime module and put JSRuntime in it. r=wmccloskey.

--HG--
rename : js/src/jscntxtinlines.h => js/src/vm/Runtime-inl.h
rename : js/src/jscntxt.cpp => js/src/vm/Runtime.cpp
rename : js/src/jscntxt.h => js/src/vm/Runtime.h
This commit is contained in:
Nicholas Nethercote 2013-07-07 23:18:48 -07:00
parent 732e8395a8
commit 4eee9162ad
16 changed files with 2106 additions and 1964 deletions

View File

@ -37,6 +37,7 @@
#include "vm/ArgumentsObject-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Runtime-inl.h"
using namespace js;
using namespace js::gc;

View File

@ -99,128 +99,6 @@ js::TraceCycleDetectionSet(JSTracer *trc, js::ObjectSet &set)
}
}
void
NewObjectCache::clearNurseryObjects(JSRuntime *rt)
{
for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
Entry &e = entries[i];
JSObject *obj = reinterpret_cast<JSObject *>(&e.templateObject);
if (IsInsideNursery(rt, e.key) ||
IsInsideNursery(rt, obj->slots) ||
IsInsideNursery(rt, obj->elements))
{
mozilla::PodZero(&e);
}
}
}
void
JSRuntime::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *rtSizes)
{
rtSizes->object = mallocSizeOf(this);
rtSizes->atomsTable = atoms.sizeOfExcludingThis(mallocSizeOf);
rtSizes->contexts = 0;
for (ContextIter acx(this); !acx.done(); acx.next())
rtSizes->contexts += acx->sizeOfIncludingThis(mallocSizeOf);
rtSizes->dtoa = mallocSizeOf(mainThread.dtoaState);
rtSizes->temporary = tempLifoAlloc.sizeOfExcludingThis(mallocSizeOf);
rtSizes->code = JS::CodeSizes();
if (execAlloc_)
execAlloc_->sizeOfCode(&rtSizes->code);
rtSizes->regexpData = bumpAlloc_ ? bumpAlloc_->sizeOfNonHeapData() : 0;
rtSizes->interpreterStack = interpreterStack_.sizeOfExcludingThis(mallocSizeOf);
rtSizes->gcMarker = gcMarker.sizeOfExcludingThis(mallocSizeOf);
rtSizes->mathCache = mathCache_ ? mathCache_->sizeOfIncludingThis(mallocSizeOf) : 0;
rtSizes->scriptData = scriptDataTable.sizeOfExcludingThis(mallocSizeOf);
for (ScriptDataTable::Range r = scriptDataTable.all(); !r.empty(); r.popFront())
rtSizes->scriptData += mallocSizeOf(r.front());
}
void
JSRuntime::triggerOperationCallback()
{
AutoLockForOperationCallback lock(this);
/*
* Invalidate ionTop to trigger its over-recursion check. Note this must be
* set before interrupt, to avoid racing with js_InvokeOperationCallback,
* into a weird state where interrupt is stuck at 0 but ionStackLimit is
* MAXADDR.
*/
mainThread.setIonStackLimit(-1);
/*
* Use JS_ATOMIC_SET in the hope that it ensures the write will become
* immediately visible to other processors polling the flag.
*/
JS_ATOMIC_SET(&interrupt, 1);
#ifdef JS_ION
/* asm.js code uses a separate mechanism to halt running code. */
TriggerOperationCallbackForAsmJSCode(this);
#endif
}
void
JSRuntime::setJitHardening(bool enabled)
{
jitHardening = enabled;
if (execAlloc_)
execAlloc_->setRandomize(enabled);
}
JSC::ExecutableAllocator *
JSRuntime::createExecutableAllocator(JSContext *cx)
{
JS_ASSERT(!execAlloc_);
JS_ASSERT(cx->runtime() == this);
JSC::AllocationBehavior randomize =
jitHardening ? JSC::AllocationCanRandomize : JSC::AllocationDeterministic;
execAlloc_ = js_new<JSC::ExecutableAllocator>(randomize);
if (!execAlloc_)
js_ReportOutOfMemory(cx);
return execAlloc_;
}
WTF::BumpPointerAllocator *
JSRuntime::createBumpPointerAllocator(JSContext *cx)
{
JS_ASSERT(!bumpAlloc_);
JS_ASSERT(cx->runtime() == this);
bumpAlloc_ = js_new<WTF::BumpPointerAllocator>();
if (!bumpAlloc_)
js_ReportOutOfMemory(cx);
return bumpAlloc_;
}
MathCache *
JSRuntime::createMathCache(JSContext *cx)
{
JS_ASSERT(!mathCache_);
JS_ASSERT(cx->runtime() == this);
MathCache *newMathCache = js_new<MathCache>();
if (!newMathCache) {
js_ReportOutOfMemory(cx);
return NULL;
}
mathCache_ = newMathCache;
return mathCache_;
}
void
JSCompartment::sweepCallsiteClones()
{
@ -1221,50 +1099,6 @@ JSContext::~JSContext()
JS_ASSERT(!resolvingList);
}
bool
JSRuntime::setDefaultLocale(const char *locale)
{
if (!locale)
return false;
resetDefaultLocale();
defaultLocale = JS_strdup(this, locale);
return defaultLocale != NULL;
}
void
JSRuntime::resetDefaultLocale()
{
js_free(defaultLocale);
defaultLocale = NULL;
}
const char *
JSRuntime::getDefaultLocale()
{
if (defaultLocale)
return defaultLocale;
char *locale, *lang, *p;
#ifdef HAVE_SETLOCALE
locale = setlocale(LC_ALL, NULL);
#else
locale = getenv("LANG");
#endif
// convert to a well-formed BCP 47 language tag
if (!locale || !strcmp(locale, "C"))
locale = const_cast<char*>("und");
lang = JS_strdup(this, locale);
if (!lang)
return NULL;
if ((p = strchr(lang, '.')))
*p = '\0';
while ((p = strchr(lang, '_')))
*p = '-';
defaultLocale = lang;
return defaultLocale;
}
/*
* Since this function is only called in the context of a pending exception,
* the caller must subsequently take an error path. If wrapping fails, it will
@ -1351,74 +1185,6 @@ JSContext::currentlyRunning() const
return false;
}
void
JSRuntime::setGCMaxMallocBytes(size_t value)
{
/*
* For compatibility treat any value that exceeds PTRDIFF_T_MAX to
* mean that value.
*/
gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
for (ZonesIter zone(this); !zone.done(); zone.next())
zone->setGCMaxMallocBytes(value);
}
void
JSRuntime::updateMallocCounter(size_t nbytes)
{
updateMallocCounter(NULL, nbytes);
}
void
JSRuntime::updateMallocCounter(JS::Zone *zone, size_t nbytes)
{
/* We tolerate any thread races when updating gcMallocBytes. */
ptrdiff_t oldCount = gcMallocBytes;
ptrdiff_t newCount = oldCount - ptrdiff_t(nbytes);
gcMallocBytes = newCount;
if (JS_UNLIKELY(newCount <= 0 && oldCount > 0))
onTooMuchMalloc();
else if (zone)
zone->updateMallocCounter(nbytes);
}
JS_FRIEND_API(void)
JSRuntime::onTooMuchMalloc()
{
TriggerGC(this, JS::gcreason::TOO_MUCH_MALLOC);
}
JS_FRIEND_API(void *)
JSRuntime::onOutOfMemory(void *p, size_t nbytes)
{
return onOutOfMemory(p, nbytes, NULL);
}
JS_FRIEND_API(void *)
JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
{
if (isHeapBusy())
return NULL;
/*
* Retry when we are done with the background sweeping and have stopped
* all the allocations and released the empty GC chunks.
*/
JS::ShrinkGCBuffers(this);
gcHelperThread.waitBackgroundSweepOrAllocEnd();
if (!p)
p = js_malloc(nbytes);
else if (p == reinterpret_cast<void *>(1))
p = js_calloc(nbytes);
else
p = js_realloc(p, nbytes);
if (p)
return p;
if (cx)
js_ReportOutOfMemory(cx);
return NULL;
}
static bool
ComputeIsJITBroken()
{

File diff suppressed because it is too large Load Diff

View File

@ -27,55 +27,6 @@
namespace js {
inline bool
NewObjectCache::lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
{
JS_ASSERT(!proto->is<GlobalObject>());
return lookup(clasp, proto, kind, pentry);
}
inline bool
NewObjectCache::lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry)
{
return lookup(clasp, global, kind, pentry);
}
inline void
NewObjectCache::fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj)
{
//JS_ASSERT(global == obj->getGlobal());
return fill(entry, clasp, global, kind, obj);
}
inline void
NewObjectCache::copyCachedToObject(JSObject *dst, JSObject *src, gc::AllocKind kind)
{
js_memcpy(dst, src, gc::Arena::thingSize(kind));
#ifdef JSGC_GENERATIONAL
Shape::writeBarrierPost(dst->shape_, &dst->shape_);
types::TypeObject::writeBarrierPost(dst->type_, &dst->type_);
#endif
}
inline JSObject *
NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_, js::gc::InitialHeap heap)
{
// The new object cache does not account for metadata attached via callbacks.
JS_ASSERT(!cx->compartment()->objectMetadataCallback);
JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
Entry *entry = &entries[entry_];
JSObject *obj = js_NewGCObject<NoGC>(cx, entry->kind, heap);
if (obj) {
copyCachedToObject(obj, reinterpret_cast<JSObject *>(&entry->templateObject), entry->kind);
Probes::createObject(cx, obj);
return obj;
}
return NULL;
}
#ifdef JS_CRASH_DIAGNOSTICS
class CompartmentChecker
{

View File

@ -117,6 +117,7 @@ namespace js {
class AutoDebugModeGC;
class ArrayBufferObject;
class DebugScopes;
class WeakMapBase;
}
struct JSCompartment

View File

@ -50,6 +50,7 @@
#include "vm/BooleanObject-inl.h"
#include "vm/NumberObject-inl.h"
#include "vm/RegExpStatics-inl.h"
#include "vm/Runtime-inl.h"
#include "vm/Shape-inl.h"
#include "vm/StringObject-inl.h"

View File

@ -31,7 +31,7 @@ class WeakCache : public HashMap<Key, Value, HashPolicy, AllocPolicy> {
public:
explicit WeakCache(JSRuntime *rt) : Base(rt) { }
explicit WeakCache(JSContext *cx) : Base(cx) { }
explicit WeakCache(JSContext *cx) : Base(cx->runtime()) { }
public:
// Sweep all entries which have unmarked key or value.
@ -82,7 +82,7 @@ class WeakValueCache : public HashMap<Key, Value, HashPolicy, AllocPolicy>
typedef typename Base::Enum Enum;
explicit WeakValueCache(JSRuntime *rt) : Base(rt) { }
explicit WeakValueCache(JSContext *cx) : Base(cx) { }
explicit WeakValueCache(JSContext *cx) : Base(cx->runtime()) { }
public:
// Sweep all entries which have unmarked key or value.

View File

@ -134,7 +134,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
typedef typename Base::Range Range;
explicit WeakMap(JSContext *cx, JSObject *memOf=NULL)
: Base(cx), WeakMapBase(memOf, cx->compartment()) { }
: Base(cx->runtime()), WeakMapBase(memOf, cx->compartment()) { }
private:
bool markValue(JSTracer *trc, Value *x) {

View File

@ -116,6 +116,7 @@ CPP_SOURCES += [
'RegExpObject.cpp',
'RegExpStatics.cpp',
'RootMarking.cpp',
'Runtime.cpp',
'SPSProfiler.cpp',
'ScopeObject.cpp',
'SelfHosting.cpp',

View File

@ -364,7 +364,7 @@ Breakpoint::nextInSite()
Debugger::Debugger(JSContext *cx, JSObject *dbg)
: object(dbg), uncaughtExceptionHook(NULL), enabled(true),
frames(cx), scripts(cx), sources(cx), objects(cx), environments(cx)
frames(cx->runtime()), scripts(cx), sources(cx), objects(cx), environments(cx)
{
assertSameCompartment(cx, dbg);
@ -2266,7 +2266,9 @@ class Debugger::ScriptQuery {
public:
/* Construct a ScriptQuery to use matching scripts for |dbg|. */
ScriptQuery(JSContext *cx, Debugger *dbg):
cx(cx), debugger(dbg), compartments(cx), url(cx), innermostForCompartment(cx) {}
cx(cx), debugger(dbg), compartments(cx->runtime()), url(cx),
innermostForCompartment(cx->runtime())
{}
/*
* Initialize this ScriptQuery. Raise an error and return false if we

View File

@ -51,7 +51,7 @@ class DebuggerWeakMap : private WeakMap<Key, Value, DefaultHasher<Key> >
public:
typedef WeakMap<Key, Value, DefaultHasher<Key> > Base;
explicit DebuggerWeakMap(JSContext *cx)
: Base(cx), zoneCounts(cx) { }
: Base(cx), zoneCounts(cx->runtime()) { }
public:
/* Expose those parts of HashMap public interface that are used by Debugger methods. */

81
js/src/vm/Runtime-inl.h Normal file
View File

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef vm_Runtime_inl_h
#define vm_Runtime_inl_h
#include "vm/Runtime.h"
#include "jscompartment.h"
#include "jsfriendapi.h"
#include "jsgc.h"
#include "jsiter.h"
#include "builtin/Object.h" // For js::obj_construct
#include "frontend/ParseMaps.h"
#include "ion/IonFrames.h" // For GetPcScript
#include "vm/Interpreter.h"
#include "vm/Probes.h"
#include "vm/RegExpObject.h"
#include "jsgcinlines.h"
#include "vm/ObjectImpl-inl.h"
namespace js {
inline bool
NewObjectCache::lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
{
JS_ASSERT(!proto->is<GlobalObject>());
return lookup(clasp, proto, kind, pentry);
}
inline bool
NewObjectCache::lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry)
{
return lookup(clasp, global, kind, pentry);
}
inline void
NewObjectCache::fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj)
{
//JS_ASSERT(global == obj->getGlobal());
return fill(entry, clasp, global, kind, obj);
}
inline void
NewObjectCache::copyCachedToObject(JSObject *dst, JSObject *src, gc::AllocKind kind)
{
js_memcpy(dst, src, gc::Arena::thingSize(kind));
#ifdef JSGC_GENERATIONAL
Shape::writeBarrierPost(dst->shape_, &dst->shape_);
types::TypeObject::writeBarrierPost(dst->type_, &dst->type_);
#endif
}
inline JSObject *
NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_, js::gc::InitialHeap heap)
{
// The new object cache does not account for metadata attached via callbacks.
JS_ASSERT(!cx->compartment()->objectMetadataCallback);
JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
Entry *entry = &entries[entry_];
JSObject *obj = js_NewGCObject<NoGC>(cx, entry->kind, heap);
if (obj) {
copyCachedToObject(obj, reinterpret_cast<JSObject *>(&entry->templateObject), entry->kind);
Probes::createObject(cx, obj);
return obj;
}
return NULL;
}
} /* namespace js */
#endif /* vm_Runtime_inl_h */

284
js/src/vm/Runtime.cpp Normal file
View File

@ -0,0 +1,284 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "vm/Runtime.h"
#include <locale.h>
#include <stdarg.h>
#include <string.h>
#include "mozilla/MemoryReporting.h"
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsprf.h"
#include "jsatom.h"
#include "jscompartment.h"
#include "jsdbgapi.h"
#include "jsexn.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jsiter.h"
#include "jsmath.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jspubtd.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jsworkers.h"
#ifdef JS_ION
#include "ion/Ion.h"
#endif
#include "gc/Marking.h"
#include "js/CharacterEncoding.h"
#include "js/MemoryMetrics.h"
#include "vm/Shape.h"
#include "yarr/BumpPointerAllocator.h"
#include "jsobjinlines.h"
#include "vm/Stack-inl.h"
using namespace js;
using namespace js::gc;
using mozilla::PodZero;
void
NewObjectCache::clearNurseryObjects(JSRuntime *rt)
{
for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
Entry &e = entries[i];
JSObject *obj = reinterpret_cast<JSObject *>(&e.templateObject);
if (IsInsideNursery(rt, e.key) ||
IsInsideNursery(rt, obj->slots) ||
IsInsideNursery(rt, obj->elements))
{
PodZero(&e);
}
}
}
void
JSRuntime::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *rtSizes)
{
rtSizes->object = mallocSizeOf(this);
rtSizes->atomsTable = atoms.sizeOfExcludingThis(mallocSizeOf);
rtSizes->contexts = 0;
for (ContextIter acx(this); !acx.done(); acx.next())
rtSizes->contexts += acx->sizeOfIncludingThis(mallocSizeOf);
rtSizes->dtoa = mallocSizeOf(mainThread.dtoaState);
rtSizes->temporary = tempLifoAlloc.sizeOfExcludingThis(mallocSizeOf);
rtSizes->code = JS::CodeSizes();
if (execAlloc_)
execAlloc_->sizeOfCode(&rtSizes->code);
rtSizes->regexpData = bumpAlloc_ ? bumpAlloc_->sizeOfNonHeapData() : 0;
rtSizes->interpreterStack = interpreterStack_.sizeOfExcludingThis(mallocSizeOf);
rtSizes->gcMarker = gcMarker.sizeOfExcludingThis(mallocSizeOf);
rtSizes->mathCache = mathCache_ ? mathCache_->sizeOfIncludingThis(mallocSizeOf) : 0;
rtSizes->scriptData = scriptDataTable.sizeOfExcludingThis(mallocSizeOf);
for (ScriptDataTable::Range r = scriptDataTable.all(); !r.empty(); r.popFront())
rtSizes->scriptData += mallocSizeOf(r.front());
}
void
JSRuntime::triggerOperationCallback()
{
AutoLockForOperationCallback lock(this);
/*
* Invalidate ionTop to trigger its over-recursion check. Note this must be
* set before interrupt, to avoid racing with js_InvokeOperationCallback,
* into a weird state where interrupt is stuck at 0 but ionStackLimit is
* MAXADDR.
*/
mainThread.setIonStackLimit(-1);
/*
* Use JS_ATOMIC_SET in the hope that it ensures the write will become
* immediately visible to other processors polling the flag.
*/
JS_ATOMIC_SET(&interrupt, 1);
#ifdef JS_ION
/* asm.js code uses a separate mechanism to halt running code. */
TriggerOperationCallbackForAsmJSCode(this);
#endif
}
void
JSRuntime::setJitHardening(bool enabled)
{
jitHardening = enabled;
if (execAlloc_)
execAlloc_->setRandomize(enabled);
}
JSC::ExecutableAllocator *
JSRuntime::createExecutableAllocator(JSContext *cx)
{
JS_ASSERT(!execAlloc_);
JS_ASSERT(cx->runtime() == this);
JSC::AllocationBehavior randomize =
jitHardening ? JSC::AllocationCanRandomize : JSC::AllocationDeterministic;
execAlloc_ = js_new<JSC::ExecutableAllocator>(randomize);
if (!execAlloc_)
js_ReportOutOfMemory(cx);
return execAlloc_;
}
WTF::BumpPointerAllocator *
JSRuntime::createBumpPointerAllocator(JSContext *cx)
{
JS_ASSERT(!bumpAlloc_);
JS_ASSERT(cx->runtime() == this);
bumpAlloc_ = js_new<WTF::BumpPointerAllocator>();
if (!bumpAlloc_)
js_ReportOutOfMemory(cx);
return bumpAlloc_;
}
MathCache *
JSRuntime::createMathCache(JSContext *cx)
{
JS_ASSERT(!mathCache_);
JS_ASSERT(cx->runtime() == this);
MathCache *newMathCache = js_new<MathCache>();
if (!newMathCache) {
js_ReportOutOfMemory(cx);
return NULL;
}
mathCache_ = newMathCache;
return mathCache_;
}
bool
JSRuntime::setDefaultLocale(const char *locale)
{
if (!locale)
return false;
resetDefaultLocale();
defaultLocale = JS_strdup(this, locale);
return defaultLocale != NULL;
}
void
JSRuntime::resetDefaultLocale()
{
js_free(defaultLocale);
defaultLocale = NULL;
}
const char *
JSRuntime::getDefaultLocale()
{
if (defaultLocale)
return defaultLocale;
char *locale, *lang, *p;
#ifdef HAVE_SETLOCALE
locale = setlocale(LC_ALL, NULL);
#else
locale = getenv("LANG");
#endif
// convert to a well-formed BCP 47 language tag
if (!locale || !strcmp(locale, "C"))
locale = const_cast<char*>("und");
lang = JS_strdup(this, locale);
if (!lang)
return NULL;
if ((p = strchr(lang, '.')))
*p = '\0';
while ((p = strchr(lang, '_')))
*p = '-';
defaultLocale = lang;
return defaultLocale;
}
void
JSRuntime::setGCMaxMallocBytes(size_t value)
{
/*
* For compatibility treat any value that exceeds PTRDIFF_T_MAX to
* mean that value.
*/
gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
for (ZonesIter zone(this); !zone.done(); zone.next())
zone->setGCMaxMallocBytes(value);
}
void
JSRuntime::updateMallocCounter(size_t nbytes)
{
updateMallocCounter(NULL, nbytes);
}
void
JSRuntime::updateMallocCounter(JS::Zone *zone, size_t nbytes)
{
/* We tolerate any thread races when updating gcMallocBytes. */
ptrdiff_t oldCount = gcMallocBytes;
ptrdiff_t newCount = oldCount - ptrdiff_t(nbytes);
gcMallocBytes = newCount;
if (JS_UNLIKELY(newCount <= 0 && oldCount > 0))
onTooMuchMalloc();
else if (zone)
zone->updateMallocCounter(nbytes);
}
JS_FRIEND_API(void)
JSRuntime::onTooMuchMalloc()
{
TriggerGC(this, JS::gcreason::TOO_MUCH_MALLOC);
}
JS_FRIEND_API(void *)
JSRuntime::onOutOfMemory(void *p, size_t nbytes)
{
return onOutOfMemory(p, nbytes, NULL);
}
JS_FRIEND_API(void *)
JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
{
if (isHeapBusy())
return NULL;
/*
* Retry when we are done with the background sweeping and have stopped
* all the allocations and released the empty GC chunks.
*/
JS::ShrinkGCBuffers(this);
gcHelperThread.waitBackgroundSweepOrAllocEnd();
if (!p)
p = js_malloc(nbytes);
else if (p == reinterpret_cast<void *>(1))
p = js_calloc(nbytes);
else
p = js_realloc(p, nbytes);
if (p)
return p;
if (cx)
js_ReportOutOfMemory(cx);
return NULL;
}

1725
js/src/vm/Runtime.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1598,8 +1598,8 @@ js_IsDebugScopeSlow(JSObject *obj)
DebugScopes::DebugScopes(JSContext *cx)
: proxiedScopes(cx),
missingScopes(cx),
liveScopes(cx)
missingScopes(cx->runtime()),
liveScopes(cx->runtime())
{}
DebugScopes::~DebugScopes()

View File

@ -21,6 +21,7 @@
#include "jsobjinlines.h"
#include "vm/Shape-inl.h"
#include "vm/Runtime-inl.h"
using namespace js;
using namespace js::gc;