Bug 665404 - Create JaegerCompartments lazily. r=luke.

This commit is contained in:
Nicholas Nethercote 2011-06-22 09:16:23 +10:00
parent 0a168b2cf6
commit 6ef6e862d2
8 changed files with 48 additions and 17 deletions

View File

@ -391,7 +391,7 @@ LeaveTraceIfArgumentsObject(JSContext *cx, JSObject *obj)
#ifdef JS_METHODJIT
inline js::mjit::JaegerCompartment *JSContext::jaegerCompartment()
{
return compartment->jaegerCompartment;
return compartment->jaegerCompartment();
}
#endif

View File

@ -77,7 +77,7 @@ JSCompartment::JSCompartment(JSRuntime *rt)
data(NULL),
active(false),
#ifdef JS_METHODJIT
jaegerCompartment(NULL),
jaegerCompartment_(NULL),
#endif
#if ENABLE_YARR_JIT
regExpAllocator(NULL),
@ -106,7 +106,7 @@ JSCompartment::~JSCompartment()
#endif
#ifdef JS_METHODJIT
Foreground::delete_(jaegerCompartment);
Foreground::delete_(jaegerCompartment_);
#endif
#ifdef JS_TRACER
@ -145,20 +145,31 @@ JSCompartment::init()
if (!backEdgeTable.init())
return false;
#ifdef JS_METHODJIT
jaegerCompartment = rt->new_<mjit::JaegerCompartment>();
if (!jaegerCompartment || !jaegerCompartment->Initialize())
return false;
#endif
return true;
}
#ifdef JS_METHODJIT
bool
JSCompartment::ensureJaegerCompartmentExists(JSContext *cx)
{
if (jaegerCompartment_)
return true;
mjit::JaegerCompartment *jc = cx->new_<mjit::JaegerCompartment>();
if (!jc)
return false;
if (!jc->Initialize()) {
cx->delete_(jc);
return false;
}
jaegerCompartment_ = jc;
return true;
}
size_t
JSCompartment::getMjitCodeSize() const
{
return jaegerCompartment->execAlloc()->getCodeSize();
return jaegerCompartment_ ? jaegerCompartment_->execAlloc()->getCodeSize() : 0;
}
#endif

View File

@ -412,13 +412,27 @@ struct JS_FRIEND_API(JSCompartment) {
js::WrapperMap crossCompartmentWrappers;
#ifdef JS_METHODJIT
js::mjit::JaegerCompartment *jaegerCompartment;
private:
/* This is created lazily because many compartments don't need it. */
js::mjit::JaegerCompartment *jaegerCompartment_;
/*
* This function is here so that xpconnect/src/xpcjsruntime.cpp doesn't
* need to see the declaration of JaegerCompartment, which would require
* #including MethodJIT.h into xpconnect/src/xpcjsruntime.cpp, which is
* difficult due to reasons explained in bug 483677.
*/
public:
bool hasJaegerCompartment() {
return !!jaegerCompartment_;
}
js::mjit::JaegerCompartment *jaegerCompartment() const {
JS_ASSERT(jaegerCompartment_);
return jaegerCompartment_;
}
bool ensureJaegerCompartmentExists(JSContext *cx);
size_t getMjitCodeSize() const;
#endif
WTF::BumpPointerAllocator *regExpAllocator;

View File

@ -481,7 +481,10 @@ RegExp::compileHelper(JSContext *cx, JSLinearString &pattern)
#if ENABLE_YARR_JIT && defined(JS_METHODJIT)
if (EnableYarrJIT(cx) && !yarrPattern.m_containsBackreferences) {
JSC::Yarr::JSGlobalData globalData(cx->compartment->jaegerCompartment->execAlloc());
bool ok = cx->compartment->ensureJaegerCompartmentExists(cx);
if (!ok)
return false;
JSC::Yarr::JSGlobalData globalData(cx->compartment->jaegerCompartment()->execAlloc());
JSC::Yarr::jitCompile(yarrPattern, &globalData, codeBlock);
if (!codeBlock.isFallBack())
return true;

View File

@ -147,7 +147,7 @@ class LinkerHelper : public JSC::LinkBuffer
// The pool is incref'd after this call, so it's necessary to release()
// on any failure.
JSScript *script = cx->fp()->script();
JSC::ExecutableAllocator *allocator = script->compartment->jaegerCompartment->execAlloc();
JSC::ExecutableAllocator *allocator = script->compartment->jaegerCompartment()->execAlloc();
JSC::ExecutablePool *pool;
m_code = executableAllocAndCopy(masm, allocator, &pool);
if (!m_code) {

View File

@ -247,6 +247,9 @@ mjit::TryCompile(JSContext *cx, StackFrame *fp)
if (fp->script()->hasSharps)
return Compile_Abort;
#endif
bool ok = cx->compartment->ensureJaegerCompartmentExists(cx);
if (!ok)
return Compile_Abort;
// Ensure that constructors have at least one slot.
if (fp->isConstructing() && !fp->script()->nslots)
@ -411,7 +414,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
JSC::ExecutablePool *execPool;
uint8 *result =
(uint8 *)script->compartment->jaegerCompartment->execAlloc()->alloc(codeSize, &execPool);
(uint8 *)script->compartment->jaegerCompartment()->execAlloc()->alloc(codeSize, &execPool);
if (!result) {
js_ReportOutOfMemory(cx);
return Compile_Error;

View File

@ -118,14 +118,14 @@ extern "C" void JaegerTrampolineReturn();
extern "C" void JS_FASTCALL
PushActiveVMFrame(VMFrame &f)
{
f.entryfp->script()->compartment->jaegerCompartment->pushActiveFrame(&f);
f.entryfp->script()->compartment->jaegerCompartment()->pushActiveFrame(&f);
f.regs.fp()->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void*, JaegerTrampolineReturn));
}
extern "C" void JS_FASTCALL
PopActiveVMFrame(VMFrame &f)
{
f.entryfp->script()->compartment->jaegerCompartment->popActiveFrame();
f.entryfp->script()->compartment->jaegerCompartment()->popActiveFrame();
}
extern "C" void JS_FASTCALL

View File

@ -128,7 +128,7 @@ Recompiler::recompile()
// Find all JIT'd stack frames to account for return addresses that will
// need to be patched after recompilation.
for (VMFrame *f = script->compartment->jaegerCompartment->activeFrame();
for (VMFrame *f = script->compartment->jaegerCompartment()->activeFrame();
f != NULL;
f = f->previous) {