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

View File

@ -3988,3 +3988,9 @@ LIRGenerator::visitArrayState(MArrayState *objState)
// ArrayState nodes are always recovered on bailouts // ArrayState nodes are always recovered on bailouts
MOZ_CRASH("Unexpected ArrayState node during Lowering."); 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 visitBeta(MBeta *ins);
bool visitObjectState(MObjectState *ins); bool visitObjectState(MObjectState *ins);
bool visitArrayState(MArrayState *ins); bool visitArrayState(MArrayState *ins);
bool visitUnknownValue(MUnknownValue *ins);
}; };
} // namespace jit } // 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 #undef INSTRUCTION_HEADER
void MUse::init(MDefinition *producer, MNode *consumer) void MUse::init(MDefinition *producer, MNode *consumer)

View File

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

View File

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