Bug 588021: Port SETPROP PIC for ARM. (r=dmandelin)

This commit is contained in:
Chris Leary 2011-01-13 22:41:42 -08:00
parent 388045ee8b
commit 0422829982
8 changed files with 245 additions and 193 deletions

View File

@ -2914,6 +2914,7 @@ i?86-*)
ENABLE_MONOIC=1
ENABLE_POLYIC=1
ENABLE_POLYIC_GETPROP=1
ENABLE_POLYIC_SETPROP=1
ENABLE_POLYIC_BIND=1
ENABLE_POLYIC_NAME=1
AC_DEFINE(JS_CPU_X86)
@ -2926,6 +2927,7 @@ x86_64*-*)
ENABLE_MONOIC=1
ENABLE_POLYIC=1
ENABLE_POLYIC_GETPROP=1
ENABLE_POLYIC_SETPROP=1
ENABLE_POLYIC_BIND=1
ENABLE_POLYIC_NAME=1
AC_DEFINE(JS_CPU_X64)
@ -2938,6 +2940,7 @@ arm*-*)
ENABLE_MONOIC=1
ENABLE_POLYIC=1
ENABLE_POLYIC_GETPROP=1
ENABLE_POLYIC_SETPROP=1
ENABLE_POLYIC_BIND=1
ENABLE_POLYIC_NAME=1
AC_DEFINE(JS_CPU_ARM)

View File

@ -48,6 +48,12 @@
#include "assembler/jit/ExecutableAllocator.h"
#include <limits.h>
#if defined JS_CPU_ARM
# define POST_INST_OFFSET(__expr) ((__expr) - sizeof(ARMWord))
#else
# define POST_INST_OFFSET(__expr) (__expr)
#endif
namespace js {
namespace mjit {

View File

@ -3372,6 +3372,9 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
PICGenInfo pic(kind, op, usePropCache);
pic.atom = atom;
RESERVE_IC_SPACE(masm);
RESERVE_OOL_SPACE(stubcc.masm);
/* Guard that the type is an object. */
Jump typeCheck;
if (!lhs->isTypeKnown()) {
@ -3415,11 +3418,11 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
/* Guard on shape. */
masm.loadShape(objReg, shapeReg);
pic.shapeGuard = masm.label();
DataLabel32 inlineShapeOffsetLabel;
DataLabel32 inlineShapeData;
Jump j = masm.branch32WithPatch(Assembler::NotEqual, shapeReg,
Imm32(int32(JSObjectMap::INVALID_SHAPE)),
inlineShapeOffsetLabel);
DBGLABEL(dbgInlineShapeJump);
inlineShapeData);
Label afterInlineShapeJump = masm.label();
/* Slow path. */
{
@ -3428,24 +3431,16 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
stubcc.leave();
passICAddress(&pic);
pic.slowPathCall = OOL_STUBCALL(ic::SetProp);
CHECK_OOL_SPACE();
}
/* Load dslots. */
#if defined JS_NUNBOX32
DBGLABEL(dbgDslots);
#elif defined JS_PUNBOX64
Label dslotsLoadLabel = masm.label();
#endif
masm.loadPtr(Address(objReg, offsetof(JSObject, slots)), objReg);
Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, offsetof(JSObject, slots)),
objReg);
/* Store RHS into object slot. */
Address slot(objReg, 1 << 24);
#if defined JS_NUNBOX32
Label dbgInlineStoreType = masm.storeValue(vr, slot);
#elif defined JS_PUNBOX64
masm.storeValue(vr, slot);
#endif
DBGLABEL(dbgAfterValueStore);
Label inlineValueStore = masm.storeValueWithAddressOffsetPatch(vr, slot);
pic.fastPathRejoin = masm.label();
frame.freeReg(objReg);
@ -3464,27 +3459,13 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
RETURN_IF_OOM(false);
SetPropLabels &labels = pic.setPropLabels();
labels.setInlineShapeOffset(masm.differenceBetween(pic.shapeGuard, inlineShapeOffsetLabel));
#if defined JS_PUNBOX64
labels.setDslotsLoadOffset(masm.differenceBetween(pic.fastPathRejoin, dslotsLoadLabel));
JS_ASSERT(masm.differenceBetween(inlineShapeOffsetLabel, dbgInlineShapeJump) == SETPROP_INLINE_SHAPE_JUMP);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgAfterValueStore) == SETPROP_INLINE_STORE_VALUE);
#elif defined JS_NUNBOX32
JS_ASSERT(masm.differenceBetween(pic.shapeGuard, dbgInlineShapeJump) == SETPROP_INLINE_SHAPE_JUMP);
if (vr.isConstant()) {
/* Constants are offset inside the opcode by 4. */
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgInlineStoreType)-4 == SETPROP_INLINE_STORE_CONST_TYPE);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgAfterValueStore)-4 == SETPROP_INLINE_STORE_CONST_DATA);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgDslots) == SETPROP_DSLOTS_BEFORE_CONSTANT);
} else if (vr.isTypeKnown()) {
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgInlineStoreType)-4 == SETPROP_INLINE_STORE_KTYPE_TYPE);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgAfterValueStore) == SETPROP_INLINE_STORE_KTYPE_DATA);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgDslots) == SETPROP_DSLOTS_BEFORE_KTYPE);
} else {
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgInlineStoreType) == SETPROP_INLINE_STORE_DYN_TYPE);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgAfterValueStore) == SETPROP_INLINE_STORE_DYN_DATA);
JS_ASSERT(masm.differenceBetween(pic.fastPathRejoin, dbgDslots) == SETPROP_DSLOTS_BEFORE_DYNAMIC);
}
labels.setInlineShapeData(masm, pic.shapeGuard, inlineShapeData);
labels.setDslotsLoad(masm, pic.fastPathRejoin, dslotsLoadLabel, vr);
labels.setInlineValueStore(masm, pic.fastPathRejoin, inlineValueStore, vr);
#ifdef JS_CPU_X64
labels.setInlineShapeJump(masm, inlineShapeData, afterInlineShapeJump);
#else
labels.setInlineShapeJump(masm, pic.shapeGuard, afterInlineShapeJump);
#endif
pics.append(pic);
@ -3492,6 +3473,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
}
#endif
#ifdef JS_POLYIC_NAME
void
mjit::Compiler::jsop_name(JSAtom *atom)

