Clean up exec pool and LinkBuffer use (bug 601041, r=dmandelin).

This commit is contained in:
David Anderson 2010-10-01 09:47:44 -07:00
Родитель 46880287d4
Коммит 28a60376f5
13 изменённых файлов: 203 добавлений и 248 удалений

Просмотреть файл

@ -67,7 +67,7 @@ public:
// m_code uses m_executablePool, *not* executablePool, since this is no longer valid.
LinkBuffer(MacroAssembler* masm, ExecutablePool* executablePool)
: m_executablePool(executablePool)
, m_code(masm->m_assembler.executableCopy(m_executablePool))
, m_code(executableCopy(*masm, executablePool))
, m_size(masm->m_assembler.size())
#ifndef NDEBUG
, m_completed(false)
@ -75,6 +75,16 @@ public:
{
}
LinkBuffer()
: m_executablePool(NULL)
, m_code(NULL)
, m_size(0)
#ifndef NDEBUG
, m_completed(false)
#endif
{
}
LinkBuffer(uint8* ncode, size_t size)
: m_executablePool(NULL)
, m_code(ncode)
@ -179,7 +189,7 @@ public:
return CodeLocationLabel(code());
}
private:
protected:
// Keep this private! - the underlying code should only be obtained externally via
// finalizeCode() or finalizeCodeAddendum().
void* code()
@ -187,6 +197,11 @@ private:
return m_code;
}
void *executableCopy(MacroAssembler &masm, ExecutablePool *pool)
{
return masm.m_assembler.executableCopy(pool);
}
void performFinalization()
{
#ifndef NDEBUG

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* ***** BEGIN LICENSE BLOCK *****
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version

Просмотреть файл

@ -244,7 +244,7 @@ namespace mjit {
struct ThreadData
{
JSC::ExecutableAllocator *execPool;
JSC::ExecutableAllocator *execAlloc;
// Trampolines for JIT code.
Trampolines trampolines;

Просмотреть файл

@ -45,7 +45,7 @@
#include "jstl.h"
#include "assembler/assembler/MacroAssemblerCodeRef.h"
#include "assembler/assembler/MacroAssembler.h"
#include "assembler/assembler/RepatchBuffer.h"
#include "assembler/assembler/LinkBuffer.h"
#include "assembler/moco/MocoStubs.h"
#include "methodjit/MethodJIT.h"
#include "methodjit/MachineRegs.h"
@ -91,11 +91,11 @@ struct ImmIntPtr : public JSC::MacroAssembler::ImmPtr
class BaseAssembler : public JSC::MacroAssembler
{
struct CallPatch {
CallPatch(ptrdiff_t distance, void *fun)
: distance(distance), fun(fun)
CallPatch(Call cl, void *fun)
: call(cl), fun(fun)
{ }
ptrdiff_t distance;
Call call;
JSC::FunctionPtr fun;
};
@ -326,8 +326,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
Call call(void *fun) {
Call cl = JSC::MacroAssembler::call();
callPatches.append(CallPatch(differenceBetween(startLabel, cl), fun));
callPatches.append(CallPatch(cl, fun));
return cl;
}
@ -335,14 +334,10 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
return MacroAssembler::call(reg);
}
void finalize(uint8 *ncode) {
JSC::JITCode jc(ncode, size());
JSC::CodeBlock cb(jc);
JSC::RepatchBuffer repatchBuffer(&cb);
void finalize(JSC::LinkBuffer &linker) {
for (size_t i = 0; i < callPatches.length(); i++) {
JSC::MacroAssemblerCodePtr cp(ncode + callPatches[i].distance);
repatchBuffer.relink(JSC::CodeLocationCall(cp), callPatches[i].fun);
CallPatch &patch = callPatches[i];
linker.link(patch.call, JSC::FunctionPtr(patch.fun));
}
}
};

Просмотреть файл

@ -43,31 +43,89 @@
#include "jscntxt.h"
#include "jstl.h"
#include "assembler/assembler/MacroAssembler.h"
#include "assembler/assembler/LinkBuffer.h"
namespace js {
namespace mjit {
class CompilerBase
class BaseCompiler
{
protected:
typedef JSC::MacroAssembler::Label Label;
typedef JSC::MacroAssembler::ImmPtr ImmPtr;
typedef JSC::MacroAssembler::RegisterID RegisterID;
typedef JSC::MacroAssembler::Address Address;
typedef JSC::MacroAssembler MacroAssembler;
private:
JSContext *cx;
public:
CompilerBase(JSContext *cx)
: cx(cx)
BaseCompiler() : cx(NULL)
{ }
BaseCompiler(JSContext *cx) : cx(cx)
{ }
protected:
JSC::ExecutablePool *getExecPool(size_t size) {
typedef JSC::MacroAssembler::Label Label;
typedef JSC::MacroAssembler::Imm32 Imm32;
typedef JSC::MacroAssembler::ImmPtr ImmPtr;
typedef JSC::MacroAssembler::RegisterID RegisterID;
typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
typedef JSC::MacroAssembler::Address Address;
typedef JSC::MacroAssembler::BaseIndex BaseIndex;
typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
typedef JSC::MacroAssembler MacroAssembler;
typedef JSC::MacroAssembler::Jump Jump;
typedef JSC::MacroAssembler::JumpList JumpList;
typedef JSC::MacroAssembler::Call Call;
typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
typedef JSC::FunctionPtr FunctionPtr;
typedef JSC::RepatchBuffer RepatchBuffer;
typedef JSC::CodeBlock CodeBlock;
typedef JSC::CodeLocationLabel CodeLocationLabel;
typedef JSC::JITCode JITCode;
typedef JSC::ReturnAddressPtr ReturnAddressPtr;
typedef JSC::MacroAssemblerCodePtr MacroAssemblerCodePtr;
JSC::ExecutablePool *
getExecPool(size_t size) {
return BaseCompiler::GetExecPool(cx, size);
}
public:
static JSC::ExecutablePool *
GetExecPool(JSContext *cx, size_t size) {
ThreadData *jaegerData = &JS_METHODJIT_DATA(cx);
return jaegerData->execPool->poolForSize(size);
JSC::ExecutablePool *pool = jaegerData->execAlloc->poolForSize(size);
if (!pool)
js_ReportOutOfMemory(cx);
return pool;
}
};
// This class wraps JSC::LinkBuffer for Mozilla-specific memory handling.
// Every return |false| guarantees an OOM that has been correctly propagated,
// and should continue to propagate.
class LinkerHelper : public JSC::LinkBuffer
{
protected:
JSContext *cx;
public:
LinkerHelper(JSContext *cx) : cx(cx)
{ }
JSC::ExecutablePool *init(Assembler &masm) {
// The pool is incref'd after this call, so it's necessary to release()
// on any failure.
JSC::ExecutablePool *ep = BaseCompiler::GetExecPool(cx, masm.size());
if (!ep)
return ep;
m_size = masm.size();
m_code = executableCopy(masm, ep);
if (!m_code) {
ep->release();
js_ReportOutOfMemory(cx);
return NULL;
}
return ep;
}
};

Просмотреть файл

@ -75,7 +75,11 @@ static const char *OpcodeNames[] = {
#endif
mjit::Compiler::Compiler(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain)
: cx(cx), script(script), scopeChain(scopeChain), globalObj(scopeChain->getGlobal()), fun(fun),
: BaseCompiler(cx),
script(script),
scopeChain(scopeChain),
globalObj(scopeChain->getGlobal()),
fun(fun),
analysis(cx, script), jumpMap(NULL), frame(cx, script, masm),
branchPatches(ContextAllocPolicy(cx)),
#if defined JS_MONOIC
@ -450,21 +454,11 @@ mjit::Compiler::finishThisUp()
#endif /* JS_MONOIC */
for (size_t i = 0; i < callPatches.length(); i++) {
void *joinPoint = fullCode.locationOf(callPatches[i].joinPoint).executableAddress();
CallPatchInfo &patch = callPatches[i];
/* Patch the write of ncode in the hot path. */
JSC::CodeLocationDataLabelPtr fastNcode =
fullCode.locationOf(callPatches[i].fastNcodePatch);
JSC::RepatchBuffer fastRepatch((uint8*)fastNcode.executableAddress() - 32, 64, false);
fastRepatch.repatch(fastNcode, joinPoint);
/* Patch the write of ncode in the slow path. */
if (callPatches[i].hasSlowNcode) {
JSC::CodeLocationDataLabelPtr slowNcode =
stubCode.locationOf(callPatches[i].slowNcodePatch);
JSC::RepatchBuffer slowRepatch((uint8*)slowNcode.executableAddress() - 32, 64, false);
slowRepatch.repatch(slowNcode, joinPoint);
}
fullCode.patch(patch.fastNcodePatch, fullCode.locationOf(patch.joinPoint));
if (patch.hasSlowNcode)
stubCode.patch(patch.slowNcodePatch, fullCode.locationOf(patch.joinPoint));
}
#if defined JS_POLYIC
@ -525,8 +519,8 @@ mjit::Compiler::finishThisUp()
}
/* Patch all outgoing calls. */
masm.finalize(result);
stubcc.finalize(result + masm.size());
masm.finalize(fullCode);
stubcc.masm.finalize(stubCode);
JSC::ExecutableAllocator::makeExecutable(result, masm.size() + stubcc.size());
JSC::ExecutableAllocator::cacheFlush(result, masm.size() + stubcc.size());
@ -534,6 +528,7 @@ mjit::Compiler::finishThisUp()
script->ncode = (uint8 *)(result + masm.distanceOf(invokeLabel));
/* Build the table of call sites. */
script->jit->nCallSites = callSites.length();
if (callSites.length()) {
CallSite *callSiteList = (CallSite *)cursor;
cursor += sizeof(CallSite) * callSites.length();
@ -1691,13 +1686,6 @@ mjit::Compiler::labelOf(jsbytecode *pc)
return jumpMap[offs];
}
JSC::ExecutablePool *
mjit::Compiler::getExecPool(size_t size)
{
ThreadData *jaegerData = &JS_METHODJIT_DATA(cx);
return jaegerData->execPool->poolForSize(size);
}
uint32
mjit::Compiler::fullAtomIndex(jsbytecode *pc)
{

Просмотреть файл

@ -45,6 +45,7 @@
#include "BytecodeAnalyzer.h"
#include "MethodJIT.h"
#include "CodeGenIncludes.h"
#include "BaseCompiler.h"
#include "StubCompiler.h"
#include "MonoIC.h"
#include "PolyIC.h"
@ -52,21 +53,8 @@
namespace js {
namespace mjit {
class Compiler
class Compiler : public BaseCompiler
{
typedef JSC::MacroAssembler::Label Label;
typedef JSC::MacroAssembler::Imm32 Imm32;
typedef JSC::MacroAssembler::ImmPtr ImmPtr;
typedef JSC::MacroAssembler::RegisterID RegisterID;
typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
typedef JSC::MacroAssembler::Address Address;
typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
typedef JSC::MacroAssembler::BaseIndex BaseIndex;
typedef JSC::MacroAssembler::Jump Jump;
typedef JSC::MacroAssembler::JumpList JumpList;
typedef JSC::MacroAssembler::Call Call;
typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
struct BranchPatch {
BranchPatch(const Jump &j, jsbytecode *pc)
@ -208,7 +196,6 @@ class Compiler
bool ool;
};
JSContext *cx;
JSScript *script;
JSObject *scopeChain;
JSObject *globalObj;
@ -259,7 +246,6 @@ class Compiler
/* Non-emitting helpers. */
uint32 fullAtomIndex(jsbytecode *pc);
void jumpInScript(Jump j, jsbytecode *pc);
JSC::ExecutablePool *getExecPool(size_t size);
bool compareTwoValues(JSContext *cx, JSOp op, const Value &lhs, const Value &rhs);
void addCallSite(uint32 id, bool stub);

Просмотреть файл

@ -685,13 +685,13 @@ JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
bool
ThreadData::Initialize()
{
execPool = new JSC::ExecutableAllocator();
if (!execPool)
execAlloc = new JSC::ExecutableAllocator();
if (!execAlloc)
return false;
TrampolineCompiler tc(execPool, &trampolines);
TrampolineCompiler tc(execAlloc, &trampolines);
if (!tc.compile()) {
delete execPool;
delete execAlloc;
return false;
}
@ -709,7 +709,7 @@ void
ThreadData::Finish()
{
TrampolineCompiler::release(&trampolines);
delete execPool;
delete execAlloc;
#ifdef JS_METHODJIT_PROFILE_STUBS
FILE *fp = fopen("/tmp/stub-profiling", "wt");
# define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) \

Просмотреть файл

@ -277,28 +277,24 @@ SlowNewFromIC(VMFrame &f, uint32 index)
* scripted native, then a small stub is generated which inlines the native
* invocation.
*/
class CallCompiler
class CallCompiler : public BaseCompiler
{
VMFrame &f;
JSContext *cx;
CallICInfo &ic;
Value *vp;
bool callingNew;
public:
CallCompiler(VMFrame &f, CallICInfo &ic, bool callingNew)
: f(f), cx(f.cx), ic(ic), vp(f.regs.sp - (ic.argc + 2)), callingNew(callingNew)
: BaseCompiler(f.cx), f(f), ic(ic), vp(f.regs.sp - (ic.argc + 2)), callingNew(callingNew)
{
}
JSC::ExecutablePool *poolForSize(size_t size, CallICInfo::PoolIndex index)
{
mjit::ThreadData *jm = &JS_METHODJIT_DATA(cx);
JSC::ExecutablePool *ep = jm->execPool->poolForSize(size);
if (!ep) {
js_ReportOutOfMemory(f.cx);
JSC::ExecutablePool *ep = getExecPool(size);
if (!ep)
return NULL;
}
JS_ASSERT(!ic.pools[index]);
ic.pools[index] = ep;
return ep;

Просмотреть файл

@ -40,7 +40,9 @@
#include "StubCalls.h"
#include "CodeGenIncludes.h"
#include "StubCalls-inl.h"
#include "BaseCompiler.h"
#include "assembler/assembler/LinkBuffer.h"
#include "assembler/assembler/RepatchBuffer.h"
#include "jsscope.h"
#include "jsnum.h"
#include "jsobjinlines.h"
@ -58,21 +60,32 @@ using namespace js::mjit::ic;
/* Rough over-estimate of how much memory we need to unprotect. */
static const uint32 INLINE_PATH_LENGTH = 64;
typedef JSC::FunctionPtr FunctionPtr;
typedef JSC::RepatchBuffer RepatchBuffer;
typedef JSC::CodeBlock CodeBlock;
typedef JSC::CodeLocationLabel CodeLocationLabel;
typedef JSC::JITCode JITCode;
typedef JSC::MacroAssembler::Jump Jump;
typedef JSC::MacroAssembler::RegisterID RegisterID;
typedef JSC::MacroAssembler::Label Label;
typedef JSC::MacroAssembler::Imm32 Imm32;
typedef JSC::MacroAssembler::ImmPtr ImmPtr;
typedef JSC::MacroAssembler::Address Address;
typedef JSC::ReturnAddressPtr ReturnAddressPtr;
typedef JSC::MacroAssemblerCodePtr MacroAssemblerCodePtr;
// Helper class to simplify LinkBuffer usage in PIC stub generators.
// This guarantees correct OOM and refcount handling for buffers while they
// are instantiated and rooted.
class PICLinker : public LinkerHelper
{
ic::PICInfo &pic;
class PICStubCompiler
public:
PICLinker(JSContext *cx, ic::PICInfo &pic)
: LinkerHelper(cx), pic(pic)
{ }
bool init(Assembler &masm) {
JSC::ExecutablePool *pool = LinkerHelper::init(masm);
if (!pool)
return false;
if (!pic.execPools.append(pool)) {
pool->release();
js_ReportOutOfMemory(cx);
return false;
}
return true;
}
};
class PICStubCompiler : public BaseCompiler
{
protected:
const char *type;
@ -82,7 +95,7 @@ class PICStubCompiler
public:
PICStubCompiler(const char *type, VMFrame &f, JSScript *script, ic::PICInfo &pic)
: type(type), f(f), script(script), pic(pic)
: BaseCompiler(f.cx), type(type), f(f), script(script), pic(pic)
{ }
bool isCallOp() const
@ -115,19 +128,13 @@ class PICStubCompiler
return true;
}
JSC::ExecutablePool *getExecPool(size_t size)
{
mjit::ThreadData *jd = &JS_METHODJIT_DATA(f.cx);
return jd->execPool->poolForSize(size);
}
protected:
void spew(const char *event, const char *op)
{
#ifdef JS_METHODJIT_SPEW
JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
type, event, op, script->filename,
js_FramePCToLineNumber(f.cx, f.fp()));
js_FramePCToLineNumber(cx, f.fp()));
#endif
}
};
@ -308,8 +315,8 @@ class SetPropCompiler : public PICStubCompiler
bool generateStub(uint32 initialShape, const Shape *shape, bool adding)
{
/* Exits to the slow path. */
Vector<Jump, 8> slowExits(f.cx);
Vector<Jump, 8> otherGuards(f.cx);
Vector<Jump, 8> slowExits(cx);
Vector<Jump, 8> otherGuards(cx);
Assembler masm;
@ -488,15 +495,10 @@ class SetPropCompiler : public PICStubCompiler
pic.secondShapeGuard = 0;
}
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep || !pic.execPools.append(ep)) {
if (ep)
ep->release();
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
JSC::LinkBuffer buffer(&masm, ep);
buffer.link(shapeGuard, pic.slowPathStart);
if (slowExit.isSet())
buffer.link(slowExit.get(), pic.slowPathStart);
@ -556,7 +558,7 @@ class SetPropCompiler : public PICStubCompiler
return disable("ops set property hook");
#ifdef JS_THREADSAFE
if (!CX_OWNS_OBJECT_TITLE(f.cx, obj))
if (!CX_OWNS_OBJECT_TITLE(cx, obj))
return disable("shared object");
#endif
@ -564,12 +566,12 @@ class SetPropCompiler : public PICStubCompiler
JSObject *holder;
JSProperty *prop = NULL;
if (!obj->lookupProperty(f.cx, id, &holder, &prop))
if (!obj->lookupProperty(cx, id, &holder, &prop))
return false;
/* If the property exists but is on a prototype, treat as addprop. */
if (prop && holder != obj) {
AutoPropertyDropper dropper(f.cx, holder, prop);
AutoPropertyDropper dropper(cx, holder, prop);
const Shape *shape = (const Shape *) prop;
if (!holder->isNative())
@ -603,7 +605,7 @@ class SetPropCompiler : public PICStubCompiler
uint32 initialShape = obj->shape();
if (!obj->ensureClassReservedSlots(f.cx))
if (!obj->ensureClassReservedSlots(cx))
return false;
uint32 slots = obj->numSlots();
@ -623,7 +625,7 @@ class SetPropCompiler : public PICStubCompiler
}
const Shape *shape =
obj->putProperty(f.cx, id, getter, clasp->setProperty,
obj->putProperty(cx, id, getter, clasp->setProperty,
SHAPE_INVALID_SLOT, JSPROP_ENUMERATE, flags, 0);
if (!shape)
@ -660,7 +662,7 @@ class SetPropCompiler : public PICStubCompiler
return generateStub(initialShape, shape, true);
}
AutoPropertyDropper dropper(f.cx, holder, prop);
AutoPropertyDropper dropper(cx, holder, prop);
const Shape *shape = (const Shape *) prop;
if (pic.kind == ic::PICInfo::SETMETHOD && !shape->isMethod())
@ -803,15 +805,10 @@ class GetPropCompiler : public PICStubCompiler
masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep || !pic.execPools.append(ep)) {
if (ep)
ep->release();
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
JSC::LinkBuffer buffer(&masm, ep);
buffer.link(notArgs, pic.slowPathStart);
buffer.link(overridden, pic.slowPathStart);
buffer.link(done, pic.storeBack);
@ -846,15 +843,10 @@ class GetPropCompiler : public PICStubCompiler
masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep || !pic.execPools.append(ep)) {
if (ep)
ep->release();
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
JSC::LinkBuffer buffer(&masm, ep);
buffer.link(notArray, pic.slowPathStart);
buffer.link(oob, pic.slowPathStart);
buffer.link(done, pic.storeBack);
@ -881,12 +873,12 @@ class GetPropCompiler : public PICStubCompiler
JSObject *holder;
JSProperty *prop;
if (!obj->lookupProperty(f.cx, ATOM_TO_JSID(atom), &holder, &prop))
if (!obj->lookupProperty(cx, ATOM_TO_JSID(atom), &holder, &prop))
return false;
if (!prop)
return disable("property not found");
AutoPropertyDropper dropper(f.cx, holder, prop);
AutoPropertyDropper dropper(cx, holder, prop);
const Shape *shape = (const Shape *)prop;
if (holder != obj)
return disable("proto walk on String.prototype");
@ -937,21 +929,15 @@ class GetPropCompiler : public PICStubCompiler
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep || !pic.execPools.append(ep)) {
if (ep)
ep->release();
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
JSC::LinkBuffer patchBuffer(&masm, ep);
buffer.link(notString, pic.slowPathStart.labelAtOffset(pic.u.get.typeCheckOffset));
buffer.link(shapeMismatch, pic.slowPathStart);
buffer.link(done, pic.storeBack);
patchBuffer.link(notString, pic.slowPathStart.labelAtOffset(pic.u.get.typeCheckOffset));
patchBuffer.link(shapeMismatch, pic.slowPathStart);
patchBuffer.link(done, pic.storeBack);
CodeLocationLabel cs = patchBuffer.finalizeCodeAddendum();
CodeLocationLabel cs = buffer.finalizeCodeAddendum();
JaegerSpew(JSpew_PICs, "generate string call stub at %p\n",
cs.executableAddress());
@ -980,19 +966,14 @@ class GetPropCompiler : public PICStubCompiler
masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep || !pic.execPools.append(ep)) {
if (ep)
ep->release();
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
JSC::LinkBuffer patchBuffer(&masm, ep);
patchBuffer.link(notString, pic.slowPathStart.labelAtOffset(pic.u.get.typeCheckOffset));
patchBuffer.link(done, pic.storeBack);
buffer.link(notString, pic.slowPathStart.labelAtOffset(pic.u.get.typeCheckOffset));
buffer.link(done, pic.storeBack);
CodeLocationLabel start = patchBuffer.finalizeCodeAddendum();
CodeLocationLabel start = buffer.finalizeCodeAddendum();
JaegerSpew(JSpew_PICs, "generate string length stub at %p\n",
start.executableAddress());
@ -1048,7 +1029,7 @@ class GetPropCompiler : public PICStubCompiler
bool generateStub(JSObject *holder, const Shape *shape)
{
Vector<Jump, 8> shapeMismatches(f.cx);
Vector<Jump, 8> shapeMismatches(cx);
Assembler masm;
@ -1143,20 +1124,9 @@ class GetPropCompiler : public PICStubCompiler
}
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep) {
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
// :TODO: this can OOM
JSC::LinkBuffer buffer(&masm, ep);
if (!pic.execPools.append(ep)) {
ep->release();
js_ReportOutOfMemory(f.cx);
return false;
}
// The guard exit jumps to the original slow case.
for (Jump *pj = shapeMismatches.begin(); pj != shapeMismatches.end(); ++pj)
@ -1219,13 +1189,13 @@ class GetPropCompiler : public PICStubCompiler
JSObject *holder;
JSProperty *prop;
if (!aobj->lookupProperty(f.cx, ATOM_TO_JSID(atom), &holder, &prop))
if (!aobj->lookupProperty(cx, ATOM_TO_JSID(atom), &holder, &prop))
return false;
if (!prop)
return disable("lookup failed");
AutoPropertyDropper dropper(f.cx, holder, prop);
AutoPropertyDropper dropper(cx, holder, prop);
if (!holder->isNative())
return disable("non-native holder");
@ -1414,7 +1384,7 @@ class GetElemCompiler : public PICStubCompiler
bool generateStub(JSObject *holder, const Shape *shape)
{
JS_ASSERT(pic.u.get.idReg != pic.shapeReg);
Vector<Jump, 8> shapeMismatches(f.cx);
Vector<Jump, 8> shapeMismatches(cx);
Assembler masm;
@ -1506,20 +1476,9 @@ class GetElemCompiler : public PICStubCompiler
}
Jump done = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep) {
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
// :TODO: this can OOM
JSC::LinkBuffer buffer(&masm, ep);
if (!pic.execPools.append(ep)) {
ep->release();
js_ReportOutOfMemory(f.cx);
return false;
}
// The guard exit jumps to the original slow case.
for (Jump *pj = shapeMismatches.begin(); pj != shapeMismatches.end(); ++pj)
@ -1529,11 +1488,11 @@ class GetElemCompiler : public PICStubCompiler
buffer.link(done, pic.storeBack);
CodeLocationLabel cs = buffer.finalizeCodeAddendum();
#if DEBUG
char *chars = js_DeflateString(f.cx, id->chars(), id->length());
char *chars = js_DeflateString(cx, id->chars(), id->length());
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom 0x%x (\"%s\") shape 0x%x (%s: %d)\n",
type, cs.executableAddress(), id, chars, holder->shape(), script->filename,
js_FramePCToLineNumber(f.cx, f.fp()));
f.cx->free(chars);
js_FramePCToLineNumber(cx, f.fp()));
cx->free(chars);
#endif
PICRepatchBuffer repatcher(pic, pic.lastPathStart());
@ -1563,18 +1522,18 @@ class GetElemCompiler : public PICStubCompiler
return true;
}
JSAtom *atom = js_AtomizeString(f.cx, id, 0);
JSAtom *atom = js_AtomizeString(cx, id, 0);
if (!atom)
return false;
JSObject *holder;
JSProperty *prop;
if (!obj->lookupProperty(f.cx, ATOM_TO_JSID(atom), &holder, &prop))
if (!obj->lookupProperty(cx, ATOM_TO_JSID(atom), &holder, &prop))
return false;
if (!prop)
return disable("lookup failed");
AutoPropertyDropper dropper(f.cx, holder, prop);
AutoPropertyDropper dropper(cx, holder, prop);
if (!obj->isNative())
return disable("non-native obj");
@ -1681,7 +1640,7 @@ class ScopeNameCompiler : public PICStubCompiler
bool generateGlobalStub()
{
Assembler masm;
JumpList fails(f.cx);
JumpList fails(cx);
/* For GETXPROP, the object is already in objReg. */
if (pic.kind == ic::PICInfo::NAME)
@ -1724,20 +1683,9 @@ class ScopeNameCompiler : public PICStubCompiler
JS_ASSERT(masm.differenceBetween(failLabel, dbgJumpOffset) == SCOPENAME_JUMP_OFFSET);
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep) {
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
// :TODO: this can OOM
JSC::LinkBuffer buffer(&masm, ep);
if (!pic.execPools.append(ep)) {
ep->release();
js_ReportOutOfMemory(f.cx);
return false;
}
buffer.link(failJump, pic.slowPathStart);
buffer.link(done, pic.storeBack);
@ -1765,7 +1713,7 @@ class ScopeNameCompiler : public PICStubCompiler
bool generateCallStub()
{
Assembler masm;
Vector<Jump, 8, ContextAllocPolicy> fails(f.cx);
Vector<Jump, 8, ContextAllocPolicy> fails(cx);
/* For GETXPROP, the object is already in objReg. */
if (pic.kind == ic::PICInfo::NAME)
@ -1839,20 +1787,9 @@ class ScopeNameCompiler : public PICStubCompiler
Label failLabel = masm.label();
Jump failJump = masm.jump();
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep) {
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
// :TODO: this can OOM
JSC::LinkBuffer buffer(&masm, ep);
if (!pic.execPools.append(ep)) {
ep->release();
js_ReportOutOfMemory(f.cx);
return false;
}
buffer.link(failJump, pic.slowPathStart);
buffer.link(done, pic.storeBack);
@ -1873,7 +1810,7 @@ class ScopeNameCompiler : public PICStubCompiler
bool updateForName()
{
if (!js_FindProperty(f.cx, ATOM_TO_JSID(atom), &obj, &holder, &prop))
if (!js_FindProperty(cx, ATOM_TO_JSID(atom), &obj, &holder, &prop))
return false;
return update();
@ -1883,7 +1820,7 @@ class ScopeNameCompiler : public PICStubCompiler
{
obj = scopeChain;
if (!obj->lookupProperty(f.cx, ATOM_TO_JSID(atom), &holder, &prop))
if (!obj->lookupProperty(cx, ATOM_TO_JSID(atom), &holder, &prop))
return false;
return update();
@ -1924,8 +1861,6 @@ class ScopeNameCompiler : public PICStubCompiler
bool retrieve(Value *vp)
{
JSContext *cx = f.cx;
if (prop && (!obj->isNative() || !holder->isNative())) {
holder->dropProperty(cx, prop);
if (!obj->getProperty(cx, ATOM_TO_JSID(atom), vp))
@ -2001,7 +1936,7 @@ class BindNameCompiler : public PICStubCompiler
bool generateStub(JSObject *obj)
{
Assembler masm;
js::Vector<Jump, 8, ContextAllocPolicy> fails(f.cx);
js::Vector<Jump, 8, ContextAllocPolicy> fails(cx);
/* Guard on the shape of the scope chain. */
masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfScopeChain()), pic.objReg);
@ -2039,20 +1974,9 @@ class BindNameCompiler : public PICStubCompiler
JS_ASSERT(masm.differenceBetween(failLabel, dbgStubJumpOffset) == BINDNAME_STUB_JUMP_OFFSET);
JSC::ExecutablePool *ep = getExecPool(masm.size());
if (!ep) {
js_ReportOutOfMemory(f.cx);
PICLinker buffer(cx, pic);
if (!buffer.init(masm))
return false;
}
// :TODO: this can OOM
JSC::LinkBuffer buffer(&masm, ep);
if (!pic.execPools.append(ep)) {
ep->release();
js_ReportOutOfMemory(f.cx);
return false;
}
buffer.link(failJump, pic.slowPathStart);
buffer.link(done, pic.storeBack);
@ -2078,7 +2002,7 @@ class BindNameCompiler : public PICStubCompiler
{
JS_ASSERT(scopeChain->getParent());
JSObject *obj = js_FindIdentifierBase(f.cx, scopeChain, ATOM_TO_JSID(atom));
JSObject *obj = js_FindIdentifierBase(cx, scopeChain, ATOM_TO_JSID(atom));
if (!obj)
return obj;

Просмотреть файл

@ -199,12 +199,6 @@ StubCompiler::fixCrossJumps(uint8 *ncode, size_t offset, size_t total)
slow.link(joins[i].from, fast.locationOf(joins[i].to));
}
void
StubCompiler::finalize(uint8 *ncode)
{
masm.finalize(ncode);
}
JSC::MacroAssembler::Call
StubCompiler::vpInc(JSOp op, uint32 depth)
{

Просмотреть файл

@ -158,7 +158,6 @@ class StubCompiler
/* Finish all native code patching. */
void fixCrossJumps(uint8 *ncode, size_t offset, size_t total);
void finalize(uint8 *ncode);
void jumpInScript(Jump j, jsbytecode *target);
void crossJump(Jump j, Label l);

Просмотреть файл

@ -100,8 +100,8 @@ TrampolineCompiler::compileTrampoline(Trampolines::TrampolinePtr *where, JSC::Ex
return false;
JSC::LinkBuffer buffer(&masm, *pool);
masm.finalize(buffer);
uint8 *result = (uint8*)buffer.finalizeCodeAddendum().dataLocation();
masm.finalize(result);
*where = JS_DATA_TO_FUNC_PTR(Trampolines::TrampolinePtr, result + masm.distanceOf(entry));
return true;