Backout ce0afdc6ea1f (bug 1041688) for regressions.

This commit is contained in:
Brian Hackett 2014-09-11 13:37:46 -07:00
parent e3de2d87d8
commit 3db1207b1e
9 changed files with 77 additions and 17 deletions

View File

@ -2034,7 +2034,8 @@ IonCompile(JSContext *cx, JSScript *script,
const OptimizationInfo *optimizationInfo = js_IonOptimizations.get(optimizationLevel); const OptimizationInfo *optimizationInfo = js_IonOptimizations.get(optimizationLevel);
const JitCompileOptions options(cx); const JitCompileOptions options(cx);
IonBuilder *builder = alloc->new_<IonBuilder>(CompileCompartment::get(cx->compartment()), IonBuilder *builder = alloc->new_<IonBuilder>((JSContext *) nullptr,
CompileCompartment::get(cx->compartment()),
options, temp, graph, constraints, options, temp, graph, constraints,
inspector, info, optimizationInfo, inspector, info, optimizationInfo,
baselineFrameInspector); baselineFrameInspector);

View File

@ -2792,7 +2792,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
BaselineInspector inspector(script); BaselineInspector inspector(script);
const JitCompileOptions options(cx); const JitCompileOptions options(cx);
IonBuilder builder(CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints, IonBuilder builder(cx, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
&inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr); &inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
if (!builder.build()) { if (!builder.build()) {
@ -3019,7 +3019,7 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
BaselineInspector inspector(script); BaselineInspector inspector(script);
const JitCompileOptions options(cx); const JitCompileOptions options(cx);
IonBuilder builder(CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints, IonBuilder builder(nullptr, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
&inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr); &inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
if (!builder.build()) { if (!builder.build()) {

View File

@ -106,7 +106,7 @@ jit::NewBaselineFrameInspector(TempAllocator *temp, BaselineFrame *frame, Compil
return inspector; return inspector;
} }
IonBuilder::IonBuilder(CompileCompartment *comp, IonBuilder::IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
const JitCompileOptions &options, TempAllocator *temp, const JitCompileOptions &options, TempAllocator *temp,
MIRGraph *graph, types::CompilerConstraintList *constraints, MIRGraph *graph, types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info, BaselineInspector *inspector, CompileInfo *info,
@ -115,6 +115,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
uint32_t loopDepth) uint32_t loopDepth)
: MIRGenerator(comp, options, temp, graph, info, optimizationInfo), : MIRGenerator(comp, options, temp, graph, info, optimizationInfo),
backgroundCodegen_(nullptr), backgroundCodegen_(nullptr),
analysisContext(analysisContext),
baselineFrame_(baselineFrame), baselineFrame_(baselineFrame),
constraints_(constraints), constraints_(constraints),
analysis_(*temp, info->script()), analysis_(*temp, info->script()),
@ -146,6 +147,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
abortReason_ = AbortReason_Disable; abortReason_ = AbortReason_Disable;
JS_ASSERT(script()->hasBaselineScript() == (info->executionMode() != ArgumentsUsageAnalysis)); JS_ASSERT(script()->hasBaselineScript() == (info->executionMode() != ArgumentsUsageAnalysis));
JS_ASSERT(!!analysisContext == (info->executionMode() == DefinitePropertiesAnalysis));
if (!info->executionModeIsAnalysis()) if (!info->executionModeIsAnalysis())
script()->baselineScript()->setIonCompiledOrInlined(); script()->baselineScript()->setIonCompiledOrInlined();
@ -154,6 +156,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
void void
IonBuilder::clearForBackEnd() IonBuilder::clearForBackEnd()
{ {
JS_ASSERT(!analysisContext);
baselineFrame_ = nullptr; baselineFrame_ = nullptr;
// The caches below allocate data from the malloc heap. Release this before // The caches below allocate data from the malloc heap. Release this before
@ -346,6 +349,22 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
if (!target->isInterpreted()) if (!target->isInterpreted())
return DontInline(nullptr, "Non-interpreted target"); return DontInline(nullptr, "Non-interpreted target");
// Allow constructing lazy scripts when performing the definite properties
// analysis, as baseline has not been used to warm the caller up yet.
if (target->isInterpreted() && info().executionMode() == DefinitePropertiesAnalysis) {
RootedScript script(analysisContext, target->getOrCreateScript(analysisContext));
if (!script)
return InliningDecision_Error;
if (!script->hasBaselineScript() && script->canBaselineCompile()) {
MethodStatus status = BaselineCompile(analysisContext, script);
if (status == Method_Error)
return InliningDecision_Error;
if (status != Method_Compiled)
return InliningDecision_DontInline;
}
}
if (!target->hasScript()) if (!target->hasScript())
return DontInline(nullptr, "Lazy script"); return DontInline(nullptr, "Lazy script");
@ -4184,10 +4203,16 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
AutoAccumulateReturns aar(graph(), returns); AutoAccumulateReturns aar(graph(), returns);
// Build the graph. // Build the graph.
IonBuilder inlineBuilder(compartment, options, &alloc(), &graph(), constraints(), IonBuilder inlineBuilder(analysisContext, compartment, options, &alloc(), &graph(), constraints(),
&inspector, info, &optimizationInfo(), nullptr, inliningDepth_ + 1, &inspector, info, &optimizationInfo(), nullptr, inliningDepth_ + 1,
loopDepth_); loopDepth_);
if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) { if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
if (analysisContext && analysisContext->isExceptionPending()) {
JitSpew(JitSpew_Abort, "Inline builder raised exception.");
abortReason_ = AbortReason_Error;
return false;
}
// Inlining the callee failed. Mark the callee as uninlineable only if // Inlining the callee failed. Mark the callee as uninlineable only if
// the inlining was aborted for a non-exception reason. // the inlining was aborted for a non-exception reason.
if (inlineBuilder.abortReason_ == AbortReason_Disable) { if (inlineBuilder.abortReason_ == AbortReason_Disable) {
@ -6418,6 +6443,8 @@ IonBuilder::testSingletonProperty(JSObject *obj, PropertyName *name)
return nullptr; return nullptr;
types::TypeObjectKey *objType = types::TypeObjectKey::get(obj); types::TypeObjectKey *objType = types::TypeObjectKey::get(obj);
if (analysisContext)
objType->ensureTrackedProperty(analysisContext, NameToId(name));
if (objType->unknownProperties()) if (objType->unknownProperties())
return nullptr; return nullptr;
@ -6499,6 +6526,8 @@ IonBuilder::testSingletonPropertyTypes(MDefinition *obj, JSObject *singleton, Pr
types::TypeObjectKey *object = types->getObject(i); types::TypeObjectKey *object = types->getObject(i);
if (!object) if (!object)
continue; continue;
if (analysisContext)
object->ensureTrackedProperty(analysisContext, NameToId(name));
const Class *clasp = object->clasp(); const Class *clasp = object->clasp();
if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name)) if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name))
@ -6706,6 +6735,8 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
} }
types::TypeObjectKey *staticType = types::TypeObjectKey::get(staticObject); types::TypeObjectKey *staticType = types::TypeObjectKey::get(staticObject);
if (analysisContext)
staticType->ensureTrackedProperty(analysisContext, NameToId(name));
if (staticType->unknownProperties()) { if (staticType->unknownProperties()) {
*psucceeded = false; *psucceeded = false;
@ -6724,7 +6755,7 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
} }
types::TemporaryTypeSet *types = bytecodeTypes(pc); types::TemporaryTypeSet *types = bytecodeTypes(pc);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), staticType, BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), staticType,
name, types, /* updateObserved = */ true); name, types, /* updateObserved = */ true);
JSObject *singleton = types->getSingleton(); JSObject *singleton = types->getSingleton();
@ -7540,7 +7571,8 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index)
// Emit GetElementCache. // Emit GetElementCache.
types::TemporaryTypeSet *types = bytecodeTypes(pc); types::TemporaryTypeSet *types = bytecodeTypes(pc);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, types); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj,
nullptr, types);
// Always add a barrier if the index might be a string or symbol, so that // Always add a barrier if the index might be a string or symbol, so that
// the cache can attach stubs for particular properties. // the cache can attach stubs for particular properties.
@ -7588,7 +7620,8 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
AddObjectsForPropertyRead(obj, nullptr, types); AddObjectsForPropertyRead(obj, nullptr, types);
} }
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, types); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj,
nullptr, types);
bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj); bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
// Reads which are on holes in the object do not have to bail out if // Reads which are on holes in the object do not have to bail out if
@ -8904,7 +8937,8 @@ IonBuilder::jsop_getprop(PropertyName *name)
if (!getPropTryArgumentsCallee(&emitted, obj, name) || emitted) if (!getPropTryArgumentsCallee(&emitted, obj, name) || emitted)
return emitted; return emitted;
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, name, types); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, name, types);
// Always use a call if we are performing analysis and // Always use a call if we are performing analysis and
// not actually emitting code, to simplify later analysis. Also skip deeper // not actually emitting code, to simplify later analysis. Also skip deeper
@ -9586,7 +9620,8 @@ IonBuilder::getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *na
// Passing the inner object to GetProperty IC is safe, see the // Passing the inner object to GetProperty IC is safe, see the
// needsOuterizedThisObject check in IsCacheableGetPropCallNative. // needsOuterizedThisObject check in IsCacheableGetPropCallNative.
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), inner, name, types); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
inner, name, types);
if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted) if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted)
return *emitted; return *emitted;

