@@ -937,6 +937,16 @@ static void EmitMissingPropResult(CacheIRWriter& writer, NativeObject* obj,
937937 writer.loadUndefinedResult();
938938}
939939
940+ static ValOperandId EmitLoadSlot(CacheIRWriter& writer, NativeObject* holder,
941+ ObjOperandId holderId, uint32_t slot) {
942+ if (holder->isFixedSlot(slot)) {
943+ return writer.loadFixedSlot(holderId,
944+ NativeObject::getFixedSlotOffset(slot));
945+ }
946+ size_t dynamicSlotIndex = holder->dynamicSlotIndex(slot);
947+ return writer.loadDynamicSlot(holderId, dynamicSlotIndex);
948+ }
949+
940950void IRGenerator::emitCallGetterResultNoGuards(NativeGetPropKind kind,
941951 NativeObject* obj,
942952 NativeObject* holder,
@@ -971,6 +981,7 @@ void IRGenerator::emitCallGetterResultNoGuards(NativeGetPropKind kind,
971981void IRGenerator::emitGuardGetterSetterSlot(NativeObject* holder,
972982 PropertyInfo prop,
973983 ObjOperandId holderId,
984+ AccessorKind kind,
974985 bool holderIsConstant) {
975986 // If the holder is guaranteed to be the same object, and it never had a
976987 // slot holding a GetterSetter mutated or deleted, its Shape will change when
@@ -980,6 +991,25 @@ void IRGenerator::emitGuardGetterSetterSlot(NativeObject* holder,
980991 }
981992
982993 size_t slot = prop.slot();
994+
995+ // For the same reasons as emitCalleeGuard, we guard on the BaseScript
996+ // instead of the GetterSetter if the callee is scripted and this isn't
997+ // the first IC stub.
998+ if (!isFirstStub_) {
999+ bool isGetter = kind == AccessorKind::Getter;
1000+ JSObject* accessor = isGetter ? holder->getGetter(prop)
1001+ : holder->getSetter(prop);
1002+ JSFunction* fun = &accessor->as<JSFunction>();
1003+ if (fun->hasBaseScript()) {
1004+ ValOperandId getterSetterId = EmitLoadSlot(writer, holder, holderId, slot);
1005+ ObjOperandId functionId = writer.loadGetterSetterFunction(getterSetterId,
1006+ isGetter);
1007+ writer.saveScriptedGetterSetterCallee(functionId);
1008+ writer.guardFunctionScript(functionId, fun->baseScript());
1009+ return;
1010+ }
1011+ }
1012+
9831013 Value slotVal = holder->getSlot(slot);
9841014 MOZ_ASSERT(slotVal.isPrivateGCThing());
9851015
@@ -1014,9 +1044,10 @@ void GetPropIRGenerator::emitCallGetterResultGuards(NativeObject* obj,
10141044 TestMatchingHolder(writer, holder, holderId);
10151045
10161046 emitGuardGetterSetterSlot(holder, prop, holderId,
1047+ AccessorKind::Getter,
10171048 /* holderIsConstant = */ true);
10181049 } else {
1019- emitGuardGetterSetterSlot(holder, prop, objId);
1050+ emitGuardGetterSetterSlot(holder, prop, objId, AccessorKind::Getter );
10201051 }
10211052 } else {
10221053 GetterSetter* gs = holder->getGetterSetter(prop);
@@ -1114,16 +1145,6 @@ void GetPropIRGenerator::emitCallDOMGetterResult(NativeObject* obj,
11141145 emitCallDOMGetterResultNoGuards(holder, prop, objId);
11151146}
11161147
1117- static ValOperandId EmitLoadSlot(CacheIRWriter& writer, NativeObject* holder,
1118- ObjOperandId holderId, uint32_t slot) {
1119- if (holder->isFixedSlot(slot)) {
1120- return writer.loadFixedSlot(holderId,
1121- NativeObject::getFixedSlotOffset(slot));
1122- }
1123- size_t dynamicSlotIndex = holder->dynamicSlotIndex(slot);
1124- return writer.loadDynamicSlot(holderId, dynamicSlotIndex);
1125- }
1126-
11271148void GetPropIRGenerator::attachMegamorphicNativeSlot(ObjOperandId objId,
11281149 jsid id) {
11291150 MOZ_ASSERT(mode_ == ICState::Mode::Megamorphic);
@@ -1822,7 +1843,8 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando(
18221843 // and not the expando object.
18231844 MOZ_ASSERT(kind == NativeGetPropKind::NativeGetter ||
18241845 kind == NativeGetPropKind::ScriptedGetter);
1825- emitGuardGetterSetterSlot(nativeExpandoObj, *prop, expandoObjId);
1846+ emitGuardGetterSetterSlot(nativeExpandoObj, *prop, expandoObjId,
1847+ AccessorKind::Getter);
18261848 emitCallGetterResultNoGuards(kind, nativeExpandoObj, nativeExpandoObj,
18271849 *prop, receiverId);
18281850 }
@@ -1972,6 +1994,7 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed(
19721994 kind == NativeGetPropKind::ScriptedGetter);
19731995 MOZ_ASSERT(!isSuper());
19741996 emitGuardGetterSetterSlot(holder, *prop, holderId,
1997+ AccessorKind::Getter,
19751998 /* holderIsConstant = */ true);
19761999 emitCallGetterResultNoGuards(kind, nativeProtoObj, holder, *prop,
19772000 receiverId);
@@ -3625,11 +3648,13 @@ AttachDecision GetNameIRGenerator::tryAttachGlobalNameGetter(ObjOperandId objId,
36253648 ObjOperandId holderId = writer.loadObject(holder);
36263649 writer.guardShape(holderId, holder->shape());
36273650 emitGuardGetterSetterSlot(holder, *prop, holderId,
3651+ AccessorKind::Getter,
36283652 /* holderIsConstant = */ true);
36293653 } else {
36303654 // Note: pass true for |holderIsConstant| because the holder must be the
36313655 // current global object.
36323656 emitGuardGetterSetterSlot(holder, *prop, globalId,
3657+ AccessorKind::Getter,
36333658 /* holderIsConstant = */ true);
36343659 }
36353660
@@ -4876,9 +4901,10 @@ AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj,
48764901 TestMatchingHolder(writer, holder, holderId);
48774902
48784903 emitGuardGetterSetterSlot(holder, *prop, holderId,
4904+ AccessorKind::Setter,
48794905 /* holderIsConstant = */ true);
48804906 } else {
4881- emitGuardGetterSetterSlot(holder, *prop, objId);
4907+ emitGuardGetterSetterSlot(holder, *prop, objId, AccessorKind::Setter );
48824908 }
48834909 } else {
48844910 GetterSetter* gs = holder->getGetterSetter(*prop);
@@ -5340,7 +5366,7 @@ AttachDecision SetPropIRGenerator::tryAttachDOMProxyUnshadowed(
53405366 ObjOperandId holderId = writer.loadObject(holder);
53415367 TestMatchingHolder(writer, holder, holderId);
53425368
5343- emitGuardGetterSetterSlot(holder, *prop, holderId,
5369+ emitGuardGetterSetterSlot(holder, *prop, holderId, AccessorKind::Setter,
53445370 /* holderIsConstant = */ true);
53455371
53465372 // EmitCallSetterNoGuards expects |obj| to be the object the property is
@@ -5398,7 +5424,8 @@ AttachDecision SetPropIRGenerator::tryAttachDOMProxyExpando(
53985424 obj, objId, expandoVal, nativeExpandoObj);
53995425
54005426 MOZ_ASSERT(holder == nativeExpandoObj);
5401- emitGuardGetterSetterSlot(nativeExpandoObj, *prop, expandoObjId);
5427+ emitGuardGetterSetterSlot(nativeExpandoObj, *prop, expandoObjId,
5428+ AccessorKind::Setter);
54025429 emitCallSetterNoGuards(nativeExpandoObj, nativeExpandoObj, *prop, objId,
54035430 rhsId);
54045431 trackAttached("SetProp.DOMProxyExpandoSetter");
0 commit comments