Bug 1005922: IonMonkey: Remove bailing on NewObject/NewArray during arguments usage analysis; r=h4writer

This commit is contained in:
Inanc Seylan 2014-09-11 18:55:23 +02:00
parent 0a080259e9
commit f57dbeff7d
6 changed files with 75 additions and 19 deletions

View File

@ -5723,11 +5723,24 @@ bool
IonBuilder::jsop_newarray(uint32_t count)
{
JSObject *templateObject = inspector->getTemplateObject(pc);
if (!templateObject)
if (!templateObject) {
if (info().executionMode() == ArgumentsUsageAnalysis) {
MUnknownValue *unknown = MUnknownValue::New(alloc());
current->add(unknown);
current->push(unknown);
return true;
}
return abort("No template object for NEWARRAY");
}
JS_ASSERT(templateObject->is<ArrayObject>());
if (templateObject->type()->unknownProperties()) {
if (info().executionMode() == ArgumentsUsageAnalysis) {
MUnknownValue *unknown = MUnknownValue::New(alloc());
current->add(unknown);
current->push(unknown);
return true;
}
// We will get confused in jsop_initelem_array if we can't find the
// type object being initialized.
return abort("New array has unknown properties");
@ -5778,8 +5791,15 @@ bool
IonBuilder::jsop_newobject()
{
JSObject *templateObject = inspector->getTemplateObject(pc);
if (!templateObject)
if (!templateObject) {
if (info().executionMode() == ArgumentsUsageAnalysis) {
MUnknownValue *unknown = MUnknownValue::New(alloc());
current->add(unknown);
current->push(unknown);
return true;
}
return abort("No template object for NEWOBJECT");
}
JS_ASSERT(templateObject->is<JSObject>());
MConstant *templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
@ -5819,15 +5839,19 @@ IonBuilder::jsop_initelem_array()
// intializer, and that arrays are marked as non-packed when writing holes
// to them during initialization.
bool needStub = false;
types::TypeObjectKey *initializer = obj->resultTypeSet()->getObject(0);
if (value->type() == MIRType_MagicHole) {
if (!initializer->hasFlags(constraints(), types::OBJECT_FLAG_NON_PACKED))
needStub = true;
} else if (!initializer->unknownProperties()) {
types::HeapTypeSetKey elemTypes = initializer->property(JSID_VOID);
if (!TypeSetIncludes(elemTypes.maybeTypes(), value->type(), value->resultTypeSet())) {
elemTypes.freeze(constraints());
needStub = true;
if (obj->isUnknownValue()) {
needStub = true;
} else {
types::TypeObjectKey *initializer = obj->resultTypeSet()->getObject(0);
if (value->type() == MIRType_MagicHole) {
if (!initializer->hasFlags(constraints(), types::OBJECT_FLAG_NON_PACKED))
needStub = true;
} else if (!initializer->unknownProperties()) {
types::HeapTypeSetKey elemTypes = initializer->property(JSID_VOID);
if (!TypeSetIncludes(elemTypes.maybeTypes(), value->type(), value->resultTypeSet())) {
elemTypes.freeze(constraints());
needStub = true;
}
}
}
@ -5888,20 +5912,28 @@ IonBuilder::jsop_initprop(PropertyName *name)
MDefinition *value = current->pop();
MDefinition *obj = current->peek(-1);
JSObject *templateObject = obj->toNewObject()->templateObject();
JSObject *templateObject = nullptr;
Shape *shape = nullptr;
Shape *shape = templateObject->lastProperty()->searchLinear(NameToId(name));
bool useSlowPath = false;
if (!shape) {
// JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
MInitProp *init = MInitProp::New(alloc(), obj, name, value);
current->add(init);
return resumeAfter(init);
if (obj->isUnknownValue()) {
useSlowPath = true;
} else {
templateObject = obj->toNewObject()->templateObject();
shape = templateObject->lastProperty()->searchLinear(NameToId(name));
if (!shape)
useSlowPath = true;
}
if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
&obj, name, &value, /* canModify = */ true))
{
useSlowPath = true;
}
if (useSlowPath) {
// JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
MInitProp *init = MInitProp::New(alloc(), obj, name, value);
current->add(init);

View File

@ -3988,3 +3988,9 @@ LIRGenerator::visitArrayState(MArrayState *objState)
// ArrayState nodes are always recovered on bailouts
MOZ_CRASH("Unexpected ArrayState node during Lowering.");
}
bool
LIRGenerator::visitUnknownValue(MUnknownValue *ins)
{
MOZ_CRASH("Can not lower unknown value.");
}

View File

@ -278,6 +278,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitBeta(MBeta *ins);
bool visitObjectState(MObjectState *ins);
bool visitArrayState(MArrayState *ins);
bool visitUnknownValue(MUnknownValue *ins);
};
} // namespace jit

View File

@ -11709,6 +11709,21 @@ class MAsmJSCall MOZ_FINAL : public MVariadicInstruction
}
};
class MUnknownValue : public MNullaryInstruction
{
protected:
MUnknownValue() {
setResultType(MIRType_Value);
}
public:
INSTRUCTION_HEADER(UnknownValue)
static MUnknownValue *New(TempAllocator &alloc) {
return new(alloc) MUnknownValue();
}
};
#undef INSTRUCTION_HEADER
void MUse::init(MDefinition *producer, MNode *consumer)

View File

@ -242,7 +242,8 @@ namespace jit {
_(ForkJoinGetSlice) \
_(GuardThreadExclusive) \
_(InterruptCheckPar) \
_(RecompileCheck)
_(RecompileCheck) \
_(UnknownValue)
// Forward declarations of MIR types.
#define FORWARD_DECLARE(op) class M##op;

View File

@ -341,6 +341,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
UNSAFE_OP(AsmJSParameter)
UNSAFE_OP(AsmJSCall)
DROP_OP(RecompileCheck)
UNSAFE_OP(UnknownValue)
// It looks like this could easily be made safe:
UNSAFE_OP(ConvertElementsToDoubles)