Bug 909717 - Backout due to orange + style nit orange fix on a CLOSED TREE.

This commit is contained in:
Hannes Verschore 2013-09-06 16:25:35 +02:00
Родитель 823658751f
Коммит 9876afe3fd
14 изменённых файлов: 138 добавлений и 321 удалений

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

@ -1312,9 +1312,9 @@ CodeGenerator::visitGuardThreadLocalObject(LGuardThreadLocalObject *lir)
}
bool
CodeGenerator::visitTypeBarrierV(LTypeBarrierV *lir)
CodeGenerator::visitTypeBarrier(LTypeBarrier *lir)
{
ValueOperand operand = ToValue(lir, LTypeBarrierV::Input);
ValueOperand operand = ToValue(lir, LTypeBarrier::Input);
Register scratch = ToTempUnboxRegister(lir->temp());
Label matched, miss;
@ -1326,21 +1326,6 @@ CodeGenerator::visitTypeBarrierV(LTypeBarrierV *lir)
return true;
}
bool
CodeGenerator::visitTypeBarrierO(LTypeBarrierO *lir)
{
Register obj = ToRegister(lir->object());
Register scratch = ToTempUnboxRegister(lir->temp());
Label matched, miss;
masm.guardObjectType(obj, lir->mir()->resultTypeSet(), scratch, &matched, &miss);
masm.jump(&miss);
if (!bailoutFrom(&miss, lir->snapshot()))
return false;
masm.bind(&matched);
return true;
}
bool
CodeGenerator::visitMonitorTypes(LMonitorTypes *lir)
{

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

@ -91,8 +91,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitElements(LElements *lir);
bool visitConvertElementsToDoubles(LConvertElementsToDoubles *lir);
bool visitMaybeToDoubleElement(LMaybeToDoubleElement *lir);
bool visitTypeBarrierV(LTypeBarrierV *lir);
bool visitTypeBarrierO(LTypeBarrierO *lir);
bool visitTypeBarrier(LTypeBarrier *lir);
bool visitMonitorTypes(LMonitorTypes *lir);
bool visitPostWriteBarrierO(LPostWriteBarrierO *lir);
bool visitPostWriteBarrierV(LPostWriteBarrierV *lir);

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

@ -86,7 +86,7 @@ jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
// parameter passing might be live. Rewriting uses of these terms
// in resume points may affect the interpreter's behavior. Rather
// than doing a more sophisticated analysis, just ignore these.
if (ins->isUnbox() || ins->isParameter() || ins->isTypeBarrier())
if (ins->isUnbox() || ins->isParameter())
continue;
// If the instruction's behavior has been constant folded into a
@ -1286,13 +1286,7 @@ TryEliminateTypeBarrierFromTest(MTypeBarrier *barrier, bool filtersNull, bool fi
// types that have been seen in the first access but not the second.
// A test 'if (x.f)' filters both null and undefined.
// Disregard the possible unbox added before the Typebarrier for checking.
MDefinition *input = barrier->input();
if (input->isUnbox() && input->toUnbox()->mode() == MUnbox::TypeBarrier)
input = input->toUnbox()->input();
if (test->getOperand(0) == input && direction == TRUE_BRANCH) {
if (test->getOperand(0) == barrier->input() && direction == TRUE_BRANCH) {
*eliminated = true;
barrier->replaceAllUsesWith(barrier->input());
return;
@ -1306,7 +1300,7 @@ TryEliminateTypeBarrierFromTest(MTypeBarrier *barrier, bool filtersNull, bool fi
if (compareType != MCompare::Compare_Undefined && compareType != MCompare::Compare_Null)
return;
if (compare->getOperand(0) != input)
if (compare->getOperand(0) != barrier->input())
return;
JSOp op = compare->jsop();
@ -1338,13 +1332,6 @@ TryEliminateTypeBarrier(MTypeBarrier *barrier, bool *eliminated)
const types::StackTypeSet *barrierTypes = barrier->resultTypeSet();
const types::StackTypeSet *inputTypes = barrier->input()->resultTypeSet();
// Disregard the possible unbox added before the Typebarrier.
if (barrier->input()->isUnbox() &&
barrier->input()->toUnbox()->mode() == MUnbox::TypeBarrier)
{
inputTypes = barrier->input()->toUnbox()->input()->resultTypeSet();
}
if (!barrierTypes || !inputTypes)
return true;

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

@ -930,48 +930,46 @@ IonBuilder::addOsrValueTypeBarrier(uint32_t slot, MInstruction **def_,
def = barrier;
}
if (type != def->type()) {
switch (type) {
case MIRType_Boolean:
case MIRType_Int32:
case MIRType_Double:
case MIRType_String:
case MIRType_Object:
{
MUnbox *unbox = MUnbox::New(def, type, MUnbox::Fallible);
osrBlock->insertBefore(osrBlock->lastIns(), unbox);
osrBlock->rewriteSlot(slot, unbox);
def = unbox;
break;
}
switch (type) {
case MIRType_Boolean:
case MIRType_Int32:
case MIRType_Double:
case MIRType_String:
case MIRType_Object:
{
MUnbox *unbox = MUnbox::New(def, type, MUnbox::Fallible);
osrBlock->insertBefore(osrBlock->lastIns(), unbox);
osrBlock->rewriteSlot(slot, unbox);
def = unbox;
break;
}
case MIRType_Null:
{
MConstant *c = MConstant::New(NullValue());
osrBlock->insertBefore(osrBlock->lastIns(), c);
osrBlock->rewriteSlot(slot, c);
def = c;
break;
}
case MIRType_Null:
{
MConstant *c = MConstant::New(NullValue());
osrBlock->insertBefore(osrBlock->lastIns(), c);
osrBlock->rewriteSlot(slot, c);
def = c;
break;
}
case MIRType_Undefined:
{
MConstant *c = MConstant::New(UndefinedValue());
osrBlock->insertBefore(osrBlock->lastIns(), c);
osrBlock->rewriteSlot(slot, c);
def = c;
break;
}
case MIRType_Undefined:
{
MConstant *c = MConstant::New(UndefinedValue());
osrBlock->insertBefore(osrBlock->lastIns(), c);
osrBlock->rewriteSlot(slot, c);
def = c;
break;
}
case MIRType_Magic:
JS_ASSERT(lazyArguments_);
osrBlock->rewriteSlot(slot, lazyArguments_);
def = lazyArguments_;
break;
case MIRType_Magic:
JS_ASSERT(lazyArguments_);
osrBlock->rewriteSlot(slot, lazyArguments_);
def = lazyArguments_;
break;
default:
break;
}
default:
break;
}
JS_ASSERT(def == osrBlock->getSlot(slot));
@ -3756,9 +3754,9 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
if (!types->unknown()) {
MTypeBarrier *barrier = MTypeBarrier::New(callInfo.thisArg(), cloneTypeSet(types), Bailout_Normal);
current->add(barrier);
callInfo.setThis(barrier);
// object or missing
JS_ASSERT(barrier->type() == MIRType_Object || barrier->type() == MIRType_Value);
MUnbox *unbox = MUnbox::New(barrier, MIRType_Object, MUnbox::Infallible);
current->add(unbox);
callInfo.setThis(unbox);
}
}
@ -4044,12 +4042,19 @@ IonBuilder::getInlineableGetPropertyCache(CallInfo &callInfo)
}
// Optimize away the following common pattern:
// MTypeBarrier[MIRType_Object] <- MGetPropertyCache
if (funcDef->isTypeBarrier()) {
MTypeBarrier *barrier = funcDef->toTypeBarrier();
if (barrier->hasUses())
// MUnbox[MIRType_Object, Infallible] <- MTypeBarrier <- MGetPropertyCache
if (funcDef->isUnbox()) {
MUnbox *unbox = funcDef->toUnbox();
if (unbox->mode() != MUnbox::Infallible)
return NULL;
if (barrier->type() != MIRType_Object)
if (unbox->hasUses())
return NULL;
if (!unbox->input()->isTypeBarrier())
return NULL;
MTypeBarrier *barrier = unbox->input()->toTypeBarrier();
// Test if usecount() > 1
if (!barrier->hasOneUse())
return NULL;
if (!barrier->input()->isGetPropertyCache())
return NULL;
@ -4163,16 +4168,16 @@ IonBuilder::inlineTypeObjectFallback(CallInfo &callInfo, MBasicBlock *dispatchBl
{
// Getting here implies the following:
// 1. The call function is an MGetPropertyCache, or an MGetPropertyCache
// followed by an MTypeBarrier.
JS_ASSERT(callInfo.fun()->isGetPropertyCache() || callInfo.fun()->isTypeBarrier());
// followed by an MTypeBarrier, followed by an MUnbox.
JS_ASSERT(callInfo.fun()->isGetPropertyCache() || callInfo.fun()->isUnbox());
// 2. The MGetPropertyCache has inlineable cases by guarding on the TypeObject.
JS_ASSERT(dispatch->numCases() > 0);
// 3. The MGetPropertyCache (and, if applicable, MTypeBarrier) only
// 3. The MGetPropertyCache (and, if applicable, MTypeBarrier and MUnbox) only
// have at most a single use.
JS_ASSERT_IF(callInfo.fun()->isGetPropertyCache(), !cache->hasUses());
JS_ASSERT_IF(callInfo.fun()->isTypeBarrier(), cache->useCount() == 1);
JS_ASSERT_IF(callInfo.fun()->isUnbox(), cache->hasOneUse());
// This means that no resume points yet capture the MGetPropertyCache,
// so everything from the MGetPropertyCache up until the call is movable.
@ -4226,14 +4231,19 @@ IonBuilder::inlineTypeObjectFallback(CallInfo &callInfo, MBasicBlock *dispatchBl
getPropBlock->addFromElsewhere(cache);
getPropBlock->push(cache);
} else {
MTypeBarrier *barrier = callInfo.fun()->toTypeBarrier();
JS_ASSERT(barrier->type() == MIRType_Object);
JS_ASSERT(barrier->input()->isGetPropertyCache());
JS_ASSERT(barrier->input()->toGetPropertyCache() == cache);
MUnbox *unbox = callInfo.fun()->toUnbox();
JS_ASSERT(unbox->input()->isTypeBarrier());
JS_ASSERT(unbox->type() == MIRType_Object);
JS_ASSERT(unbox->mode() == MUnbox::Infallible);
MTypeBarrier *typeBarrier = unbox->input()->toTypeBarrier();
JS_ASSERT(typeBarrier->input()->isGetPropertyCache());
JS_ASSERT(typeBarrier->input()->toGetPropertyCache() == cache);
getPropBlock->addFromElsewhere(cache);
getPropBlock->addFromElsewhere(barrier);
getPropBlock->push(barrier);
getPropBlock->addFromElsewhere(typeBarrier);
getPropBlock->addFromElsewhere(unbox);
getPropBlock->push(unbox);
}
// Construct an end block with the correct resume point.
@ -6177,14 +6187,38 @@ IonBuilder::pushTypeBarrier(MInstruction *ins, types::StackTypeSet *observed, bo
current->pop();
MInstruction *barrier = MTypeBarrier::New(ins, cloneTypeSet(observed));
current->add(barrier);
MInstruction *barrier;
JSValueType type = observed->getKnownTypeTag();
if (barrier->type() == MIRType_Undefined)
return pushConstant(UndefinedValue());
if (barrier->type() == MIRType_Null)
return pushConstant(NullValue());
// An unbox instruction isn't enough to capture JSVAL_TYPE_OBJECT. Use a type
// barrier followed by an infallible unbox.
bool isObject = false;
if (type == JSVAL_TYPE_OBJECT && !observed->hasType(types::Type::AnyObjectType())) {
type = JSVAL_TYPE_UNKNOWN;
isObject = true;
}
switch (type) {
case JSVAL_TYPE_UNKNOWN:
case JSVAL_TYPE_UNDEFINED:
case JSVAL_TYPE_NULL:
barrier = MTypeBarrier::New(ins, cloneTypeSet(observed));
current->add(barrier);
if (type == JSVAL_TYPE_UNDEFINED)
return pushConstant(UndefinedValue());
if (type == JSVAL_TYPE_NULL)
return pushConstant(NullValue());
if (isObject) {
barrier = MUnbox::New(barrier, MIRType_Object, MUnbox::Infallible);
current->add(barrier);
}
break;
default:
MUnbox::Mode mode = ins->isEffectful() ? MUnbox::TypeBarrier : MUnbox::TypeGuard;
barrier = MUnbox::New(ins, MIRTypeFromValueType(type), mode);
current->add(barrier);
}
current->push(barrier);
return true;
}

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

@ -96,32 +96,13 @@ MacroAssembler::guardTypeSet(const Source &address, const TypeSet *types,
JS_ASSERT(scratch != InvalidReg);
branchTestObject(NotEqual, tag, miss);
Register obj = extractObject(address, scratch);
guardObjectType(obj, types, scratch, matched, miss);
}
}
template <typename TypeSet> void
MacroAssembler::guardObjectType(Register obj, const TypeSet *types,
Register scratch, Label *matched, Label *miss)
{
JS_ASSERT(!types->unknown());
JS_ASSERT(!types->hasType(types::Type::AnyObjectType()));
JS_ASSERT(types->getObjectCount());
JS_ASSERT(scratch != InvalidReg);
unsigned count = types->getObjectCount();
for (unsigned i = 0; i < count; i++) {
if (JSObject *object = types->getSingleObject(i))
branchPtr(Equal, obj, ImmGCPtr(object), matched);
}
// Note: Some platforms give the same register for obj and scratch.
// Make sure when writing to scratch, the obj register isn't used anymore!
bool hasTypeObjects = false;
unsigned count = types->getObjectCount();
for (unsigned i = 0; i < count; i++) {
if (JSObject *object = types->getSingleObject(i))
branchPtr(Equal, obj, ImmGCPtr(object), matched);
else
hasTypeObjects = true;
}
if (hasTypeObjects) {
loadPtr(Address(obj, JSObject::offsetOfType()), scratch);
for (unsigned i = 0; i < count; i++) {
@ -161,13 +142,6 @@ template void MacroAssembler::guardTypeSet(const Address &address, const TypeWra
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const TypeWrapper *types,
Register scratch, Label *matched, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const types::StackTypeSet *types,
Register scratch, Label *matched, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const types::TypeSet *types,
Register scratch, Label *matched, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const TypeWrapper *types,
Register scratch, Label *matched, Label *miss);
template void MacroAssembler::guardType(const Address &address, types::Type type,
Register scratch, Label *matched, Label *miss);
template void MacroAssembler::guardType(const ValueOperand &value, types::Type type,

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

@ -162,9 +162,6 @@ class MacroAssembler : public MacroAssemblerSpecific
template <typename Source, typename TypeSet>
void guardTypeSet(const Source &address, const TypeSet *types, Register scratch,
Label *matched, Label *miss);
template <typename TypeSet>
void guardObjectType(Register obj, const TypeSet *types,
Register scratch, Label *matched, Label *miss);
template <typename Source>
void guardType(const Source &address, types::Type type, Register scratch,
Label *matched, Label *miss);

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

@ -4449,12 +4449,12 @@ class LGuardThreadLocalObject : public LCallInstructionHelper<0, 2, 1>
};
// Guard that a value is in a TypeSet.
class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1>
class LTypeBarrier : public LInstructionHelper<0, BOX_PIECES, 1>
{
public:
LIR_HEADER(TypeBarrierV)
LIR_HEADER(TypeBarrier)
LTypeBarrierV(const LDefinition &temp) {
LTypeBarrier(const LDefinition &temp) {
setTemp(0, temp);
}
@ -4468,27 +4468,6 @@ class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1>
}
};
// Guard that a object is in a TypeSet.
class LTypeBarrierO : public LInstructionHelper<0, 1, 1>
{
public:
LIR_HEADER(TypeBarrierO)
LTypeBarrierO(const LAllocation &obj, const LDefinition &temp) {
setOperand(0, obj);
setTemp(0, temp);
}
const MTypeBarrier *mir() const {
return mir_->toTypeBarrier();
}
const LAllocation *object() {
return getOperand(0);
}
const LDefinition *temp() {
return getTemp(0);
}
};
// Guard that a value is in a TypeSet.
class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1>
{

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

@ -143,8 +143,7 @@
_(GuardObjectType) \
_(GuardClass) \
_(GuardThreadLocalObject) \
_(TypeBarrierV) \
_(TypeBarrierO) \
_(TypeBarrier) \
_(MonitorTypes) \
_(PostWriteBarrierO) \
_(PostWriteBarrierV) \

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

@ -1840,45 +1840,12 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
bool needTemp = !types->unknownObject() && types->getObjectCount() > 0;
LDefinition tmp = needTemp ? temp() : tempToUnbox();
MIRType inputType = ins->getOperand(0)->type();
MIRType outputType = ins->type();
JS_ASSERT(inputType == outputType);
JS_ASSERT_IF(ins->certainBail(), outputType == MIRType_Value);
// Handle typebarrier that will always bail.
// (Emit LBail for visibility).
if (ins->certainBail()) {
JS_ASSERT(outputType == MIRType_Value);
LBail *bail = new LBail();
if (!assignSnapshot(bail, ins->bailoutKind()))
return false;
return redefine(ins, ins->input()) && add(bail, ins);
}
// Handle typebarrier with Value as input.
if (inputType == MIRType_Value) {
LTypeBarrierV *barrier = new LTypeBarrierV(tmp);
if (!useBox(barrier, LTypeBarrierV::Input, ins->input()))
return false;
if (!assignSnapshot(barrier, ins->bailoutKind()))
return false;
return redefine(ins, ins->input()) && add(barrier, ins);
}
// Handle typebarrier with specific TypeObject/SingleObjects.
if (inputType == MIRType_Object && !types->hasType(types::Type::AnyObjectType()) &&
types->getObjectCount())
{
LTypeBarrierO *barrier = new LTypeBarrierO(useRegister(ins->getOperand(0)) ,tmp);
if (!assignSnapshot(barrier, ins->bailoutKind()))
return false;
return redefine(ins, ins->getOperand(0)) && add(barrier, ins);
}
// Handle remaining cases: No-op, unbox did everything.
return redefine(ins, ins->getOperand(0));
LTypeBarrier *barrier = new LTypeBarrier(tmp);
if (!useBox(barrier, LTypeBarrier::Input, ins->input()))
return false;
if (!assignSnapshot(barrier, ins->bailoutKind()))
return false;
return redefine(ins, ins->input()) && add(barrier, ins);
}
bool

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

@ -620,44 +620,11 @@ MUnbox::printOpcode(FILE *fp) const
case Fallible: fprintf(fp, " (fallible)"); break;
case Infallible: fprintf(fp, " (infallible)"); break;
case TypeBarrier: fprintf(fp, " (typebarrier)"); break;
default: break;
}
if (mode() == Infallible)
return;
switch(bailoutKind()) {
case Bailout_Normal: fprintf(fp, " (normal)"); break;
case Bailout_ArgumentCheck: fprintf(fp, " (args)"); break;
case Bailout_TypeBarrier: fprintf(fp, " (typebarrier)"); break;
case Bailout_Monitor: fprintf(fp, " (monitor)"); break;
case Bailout_BoundsCheck: fprintf(fp, " (boundscheck)"); break;
case Bailout_ShapeGuard: fprintf(fp, " (shapeguard)"); break;
case Bailout_CachedShapeGuard: fprintf(fp, " (cached shapeguard)"); break;
case TypeGuard: fprintf(fp, " (typeguard)"); break;
default: break;
}
}
void
MTypeBarrier::printOpcode(FILE *fp) const
{
PrintOpcodeName(fp, op());
fprintf(fp, " ");
getOperand(0)->printName(fp);
fprintf(fp, " ");
switch(bailoutKind()) {
case Bailout_Normal: fprintf(fp, " (normal)"); break;
case Bailout_ArgumentCheck: fprintf(fp, " (args)"); break;
case Bailout_TypeBarrier: fprintf(fp, " (typebarrier)"); break;
case Bailout_Monitor: fprintf(fp, " (monitor)"); break;
case Bailout_BoundsCheck: fprintf(fp, " (boundscheck)"); break;
case Bailout_ShapeGuard: fprintf(fp, " (shapeguard)"); break;
case Bailout_CachedShapeGuard: fprintf(fp, " (cached shapeguard)"); break;
default: break;
}
}
void
MPhi::removeOperand(size_t index)
{

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

@ -2129,14 +2129,14 @@ class MUnbox : public MUnaryInstruction, public BoxInputsPolicy
enum Mode {
Fallible, // Check the type, and deoptimize if unexpected.
Infallible, // Type guard is not necessary.
TypeBarrier // Guard on the type, and act like a TypeBarrier on failure.
TypeBarrier, // Guard on the type, and act like a TypeBarrier on failure.
TypeGuard // Guard on the type, and deoptimize otherwise.
};
private:
Mode mode_;
BailoutKind bailoutKind_;
MUnbox(MDefinition *ins, MIRType type, Mode mode, BailoutKind kind)
MUnbox(MDefinition *ins, MIRType type, Mode mode)
: MUnaryInstruction(ins),
mode_(mode)
{
@ -2151,24 +2151,17 @@ class MUnbox : public MUnaryInstruction, public BoxInputsPolicy
setResultTypeSet(ins->resultTypeSet());
setMovable();
if (mode_ == TypeBarrier)
if (mode_ == TypeBarrier || mode_ == TypeGuard)
setGuard();
bailoutKind_ = kind;
if (mode_ == TypeGuard)
mode_ = Fallible;
}
public:
INSTRUCTION_HEADER(Unbox)
static MUnbox *New(MDefinition *ins, MIRType type, Mode mode)
{
BailoutKind kind = Bailout_Normal;
if (mode == TypeBarrier && ins->isEffectful())
kind = Bailout_TypeBarrier;
return new MUnbox(ins, type, mode, kind);
}
static MUnbox *New(MDefinition *ins, MIRType type, Mode mode, BailoutKind kind)
{
return new MUnbox(ins, type, mode, kind);
return new MUnbox(ins, type, mode);
}
TypePolicy *typePolicy() {
@ -2181,7 +2174,9 @@ class MUnbox : public MUnaryInstruction, public BoxInputsPolicy
BailoutKind bailoutKind() const {
// If infallible, no bailout should be generated.
JS_ASSERT(fallible());
return bailoutKind_;
return mode() == Fallible
? Bailout_Normal
: Bailout_TypeBarrier;
}
bool fallible() const {
return mode() != Infallible;
@ -7553,7 +7548,7 @@ class MGuardThreadLocalObject
// that value.
class MTypeBarrier
: public MUnaryInstruction,
public TypeBarrierPolicy
public BoxInputsPolicy
{
BailoutKind bailoutKind_;
@ -7561,11 +7556,8 @@ class MTypeBarrier
: MUnaryInstruction(def)
{
JS_ASSERT(!types->unknown());
MIRType type = MIRTypeFromValueType(types->getKnownTypeTag());
setResultType(type);
setResultType(MIRType_Value);
setResultTypeSet(types);
setGuard();
setMovable();
bailoutKind_ = bailoutKind;
@ -7575,16 +7567,16 @@ class MTypeBarrier
INSTRUCTION_HEADER(TypeBarrier)
static MTypeBarrier *New(MDefinition *def, types::StackTypeSet *types) {
BailoutKind kind = def->isEffectful() ? Bailout_TypeBarrier : Bailout_Normal;
return new MTypeBarrier(def, types, kind);
BailoutKind bailoutKind = def->isEffectful()
? Bailout_TypeBarrier
: Bailout_Normal;
return new MTypeBarrier(def, types, bailoutKind);
}
static MTypeBarrier *New(MDefinition *def, types::StackTypeSet *types,
BailoutKind kind) {
return new MTypeBarrier(def, types, kind);
BailoutKind bailoutKind) {
return new MTypeBarrier(def, types, bailoutKind);
}
void printOpcode(FILE *fp) const;
TypePolicy *typePolicy() {
return this;
}
@ -7601,17 +7593,6 @@ class MTypeBarrier
virtual bool neverHoist() const {
return resultTypeSet()->empty();
}
bool certainBail() const {
// If mirtype of input doesn't agree with mirtype of barrier,
// we will definitely bail.
MIRType type = MIRTypeFromValueType(resultTypeSet()->getKnownTypeTag());
if (type == MIRType_Value)
return false;
if (input()->type() == MIRType_Value)
return false;
return input()->type() != type;
}
};
// Like MTypeBarrier, guard that the value is in the given type set. This is

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

@ -11,8 +11,8 @@
#include "jit/Ion.h"
#include "jit/IonBuilder.h"
#include "jit/IonSpewer.h"
#include "jit/MIR.h"
#include "jit/AsmJS.h"
#include "jit/MIR.h"
#include "jsinferinlines.h"

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

@ -220,52 +220,6 @@ ComparePolicy::adjustInputs(MInstruction *def)
return true;
}
bool
TypeBarrierPolicy::adjustInputs(MInstruction *def)
{
MTypeBarrier *ins = def->toTypeBarrier();
MIRType inputType = ins->getOperand(0)->type();
MIRType outputType = ins->type();
// Input and output type are already in accordance.
if (inputType == outputType)
return true;
// Output is a value, currently box the input.
// Optimization: decrease resultTypeSet to only include the inputType.
// This will remove the need for boxing.
if (outputType == MIRType_Value) {
JS_ASSERT(inputType != MIRType_Value);
ins->replaceOperand(0, boxAt(ins, ins->getOperand(0)));
return true;
}
// Input is a value. Unbox the input to the requested type.
if (inputType == MIRType_Value) {
JS_ASSERT(outputType != MIRType_Value);
// We can't unbox a value to null/undefined. So keep output also a value.
if (IsNullOrUndefined(outputType) || outputType == MIRType_Magic) {
ins->setResultType(MIRType_Value);
outputType = MIRType_Value;
return true;
}
MUnbox *unbox = MUnbox::New(ins->getOperand(0), outputType,
MUnbox::TypeBarrier, ins->bailoutKind());
ins->block()->insertBefore(ins, unbox);
ins->replaceOperand(0, unbox);
return true;
}
// In the remaining cases we will alway bail. OutputType doesn't matter.
// Take inputType so we can use redefine during lowering.
JS_ASSERT(ins->certainBail());
ins->setResultType(inputType);
return true;
}
bool
TestPolicy::adjustInputs(MInstruction *ins)
{

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

@ -86,12 +86,6 @@ class TestPolicy : public BoxInputsPolicy
bool adjustInputs(MInstruction *ins);
};
class TypeBarrierPolicy : public BoxInputsPolicy
{
public:
bool adjustInputs(MInstruction *ins);
};
class CallPolicy : public BoxInputsPolicy
{
public: