Bug 843733 - IonMonkey ARM, Allocate assembly template in temporary space. r=dvander,mrosenberg

This commit is contained in:
Nicolas B. Pierron 2013-03-04 12:43:53 -08:00
parent 5eb0209309
commit 0902f1e95b
6 changed files with 54 additions and 31 deletions

View File

@ -715,7 +715,7 @@ bool
GetPropertyIC::attachReadSlot(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
HandleShape shape)
{
MacroAssembler masm;
MacroAssembler masm(cx);
RepatchLabel failures;
GetNativePropertyStub getprop;
@ -732,7 +732,7 @@ GetPropertyIC::attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj,
JSObject *holder, HandleShape shape,
const SafepointIndex *safepointIndex, void *returnAddr)
{
MacroAssembler masm;
MacroAssembler masm(cx);
RepatchLabel failures;
JS_ASSERT(!idempotent());
@ -763,7 +763,7 @@ GetPropertyIC::attachArrayLength(JSContext *cx, IonScript *ion, JSObject *obj)
JS_ASSERT(!idempotent());
Label failures;
MacroAssembler masm;
MacroAssembler masm(cx);
// Guard object is a dense array.
RootedObject globalObj(cx, &script->global());
@ -814,7 +814,7 @@ GetPropertyIC::attachTypedArrayLength(JSContext *cx, IonScript *ion, JSObject *o
JS_ASSERT(!idempotent());
Label failures;
MacroAssembler masm;
MacroAssembler masm(cx);
Register tmpReg;
if (output().hasValue()) {
@ -1062,7 +1062,7 @@ bool
SetPropertyIC::attachNativeExisting(JSContext *cx, IonScript *ion,
HandleObject obj, HandleShape shape)
{
MacroAssembler masm;
MacroAssembler masm(cx);
RepatchLabel exit_;
CodeOffsetJump exitOffset =
@ -1103,7 +1103,7 @@ SetPropertyIC::attachSetterCall(JSContext *cx, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr)
{
MacroAssembler masm;
MacroAssembler masm(cx);
// Need to set correct framePushed on the masm so that exit frame descriptors are
// properly constructed.
@ -1266,7 +1266,7 @@ SetPropertyIC::attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj,
HandleShape oldShape, HandleShape newShape,
HandleShape propShape)
{
MacroAssembler masm;
MacroAssembler masm(cx);
Label failures;
@ -1526,7 +1526,7 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
RepatchLabel failures;
Label nonRepatchFailures;
MacroAssembler masm;
MacroAssembler masm(cx);
// Guard on the index value.
ValueOperand val = index().reg().valueReg();
@ -1546,7 +1546,7 @@ GetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, c
JS_ASSERT(idval.isInt32());
Label failures;
MacroAssembler masm;
MacroAssembler masm(cx);
Register scratchReg = output().scratchReg().gpr();
JS_ASSERT(scratchReg != InvalidReg);
@ -1615,7 +1615,7 @@ GetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, JSObject *o
JS_ASSERT(idval.isInt32());
Label failures;
MacroAssembler masm;
MacroAssembler masm(cx);
// The array type is the object within the table of typed array classes.
int arrayType = TypedArray::type(obj);
@ -1757,7 +1757,7 @@ BindNameIC::attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain)
{
JS_ASSERT(scopeChain->isGlobal());
MacroAssembler masm;
MacroAssembler masm(cx);
// Guard on the scope chain.
RepatchLabel exit_;
@ -1827,7 +1827,7 @@ BindNameIC::attachNonGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain,
{
JS_ASSERT(IsCacheableNonGlobalScope(scopeChain));
MacroAssembler masm;
MacroAssembler masm(cx);
// Guard on the shape of the scope chain.
RepatchLabel failures;
@ -1926,7 +1926,7 @@ bool
NameIC::attach(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject holder, HandleShape shape)
{
AssertCanGC();
MacroAssembler masm;
MacroAssembler masm(cx);
Label failures;
Register scratchReg = outputReg().valueReg().scratchReg();
@ -2048,7 +2048,7 @@ bool
CallsiteCloneIC::attach(JSContext *cx, IonScript *ion, HandleFunction original,
HandleFunction clone)
{
MacroAssembler masm;
MacroAssembler masm(cx);
// Guard against object identity on the original.
RepatchLabel exit;

View File

@ -83,12 +83,13 @@ class MacroAssembler : public MacroAssemblerSpecific
if (!GetIonContext()->temp)
alloc_.construct(cx);
#ifdef JS_CPU_ARM
initWithAllocator();
m_buffer.id = GetIonContext()->getNextAssemblerId();
#endif
}
// This constructor should only be used when there is no IonContext active
// (for example, Trampoline-$(ARCH).cpp).
// (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp).
MacroAssembler(JSContext *cx)
: enoughMemory_(true),
sps_(NULL) // no need for instrumentation in trampolines and such
@ -97,6 +98,7 @@ class MacroAssembler : public MacroAssemblerSpecific
ionContext_.construct(cx, cx->compartment, (js::ion::TempAllocator *)NULL);
alloc_.construct(cx);
#ifdef JS_CPU_ARM
initWithAllocator();
m_buffer.id = GetIonContext()->getNextAssemblerId();
#endif
}

View File

@ -1221,6 +1221,13 @@ class Assembler
dtmActive(false),
dtmCond(Always)
{
}
// We need to wait until an AutoIonContextAlloc is created by the
// IonMacroAssembler, before allocating any space.
void initWithAllocator() {
m_buffer.initWithAllocator();
// Set up the backwards double region
new (&pools_[2]) Pool (1024, 8, 4, 8, 8, true);
// Set up the backwards 32 bit region
@ -1236,6 +1243,7 @@ class Assembler
}
}
}
static Condition InvertCondition(Condition cond);
// MacroAssemblers hold onto gcthings, so they are traced by the GC.

View File

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=4 sw=4 et tw=99:
*
@ -202,7 +203,6 @@ IonCode *
IonRuntime::generateInvalidator(JSContext *cx)
{
// See large comment in x86's IonRuntime::generateInvalidator.
AutoIonContextAlloc aica(cx);
MacroAssembler masm(cx);
//masm.as_bkpt();
// At this point, one of two things has happened.
@ -437,7 +437,7 @@ GenerateBailoutThunk(MacroAssembler &masm, uint32_t frameClass)
IonCode *
IonRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass)
{
MacroAssembler masm;
MacroAssembler masm(cx);
Label bailout;
for (size_t i = 0; i < BAILOUT_TABLE_SIZE; i++)
@ -453,7 +453,7 @@ IonRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass)
IonCode *
IonRuntime::generateBailoutHandler(JSContext *cx)
{
MacroAssembler masm;
MacroAssembler masm(cx);
GenerateBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID);
Linker linker(masm);
@ -472,7 +472,7 @@ IonRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
return p->value;
// Generate a separated code for the wrapper.
MacroAssembler masm;
MacroAssembler masm(cx);
GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
// Wrapper register set is a superset of Volatile register set.
@ -611,7 +611,7 @@ IonRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
IonCode *
IonRuntime::generatePreBarrier(JSContext *cx, MIRType type)
{
MacroAssembler masm;
MacroAssembler masm(cx);
RegisterSet save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
FloatRegisterSet(FloatRegisters::VolatileMask));

View File

@ -75,9 +75,11 @@ struct BufferSlice : public InlineForwardListNode<BufferSlice<SliceSize> > {
};
template<int SliceSize, class Inst>
struct AssemblerBuffer {
struct AssemblerBuffer
: public IonAllocPolicy
{
public:
AssemblerBuffer() : head(NULL), tail(NULL), m_bail(false), m_oom(false), bufferSize(0) {}
AssemblerBuffer() : head(NULL), tail(NULL), m_oom(false), m_bail(false), bufferSize(0) {}
protected:
typedef BufferSlice<SliceSize> Slice;
typedef AssemblerBuffer<SliceSize, Inst> AssemblerBuffer_;
@ -95,7 +97,7 @@ struct AssemblerBuffer {
return !(size() & (alignment - 1));
}
virtual Slice *newSlice() {
Slice *tmp = static_cast<Slice*>(malloc(sizeof(Slice)));
Slice *tmp = static_cast<Slice*>(malloc_(sizeof(Slice)));
if (!tmp) {
m_oom = true;
return NULL;

View File

@ -14,7 +14,9 @@ namespace js {
namespace ion {
typedef Vector<BufferOffset, 512, IonAllocPolicy> LoadOffsets;
struct Pool {
struct Pool
: public IonAllocPolicy
{
const int maxOffset;
const int immSize;
const int instSize;
@ -50,7 +52,7 @@ struct Pool {
: maxOffset(maxOffset_), immSize(immSize_), instSize(instSize),
bias(bias_), alignment(alignment_),
isBackref(isBackref_), canDedup(canDedup_), other(other_),
poolData(static_cast<uint8_t *>(malloc(8*immSize))), numEntries(0),
poolData(static_cast<uint8_t *>(malloc_(8*immSize))), numEntries(0),
buffSize(8), loadOffsets(), limitingUser(), limitingUsee(INT_MIN)
{
}
@ -128,7 +130,8 @@ struct Pool {
uint32_t insertEntry(uint8_t *data, BufferOffset off) {
if (numEntries == buffSize) {
buffSize <<= 1;
poolData = static_cast<uint8_t*>(realloc(poolData, immSize * buffSize));
poolData = static_cast<uint8_t*>(realloc_(poolData, immSize * numEntries,
immSize * buffSize));
if (poolData == NULL) {
buffSize = 0;
return -1;
@ -142,7 +145,7 @@ struct Pool {
bool reset() {
numEntries = 0;
buffSize = 8;
poolData = static_cast<uint8_t*>(malloc(buffSize * immSize));
poolData = static_cast<uint8_t*>(malloc_(buffSize * immSize));
if (poolData == NULL)
return false;
other = new Pool(other->maxOffset, other->immSize, other->instSize, other->bias,
@ -345,7 +348,7 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
}
virtual BufferSlice *newSlice() {
BufferSlice *tmp = static_cast<BufferSlice*>(malloc(sizeof(BufferSlice)));
BufferSlice *tmp = static_cast<BufferSlice*>(this->malloc_(sizeof(BufferSlice)));
if (!tmp) {
this->m_oom = true;
return NULL;
@ -359,7 +362,7 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
footerSize(footerSize_),
pools(pools_),
instBufferAlign(instBufferAlign_), numDumps(0),
poolInfo(static_cast<PoolInfo*>(calloc(sizeof(PoolInfo), 1 << logBasePoolInfo))),
poolInfo(NULL),
poolSize(0), canNotPlacePool(0), inBackref(false),
perforatedNode(NULL), id(-1)
{
@ -367,6 +370,13 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
entryCount[idx] = 0;
}
}
// We need to wait until an AutoIonContextAlloc is created by the
// IonMacroAssembler, before allocating any space.
void initWithAllocator() {
poolInfo = static_cast<PoolInfo*>(this->calloc_(sizeof(PoolInfo) * (1 << logBasePoolInfo)));
}
const PoolInfo & getInfo(int x) const {
static const PoolInfo nil = {0,0,0};
if (x < 0 || x >= numDumps)
@ -661,7 +671,8 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
JS_ASSERT(perforatedNode != NULL);
if (numDumps >= (1<<logBasePoolInfo) && (numDumps & (numDumps-1)) == 0) {
// need to resize.
poolInfo = static_cast<PoolInfo*>(realloc(poolInfo, sizeof(PoolInfo) * numDumps * 2));
poolInfo = static_cast<PoolInfo*>(realloc_(poolInfo, sizeof(PoolInfo) * numDumps,
sizeof(PoolInfo) * numDumps * 2));
if (poolInfo == NULL) {
this->fail_oom();
return;
@ -758,7 +769,7 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
}
// bind the current pool to the perforation point.
Pool **tmp = &perforatedNode->data;
*tmp = static_cast<Pool*>(malloc(sizeof(Pool) * numPoolKinds));
*tmp = static_cast<Pool*>(this->malloc_(sizeof(Pool) * numPoolKinds));
if (tmp == NULL) {
this->fail_oom();
return;