mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 604798: move JM global data to compartment, r=dvander
This commit is contained in:
parent
186692a59a
commit
0e7c06846a
@ -495,9 +495,6 @@ JSThreadData::init()
|
||||
return false;
|
||||
#ifdef JS_TRACER
|
||||
InitJIT(&traceMonitor);
|
||||
#endif
|
||||
#ifdef JS_METHODJIT
|
||||
jmData.Initialize();
|
||||
#endif
|
||||
dtoaState = js_NewDtoaState();
|
||||
if (!dtoaState) {
|
||||
@ -533,9 +530,6 @@ JSThreadData::finish()
|
||||
propertyCache.~PropertyCache();
|
||||
#if defined JS_TRACER
|
||||
FinishJIT(&traceMonitor);
|
||||
#endif
|
||||
#if defined JS_METHODJIT
|
||||
jmData.Finish();
|
||||
#endif
|
||||
stackSpace.finish();
|
||||
delete mathCache;
|
||||
|
@ -128,10 +128,6 @@ namespace JSC {
|
||||
|
||||
namespace js {
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
struct VMFrame;
|
||||
#endif
|
||||
|
||||
/* Tracer constants. */
|
||||
static const size_t MONITOR_N_GLOBAL_STATES = 4;
|
||||
static const size_t FRAGMENT_TABLE_SIZE = 512;
|
||||
@ -163,7 +159,7 @@ typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > FragStat
|
||||
#endif
|
||||
|
||||
namespace mjit {
|
||||
class CallStackIterator;
|
||||
class JaegerCompartment;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -227,34 +223,6 @@ struct TracerState
|
||||
~TracerState();
|
||||
};
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
namespace mjit {
|
||||
struct Trampolines
|
||||
{
|
||||
typedef void (*TrampolinePtr)();
|
||||
TrampolinePtr forceReturn;
|
||||
JSC::ExecutablePool *forceReturnPool;
|
||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||
TrampolinePtr forceReturnFast;
|
||||
JSC::ExecutablePool *forceReturnFastPool;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ThreadData
|
||||
{
|
||||
JSC::ExecutableAllocator *execAlloc;
|
||||
|
||||
// Trampolines for JIT code.
|
||||
Trampolines trampolines;
|
||||
|
||||
VMFrame *activeFrame;
|
||||
|
||||
bool Initialize();
|
||||
void Finish();
|
||||
};
|
||||
}
|
||||
#endif /* JS_METHODJIT */
|
||||
|
||||
/*
|
||||
* Storage for the execution state and store during trace execution. Generated
|
||||
* code depends on the fact that the globals begin |MAX_NATIVE_STACK_SLOTS|
|
||||
@ -1158,10 +1126,6 @@ struct JSThreadData {
|
||||
unsigned iterationCounter;
|
||||
#endif
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
js::mjit::ThreadData jmData;
|
||||
#endif
|
||||
|
||||
/* Lock-free hashed lists of scripts created by eval to garbage-collect. */
|
||||
JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE];
|
||||
|
||||
@ -1757,7 +1721,6 @@ struct JSRuntime {
|
||||
#define JS_GSN_CACHE(cx) (JS_THREAD_DATA(cx)->gsnCache)
|
||||
#define JS_PROPERTY_CACHE(cx) (JS_THREAD_DATA(cx)->propertyCache)
|
||||
#define JS_TRACE_MONITOR(cx) (JS_THREAD_DATA(cx)->traceMonitor)
|
||||
#define JS_METHODJIT_DATA(cx) (JS_THREAD_DATA(cx)->jmData)
|
||||
#define JS_SCRIPTS_TO_GC(cx) (JS_THREAD_DATA(cx)->scriptsToGC)
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2254,6 +2217,10 @@ struct JSContext
|
||||
js::Vector<JSGenerator *, 2, js::SystemAllocPolicy> genStack;
|
||||
|
||||
public:
|
||||
#ifdef JS_METHODJIT
|
||||
inline js::mjit::JaegerCompartment *jaegerCompartment();
|
||||
#endif
|
||||
|
||||
/* Return the generator object for the given generator frame. */
|
||||
JSGenerator *generatorFor(JSStackFrame *fp) const;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "jsxml.h"
|
||||
#include "jsregexp.h"
|
||||
#include "jsgc.h"
|
||||
#include "jscompartment.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -77,6 +78,13 @@ GetGlobalForScopeChain(JSContext *cx)
|
||||
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
inline js::mjit::JaegerCompartment *JSContext::jaegerCompartment()
|
||||
{
|
||||
return compartment->jaegerCompartment;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool
|
||||
JSContext::ensureGeneratorStackSpace()
|
||||
{
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "jsiter.h"
|
||||
#include "jsproxy.h"
|
||||
#include "jsscope.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/PolyIC.h"
|
||||
#include "methodjit/MonoIC.h"
|
||||
|
||||
@ -61,6 +62,9 @@ JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
|
||||
JSCompartment::~JSCompartment()
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
delete jaegerCompartment;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@ -74,7 +78,16 @@ JSCompartment::init()
|
||||
#ifdef JS_GCMETER
|
||||
memset(&compartmentStats, 0, sizeof(JSGCArenaStats) * FINALIZE_LIMIT);
|
||||
#endif
|
||||
return crossCompartmentWrappers.init();
|
||||
if (!crossCompartmentWrappers.init())
|
||||
return false;
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
if (!(jaegerCompartment = new mjit::JaegerCompartment))
|
||||
return false;
|
||||
return jaegerCompartment->Initialize();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -54,25 +54,34 @@
|
||||
#pragma warning(disable:4251) /* Silence warning about JS_FRIEND_API and data members. */
|
||||
#endif
|
||||
|
||||
struct JS_FRIEND_API(JSCompartment) {
|
||||
JSRuntime *rt;
|
||||
JSPrincipals *principals;
|
||||
js::gc::Chunk *chunk;
|
||||
namespace js {
|
||||
namespace mjit {
|
||||
class JaegerCompartment;
|
||||
}
|
||||
}
|
||||
|
||||
js::gc::ArenaList arenas[js::gc::FINALIZE_LIMIT];
|
||||
js::gc::FreeLists freeLists;
|
||||
struct JS_FRIEND_API(JSCompartment) {
|
||||
JSRuntime *rt;
|
||||
JSPrincipals *principals;
|
||||
js::gc::Chunk *chunk;
|
||||
|
||||
js::gc::ArenaList arenas[js::gc::FINALIZE_LIMIT];
|
||||
js::gc::FreeLists freeLists;
|
||||
|
||||
#ifdef JS_GCMETER
|
||||
js::gc::JSGCArenaStats compartmentStats[js::gc::FINALIZE_LIMIT];
|
||||
js::gc::JSGCArenaStats compartmentStats[js::gc::FINALIZE_LIMIT];
|
||||
#endif
|
||||
|
||||
void *data;
|
||||
bool marked;
|
||||
js::WrapperMap crossCompartmentWrappers;
|
||||
bool debugMode;
|
||||
void *data;
|
||||
bool marked;
|
||||
js::WrapperMap crossCompartmentWrappers;
|
||||
|
||||
/* List all scripts in this compartment. */
|
||||
JSCList scripts;
|
||||
#ifdef JS_METHODJIT
|
||||
js::mjit::JaegerCompartment *jaegerCompartment;
|
||||
#endif
|
||||
|
||||
bool debugMode; // true iff debug mode on
|
||||
JSCList scripts; // scripts in this compartment
|
||||
|
||||
/*
|
||||
* Weak references to lazily-created, well-known XML singletons.
|
||||
@ -81,8 +90,8 @@ struct JS_FRIEND_API(JSCompartment) {
|
||||
* the object graph usually associated with a JSContext's global object,
|
||||
* including the set of standard class objects. See jsxml.c for details.
|
||||
*/
|
||||
JSObject *anynameObject;
|
||||
JSObject *functionNamespaceObject;
|
||||
JSObject *anynameObject;
|
||||
JSObject *functionNamespaceObject;
|
||||
|
||||
JSCompartment(JSRuntime *cx);
|
||||
~JSCompartment();
|
||||
|
@ -131,7 +131,7 @@ js_SetDebugMode(JSContext *cx, JSBool debug)
|
||||
* correctness. We set the debug flag to false so that the caller
|
||||
* will not later attempt to use debugging features.
|
||||
*/
|
||||
mjit::Recompiler recompiler(cx, script);
|
||||
js::mjit::Recompiler recompiler(cx, script);
|
||||
if (!recompiler.recompile()) {
|
||||
cx->compartment->debugMode = JS_FALSE;
|
||||
return JS_FALSE;
|
||||
@ -281,7 +281,7 @@ JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
if (script->hasJITCode()) {
|
||||
mjit::Recompiler recompiler(cx, script);
|
||||
js::mjit::Recompiler recompiler(cx, script);
|
||||
if (!recompiler.recompile())
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -93,8 +93,7 @@ class BaseCompiler : public MacroAssemblerTypedefs
|
||||
public:
|
||||
static JSC::ExecutablePool *
|
||||
GetExecPool(JSContext *cx, size_t size) {
|
||||
ThreadData *jaegerData = &JS_METHODJIT_DATA(cx);
|
||||
JSC::ExecutablePool *pool = jaegerData->execAlloc->poolForSize(size);
|
||||
JSC::ExecutablePool *pool = cx->jaegerCompartment()->poolForSize(size);
|
||||
if (!pool)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return pool;
|
||||
|
@ -515,7 +515,7 @@ js_InternalThrow(VMFrame &f)
|
||||
cx->throwing = JS_FALSE;
|
||||
cx->fp()->setReturnValue(rval);
|
||||
return JS_FUNC_TO_DATA_PTR(void *,
|
||||
JS_METHODJIT_DATA(cx).trampolines.forceReturn);
|
||||
cx->jaegerCompartment()->forceReturnTrampoline());
|
||||
|
||||
case JSTRAP_THROW:
|
||||
cx->exception = rval;
|
||||
|
@ -116,17 +116,14 @@ extern "C" void JaegerTrampolineReturn();
|
||||
extern "C" void JS_FASTCALL
|
||||
PushActiveVMFrame(VMFrame &f)
|
||||
{
|
||||
f.previous = JS_METHODJIT_DATA(f.cx).activeFrame;
|
||||
JS_METHODJIT_DATA(f.cx).activeFrame = &f;
|
||||
|
||||
f.cx->jaegerCompartment()->pushActiveFrame(&f);
|
||||
f.regs.fp->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void*, JaegerTrampolineReturn));
|
||||
}
|
||||
|
||||
extern "C" void JS_FASTCALL
|
||||
PopActiveVMFrame(VMFrame &f)
|
||||
{
|
||||
JS_ASSERT(JS_METHODJIT_DATA(f.cx).activeFrame);
|
||||
JS_METHODJIT_DATA(f.cx).activeFrame = JS_METHODJIT_DATA(f.cx).activeFrame->previous;
|
||||
f.cx->jaegerCompartment()->popActiveFrame();
|
||||
}
|
||||
|
||||
extern "C" void JS_FASTCALL
|
||||
@ -683,7 +680,7 @@ JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
bool
|
||||
ThreadData::Initialize()
|
||||
JaegerCompartment::Initialize()
|
||||
{
|
||||
execAlloc = new JSC::ExecutableAllocator();
|
||||
if (!execAlloc)
|
||||
@ -700,13 +697,13 @@ ThreadData::Initialize()
|
||||
StubCallsForOp[i] = 0;
|
||||
#endif
|
||||
|
||||
activeFrame = NULL;
|
||||
activeFrame_ = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadData::Finish()
|
||||
JaegerCompartment::Finish()
|
||||
{
|
||||
TrampolineCompiler::release(&trampolines);
|
||||
delete execAlloc;
|
||||
|
@ -140,6 +140,70 @@ extern "C" void JaegerStubVeneer(void);
|
||||
#endif
|
||||
|
||||
namespace mjit {
|
||||
|
||||
/*
|
||||
* Trampolines to force returns from jit code.
|
||||
* See also TrampolineCompiler::generateForceReturn(Fast).
|
||||
*/
|
||||
struct Trampolines {
|
||||
typedef void (*TrampolinePtr)();
|
||||
|
||||
TrampolinePtr forceReturn;
|
||||
JSC::ExecutablePool *forceReturnPool;
|
||||
|
||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||
TrampolinePtr forceReturnFast;
|
||||
JSC::ExecutablePool *forceReturnFastPool;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Method JIT compartment data. Currently, there is exactly one per
|
||||
* JS compartment. It would be safe for multiple JS compartments to
|
||||
* share a JaegerCompartment as long as only one thread can enter
|
||||
* the JaegerCompartment at a time.
|
||||
*/
|
||||
class JaegerCompartment {
|
||||
JSC::ExecutableAllocator *execAlloc; // allocator for jit code
|
||||
Trampolines trampolines; // force-return trampolines
|
||||
VMFrame *activeFrame_; // current active VMFrame
|
||||
|
||||
friend struct JSCompartment;
|
||||
bool Initialize();
|
||||
void Finish();
|
||||
|
||||
~JaegerCompartment() { Finish(); }
|
||||
|
||||
public:
|
||||
JSC::ExecutablePool *poolForSize(size_t size) {
|
||||
return execAlloc->poolForSize(size);
|
||||
}
|
||||
|
||||
VMFrame *activeFrame() {
|
||||
return activeFrame_;
|
||||
}
|
||||
|
||||
void pushActiveFrame(VMFrame *f) {
|
||||
f->previous = activeFrame_;
|
||||
activeFrame_ = f;
|
||||
}
|
||||
|
||||
void popActiveFrame() {
|
||||
JS_ASSERT(activeFrame_);
|
||||
activeFrame_ = activeFrame_->previous;
|
||||
}
|
||||
|
||||
Trampolines::TrampolinePtr forceReturnTrampoline() const {
|
||||
return trampolines.forceReturn;
|
||||
}
|
||||
|
||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||
Trampolines::TrampolinePtr forceReturnFastTrampoline() const {
|
||||
return trampolines.forceReturnFast;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace ic {
|
||||
# if defined JS_POLYIC
|
||||
struct PICInfo;
|
||||
|
@ -143,7 +143,7 @@ Recompiler::recompile()
|
||||
}
|
||||
|
||||
/* Iterate over VMFrames saving the machine and scripted return. */
|
||||
for (VMFrame *f = JS_METHODJIT_DATA(cx).activeFrame;
|
||||
for (VMFrame *f = cx->jaegerCompartment()->activeFrame();
|
||||
f != NULL;
|
||||
f = f->previous) {
|
||||
|
||||
|
@ -1294,10 +1294,10 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc)
|
||||
f.cx->fp()->setReturnValue(rval);
|
||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||
JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
|
||||
f.cx->jaegerCompartment()->forceReturnFastTrampoline());
|
||||
#else
|
||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
|
||||
f.cx->jaegerCompartment()->forceReturnTrampoline());
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1334,10 +1334,10 @@ stubs::Trap(VMFrame &f, jsbytecode *pc)
|
||||
f.cx->fp()->setReturnValue(rval);
|
||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||
JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
|
||||
f.cx->jaegerCompartment()->forceReturnFastTrampoline());
|
||||
#else
|
||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
|
||||
f.cx->jaegerCompartment()->forceReturnTrampoline());
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user