Bug 1334187 - Port In_Dense from BaselineIC to CacheIR. r?jandem
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -870,24 +870,16 @@ TypedThingRequiresFloatingPoint(JSObject
{
Scalar::Type type = TypedThingElementType(obj);
return type == Scalar::Uint32 ||
type == Scalar::Float32 ||
type == Scalar::Float64;
}
static bool
-IsNativeDenseElementAccess(HandleObject obj, HandleValue key)
-{
- if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
- return true;
- return false;
-}
-
-static bool
IsNativeOrUnboxedDenseElementAccess(HandleObject obj, HandleValue key)
{
if (!obj->isNative() && !obj->is<UnboxedArrayObject>())
return false;
if (key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
return true;
return false;
}
@@ -1995,36 +1987,16 @@ ICSetElem_TypedArray::Compiler::generate
return true;
}
//
// In_Fallback
//
static bool
-TryAttachDenseInStub(JSContext* cx, HandleScript outerScript, ICIn_Fallback* stub,
- HandleValue key, HandleObject obj, bool* attached)
-{
- MOZ_ASSERT(!*attached);
-
- if (!IsNativeDenseElementAccess(obj, key))
- return true;
-
- JitSpew(JitSpew_BaselineIC, " Generating In(Native[Int32] dense) stub");
- ICIn_Dense::Compiler compiler(cx, obj->as<NativeObject>().lastProperty());
- ICStub* denseStub = compiler.getStub(compiler.getStubSpace(outerScript));
- if (!denseStub)
- return false;
-
- *attached = true;
- stub->addNewStub(denseStub);
- return true;
-}
-
-static bool
TryAttachNativeInStub(JSContext* cx, HandleScript outerScript, ICIn_Fallback* stub,
HandleValue key, HandleObject obj, bool* attached)
{
MOZ_ASSERT(!*attached);
RootedId id(cx);
if (!IsOptimizableElementPropertyName(cx, key, &id))
return true;
@@ -2141,20 +2113,16 @@ DoInFallback(JSContext* cx, BaselineFram
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;
- if (attached)
- return true;
if (!TryAttachNativeInStub(cx, script, stub, key, obj, &attached))
return false;
if (attached)
return true;
} else {
if (!TryAttachNativeInDoesNotExistStub(cx, script, stub, key, obj, &attached))
return false;
if (attached)
@@ -2321,57 +2289,16 @@ ICInNativeDoesNotExistCompiler::generate
masm.bind(&failurePopR0Scratch);
masm.pop(R0.scratchReg());
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
-bool
-ICIn_Dense::Compiler::generateStubCode(MacroAssembler& masm)
-{
- MOZ_ASSERT(engine_ == Engine::Baseline);
-
- Label failure;
-
- masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
- masm.branchTestObject(Assembler::NotEqual, R1, &failure);
-
- AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
- Register scratch = regs.takeAny();
-
- // Unbox and shape guard object.
- Register obj = masm.extractObject(R1, ExtractTemp0);
- masm.loadPtr(Address(ICStubReg, ICIn_Dense::offsetOfShape()), scratch);
- masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure);
-
- // Load obj->elements.
- masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
-
- // Unbox key and bounds check.
- Address initLength(scratch, ObjectElements::offsetOfInitializedLength());
- Register key = masm.extractInt32(R0, ExtractTemp0);
- masm.branch32(Assembler::BelowOrEqual, initLength, key, &failure);
-
- // Hole check.
- JS_STATIC_ASSERT(sizeof(Value) == 8);
- BaseIndex element(scratch, key, TimesEight);
- masm.branchTestMagic(Assembler::Equal, element, &failure);
-
- masm.moveValue(BooleanValue(true), R0);
-
- EmitReturnFromIC(masm);
-
- // Failure case - jump to next stub
- masm.bind(&failure);
- EmitStubGuardFailure(masm);
- return true;
-}
-
static bool
DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_,
HandleObject envChain, MutableHandleValue res)
{
SharedStubInfo info(cx, frame, stub_->icEntry());
// This fallback stub may trigger debug mode toggling.
DebugModeOSRVolatileStub<ICGetName_Fallback*> stub(frame, stub_);
@@ -5972,21 +5899,16 @@ ICInNativeDoesNotExistCompiler::ICInNati
: ICStubCompiler(cx, ICStub::In_NativeDoesNotExist, Engine::Baseline),
obj_(cx, obj),
name_(cx, name),
protoChainDepth_(protoChainDepth)
{
MOZ_ASSERT(protoChainDepth_ <= ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH);
}
-ICIn_Dense::ICIn_Dense(JitCode* stubCode, HandleShape shape)
- : ICStub(In_Dense, stubCode),
- shape_(shape)
-{ }
-
ICGetIntrinsic_Constant::ICGetIntrinsic_Constant(JitCode* stubCode, const Value& value)
: ICStub(GetIntrinsic_Constant, stubCode),
value_(value)
{ }
ICGetIntrinsic_Constant::~ICGetIntrinsic_Constant()
{ }
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -894,50 +894,16 @@ class ICInNativeDoesNotExistCompiler : p
template <size_t ProtoChainDepth>
ICStub* getStubSpecific(ICStubSpace* space, Handle<ShapeVector> shapes) {
return newStub<ICIn_NativeDoesNotExistImpl<ProtoChainDepth>>(space, getStubCode(), shapes,
name_);}
ICStub* getStub(ICStubSpace* space);
};
-class ICIn_Dense : public ICStub
-{
- friend class ICStubSpace;
-
- GCPtrShape shape_;
-
- ICIn_Dense(JitCode* stubCode, HandleShape shape);
-
- public:
- GCPtrShape& shape() {
- return shape_;
- }
- static size_t offsetOfShape() {
- return offsetof(ICIn_Dense, shape_);
- }
-
- class Compiler : public ICStubCompiler {
- RootedShape shape_;
-
- protected:
- MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
- public:
- Compiler(JSContext* cx, Shape* shape)
- : ICStubCompiler(cx, ICStub::In_Dense, Engine::Baseline),
- shape_(cx, shape)
- {}
-
- ICStub* getStub(ICStubSpace* space) {
- return newStub<ICIn_Dense>(space, getStubCode(), shape_);
- }
- };
-};
-
// GetName
// JSOP_GETNAME
// JSOP_GETGNAME
class ICGetName_Fallback : public ICMonitoredFallbackStub
{
friend class ICStubSpace;
explicit ICGetName_Fallback(JitCode* stubCode)
--- a/js/src/jit/BaselineICList.h
+++ b/js/src/jit/BaselineICList.h
@@ -54,17 +54,16 @@ namespace jit {
_(SetElem_DenseOrUnboxedArray) \
_(SetElem_DenseOrUnboxedArrayAdd) \
_(SetElem_TypedArray) \
\
_(In_Fallback) \
_(In_Native) \
_(In_NativePrototype) \
_(In_NativeDoesNotExist) \
- _(In_Dense) \
\
_(GetName_Fallback) \
\
_(BindName_Fallback) \
\
_(GetIntrinsic_Fallback) \
_(GetIntrinsic_Constant) \
\
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1539,27 +1539,59 @@ GetNameIRGenerator::tryAttachEnvironment
size_t dynamicSlotOffset = holder->dynamicSlotIndex(shape->slot()) * sizeof(Value);
writer.loadEnvironmentDynamicSlotResult(lastObjId, dynamicSlotOffset);
}
writer.typeMonitorResult();
return true;
}
+static bool
+IsNativeDenseElementAccess(HandleObject obj, HandleValue key)
+{
+ if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
+ return true;
+ return false;
+}
+
InIRGenerator::InIRGenerator(JSContext* cx, jsbytecode* pc,
HandleValue key, HandleObject obj)
: IRGenerator(cx, pc, CacheKind::In),
key_(key), obj_(obj)
{ }
bool
+InIRGenerator::tryAttachDenseIn(HandleValue key, ValOperandId keyId,
+ HandleObject obj, ObjOperandId objId)
+{
+ if (!IsNativeDenseElementAccess(obj, key))
+ return false;
+
+ Int32OperandId indexId = writer.guardIsInt32Index(keyId);
+
+ writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
+ writer.loadDenseElementExistsResult(objId, indexId);
+ writer.returnFromIC();
+ return true;
+}
+
+bool
InIRGenerator::tryAttachStub()
{
MOZ_ASSERT(cacheKind_ == CacheKind::In);
+ AutoAssertNoPendingException aanpe(cx_);
+
+ ValOperandId keyId(writer.setInputOperandId(0));
+ ValOperandId valId(writer.setInputOperandId(1));
+ ObjOperandId objId = writer.guardIsObject(valId);
+
+ if (tryAttachDenseIn(key_, keyId, obj_, objId))
+ return true;
+
return false;
}
bool
IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId,
uint32_t* int32Index, Int32OperandId* int32IndexId)
{
if (index.isNumber()) {
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -963,16 +963,19 @@ class MOZ_RAII SetPropIRGenerator : publ
};
// InIRGenerator generates CacheIR for a In IC.
class MOZ_RAII InIRGenerator : public IRGenerator
{
HandleValue key_;
HandleObject obj_;
+ bool tryAttachDenseIn(HandleValue key, ValOperandId keyId,
+ HandleObject obj, ObjOperandId objId);
+
public:
InIRGenerator(JSContext* cx, jsbytecode* pc,
HandleValue key, HandleObject obj);
bool tryAttachStub();
};
} // namespace jit
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -341,21 +341,16 @@ ICStub::trace(JSTracer* trc)
case 5: inStub->toImpl<5>()->traceShapes(trc); break;
case 6: inStub->toImpl<6>()->traceShapes(trc); break;
case 7: inStub->toImpl<7>()->traceShapes(trc); break;
case 8: inStub->toImpl<8>()->traceShapes(trc); break;
default: MOZ_CRASH("Invalid proto stub.");
}
break;
}
- case ICStub::In_Dense: {
- ICIn_Dense* inStub = toIn_Dense();
- TraceEdge(trc, &inStub->shape(), "baseline-in-dense-shape");
- break;
- }
case ICStub::GetIntrinsic_Constant: {
ICGetIntrinsic_Constant* constantStub = toGetIntrinsic_Constant();
TraceEdge(trc, &constantStub->value(), "baseline-getintrinsic-constant-value");
break;
}
case ICStub::SetProp_NativeAdd: {
ICSetProp_NativeAdd* propStub = toSetProp_NativeAdd();
TraceEdge(trc, &propStub->group(), "baseline-setpropnativeadd-stub-group");