mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 588021: Port SETPROP PIC for ARM. (r=dmandelin)
This commit is contained in:
parent
388045ee8b
commit
0422829982
@ -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)
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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__ */
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user