Bug 1496847 - Restrict GetElem generic stub to access on sparse indexes only. r=tcampbell
authorKannan Vijayan <kvijayan@mozilla.com>
Tue, 16 Oct 2018 09:24:42 -0400
changeset 497217 237c50cb98bca9418e4c2e157371d0bd335b481c
parent 497216 7c5bf03859d2fb592ff5cca51552f2d1c0000893
child 497241 31724aea10cae55f30b825ade226c4d25e11a899
child 497245 bca5f70008c94e9a74c2d8d7272c10edcfa9c404
push id9996
push userarchaeopteryx@coole-files.de
push dateThu, 18 Oct 2018 18:37:15 +0000
treeherdermozilla-beta@8efe26839243 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1496847
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1496847 - Restrict GetElem generic stub to access on sparse indexes only. r=tcampbell
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -2356,16 +2356,17 @@ GetPropIRGenerator::tryAttachGenericElem
     // To allow other types to attach in the non-megamorphic case we test the specific
     // matching native reciever; however, once megamorphic we can attach for any native
     if (mode_ == ICState::Mode::Megamorphic) {
         writer.guardIsNativeObject(objId);
     } else {
         NativeObject* nobj = &obj->as<NativeObject>();
         TestMatchingNativeReceiver(writer, nobj, objId);
     }
+    writer.guardIndexGreaterThanDenseInitLength(objId, indexId);
     writer.callNativeGetElementResult(objId, indexId);
     writer.typeMonitorResult();
 
     trackAttached(mode_ == ICState::Mode::Megamorphic
                   ? "GenericElementMegamorphic": "GenericElement");
     return true;
 }
 
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -217,16 +217,17 @@ extern const char* const CacheKindNames[
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardAndGetIndexFromString)         \
     _(GuardAndGetNumberFromString)        \
     _(GuardAndGetIterator)                \
     _(GuardHasGetterSetter)               \
     _(GuardGroupHasUnanalyzedNewScript)   \
     _(GuardIndexIsNonNegative)            \
+    _(GuardIndexGreaterThanDenseInitLength) \
     _(GuardTagNotEqual)                   \
     _(GuardXrayExpandoShapeAndDefaultProto) \
     _(GuardFunctionPrototype)             \
     _(GuardNoAllocationMetadataBuilder)   \
     _(GuardObjectGroupNotPretenured)      \
     _(LoadStackValue)                     \
     _(LoadObject)                         \
     _(LoadProto)                          \
@@ -801,16 +802,20 @@ class MOZ_RAII CacheIRWriter : public JS
     void guardGroupHasUnanalyzedNewScript(ObjectGroup* group) {
         writeOp(CacheOp::GuardGroupHasUnanalyzedNewScript);
         addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
     }
 
     void guardIndexIsNonNegative(Int32OperandId index) {
         writeOpWithOperandId(CacheOp::GuardIndexIsNonNegative, index);
     }
+    void guardIndexGreaterThanDenseInitLength(ObjOperandId obj, Int32OperandId index) {
+        writeOpWithOperandId(CacheOp::GuardIndexGreaterThanDenseInitLength, obj);
+        writeOperandId(index);
+    }
     void guardTagNotEqual(ValueTagOperandId lhs, ValueTagOperandId rhs) {
         writeOpWithOperandId(CacheOp::GuardTagNotEqual, lhs);
         writeOperandId(rhs);
     }
 
     void loadFrameCalleeResult() {
         writeOp(CacheOp::LoadFrameCalleeResult);
     }
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -2816,16 +2816,42 @@ CacheIRCompiler::emitGuardIndexIsNonNega
         return false;
     }
 
     masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
     return true;
 }
 
 bool
+CacheIRCompiler::emitGuardIndexGreaterThanDenseInitLength()
+{
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Register index = allocator.useRegister(masm, reader.int32OperandId());
+    AutoScratchRegister scratch(allocator, masm);
+    AutoScratchRegister scratch2(allocator, masm);
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure)) {
+        return false;
+    }
+
+    // Load obj->elements.
+    masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
+
+    // Ensure index >= capacity.
+    Label outOfBounds;
+    Address capacity(scratch, ObjectElements::offsetOfInitializedLength());
+    masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds);
+    masm.jump(failure->label());
+    masm.bind(&outOfBounds);
+
+    return true;
+}
+
+bool
 CacheIRCompiler::emitGuardTagNotEqual()
 {
     Register lhs = allocator.useRegister(masm, reader.valueTagOperandId());
     Register rhs = allocator.useRegister(masm, reader.valueTagOperandId());
 
     FailurePath* failure;
     if (!addFailurePath(&failure)) {
         return false;
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -41,16 +41,17 @@ namespace jit {
     _(GuardMagicValue)                    \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardNoDetachedTypedObjects)        \
     _(GuardNoDenseElements)               \
     _(GuardAndGetNumberFromString)        \
     _(GuardAndGetIndexFromString)         \
     _(GuardIndexIsNonNegative)            \
+    _(GuardIndexGreaterThanDenseInitLength) \
     _(GuardTagNotEqual)                   \
     _(GuardXrayExpandoShapeAndDefaultProto)\
     _(GuardNoAllocationMetadataBuilder)   \
     _(GuardObjectGroupNotPretenured)      \
     _(LoadObject)                         \
     _(LoadProto)                          \
     _(LoadEnclosingEnvironment)           \
     _(LoadWrapperTarget)                  \