View File

@ -214,7 +214,7 @@ class IonBuilder
static int CmpSuccessors(const void *a, const void *b); static int CmpSuccessors(const void *a, const void *b);
public: public:
IonBuilder(CompileCompartment *comp, IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
const JitCompileOptions &options, TempAllocator *temp, const JitCompileOptions &options, TempAllocator *temp,
MIRGraph *graph, types::CompilerConstraintList *constraints, MIRGraph *graph, types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info, BaselineInspector *inspector, CompileInfo *info,
@ -865,6 +865,7 @@ class IonBuilder
private: private:
bool init(); bool init();
JSContext *analysisContext;
BaselineFrameInspector *baselineFrame_; BaselineFrameInspector *baselineFrame_;
// Constraints for recording dependencies on type information. // Constraints for recording dependencies on type information.

View File

@ -433,7 +433,8 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED); bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED);
bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType()); bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, returnTypes); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, nullptr, returnTypes);
if (barrier != BarrierKind::NoBarrier) if (barrier != BarrierKind::NoBarrier)
returnType = MIRType_Value; returnType = MIRType_Value;

View File

@ -3667,7 +3667,8 @@ PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
} }
BarrierKind BarrierKind
jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints, jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeObjectKey *object, PropertyName *name, types::TypeObjectKey *object, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved) types::TemporaryTypeSet *observed, bool updateObserved)
{ {
@ -3687,6 +3688,8 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
break; break;
types::TypeObjectKey *typeObj = types::TypeObjectKey::get(obj); types::TypeObjectKey *typeObj = types::TypeObjectKey::get(obj);
if (propertycx)
typeObj->ensureTrackedProperty(propertycx, NameToId(name));
if (!typeObj->unknownProperties()) { if (!typeObj->unknownProperties()) {
types::HeapTypeSetKey property = typeObj->property(NameToId(name)); types::HeapTypeSetKey property = typeObj->property(NameToId(name));
@ -3712,7 +3715,8 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
} }
BarrierKind BarrierKind
jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints, jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed) types::TemporaryTypeSet *observed)
{ {
@ -3729,7 +3733,7 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
for (size_t i = 0; i < types->getObjectCount(); i++) { for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeObjectKey *object = types->getObject(i); types::TypeObjectKey *object = types->getObject(i);
if (object) { if (object) {
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, object, name, BarrierKind kind = PropertyReadNeedsTypeBarrier(propertycx, constraints, object, name,
observed, updateObserved); observed, updateObserved);
if (kind == BarrierKind::TypeSet) if (kind == BarrierKind::TypeSet)
return BarrierKind::TypeSet; return BarrierKind::TypeSet;

View File

@ -11772,10 +11772,12 @@ bool ElementAccessMightBeCopyOnWrite(types::CompilerConstraintList *constraints,
bool ElementAccessHasExtraIndexedProperty(types::CompilerConstraintList *constraints, bool ElementAccessHasExtraIndexedProperty(types::CompilerConstraintList *constraints,
MDefinition *obj); MDefinition *obj);
MIRType DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinition *obj); MIRType DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinition *obj);
BarrierKind PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints, BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeObjectKey *object, PropertyName *name, types::TypeObjectKey *object, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved); types::TemporaryTypeSet *observed, bool updateObserved);
BarrierKind PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints, BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed); types::TemporaryTypeSet *observed);
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *constraints, BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *constraints,

View File

@ -1091,6 +1091,21 @@ TypeObjectKey::property(jsid id)
return property; return property;
} }
void
TypeObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
{
// If we are accessing a lazily defined property which actually exists in
// the VM and has not been instantiated yet, instantiate it now if we are
// on the main thread and able to do so.
if (!JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
JS_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
if (JSObject *obj = singleton()) {
if (obj->isNative() && obj->nativeLookupPure(id))
EnsureTrackPropertyTypes(cx, obj, id);
}
}
}
bool bool
HeapTypeSetKey::instantiate(JSContext *cx) HeapTypeSetKey::instantiate(JSContext *cx)
{ {

View File

@ -1465,6 +1465,7 @@ struct TypeObjectKey
void watchStateChangeForInlinedCall(CompilerConstraintList *constraints); void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
void watchStateChangeForTypedArrayData(CompilerConstraintList *constraints); void watchStateChangeForTypedArrayData(CompilerConstraintList *constraints);
HeapTypeSetKey property(jsid id); HeapTypeSetKey property(jsid id);
void ensureTrackedProperty(JSContext *cx, jsid id);
TypeObject *maybeType(); TypeObject *maybeType();
}; };