View File

@ -43,16 +43,7 @@
#if !defined jsjaeger_ic_labels_h__ && defined JS_METHODJIT
#define jsjaeger_ic_labels_h__
#include "jscntxt.h"
#include "jstl.h"
#include "jsvector.h"
#include "assembler/assembler/MacroAssembler.h"
#include "assembler/assembler/CodeLocation.h"
#include "methodjit/CodeGenIncludes.h"
#include "methodjit/MethodJIT.h"
#include "BaseAssembler.h"
#include "RematInfo.h"
#include "BaseCompiler.h"
#include "methodjit/BaseCompiler.h"
class ICOffsetInitializer {
public:
@ -134,12 +125,12 @@ struct GetPropLabels : MacroAssemblerTypedefs {
}
CodeLocationJump getInlineTypeJump(CodeLocationLabel fastPathStart) {
#if defined JS_CPU_X86 || defined JS_CPU_X64
return fastPathStart.jumpAtOffset(getInlineTypeJumpOffset());
#elif defined JS_CPU_ARM
/* Type check is after the testObject, so offset by one instruction to get the jump. */
return fastPathStart.jumpAtOffset(getInlineTypeJumpOffset() - sizeof(ARMWord));
#endif
}
void setStubShapeJump(MacroAssembler &masm, Label stubStart, Label shapeJump) {
int offset = masm.differenceBetween(stubStart, shapeJump);
setStubShapeJumpOffset(offset);
}
/* Offset-based interface */
@ -158,7 +149,7 @@ struct GetPropLabels : MacroAssemblerTypedefs {
JS_ASSERT(offset == inlineShapeOffset);
}
void setStubShapeJump(int offset) {
void setStubShapeJumpOffset(int offset) {
#ifdef JS_HAS_IC_LABELS
stubShapeJumpOffset = offset;
#endif
@ -166,12 +157,10 @@ struct GetPropLabels : MacroAssemblerTypedefs {
}
int getInlineShapeJumpOffset() {
#if defined JS_CPU_X86
return INLINE_SHAPE_JUMP;
#elif defined JS_CPU_X64
#if defined JS_CPU_X64
return getInlineShapeOffset() + INLINE_SHAPE_JUMP;
#elif defined JS_CPU_ARM
return INLINE_SHAPE_JUMP - sizeof(ARMWord);
#else
return POST_INST_OFFSET(INLINE_SHAPE_JUMP);
#endif
}
@ -183,7 +172,7 @@ struct GetPropLabels : MacroAssemblerTypedefs {
#if defined JS_CPU_X86 || defined JS_CPU_X64
return INLINE_TYPE_JUMP;
#elif defined JS_CPU_ARM
return inlineTypeJumpOffset;
return POST_INST_OFFSET(inlineTypeJumpOffset);
#endif
}
@ -203,11 +192,7 @@ struct GetPropLabels : MacroAssemblerTypedefs {
return dslotsLoadOffset;
}
int getStubShapeJumpOffset() {
#if defined JS_CPU_X86 || defined JS_CPU_X64
return stubShapeJumpOffset;
#elif defined JS_CPU_ARM
return stubShapeJumpOffset - sizeof(ARMWord);
#endif
return POST_INST_OFFSET(stubShapeJumpOffset);
}
private:
@ -243,63 +228,182 @@ struct GetPropLabels : MacroAssemblerTypedefs {
};
/* SetPropCompiler */
struct SetPropLabels {
struct SetPropLabels : MacroAssemblerTypedefs {
friend class ::ICOffsetInitializer;
#ifdef JS_PUNBOX64
void setDslotsLoadOffset(int offset) {
# ifdef JS_HAS_IC_LABELS
void setInlineValueStore(MacroAssembler &masm, Label fastPathRejoin, Label inlineValueStore,
const ValueRemat &vr) {
int offset = masm.differenceBetween(fastPathRejoin, inlineValueStore);
setInlineValueStoreOffset(offset, vr.isConstant(), vr.isTypeKnown());
}
CodeLocationLabel getInlineValueStore(CodeLocationLabel fastPathRejoin, const ValueRemat &vr) {
return fastPathRejoin.labelAtOffset(getInlineValueStoreOffset(vr.isConstant(),
vr.isTypeKnown()));
}
void setInlineShapeData(MacroAssembler &masm, Label shapeGuard, DataLabel32 inlineShapeData) {
int offset = masm.differenceBetween(shapeGuard, inlineShapeData);
setInlineShapeDataOffset(offset);
}
CodeLocationDataLabel32 getInlineShapeData(CodeLocationLabel fastPathStart, int shapeGuardOffset) {
return fastPathStart.dataLabel32AtOffset(shapeGuardOffset + getInlineShapeDataOffset());
}
CodeLocationJump getInlineShapeJump(CodeLocationLabel fastPathStart, int shapeGuardOffset) {
return fastPathStart.jumpAtOffset(shapeGuardOffset + getInlineShapeJumpOffset());
}
void setDslotsLoad(MacroAssembler &masm, Label fastPathRejoin, Label beforeLoad,
const ValueRemat &rhs) {
int offset = masm.differenceBetween(fastPathRejoin, beforeLoad);
setDslotsLoadOffset(offset, rhs.isConstant(), rhs.isTypeKnown());
}
CodeLocationInstruction getDslotsLoad(CodeLocationLabel fastPathRejoin, const ValueRemat &vr) {
return fastPathRejoin.instructionAtOffset(getDslotsLoadOffset(vr));
}
/*
* Note: on x64, the base is the inlineShapeLabel DataLabel32, whereas on other
* platforms the base is the shapeGuard.
*/
template <typename T>
void setInlineShapeJump(MacroAssembler &masm, T base, Label afterJump) {
setInlineShapeJumpOffset(masm.differenceBetween(base, afterJump));
}
void setStubShapeJump(MacroAssembler &masm, Label stubStart, Label afterShapeJump) {
int offset = masm.differenceBetween(stubStart, afterShapeJump);
setStubShapeJumpOffset(offset);
}
/* Offset-based interface. */
void setDslotsLoadOffset(int offset, bool isConstant, bool isTypeKnown) {
#if defined JS_HAS_IC_LABELS
dslotsLoadOffset = offset;
# endif
JS_ASSERT(offset == dslotsLoadOffset);
}
#endif
int getDslotsLoadOffset() {
#ifdef JS_PUNBOX64
return dslotsLoadOffset;
#elif defined JS_CPU_X86
JS_ASSERT_IF(isConstant, offset == INLINE_DSLOTS_BEFORE_CONSTANT);
JS_ASSERT_IF(isTypeKnown && !isConstant, offset == INLINE_DSLOTS_BEFORE_KTYPE);
JS_ASSERT_IF(!isTypeKnown, offset == INLINE_DSLOTS_BEFORE_DYNAMIC);
#else
JS_NOT_REACHED("this is inlined");
return 0;
# error
#endif
}
void setInlineShapeOffset(int offset) {
int getDslotsLoadOffset(const ValueRemat &vr) {
#if defined JS_CPU_X86
if (vr.isConstant())
return INLINE_DSLOTS_BEFORE_CONSTANT;
if (vr.isTypeKnown())
return INLINE_DSLOTS_BEFORE_KTYPE;
return INLINE_DSLOTS_BEFORE_DYNAMIC;
#else
(void) vr;
return dslotsLoadOffset;
#endif
}
void setInlineShapeDataOffset(int offset) {
#ifdef JS_HAS_IC_LABELS
inlineShapeOffset = offset;
inlineShapeDataOffset = offset;
#endif
JS_ASSERT(offset == inlineShapeOffset);
JS_ASSERT(offset == inlineShapeDataOffset);
}
void setStubShapeJump(int offset) {
void setStubShapeJumpOffset(int offset) {
#ifdef JS_HAS_IC_LABELS
stubShapeJump = offset;
stubShapeJumpOffset = offset;
#endif
JS_ASSERT(offset == stubShapeJump);
JS_ASSERT(offset == stubShapeJumpOffset);
}
int getInlineShapeOffset() {
return inlineShapeOffset;
void setInlineValueStoreOffset(int offset, bool isConstant, bool isTypeKnown) {
#ifdef JS_HAS_IC_LABELS
inlineValueStoreOffset = offset;
JS_ASSERT(offset == inlineValueStoreOffset);
#elif defined JS_CPU_X86
JS_ASSERT_IF(isConstant, offset == INLINE_VALUE_STORE_CONSTANT);
JS_ASSERT_IF(isTypeKnown && !isConstant, offset == INLINE_VALUE_STORE_KTYPE);
JS_ASSERT_IF(!isTypeKnown && !isConstant, offset == INLINE_VALUE_STORE_DYNAMIC);
#endif
}
int getStubShapeJump() {
return stubShapeJump;
void setInlineShapeJumpOffset(int offset) {
#ifdef JS_HAS_IC_LABELS
inlineShapeJumpOffset = offset;
#endif
JS_ASSERT(offset == inlineShapeJumpOffset);
}
int getInlineShapeJumpOffset() {
return POST_INST_OFFSET(inlineShapeDataOffset + INLINE_SHAPE_JUMP);
}
int getInlineShapeDataOffset() {
return inlineShapeDataOffset;
}
int getStubShapeJumpOffset() {
return POST_INST_OFFSET(stubShapeJumpOffset);
}
int getInlineValueStoreOffset(bool isConstant, bool isTypeKnown) {
#ifdef JS_HAS_IC_LABELS
return inlineValueStoreOffset;
#elif defined JS_CPU_X86
if (isConstant)
return INLINE_VALUE_STORE_CONSTANT;
else if (isTypeKnown)
return INLINE_VALUE_STORE_KTYPE;
else
return INLINE_VALUE_STORE_DYNAMIC;
#endif
}
private:
#ifdef JS_PUNBOX64
/* Offset from storeBack to beginning of 'mov dslots, addr'. */
#if defined JS_CPU_X86
static const int INLINE_DSLOTS_BEFORE_CONSTANT = -23;
static const int INLINE_DSLOTS_BEFORE_KTYPE = -19;
static const int INLINE_DSLOTS_BEFORE_DYNAMIC = -15;
#else
int32 dslotsLoadOffset : 8;
#endif
/* Offset from shapeGuard to end of shape comparison. */
int32 inlineShapeOffset : 8;
int32 inlineShapeDataOffset : 8;
/*
* Offset from lastStubStart to end of shape jump.
* TODO: We can redefine the location of lastStubStart to be
* after the jump -- at which point this is always 0.
*/
int32 stubShapeJump : 8;
int32 stubShapeJumpOffset : 8;
#if defined JS_CPU_X86
static const int INLINE_VALUE_STORE_CONSTANT = -20;
static const int INLINE_VALUE_STORE_KTYPE = -16;
static const int INLINE_VALUE_STORE_DYNAMIC = -12;
#else
int32 inlineValueStoreOffset : 8;
#endif
/* Offset from shapeGuard to the end of the shape jump. */
int32 inlineShapeJumpOffset : 8;
#if defined JS_CPU_X86
static const int INLINE_SHAPE_JUMP = 0;
#elif defined JS_CPU_X64
static const int INLINE_SHAPE_JUMP = 6;
#elif defined JS_CPU_ARM
static const int INLINE_SHAPE_JUMP = 12;
#else
# error
#endif
};
/* BindNameCompiler */
@ -411,4 +515,3 @@ struct ScopeNameLabels : MacroAssemblerTypedefs {
} /* namespace js */
#endif /* jsjaeger_ic_labels_h__ */

View File

@ -267,6 +267,21 @@ class NunboxAssembler : public JSC::MacroAssembler
#endif
}
/* Overloaded for store with value remat info. */
Label storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
if (vr.isConstant()) {
return storeValueWithAddressOffsetPatch(vr.value(), address);
} else if (vr.isTypeKnown()) {
ImmType type(vr.knownType());
RegisterID data(vr.dataReg());
return storeValueWithAddressOffsetPatch(type, data, address);
} else {
RegisterID type(vr.typeReg());
RegisterID data(vr.dataReg());
return storeValueWithAddressOffsetPatch(type, data, address);
}
}
/*
* Stores type first, then payload.
*/

View File

@ -83,8 +83,12 @@ ICOffsetInitializer::ICOffsetInitializer()
}
{
SetPropLabels &labels = PICInfo::setPropLabels_;
labels.inlineShapeOffset = 6;
labels.stubShapeJump = 12;
#if defined JS_CPU_X86
labels.inlineShapeDataOffset = 6;
/* Store w/ address offset patch is two movs. */
labels.inlineShapeJumpOffset = 12;
labels.stubShapeJumpOffset = 12;
#endif
}
{
BindNameLabels &labels = PICInfo::bindNameLabels_;
@ -188,62 +192,6 @@ class SetPropCompiler : public PICStubCompiler
JSAtom *atom;
int lastStubSecondShapeGuard;
static int32 dslotsLoadOffset(ic::PICInfo &pic) {
#if defined JS_NUNBOX32
if (pic.u.vr.isConstant())
return SETPROP_DSLOTS_BEFORE_CONSTANT;
if (pic.u.vr.isTypeKnown())
return SETPROP_DSLOTS_BEFORE_KTYPE;
return SETPROP_DSLOTS_BEFORE_DYNAMIC;
#elif defined JS_PUNBOX64
return pic.setPropLabels().getDslotsLoadOffset();
#endif
}
#if defined JS_NUNBOX32
inline int32 inlineTypeOffset() {
if (pic.u.vr.isConstant())
return SETPROP_INLINE_STORE_CONST_TYPE;
if (pic.u.vr.isTypeKnown())
return SETPROP_INLINE_STORE_KTYPE_TYPE;
return SETPROP_INLINE_STORE_DYN_TYPE;
}
#endif
#if defined JS_NUNBOX32
inline int32 inlineDataOffset() {
if (pic.u.vr.isConstant())
return SETPROP_INLINE_STORE_CONST_DATA;
if (pic.u.vr.isTypeKnown())
return SETPROP_INLINE_STORE_KTYPE_DATA;
return SETPROP_INLINE_STORE_DYN_DATA;
}
#endif
static int32 inlineShapeOffset(ic::PICInfo &pic) {
return pic.setPropLabels().getInlineShapeOffset();
}
static int32 inlineShapeJump(ic::PICInfo &pic) {
#if defined JS_NUNBOX32
return SETPROP_INLINE_SHAPE_JUMP;
#elif defined JS_PUNBOX64
return inlineShapeOffset(pic) + SETPROP_INLINE_SHAPE_JUMP;
#endif
}
inline int32 dslotsLoadOffset() {
return dslotsLoadOffset(pic);
}
inline int32 inlineShapeOffset() {
return inlineShapeOffset(pic);
}
inline int32 inlineShapeJump() {
return inlineShapeJump(pic);
}
public:
SetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, JSAtom *atom,
VoidStubPIC stub)
@ -253,12 +201,11 @@ class SetPropCompiler : public PICStubCompiler
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
{
repatcher.repatchLEAToLoadPtr(pic.fastPathRejoin.instructionAtOffset(dslotsLoadOffset(pic)));
repatcher.repatch(pic.fastPathStart.dataLabel32AtOffset(
pic.shapeGuard + inlineShapeOffset(pic)),
SetPropLabels &labels = pic.setPropLabels();
repatcher.repatchLEAToLoadPtr(labels.getDslotsLoad(pic.fastPathRejoin, pic.u.vr));
repatcher.repatch(labels.getInlineShapeData(pic.fastPathStart, pic.shapeGuard),
int32(JSObjectMap::INVALID_SHAPE));
repatcher.relink(pic.fastPathStart.jumpAtOffset(
pic.shapeGuard + inlineShapeJump(pic)),
repatcher.relink(labels.getInlineShapeJump(pic.fastPathStart, pic.shapeGuard),
pic.slowPathStart);
FunctionPtr target(JS_FUNC_TO_DATA_PTR(void *, ic::SetProp));
@ -271,11 +218,11 @@ class SetPropCompiler : public PICStubCompiler
JaegerSpew(JSpew_PICs, "patch setprop inline at %p\n", pic.fastPathStart.executableAddress());
Repatcher repatcher(f.jit());
SetPropLabels &labels = pic.setPropLabels();
int32 offset;
if (inlineSlot) {
JSC::CodeLocationInstruction istr;
istr = pic.fastPathRejoin.instructionAtOffset(dslotsLoadOffset());
CodeLocationInstruction istr = labels.getDslotsLoad(pic.fastPathRejoin, pic.u.vr);
repatcher.repatchLoadPtrToLEA(istr);
//
@ -293,20 +240,21 @@ class SetPropCompiler : public PICStubCompiler
offset = shape->slot * sizeof(Value);
}
uint32 shapeOffs = pic.shapeGuard + inlineShapeOffset();
repatcher.repatch(pic.fastPathStart.dataLabel32AtOffset(shapeOffs), obj->shape());
#if defined JS_NUNBOX32
repatcher.repatch(pic.fastPathRejoin.dataLabel32AtOffset(inlineTypeOffset()), offset + 4);
repatcher.repatch(pic.fastPathRejoin.dataLabel32AtOffset(inlineDataOffset()), offset);
#elif defined JS_PUNBOX64
repatcher.repatch(pic.fastPathRejoin.dataLabel32AtOffset(SETPROP_INLINE_STORE_VALUE), offset);
#endif
repatcher.repatch(labels.getInlineShapeData(pic.fastPathStart, pic.shapeGuard),
obj->shape());
repatcher.patchAddressOffsetForValueStore(labels.getInlineValueStore(pic.fastPathRejoin,
pic.u.vr),
offset, pic.u.vr.isTypeKnown());
pic.inlinePathPatched = true;
return Lookup_Cacheable;
}
int getLastStubSecondShapeGuard() const {
return lastStubSecondShapeGuard ? POST_INST_OFFSET(lastStubSecondShapeGuard) : 0;
}
void patchPreviousToHere(CodeLocationLabel cs)
{
Repatcher repatcher(pic.lastCodeBlock(f.jit()));
@ -319,10 +267,10 @@ class SetPropCompiler : public PICStubCompiler
if (pic.stubsGenerated)
shapeGuardJumpOffset = pic.setPropLabels().getStubShapeJumpOffset();
else
shapeGuardJumpOffset = pic.shapeGuard + inlineShapeJump();
shapeGuardJumpOffset = pic.shapeGuard + pic.setPropLabels().getInlineShapeJumpOffset();
repatcher.relink(label.jumpAtOffset(shapeGuardJumpOffset), cs);
if (lastStubSecondShapeGuard)
repatcher.relink(label.jumpAtOffset(lastStubSecondShapeGuard), cs);
if (int secondGuardOffset = getLastStubSecondShapeGuard())
repatcher.relink(label.jumpAtOffset(secondGuardOffset), cs);
}
LookupStatus generateStub(uint32 initialShape, const Shape *shape, bool adding, bool inlineSlot)
@ -340,8 +288,10 @@ class SetPropCompiler : public PICStubCompiler
}
Label start = masm.label();
Jump shapeGuard = masm.branch32_force32(Assembler::NotEqual, pic.shapeReg,
Imm32(initialShape));
DataLabel32 unused;
Jump shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, pic.shapeReg,
Imm32(initialShape), unused);
(void) unused;
Label stubShapeJumpLabel = masm.label();
@ -518,7 +468,7 @@ class SetPropCompiler : public PICStubCompiler
pic.stubsGenerated++;
pic.updateLastPath(buffer, start);
pic.setPropLabels().setStubShapeJump(masm.differenceBetween(start, stubShapeJumpLabel));
pic.setPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
if (pic.stubsGenerated == MAX_PIC_STUBS)
disable("max stubs reached");
@ -783,12 +733,7 @@ class GetPropCompiler : public PICStubCompiler
{ }
int getLastStubSecondShapeGuard() const {
#if defined JS_CPU_ARM
/* Jumps on ARM point at the beginning of the instruction. */
return lastStubSecondShapeGuard ? lastStubSecondShapeGuard - sizeof(JSC::ARMWord) : 0;
#else
return lastStubSecondShapeGuard;
#endif
return lastStubSecondShapeGuard ? POST_INST_OFFSET(lastStubSecondShapeGuard) : 0;
}
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
@ -1168,7 +1113,7 @@ class GetPropCompiler : public PICStubCompiler
pic.updateLastPath(buffer, start);
if (setStubShapeOffset)
pic.getPropLabels().setStubShapeJump(masm.differenceBetween(start, stubShapeJumpLabel));
pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
if (pic.stubsGenerated == MAX_PIC_STUBS)
disable("max stubs reached");

View File

@ -61,23 +61,6 @@ namespace ic {
static const uint32 MAX_PIC_STUBS = 16;
static const uint32 MAX_GETELEM_IC_STUBS = 17;
/* SetPropCompiler */
#if defined JS_CPU_X86
static const int32 SETPROP_INLINE_SHAPE_JUMP = 12; //asserted
static const int32 SETPROP_DSLOTS_BEFORE_CONSTANT = -23; //asserted
static const int32 SETPROP_DSLOTS_BEFORE_KTYPE = -19; //asserted
static const int32 SETPROP_DSLOTS_BEFORE_DYNAMIC = -15; //asserted
static const int32 SETPROP_INLINE_STORE_DYN_TYPE = -6; //asserted
static const int32 SETPROP_INLINE_STORE_DYN_DATA = 0; //asserted
static const int32 SETPROP_INLINE_STORE_KTYPE_TYPE = -10; //asserted
static const int32 SETPROP_INLINE_STORE_KTYPE_DATA = 0; //asserted
static const int32 SETPROP_INLINE_STORE_CONST_TYPE = -14; //asserted
static const int32 SETPROP_INLINE_STORE_CONST_DATA = -4; //asserted
#elif defined JS_CPU_X64
static const int32 SETPROP_INLINE_STORE_VALUE = 0; //asserted
static const int32 SETPROP_INLINE_SHAPE_JUMP = 6; //asserted
#endif
void PurgePICs(JSContext *cx);
enum LookupStatus {

View File

@ -176,6 +176,21 @@ class PunboxAssembler : public JSC::MacroAssembler
return label();
}
/* Overloaded for store with value remat info. */
Label storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
if (vr.isConstant()) {
return storeValueWithAddressOffsetPatch(vr.value(), address);
} else if (vr.isTypeKnown()) {
ImmType type(vr.knownType());
RegisterID data(vr.dataReg());
return storeValueWithAddressOffsetPatch(type, data, address);
} else {
RegisterID type(vr.typeReg());
RegisterID data(vr.dataReg());
return storeValueWithAddressOffsetPatch(type, data, address);
}
}
template <typename T>
void loadTypeTag(T address, RegisterID reg) {
loadValue(address, reg);