зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1805199) for causing multiple failures on GlobalObject.h CLOSED TREE
Backed out changeset 01e995a2bb73 (bug 1805199) Backed out changeset 91bd3ba3870f (bug 1805199) Backed out changeset 4718eaf6f421 (bug 1805199)
This commit is contained in:
Родитель
66311d259c
Коммит
9c0220e715
|
@ -1,36 +0,0 @@
|
|||
// Tests for |this| value passed to getters defined on the global.
|
||||
|
||||
function test(useWindowProxy) {
|
||||
var g = newGlobal({useWindowProxy});
|
||||
g.useWindowProxy = useWindowProxy;
|
||||
g.evaluate(`
|
||||
var x = 123;
|
||||
Object.defineProperty(this, "getX", {get: function() { return this.x; }});
|
||||
Object.defineProperty(Object.prototype, "protoGetX", {get: function() { return this.x * 2; }});
|
||||
Object.defineProperty(this, "thisIsProxy", {get: function() { return isProxy(this); }});
|
||||
|
||||
function f() {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
// GetGName
|
||||
assertEq(getX, 123);
|
||||
assertEq(protoGetX, 246);
|
||||
assertEq(thisIsProxy, useWindowProxy);
|
||||
// GetProp
|
||||
assertEq(globalThis.getX, 123);
|
||||
assertEq(globalThis.protoGetX, 246);
|
||||
assertEq(globalThis.thisIsProxy, useWindowProxy);
|
||||
}
|
||||
}
|
||||
f();
|
||||
`);
|
||||
}
|
||||
|
||||
for (let useWindowProxy of [true, false]) {
|
||||
test(useWindowProxy);
|
||||
}
|
||||
|
||||
setJitCompilerOption("ic.force-megamorphic", 1);
|
||||
|
||||
for (let useWindowProxy of [true, false]) {
|
||||
test(useWindowProxy);
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
// Tests for |this| value passed to setters defined on the global.
|
||||
|
||||
function test(useWindowProxy) {
|
||||
var g = newGlobal({useWindowProxy});
|
||||
g.useWindowProxy = useWindowProxy;
|
||||
g.evaluate(`
|
||||
var x = 123;
|
||||
Object.defineProperty(this, "checkX",
|
||||
{set: function(v) { assertEq(this.x, v); }});
|
||||
Object.defineProperty(Object.prototype, "protoCheckX",
|
||||
{set: function(v) { assertEq(this.x * 2, v); }});
|
||||
Object.defineProperty(this, "checkThisIsProxy",
|
||||
{set: function(v) { assertEq(isProxy(this), v); }});
|
||||
|
||||
function f() {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
// SetGName
|
||||
checkX = 123;
|
||||
protoCheckX = 246;
|
||||
checkThisIsProxy = useWindowProxy;
|
||||
// SetProp
|
||||
globalThis.checkX = 123;
|
||||
globalThis.protoCheckX = 246;
|
||||
globalThis.checkThisIsProxy = useWindowProxy;
|
||||
}
|
||||
}
|
||||
f();
|
||||
`);
|
||||
}
|
||||
|
||||
for (let useWindowProxy of [true, false]) {
|
||||
test(useWindowProxy);
|
||||
}
|
||||
|
||||
setJitCompilerOption("ic.force-megamorphic", 1);
|
||||
|
||||
for (let useWindowProxy of [true, false]) {
|
||||
test(useWindowProxy);
|
||||
}
|
|
@ -513,6 +513,17 @@ static NativeGetPropKind IsCacheableGetPropCall(NativeObject* obj,
|
|||
return NativeGetPropKind::None;
|
||||
}
|
||||
|
||||
// For getters that need the WindowProxy (instead of the Window) as this
|
||||
// object, don't cache if obj is the Window, since our cache will pass that
|
||||
// instead of the WindowProxy.
|
||||
if (IsWindow(obj)) {
|
||||
// Check for a getter that has jitinfo and whose jitinfo says it's
|
||||
// OK with both inner and outer objects.
|
||||
if (!getter.hasJitInfo() || getter.jitInfo()->needsOuterizedThisObject()) {
|
||||
return NativeGetPropKind::None;
|
||||
}
|
||||
}
|
||||
|
||||
// Scripted functions and natives with JIT entry can use the scripted path.
|
||||
if (getter.hasJitEntry()) {
|
||||
return NativeGetPropKind::ScriptedGetter;
|
||||
|
@ -869,17 +880,14 @@ static void EmitMissingPropResult(CacheIRWriter& writer, NativeObject* obj,
|
|||
}
|
||||
|
||||
static void EmitCallGetterResultNoGuards(JSContext* cx, CacheIRWriter& writer,
|
||||
NativeGetPropKind kind,
|
||||
NativeObject* obj,
|
||||
NativeObject* holder,
|
||||
PropertyInfo prop,
|
||||
ValOperandId receiverId) {
|
||||
MOZ_ASSERT(IsCacheableGetPropCall(obj, holder, prop) == kind);
|
||||
|
||||
JSFunction* target = &holder->getGetter(prop)->as<JSFunction>();
|
||||
bool sameRealm = cx->realm() == target->realm();
|
||||
|
||||
switch (kind) {
|
||||
switch (IsCacheableGetPropCall(obj, holder, prop)) {
|
||||
case NativeGetPropKind::NativeGetter: {
|
||||
writer.callNativeGetterResult(receiverId, target, sameRealm);
|
||||
writer.returnFromIC();
|
||||
|
@ -956,12 +964,12 @@ static void EmitCallGetterResultGuards(CacheIRWriter& writer, NativeObject* obj,
|
|||
}
|
||||
|
||||
static void EmitCallGetterResult(JSContext* cx, CacheIRWriter& writer,
|
||||
NativeGetPropKind kind, NativeObject* obj,
|
||||
NativeObject* holder, HandleId id,
|
||||
PropertyInfo prop, ObjOperandId objId,
|
||||
ValOperandId receiverId, ICState::Mode mode) {
|
||||
NativeObject* obj, NativeObject* holder,
|
||||
HandleId id, PropertyInfo prop,
|
||||
ObjOperandId objId, ValOperandId receiverId,
|
||||
ICState::Mode mode) {
|
||||
EmitCallGetterResultGuards(writer, obj, holder, id, prop, objId, mode);
|
||||
EmitCallGetterResultNoGuards(cx, writer, kind, obj, holder, prop, receiverId);
|
||||
EmitCallGetterResultNoGuards(cx, writer, obj, holder, prop, receiverId);
|
||||
}
|
||||
|
||||
static bool CanAttachDOMCall(JSContext* cx, JSJitInfo::OpType type,
|
||||
|
@ -983,12 +991,11 @@ static bool CanAttachDOMCall(JSContext* cx, JSJitInfo::OpType type,
|
|||
}
|
||||
|
||||
const JSJitInfo* jitInfo = fun->jitInfo();
|
||||
MOZ_ASSERT_IF(IsWindow(obj), !jitInfo->needsOuterizedThisObject());
|
||||
if (jitInfo->type() != type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(IsWindow(obj), !jitInfo->needsOuterizedThisObject());
|
||||
|
||||
const JSClass* clasp = obj->getClass();
|
||||
if (!clasp->isDOMClass()) {
|
||||
return false;
|
||||
|
@ -1108,7 +1115,7 @@ AttachDecision GetPropIRGenerator::tryAttachNative(HandleObject obj,
|
|||
return AttachDecision::Attach;
|
||||
}
|
||||
|
||||
EmitCallGetterResult(cx_, writer, kind, nobj, holder, id, *prop, objId,
|
||||
EmitCallGetterResult(cx_, writer, nobj, holder, id, *prop, objId,
|
||||
receiverId, mode_);
|
||||
|
||||
trackAttached("NativeGetter");
|
||||
|
@ -1157,20 +1164,6 @@ static ObjOperandId GuardAndLoadWindowProxyWindow(CacheIRWriter& writer,
|
|||
return windowObjId;
|
||||
}
|
||||
|
||||
// Whether a getter/setter on the global should have the WindowProxy as |this|
|
||||
// value instead of the Window (the global object). This always returns true for
|
||||
// scripted functions.
|
||||
static bool GetterNeedsWindowProxyThis(NativeObject* holder,
|
||||
PropertyInfo prop) {
|
||||
JSFunction* callee = &holder->getGetter(prop)->as<JSFunction>();
|
||||
return !callee->hasJitInfo() || callee->jitInfo()->needsOuterizedThisObject();
|
||||
}
|
||||
static bool SetterNeedsWindowProxyThis(NativeObject* holder,
|
||||
PropertyInfo prop) {
|
||||
JSFunction* callee = &holder->getSetter(prop)->as<JSFunction>();
|
||||
return !callee->hasJitInfo() || callee->jitInfo()->needsOuterizedThisObject();
|
||||
}
|
||||
|
||||
AttachDecision GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
HandleId id) {
|
||||
|
@ -1219,15 +1212,21 @@ AttachDecision GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj,
|
|||
return AttachDecision::Attach;
|
||||
}
|
||||
|
||||
case NativeGetPropKind::NativeGetter:
|
||||
case NativeGetPropKind::ScriptedGetter: {
|
||||
case NativeGetPropKind::NativeGetter: {
|
||||
// Make sure the native getter is okay with the IC passing the Window
|
||||
// instead of the WindowProxy as |this| value.
|
||||
JSFunction* callee = &holder->getGetter(*prop)->as<JSFunction>();
|
||||
MOZ_ASSERT(callee->isNativeWithoutJitEntry());
|
||||
if (!callee->hasJitInfo() ||
|
||||
callee->jitInfo()->needsOuterizedThisObject()) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
// If a |super| access, it is not worth the complexity to attach an IC.
|
||||
if (isSuper()) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
bool needsWindowProxy = GetterNeedsWindowProxyThis(holder, *prop);
|
||||
|
||||
// Guard the incoming object is a WindowProxy and inline a getter call
|
||||
// based on the Window object.
|
||||
maybeEmitIdGuard(id);
|
||||
|
@ -1236,20 +1235,21 @@ AttachDecision GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj,
|
|||
|
||||
if (CanAttachDOMGetterSetter(cx_, JSJitInfo::Getter, windowObj, holder,
|
||||
*prop, mode_)) {
|
||||
MOZ_ASSERT(!needsWindowProxy);
|
||||
EmitCallDOMGetterResult(cx_, writer, windowObj, holder, id, *prop,
|
||||
windowObjId);
|
||||
trackAttached("WindowProxyDOMGetter");
|
||||
} else {
|
||||
ValOperandId receiverId =
|
||||
writer.boxObject(needsWindowProxy ? objId : windowObjId);
|
||||
EmitCallGetterResult(cx_, writer, kind, windowObj, holder, id, *prop,
|
||||
ValOperandId receiverId = writer.boxObject(windowObjId);
|
||||
EmitCallGetterResult(cx_, writer, windowObj, holder, id, *prop,
|
||||
windowObjId, receiverId, mode_);
|
||||
trackAttached("WindowProxyGetter");
|
||||
}
|
||||
|
||||
return AttachDecision::Attach;
|
||||
}
|
||||
|
||||
case NativeGetPropKind::ScriptedGetter:
|
||||
MOZ_ASSERT_UNREACHABLE("Not possible for window proxies");
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unreachable");
|
||||
|
@ -1592,7 +1592,7 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando(
|
|||
MOZ_ASSERT(kind == NativeGetPropKind::NativeGetter ||
|
||||
kind == NativeGetPropKind::ScriptedGetter);
|
||||
EmitGuardGetterSetterSlot(writer, nativeExpandoObj, *prop, expandoObjId);
|
||||
EmitCallGetterResultNoGuards(cx_, writer, kind, nativeExpandoObj,
|
||||
EmitCallGetterResultNoGuards(cx_, writer, nativeExpandoObj,
|
||||
nativeExpandoObj, *prop, receiverId);
|
||||
}
|
||||
|
||||
|
@ -1696,8 +1696,8 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed(
|
|||
MOZ_ASSERT(!isSuper());
|
||||
EmitGuardGetterSetterSlot(writer, holder, *prop, holderId,
|
||||
/* holderIsConstant = */ true);
|
||||
EmitCallGetterResultNoGuards(cx_, writer, kind, nativeCheckObj, holder,
|
||||
*prop, receiverId);
|
||||
EmitCallGetterResultNoGuards(cx_, writer, nativeCheckObj, holder, *prop,
|
||||
receiverId);
|
||||
}
|
||||
} else {
|
||||
// Property was not found on the prototype chain. Deoptimize down to
|
||||
|
@ -2357,8 +2357,8 @@ AttachDecision GetPropIRGenerator::tryAttachPrimitive(ValOperandId valId,
|
|||
maybeEmitIdGuard(id);
|
||||
|
||||
ObjOperandId protoId = writer.loadObject(nproto);
|
||||
EmitCallGetterResult(cx_, writer, kind, nproto, holder, id, *prop,
|
||||
protoId, valId, mode_);
|
||||
EmitCallGetterResult(cx_, writer, nproto, holder, id, *prop, protoId,
|
||||
valId, mode_);
|
||||
|
||||
trackAttached("PrimitiveGetter");
|
||||
return AttachDecision::Attach;
|
||||
|
@ -3062,14 +3062,10 @@ AttachDecision GetNameIRGenerator::tryAttachGlobalNameGetter(ObjOperandId objId,
|
|||
GlobalObject* global = &globalLexical->global();
|
||||
|
||||
NativeGetPropKind kind = IsCacheableGetPropCall(global, holder, *prop);
|
||||
if (kind != NativeGetPropKind::NativeGetter &&
|
||||
kind != NativeGetPropKind::ScriptedGetter) {
|
||||
if (kind != NativeGetPropKind::NativeGetter) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
bool needsWindowProxy =
|
||||
IsWindow(global) && GetterNeedsWindowProxyThis(holder, *prop);
|
||||
|
||||
// Shape guard for global lexical.
|
||||
writer.guardShape(objId, globalLexical->shape());
|
||||
|
||||
|
@ -3093,19 +3089,11 @@ AttachDecision GetNameIRGenerator::tryAttachGlobalNameGetter(ObjOperandId objId,
|
|||
if (CanAttachDOMGetterSetter(cx_, JSJitInfo::Getter, global, holder, *prop,
|
||||
mode_)) {
|
||||
// The global shape guard above ensures the instance JSClass is correct.
|
||||
MOZ_ASSERT(!needsWindowProxy);
|
||||
EmitCallDOMGetterResultNoGuards(writer, holder, *prop, globalId);
|
||||
trackAttached("GlobalNameDOMGetter");
|
||||
} else {
|
||||
ObjOperandId receiverObjId;
|
||||
if (needsWindowProxy) {
|
||||
MOZ_ASSERT(cx_->global()->maybeWindowProxy());
|
||||
receiverObjId = writer.loadObject(cx_->global()->maybeWindowProxy());
|
||||
} else {
|
||||
receiverObjId = globalId;
|
||||
}
|
||||
ValOperandId receiverId = writer.boxObject(receiverObjId);
|
||||
EmitCallGetterResultNoGuards(cx_, writer, kind, global, holder, *prop,
|
||||
ValOperandId receiverId = writer.boxObject(globalId);
|
||||
EmitCallGetterResultNoGuards(cx_, writer, global, holder, *prop,
|
||||
receiverId);
|
||||
trackAttached("GlobalNameGetter");
|
||||
}
|
||||
|
@ -4077,7 +4065,11 @@ static bool IsCacheableSetPropCallNative(NativeObject* obj,
|
|||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (setter.hasJitInfo() && !setter.jitInfo()->needsOuterizedThisObject()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !IsWindow(obj);
|
||||
}
|
||||
|
||||
static bool IsCacheableSetPropCallScripted(NativeObject* obj,
|
||||
|
@ -4085,6 +4077,10 @@ static bool IsCacheableSetPropCallScripted(NativeObject* obj,
|
|||
PropertyInfo prop) {
|
||||
MOZ_ASSERT(IsCacheableProtoChain(obj, holder));
|
||||
|
||||
if (IsWindow(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!prop.isAccessorProperty()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4130,20 +4126,20 @@ static bool CanAttachSetter(JSContext* cx, jsbytecode* pc, JSObject* obj,
|
|||
|
||||
static void EmitCallSetterNoGuards(JSContext* cx, CacheIRWriter& writer,
|
||||
NativeObject* obj, NativeObject* holder,
|
||||
PropertyInfo prop, ObjOperandId receiverId,
|
||||
PropertyInfo prop, ObjOperandId objId,
|
||||
ValOperandId rhsId) {
|
||||
JSFunction* target = &holder->getSetter(prop)->as<JSFunction>();
|
||||
bool sameRealm = cx->realm() == target->realm();
|
||||
|
||||
if (target->isNativeWithoutJitEntry()) {
|
||||
MOZ_ASSERT(IsCacheableSetPropCallNative(obj, holder, prop));
|
||||
writer.callNativeSetter(receiverId, target, rhsId, sameRealm);
|
||||
writer.callNativeSetter(objId, target, rhsId, sameRealm);
|
||||
writer.returnFromIC();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsCacheableSetPropCallScripted(obj, holder, prop));
|
||||
writer.callScriptedSetter(receiverId, target, rhsId, sameRealm);
|
||||
writer.callScriptedSetter(objId, target, rhsId, sameRealm);
|
||||
writer.returnFromIC();
|
||||
}
|
||||
|
||||
|
@ -4171,9 +4167,6 @@ AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj,
|
|||
}
|
||||
auto* nobj = &obj->as<NativeObject>();
|
||||
|
||||
bool needsWindowProxy =
|
||||
IsWindow(nobj) && SetterNeedsWindowProxyThis(holder, *prop);
|
||||
|
||||
maybeEmitIdGuard(id);
|
||||
|
||||
// Use the megamorphic guard if we're in megamorphic mode, except if |obj|
|
||||
|
@ -4201,21 +4194,13 @@ AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj,
|
|||
|
||||
if (CanAttachDOMGetterSetter(cx_, JSJitInfo::Setter, nobj, holder, *prop,
|
||||
mode_)) {
|
||||
MOZ_ASSERT(!needsWindowProxy);
|
||||
EmitCallDOMSetterNoGuards(cx_, writer, holder, *prop, objId, rhsId);
|
||||
|
||||
trackAttached("DOMSetter");
|
||||
return AttachDecision::Attach;
|
||||
}
|
||||
|
||||
ObjOperandId receiverId;
|
||||
if (needsWindowProxy) {
|
||||
MOZ_ASSERT(cx_->global()->maybeWindowProxy());
|
||||
receiverId = writer.loadObject(cx_->global()->maybeWindowProxy());
|
||||
} else {
|
||||
receiverId = objId;
|
||||
}
|
||||
EmitCallSetterNoGuards(cx_, writer, nobj, holder, *prop, receiverId, rhsId);
|
||||
EmitCallSetterNoGuards(cx_, writer, nobj, holder, *prop, objId, rhsId);
|
||||
|
||||
trackAttached("Setter");
|
||||
return AttachDecision::Attach;
|
||||
|
|
|
@ -997,11 +997,7 @@ class GlobalObject : public NativeObject {
|
|||
JSObject* maybeWindowProxy() const { return data().windowProxy; }
|
||||
|
||||
void setWindowProxy(JSObject* windowProxy) {
|
||||
// Note: the global must always be associated with the same WindowProxy.
|
||||
// CacheIR optimizations rely on this by baking in the WindowProxy for the
|
||||
// global.
|
||||
MOZ_ASSERT(!data().windowProxy);
|
||||
data().windowProxy.init(windowProxy);
|
||||
data().windowProxy = windowProxy;
|
||||
}
|
||||
|
||||
ArrayObject* getSourceURLsHolder() const { return data().sourceURLsHolder; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче