Bug 1544386 part 1 - Call ElementAccessHasExtraIndexedProperty instead of ArrayPrototypeHasIndexedProperty when inlining array natives. r=tcampbell, a=jcristau
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 08 May 2019 17:48:26 +0000
changeset 536802 109cefe117fbdd1764097e06796960082f4fee4e
parent 536801 2fb5251ef5f1e4067935d3ad3f908facea2d296f
child 536803 732bf9cb9670737b61a49011701a334e44a85d9e
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell, jcristau
bugs1544386
milestone68.0
Bug 1544386 part 1 - Call ElementAccessHasExtraIndexedProperty instead of ArrayPrototypeHasIndexedProperty when inlining array natives. r=tcampbell, a=jcristau This simplifies the code a bit because ElementAccessHasExtraIndexedProperty checks for length-overflow and sparse-indexes so the callers don't have to do that anymore. Differential Revision: https://phabricator.services.mozilla.com/D29486
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -922,19 +922,20 @@ IonBuilder::InliningResult IonBuilder::i
   if (clasp != &ArrayObject::class_) {
     return InliningStatus_NotInlined;
   }
   if (thisTypes->hasObjectFlags(constraints(), unhandledFlags)) {
     trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags);
     return InliningStatus_NotInlined;
   }
 
+  // Watch out for extra indexed properties on the object or its prototype.
   bool hasIndexedProperty;
   MOZ_TRY_VAR(hasIndexedProperty,
-              ArrayPrototypeHasIndexedProperty(this, script()));
+              ElementAccessHasExtraIndexedProperty(this, obj));
   if (hasIndexedProperty) {
     trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
     return InliningStatus_NotInlined;
   }
 
   callInfo.setImplicitlyUsedUnchecked();
 
   obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false);
@@ -1041,26 +1042,20 @@ IonBuilder::InliningResult IonBuilder::i
   TemporaryTypeSet* thisTypes = obj->resultTypeSet();
   if (!thisTypes) {
     return InliningStatus_NotInlined;
   }
   const Class* clasp = thisTypes->getKnownClass(constraints());
   if (clasp != &ArrayObject::class_) {
     return InliningStatus_NotInlined;
   }
-  if (thisTypes->hasObjectFlags(
-          constraints(),
-          OBJECT_FLAG_SPARSE_INDEXES | OBJECT_FLAG_LENGTH_OVERFLOW)) {
-    trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags);
-    return InliningStatus_NotInlined;
-  }
 
   bool hasIndexedProperty;
   MOZ_TRY_VAR(hasIndexedProperty,
-              ArrayPrototypeHasIndexedProperty(this, script()));
+              ElementAccessHasExtraIndexedProperty(this, obj));
   if (hasIndexedProperty) {
     trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
     return InliningStatus_NotInlined;
   }
 
   TemporaryTypeSet::DoubleConversion conversion =
       thisTypes->convertDoubleElements(constraints());
   if (conversion == TemporaryTypeSet::AmbiguousDoubleConversion) {
@@ -1178,27 +1173,21 @@ IonBuilder::InliningResult IonBuilder::i
   if (!thisTypes) {
     return InliningStatus_NotInlined;
   }
 
   const Class* clasp = thisTypes->getKnownClass(constraints());
   if (clasp != &ArrayObject::class_) {
     return InliningStatus_NotInlined;
   }
-  if (thisTypes->hasObjectFlags(
-          constraints(),
-          OBJECT_FLAG_SPARSE_INDEXES | OBJECT_FLAG_LENGTH_OVERFLOW)) {
-    trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags);
-    return InliningStatus_NotInlined;
-  }
-
-  // Watch out for indexed properties on the prototype.
+
+  // Watch out for extra indexed properties on the object or its prototype.
   bool hasIndexedProperty;
   MOZ_TRY_VAR(hasIndexedProperty,
-              ArrayPrototypeHasIndexedProperty(this, script()));
+              ElementAccessHasExtraIndexedProperty(this, obj));
   if (hasIndexedProperty) {
     trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
     return InliningStatus_NotInlined;
   }
 
   // The group of the result will be dynamically fixed up to match the input
   // object, allowing us to handle 'this' objects that might have more than
   // one group. Make sure that no singletons can be sliced here.
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -5967,26 +5967,16 @@ AbortReasonOr<bool> PrototypeHasIndexedP
     if (!builder->alloc().ensureBallast()) {
       return builder->abort(AbortReason::Alloc);
     }
   } while (obj);
 
   return false;
 }
 
-// Whether Array.prototype, or an object on its proto chain, has an indexed
-// property.
-AbortReasonOr<bool> jit::ArrayPrototypeHasIndexedProperty(IonBuilder* builder,
-                                                          JSScript* script) {
-  if (JSObject* proto = script->global().maybeGetArrayPrototype()) {
-    return PrototypeHasIndexedProperty(builder, proto);
-  }
-  return true;
-}
-
 // Whether obj or any of its prototypes have an indexed property.
 AbortReasonOr<bool> jit::TypeCanHaveExtraIndexedProperties(
     IonBuilder* builder, TemporaryTypeSet* types) {
   const Class* clasp = types->getKnownClass(builder->constraints());
 
   // Note: typed arrays have indexed properties not accounted for by type
   // information, though these are all in bounds and will be accounted for
   // by JIT paths.
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -12138,18 +12138,16 @@ bool CanWriteProperty(TempAllocator& all
                       HeapTypeSetKey property, MDefinition* value,
                       MIRType implicitType = MIRType::None);
 bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc,
                                    CompilerConstraintList* constraints,
                                    MBasicBlock* current, MDefinition** pobj,
                                    PropertyName* name, MDefinition** pvalue,
                                    bool canModify,
                                    MIRType implicitType = MIRType::None);
-AbortReasonOr<bool> ArrayPrototypeHasIndexedProperty(IonBuilder* builder,
-                                                     JSScript* script);
 AbortReasonOr<bool> TypeCanHaveExtraIndexedProperties(IonBuilder* builder,
                                                       TemporaryTypeSet* types);
 
 inline MIRType MIRTypeForTypedArrayRead(Scalar::Type arrayType,
                                         bool observedDouble) {
   switch (arrayType) {
     case Scalar::Int8:
     case Scalar::Uint8: