From 0146e7a2b05f6f3140de255d653e2530a7d5bd7a Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 15 Nov 2016 15:54:12 +0100 Subject: [PATCH] Bug 1310125 part 1 - Don't use |holder| for own property getters/setters in IonBuilder. r=h4writer --- js/src/jit/BaselineInspector.cpp | 18 +++++++++-------- js/src/jit/IonBuilder.cpp | 33 ++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 751de8ee9c22..6d2b8280becb 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -709,7 +709,7 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap MOZ_ASSERT(receivers.empty()); MOZ_ASSERT(convertUnboxedGroups.empty()); - *holder = nullptr; + *commonGetter = nullptr; const ICEntry& entry = icEntryFromPC(pc); for (ICStub* stub = entry.firstStub(); stub; stub = stub->next()) { @@ -722,8 +722,8 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups)) return false; - if (!*holder) { - *holder = nstub->holder(); + if (!*commonGetter) { + *holder = isOwn ? nullptr : nstub->holder().get(); *holderShape = nstub->holderShape(); *commonGetter = nstub->getter(); *globalShape = GlobalShapeForGetPropFunction(nstub); @@ -748,9 +748,10 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap } } - if (!*holder) + if (!*commonGetter) return false; + MOZ_ASSERT(*isOwnProperty == !*holder); MOZ_ASSERT(*isOwnProperty == (receivers.empty() && convertUnboxedGroups.empty())); return true; } @@ -767,7 +768,7 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap MOZ_ASSERT(receivers.empty()); MOZ_ASSERT(convertUnboxedGroups.empty()); - *holder = nullptr; + *commonSetter = nullptr; const ICEntry& entry = icEntryFromPC(pc); for (ICStub* stub = entry.firstStub(); stub; stub = stub->next()) { @@ -777,8 +778,8 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups)) return false; - if (!*holder) { - *holder = nstub->holder(); + if (!*commonSetter) { + *holder = isOwn ? nullptr : nstub->holder().get(); *holderShape = nstub->holderShape(); *commonSetter = nstub->setter(); *isOwnProperty = isOwn; @@ -795,9 +796,10 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap } } - if (!*holder) + if (!*commonSetter) return false; + MOZ_ASSERT(*isOwnProperty == !*holder); return true; } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 3c221edf290c..f37c125b4e09 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -11154,6 +11154,7 @@ IonBuilder::testCommonGetterSetter(TemporaryTypeSet* types, PropertyName* name, Shape* globalShape/* = nullptr*/, MDefinition** globalGuard/* = nullptr */) { + MOZ_ASSERT(foundProto); MOZ_ASSERT_IF(globalShape, globalGuard); bool guardGlobal; @@ -12140,7 +12141,7 @@ IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Sh const BaselineInspector::ObjectGroupVector& convertUnboxedGroups, bool isOwnProperty) { - MOZ_ASSERT(holder); + MOZ_ASSERT(isOwnProperty == !holder); MOZ_ASSERT(holderShape); obj = convertUnboxedObjects(obj, convertUnboxedGroups); @@ -12179,13 +12180,17 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName TemporaryTypeSet* objTypes = obj->resultTypeSet(); MDefinition* guard = nullptr; MDefinition* globalGuard = nullptr; - bool canUseTIForGetter = - testCommonGetterSetter(objTypes, name, /* isGetter = */ true, - foundProto, lastProperty, commonGetter, &guard, - globalShape, &globalGuard); + bool canUseTIForGetter = false; + if (!isOwnProperty) { + // If it's not an own property, try to use TI to avoid shape guards. + // For own properties we use the path below. + canUseTIForGetter = testCommonGetterSetter(objTypes, name, /* isGetter = */ true, + foundProto, lastProperty, commonGetter, &guard, + globalShape, &globalGuard); + } if (!canUseTIForGetter) { - // If type information is bad, we can still optimize the getter if we - // shape guard. + // If it's an own property or type information is bad, we can still + // optimize the getter if we shape guard. obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty, receivers, convertUnboxedGroups, isOwnProperty); @@ -12750,12 +12755,16 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj, TemporaryTypeSet* objTypes = obj->resultTypeSet(); MDefinition* guard = nullptr; - bool canUseTIForSetter = - testCommonGetterSetter(objTypes, name, /* isGetter = */ false, - foundProto, lastProperty, commonSetter, &guard); + bool canUseTIForSetter = false; + if (!isOwnProperty) { + // If it's not an own property, try to use TI to avoid shape guards. + // For own properties we use the path below. + canUseTIForSetter = testCommonGetterSetter(objTypes, name, /* isGetter = */ false, + foundProto, lastProperty, commonSetter, &guard); + } if (!canUseTIForSetter) { - // If type information is bad, we can still optimize the setter if we - // shape guard. + // If it's an own property or type information is bad, we can still + // optimize the setter if we shape guard. obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty, receivers, convertUnboxedGroups, isOwnProperty);