diff --git a/js/src/jit-test/tests/ion/bug1326150.js b/js/src/jit-test/tests/ion/bug1326150.js new file mode 100644 index 000000000000..3c9047c98325 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1326150.js @@ -0,0 +1,4 @@ +this.x = []; +Function.apply(null, this.x); +Object.defineProperty(this, "x", {get: valueOf}); +assertEq(evaluate("this.x;"), this); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 1ffc5e41e60a..3f5b67587a88 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -963,7 +963,7 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_ if (!attached && !JitOptions.disableCacheIR) { ICStubEngine engine = ICStubEngine::Baseline; GetPropIRGenerator gen(cx, pc, CacheKind::GetElem, engine, &isTemporarilyUnoptimizable, - lhs, rhs); + lhs, rhs, CanAttachGetter::Yes); if (gen.tryAttachStub()) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), engine, info.outerScript(cx), stub); diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 1e518732540a..91a71ddac79c 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -30,12 +30,14 @@ IRGenerator::IRGenerator(JSContext* cx, jsbytecode* pc, CacheKind cacheKind) GetPropIRGenerator::GetPropIRGenerator(JSContext* cx, jsbytecode* pc, CacheKind cacheKind, ICStubEngine engine, bool* isTemporarilyUnoptimizable, - HandleValue val, HandleValue idVal) + HandleValue val, HandleValue idVal, + CanAttachGetter canAttachGetter) : IRGenerator(cx, pc, cacheKind), val_(val), idVal_(idVal), engine_(engine), isTemporarilyUnoptimizable_(isTemporarilyUnoptimizable), + canAttachGetter_(canAttachGetter), preliminaryObjectAction_(PreliminaryObjectAction::None) {} @@ -223,7 +225,8 @@ enum NativeGetPropCacheability { static NativeGetPropCacheability CanAttachNativeGetProp(JSContext* cx, HandleObject obj, HandleId id, MutableHandleNativeObject holder, MutableHandleShape shape, - jsbytecode* pc, ICStubEngine engine, bool* isTemporarilyUnoptimizable) + jsbytecode* pc, ICStubEngine engine, CanAttachGetter canAttachGetter, + bool* isTemporarilyUnoptimizable) { MOZ_ASSERT(JSID_IS_STRING(id) || JSID_IS_SYMBOL(id)); @@ -253,6 +256,9 @@ CanAttachNativeGetProp(JSContext* cx, HandleObject obj, HandleId id, if (IsCacheableNoProperty(cx, obj, holder, shape, id, pc)) return CanAttachReadSlot; + if (canAttachGetter == CanAttachGetter::No) + return CanAttachNone; + if (IsCacheableGetPropCallScripted(obj, holder, shape, isTemporarilyUnoptimizable)) { // See bug 1226816. if (engine != ICStubEngine::IonSharedIC) @@ -425,7 +431,8 @@ GetPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId, Handle RootedNativeObject holder(cx_); NativeGetPropCacheability type = CanAttachNativeGetProp(cx_, obj, id, &holder, &shape, pc_, - engine_, isTemporarilyUnoptimizable_); + engine_, canAttachGetter_, + isTemporarilyUnoptimizable_); MOZ_ASSERT_IF(idempotent(), type == CanAttachNone || (type == CanAttachReadSlot && holder)); switch (type) { @@ -476,7 +483,8 @@ GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, H RootedShape shape(cx_); RootedNativeObject holder(cx_); NativeGetPropCacheability type = CanAttachNativeGetProp(cx_, windowObj, id, &holder, &shape, pc_, - engine_, isTemporarilyUnoptimizable_); + engine_, canAttachGetter_, + isTemporarilyUnoptimizable_); if (type != CanAttachCallGetter || !IsCacheableGetPropCallNative(windowObj, holder, shape)) { @@ -584,7 +592,7 @@ GetPropIRGenerator::tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId o RootedShape shape(cx_); NativeGetPropCacheability canCache = CanAttachNativeGetProp(cx_, checkObj, id, &holder, &shape, - pc_, engine_, + pc_, engine_, canAttachGetter_, isTemporarilyUnoptimizable_); MOZ_ASSERT_IF(idempotent(), canCache == CanAttachNone || (canCache == CanAttachReadSlot && holder)); diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index e57d3ccbff5f..216ba3cff95c 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -720,6 +720,8 @@ class MOZ_RAII IRGenerator CacheKind cacheKind() const { return cacheKind_; } }; +enum class CanAttachGetter { Yes, No }; + // GetPropIRGenerator generates CacheIR for a GetProp IC. class MOZ_RAII GetPropIRGenerator : public IRGenerator { @@ -727,6 +729,7 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator HandleValue idVal_; ICStubEngine engine_; bool* isTemporarilyUnoptimizable_; + CanAttachGetter canAttachGetter_; enum class PreliminaryObjectAction { None, Unlink, NotePreliminary }; PreliminaryObjectAction preliminaryObjectAction_; @@ -777,7 +780,8 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator public: GetPropIRGenerator(JSContext* cx, jsbytecode* pc, CacheKind cacheKind, ICStubEngine engine, - bool* isTemporarilyUnoptimizable, HandleValue val, HandleValue idVal); + bool* isTemporarilyUnoptimizable, HandleValue val, HandleValue idVal, + CanAttachGetter canAttachGetter); bool tryAttachStub(); bool tryAttachIdempotentStub(); diff --git a/js/src/jit/IonIC.cpp b/js/src/jit/IonIC.cpp index 5b35a4dbc05f..2e411020e9cc 100644 --- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -127,12 +127,18 @@ IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonGetProperty bool attached = false; if (!JitOptions.disableCacheIR && !ic->disabled()) { if (ic->canAttachStub()) { + // IonBuilder calls PropertyReadNeedsTypeBarrier to determine if it + // needs a type barrier. Unfortunately, PropertyReadNeedsTypeBarrier + // does not account for getters, so we should only attach a getter + // stub if we inserted a type barrier. + CanAttachGetter canAttachGetter = + ic->monitoredResult() ? CanAttachGetter::Yes : CanAttachGetter::No; jsbytecode* pc = ic->idempotent() ? nullptr : ic->pc(); RootedValue objVal(cx, ObjectValue(*obj)); bool isTemporarilyUnoptimizable; GetPropIRGenerator gen(cx, pc, ic->kind(), ICStubEngine::IonIC, &isTemporarilyUnoptimizable, - objVal, idVal); + objVal, idVal, canAttachGetter); if (ic->idempotent() ? gen.tryAttachIdempotentStub() : gen.tryAttachStub()) { attached = ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), outerScript); diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 1155709c7683..3967b9288948 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -2296,7 +2296,7 @@ DoGetPropFallback(JSContext* cx, void* payload, ICGetProp_Fallback* stub_, if (!attached && !JitOptions.disableCacheIR) { RootedValue idVal(cx, StringValue(name)); GetPropIRGenerator gen(cx, pc, CacheKind::GetProp, engine, &isTemporarilyUnoptimizable, - val, idVal); + val, idVal, CanAttachGetter::Yes); if (gen.tryAttachStub()) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), engine, info.outerScript(cx), stub);