mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
732e8395a8
commit
4eee9162ad
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
1674
js/src/jscntxt.h
1674
js/src/jscntxt.h
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
{
|
||||
|
@ -117,6 +117,7 @@ namespace js {
|
||||
class AutoDebugModeGC;
|
||||
class ArrayBufferObject;
|
||||
class DebugScopes;
|
||||
class WeakMapBase;
|
||||
}
|
||||
|
||||
struct JSCompartment
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -116,6 +116,7 @@ CPP_SOURCES += [
|
||||
'RegExpObject.cpp',
|
||||
'RegExpStatics.cpp',
|
||||
'RootMarking.cpp',
|
||||
'Runtime.cpp',
|
||||
'SPSProfiler.cpp',
|
||||
'ScopeObject.cpp',
|
||||
'SelfHosting.cpp',
|
||||
|
@ -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
|
||||
|
@ -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
81
js/src/vm/Runtime-inl.h
Normal 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
284
js/src/vm/Runtime.cpp
Normal 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
1725
js/src/vm/Runtime.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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()
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/Shape-inl.h"
|
||||
#include "vm/Runtime-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
Loading…
Reference in New Issue
Block a user