Bug 1405457 - Scalar replacement for call objects. r=nbp
authorTom Schuster <evilpies@gmail.com>
Wed, 04 Oct 2017 16:41:45 +0200
changeset 426982 53006df129c87ce9d67e005f365a0a3249cece14
parent 426981 b05f110f2d1f6e2adf905249b9cc337de86fd9d4
child 426983 faf7b551ffd63399fd8508be9a46d83f1e84686a
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewersnbp
bugs1405457
milestone58.0a1
Bug 1405457 - Scalar replacement for call objects. r=nbp
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.h
js/src/jit/Recover.cpp
js/src/jit/Recover.h
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -4804,24 +4804,26 @@ IonBuilder::createNamedLambdaObject(MDef
 }
 
 AbortReasonOr<MInstruction*>
 IonBuilder::createCallObject(MDefinition* callee, MDefinition* env)
 {
     // Get a template CallObject that we'll use to generate inline object
     // creation.
     CallObject* templateObj = inspector->templateCallObject();
+    MConstant* templateCst = MConstant::NewConstraintlessObject(alloc(), templateObj);
+    current->add(templateCst);
 
     // Allocate the object. Run-once scripts need a singleton type, so always do
     // a VM call in such cases.
     MNewCallObjectBase* callObj;
     if (script()->treatAsRunOnce() || templateObj->isSingleton())
-        callObj = MNewSingletonCallObject::New(alloc(), templateObj);
+        callObj = MNewSingletonCallObject::New(alloc(), templateCst);
     else
-        callObj = MNewCallObject::New(alloc(), templateObj);
+        callObj = MNewCallObject::New(alloc(), templateCst);
     current->add(callObj);
 
     // Initialize the object's reserved slots. No post barrier is needed here,
     // for the same reason as in createNamedLambdaObject.
     current->add(MStoreFixedSlot::New(alloc(), callObj, CallObject::enclosingEnvironmentSlot(), env));
     current->add(MStoreFixedSlot::New(alloc(), callObj, CallObject::calleeSlot(), callee));
 
     //if (!script()->functionHasParameterExprs()) {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -13142,72 +13142,62 @@ class MNewNamedLambdaObject : public MNu
     AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
     bool appendRoots(MRootList& roots) const override {
         return roots.append(templateObj_);
     }
 };
 
-class MNewCallObjectBase : public MNullaryInstruction
-{
-    CompilerGCPointer<CallObject*> templateObj_;
-
-  protected:
-    MNewCallObjectBase(Opcode op, CallObject* templateObj)
-      : MNullaryInstruction(op),
-        templateObj_(templateObj)
+class MNewCallObjectBase : public MUnaryInstruction
+                         , public SingleObjectPolicy::Data
+{
+  protected:
+    MNewCallObjectBase(Opcode op, MConstant* templateObj)
+      : MUnaryInstruction(op, templateObj)
     {
         setResultType(MIRType::Object);
     }
 
   public:
-    CallObject* templateObject() {
-        return templateObj_;
-    }
-    AliasSet getAliasSet() const override {
-        return AliasSet::None();
-    }
-    bool appendRoots(MRootList& roots) const override {
-        return roots.append(templateObj_);
+    CallObject* templateObject() const {
+        return &getOperand(0)->toConstant()->toObject().as<CallObject>();
+    }
+    AliasSet getAliasSet() const override {
+        return AliasSet::None();
     }
 };
 
 class MNewCallObject : public MNewCallObjectBase
 {
   public:
     INSTRUCTION_HEADER(NewCallObject)
-
-    explicit MNewCallObject(CallObject* templateObj)
+    TRIVIAL_NEW_WRAPPERS
+
+    explicit MNewCallObject(MConstant* templateObj)
       : MNewCallObjectBase(classOpcode, templateObj)
     {
-        MOZ_ASSERT(!templateObj->isSingleton());
-    }
-
-    static MNewCallObject*
-    New(TempAllocator& alloc, CallObject* templateObj)
-    {
-        return new(alloc) MNewCallObject(templateObj);
+        MOZ_ASSERT(!templateObject()->isSingleton());
+    }
+
+    MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
+    bool canRecoverOnBailout() const override {
+        return true;
     }
 };
 
 class MNewSingletonCallObject : public MNewCallObjectBase
 {
   public:
     INSTRUCTION_HEADER(NewSingletonCallObject)
-
-    explicit MNewSingletonCallObject(CallObject* templateObj)
+    TRIVIAL_NEW_WRAPPERS
+
+    explicit MNewSingletonCallObject(MConstant* templateObj)
       : MNewCallObjectBase(classOpcode, templateObj)
     {}
-
-    static MNewSingletonCallObject*
-    New(TempAllocator& alloc, CallObject* templateObj)
-    {
-        return new(alloc) MNewSingletonCallObject(templateObj);
-    }
 };
 
 class MNewStringObject :
   public MUnaryInstruction,
   public ConvertToStringPolicy<0>::Data
 {
     CompilerObject templateObj_;
 
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -1514,16 +1514,45 @@ RLambdaArrow::recover(JSContext* cx, Sna
 
     RootedValue result(cx);
     result.setObject(*resultObject);
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
+MNewCallObject::writeRecoverData(CompactBufferWriter& writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_NewCallObject));
+    return true;
+}
+
+RNewCallObject::RNewCallObject(CompactBufferReader& reader)
+{
+}
+
+bool
+RNewCallObject::recover(JSContext* cx, SnapshotIterator& iter) const
+{
+    Rooted<CallObject*> templateObj(cx, &iter.read().toObject().as<CallObject>());
+
+    RootedShape shape(cx, templateObj->lastProperty());
+    RootedObjectGroup group(cx, templateObj->group());
+    JSObject* resultObject = NewCallObject(cx, shape, group);
+    if (!resultObject)
+        return false;
+
+    RootedValue result(cx);
+    result.setObject(*resultObject);
+    iter.storeInstructionResult(result);
+    return true;
+}
+
+bool
 MSimdBox::writeRecoverData(CompactBufferWriter& writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_SimdBox));
     static_assert(unsigned(SimdType::Count) < 0x100, "assuming SimdType fits in 8 bits");
     writer.writeByte(uint8_t(simdType()));
     return true;
 }
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -99,16 +99,17 @@ namespace jit {
     _(ToDouble)                                 \
     _(ToFloat32)                                \
     _(TruncateToInt32)                          \
     _(NewObject)                                \
     _(NewTypedArray)                            \
     _(NewArray)                                 \
     _(NewIterator)                              \
     _(NewDerivedTypedObject)                    \
+    _(NewCallObject)                            \
     _(CreateThisWithTemplate)                   \
     _(Lambda)                                   \
     _(LambdaArrow)                              \
     _(SimdBox)                                  \
     _(ObjectState)                              \
     _(ArrayState)                               \
     _(SetArrayLength)                           \
     _(AtomicIsLockFree)                         \
@@ -634,16 +635,24 @@ class RLambda final : public RInstructio
 class RLambdaArrow final : public RInstruction
 {
   public:
     RINSTRUCTION_HEADER_NUM_OP_(LambdaArrow, 3)
 
     MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
 };
 
+class RNewCallObject final : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_NUM_OP_(NewCallObject, 1)
+
+    MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
+};
+
 class RSimdBox final : public RInstruction
 {
   private:
     uint8_t type_;
 
   public:
     RINSTRUCTION_HEADER_NUM_OP_(SimdBox, 1)