Bug 1334187 - Add CacheIR scaffolding for JSOP_IN. r?jandem
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -1217,16 +1217,17 @@ BaselineCacheIRCompiler::init(CacheKind
switch (kind) {
case CacheKind::GetProp:
MOZ_ASSERT(numInputs == 1);
allocator.initInputLocation(0, R0);
break;
case CacheKind::GetElem:
case CacheKind::SetProp:
+ case CacheKind::In:
MOZ_ASSERT(numInputs == 2);
allocator.initInputLocation(0, R0);
allocator.initInputLocation(1, R1);
break;
case CacheKind::GetName:
MOZ_ASSERT(numInputs == 1);
allocator.initInputLocation(0, R0.scratchReg(), JSVAL_TYPE_OBJECT);
#if defined(JS_NUNBOX32)
@@ -1260,16 +1261,20 @@ jit::AttachBaselineCacheIRStub(JSContext
// unlimited number of stubs.
MOZ_ASSERT(stub->numOptimizedStubs() < MaxOptimizedCacheIRStubs);
enum class CacheIRStubKind { Regular, Monitored, Updated };
uint32_t stubDataOffset;
CacheIRStubKind stubKind;
switch (kind) {
+ case CacheKind::In:
+ stubDataOffset = sizeof(ICCacheIR_Regular);
+ stubKind = CacheIRStubKind::Regular;
+ break;
case CacheKind::GetProp:
case CacheKind::GetElem:
case CacheKind::GetName:
stubDataOffset = sizeof(ICCacheIR_Monitored);
stubKind = CacheIRStubKind::Monitored;
break;
case CacheKind::SetProp:
stubDataOffset = sizeof(ICCacheIR_Updated);
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -2007,37 +2007,59 @@ TryAttachNativeInDoesNotExistStub(JSCont
stub->addNewStub(newStub);
return true;
}
static bool
DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
HandleValue key, HandleValue objValue, MutableHandleValue res)
{
+ SharedStubInfo info(cx, frame, stub_->icEntry());
+
// This fallback stub may trigger debug mode toggling.
DebugModeOSRVolatileStub<ICIn_Fallback*> stub(frame, stub_);
FallbackICSpew(cx, stub, "In");
if (!objValue.isObject()) {
ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, objValue, nullptr);
return false;
}
+ bool attached = false;
+
+ if (stub->numOptimizedStubs() >= ICIn_Fallback::MAX_OPTIMIZED_STUBS) {
+ attached = true;
+ }
+
RootedObject obj(cx, &objValue.toObject());
+ jsbytecode* pc = stub->icEntry()->pc(info.script());
+
+ if (!attached && !JitOptions.disableCacheIR) {
+ ICStubEngine engine = ICStubEngine::Baseline;
+ InIRGenerator gen(cx, pc, key, obj);
+ if (gen.tryAttachStub()) {
+ ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
+ engine, info.outerScript(cx), stub);
+ if (newStub) {
+ JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
+ attached = true;
+ }
+ }
+ }
bool cond = false;
if (!OperatorIn(cx, key, obj, &cond))
return false;
res.setBoolean(cond);
if (stub.invalid())
return true;
- if (stub->numOptimizedStubs() >= ICIn_Fallback::MAX_OPTIMIZED_STUBS)
+ if (attached)
return true;
if (obj->isNative()) {
RootedScript script(cx, frame->script());
bool attached = false;
if (cond) {
if (!TryAttachDenseInStub(cx, script, stub, key, obj, &attached))
return false;
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1539,16 +1539,30 @@ GetNameIRGenerator::tryAttachEnvironment
size_t dynamicSlotOffset = holder->dynamicSlotIndex(shape->slot()) * sizeof(Value);
writer.loadEnvironmentDynamicSlotResult(lastObjId, dynamicSlotOffset);
}
writer.typeMonitorResult();
return true;
}
+InIRGenerator::InIRGenerator(JSContext* cx, jsbytecode* pc,
+ HandleValue key, HandleObject obj)
+ : IRGenerator(cx, pc, CacheKind::In),
+ key_(key), obj_(obj)
+{ }
+
+bool
+InIRGenerator::tryAttachStub()
+{
+ MOZ_ASSERT(cacheKind_ == CacheKind::In);
+
+ return false;
+}
+
bool
IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId,
uint32_t* int32Index, Int32OperandId* int32IndexId)
{
if (index.isNumber()) {
int32_t indexSigned;
if (index.isInt32()) {
indexSigned = index.toInt32();
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -130,16 +130,17 @@ class TypedOperandId : public OperandId
};
enum class CacheKind : uint8_t
{
GetProp,
GetElem,
GetName,
SetProp,
+ In,
};
#define CACHE_IR_OPS(_) \
_(GuardIsObject) \
_(GuardIsObjectOrNull) \
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsInt32Index) \
@@ -989,12 +990,25 @@ class MOZ_RAII SetPropIRGenerator : publ
return updateStubGroup_;
}
jsid updateStubId() const {
MOZ_ASSERT(needUpdateStub_);
return updateStubId_;
}
};
+// InIRGenerator generates CacheIR for a In IC.
+class MOZ_RAII InIRGenerator : public IRGenerator
+{
+ HandleValue key_;
+ HandleObject obj_;
+
+ public:
+ InIRGenerator(JSContext* cx, jsbytecode* pc,
+ HandleValue key, HandleObject obj);
+
+ bool tryAttachStub();
+};
+
} // namespace jit
} // namespace js
#endif /* jit_CacheIR_h */
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -253,16 +253,17 @@ CodeGenerator::visitOutOfLineICFallback(
StoreValueTo(getPropIC->output()).generate(this);
restoreLiveIgnore(lir, StoreValueTo(getPropIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::GetName:
case CacheKind::SetProp:
+ case CacheKind::In:
MOZ_CRASH("Baseline-specific for now");
}
MOZ_CRASH();
}
StringObject*
MNewStringObject::templateObj() const
{
--- a/js/src/jit/IonIC.cpp
+++ b/js/src/jit/IonIC.cpp
@@ -38,16 +38,17 @@ IonIC::scratchRegisterForEntryJump()
Register temp = asGetPropertyIC()->maybeTemp();
if (temp != InvalidReg)
return temp;
TypedOrValueRegister output = asGetPropertyIC()->output();
return output.hasValue() ? output.valueReg().scratchReg() : output.typedReg().gpr();
}
case CacheKind::GetName:
case CacheKind::SetProp:
+ case CacheKind::In:
MOZ_CRASH("Baseline-specific for now");
}
MOZ_CRASH("Invalid kind");
}
void
IonIC::reset(Zone* zone)