Compile JSOP_NEWOBJECT (bug 728290 part 1, r=dvander)
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 28 Feb 2012 14:21:49 +0100
changeset 105943 7fc13fbbc3308e67f0b5bf4f0c83cc46c4bbbb6e
parent 105942 8e8ec3416e5066b93e1125c9369aaf72cb56735c
child 105944 abb6b44448af9d0604d9e3430bbf88b1b38ea079
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs728290
milestone13.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
Compile JSOP_NEWOBJECT (bug 728290 part 1, r=dvander)
js/src/ion/CodeGenerator.cpp
js/src/ion/CodeGenerator.h
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/LIR-Common.h
js/src/ion/LOpcodes.h
js/src/ion/Lowering.cpp
js/src/ion/Lowering.h
js/src/ion/MIR.h
js/src/ion/MOpcodes.h
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -894,34 +894,40 @@ CodeGenerator::generateBody()
         }
         if (masm.oom())
             return false;
     }
     return true;
 }
 
 bool
-CodeGenerator::visitNewArray(LNewArray *ins)
+CodeGenerator::visitNewArray(LNewArray *lir)
 {
     typedef JSObject *(*pf)(JSContext *, uint32, types::TypeObject *);
     static const VMFunction NewInitArrayInfo = FunctionInfo<pf>(NewInitArray);
 
-    // ReturnReg is used for the returned value, so we don't care using it
-    // because it would be erased by the function call.
-    const Register type = ReturnReg;
-    masm.movePtr(ImmWord(ins->mir()->type()), type);
-
-    pushArg(type);
-    pushArg(Imm32(ins->mir()->count()));
-    if (!callVM(NewInitArrayInfo, ins))
+    pushArg(ImmGCPtr(lir->mir()->type()));
+    pushArg(Imm32(lir->mir()->count()));
+    if (!callVM(NewInitArrayInfo, lir))
         return false;
     return true;
 }
 
 bool
+CodeGenerator::visitNewObject(LNewObject *lir)
+{
+    typedef JSObject *(*pf)(JSContext *, JSObject *, types::TypeObject *);
+    static const VMFunction Info = FunctionInfo<pf>(CopyInitializerObject);
+
+    pushArg(ImmGCPtr(lir->mir()->type()));
+    pushArg(ImmGCPtr(lir->mir()->baseObj()));
+    return callVM(Info, lir);
+}
+
+bool
 CodeGenerator::visitArrayLength(LArrayLength *lir)
 {
     Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength());
     masm.load32(length, ToRegister(lir->output()));
     return true;
 }
 
 bool
--- a/js/src/ion/CodeGenerator.h
+++ b/js/src/ion/CodeGenerator.h
@@ -100,17 +100,18 @@ class CodeGenerator : public CodeGenerat
     bool visitStoreSlotV(LStoreSlotV *store);
     bool visitElements(LElements *lir);
     bool visitFlatClosureUpvars(LFlatClosureUpvars *lir);
     bool visitTypeBarrier(LTypeBarrier *lir);
     bool visitMonitorTypes(LMonitorTypes *lir);
     bool visitCallNative(LCallNative *lir);
     bool visitCallGeneric(LCallGeneric *lir);
     bool visitDoubleToInt32(LDoubleToInt32 *lir);
-    bool visitNewArray(LNewArray *builder);
+    bool visitNewArray(LNewArray *lir);
+    bool visitNewObject(LNewObject *lir);
     bool visitArrayLength(LArrayLength *lir);
     bool visitStringLength(LStringLength *lir);
     bool visitInitializedLength(LInitializedLength *lir);
     bool visitSetInitializedLength(LSetInitializedLength *lir);
     bool visitNotV(LNotV *ins);
     bool visitBoundsCheck(LBoundsCheck *lir);
     bool visitBoundsCheckRange(LBoundsCheckRange *lir);
     bool visitBoundsCheckLower(LBoundsCheckLower *lir);
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -726,16 +726,19 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_POP:
         current->pop();
         return true;
 
       case JSOP_NEWARRAY:
         return jsop_newarray(GET_UINT24(pc));
 
+      case JSOP_NEWOBJECT:
+        return jsop_newobject(info().getObject(pc));
+
       case JSOP_INITELEM:
         return jsop_initelem();
 
       case JSOP_ENDINIT:
         return true;
 
       case JSOP_CALL:
       case JSOP_FUNCALL:
@@ -2603,16 +2606,34 @@ IonBuilder::jsop_newarray(uint32 count)
     current->push(ins);
 
     if (!resumeAfter(ins))
         return false;
     return true;
 }
 
 bool
+IonBuilder::jsop_newobject(JSObject *baseObj)
+{
+    // Don't bake in the TypeObject for non-CNG scripts.
+    JS_ASSERT(script->hasGlobal());
+
+    types::TypeObject *type = types::TypeScript::InitObject(cx, script, pc, JSProto_Object);
+    if (!type)
+        return false;
+
+    MNewObject *ins = MNewObject::New(baseObj, type);
+
+    current->add(ins);
+    current->push(ins);
+
+    return resumeAfter(ins);
+}
+
+bool
 IonBuilder::jsop_initelem()
 {
     if (oracle->propertyWriteCanSpecialize(script, pc)) {
         if (oracle->elementWriteIsDense(script, pc))
             return jsop_initelem_dense();
     }
 
     return abort("NYI: JSOP_INITELEM supports for non dense objects/arrays.");
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -306,16 +306,17 @@ class IonBuilder : public MIRGenerator
     bool jsop_setelem();
     bool jsop_setelem_dense();
     bool jsop_length();
     bool jsop_length_fastPath();
     bool jsop_not();
     bool jsop_getprop(JSAtom *atom);
     bool jsop_setprop(JSAtom *atom);
     bool jsop_newarray(uint32 count);
+    bool jsop_newobject(JSObject *baseObj);
     bool jsop_initelem();
     bool jsop_initelem_dense();
     bool jsop_regexp(RegExpObject *reobj);
     bool jsop_object(JSObject *obj);
     bool jsop_lambda(JSFunction *fun);
     bool jsop_deflocalfun(uint32 local, JSFunction *fun);
     bool jsop_this();
     bool jsop_typeof();
--- a/js/src/ion/LIR-Common.h
+++ b/js/src/ion/LIR-Common.h
@@ -230,16 +230,26 @@ class LNewArray : public LCallInstructio
   public:
     LIR_HEADER(NewArray);
 
     MNewArray *mir() const {
         return mir_->toNewArray();
     }
 };
 
+class LNewObject : public LCallInstructionHelper<1, 0, 0>
+{
+  public:
+    LIR_HEADER(NewObject);
+
+    MNewObject *mir() const {
+        return mir_->toNewObject();
+    }
+};
+
 class LCheckOverRecursed : public LInstructionHelper<0, 0, 1>
 {
   public:
     LIR_HEADER(CheckOverRecursed);
 
     LCheckOverRecursed(const LDefinition &limitreg)
     {
         setTemp(0, limitreg);
--- a/js/src/ion/LOpcodes.h
+++ b/js/src/ion/LOpcodes.h
@@ -51,16 +51,17 @@
     _(Pointer)                      \
     _(Double)                       \
     _(Value)                        \
     _(Parameter)                    \
     _(Callee)                       \
     _(TableSwitch)                  \
     _(Goto)                         \
     _(NewArray)                     \
+    _(NewObject)                    \
     _(CheckOverRecursed)            \
     _(RecompileCheck)               \
     _(DefVar)                       \
     _(CallGeneric)                  \
     _(CallNative)                   \
     _(StackArg)                     \
     _(BitNotI)                      \
     _(BitNotV)                      \
--- a/js/src/ion/Lowering.cpp
+++ b/js/src/ion/Lowering.cpp
@@ -139,16 +139,23 @@ LIRGenerator::visitNewArray(MNewArray *i
         return false;
     if (!assignSafepoint(lir, ins))
         return false;
 
     return true;
 }
 
 bool
+LIRGenerator::visitNewObject(MNewObject *ins)
+{
+    LNewObject *lir = new LNewObject();
+    return defineVMReturn(lir, ins) && assignSafepoint(lir, ins);
+}
+
+bool
 LIRGenerator::visitPrepareCall(MPrepareCall *ins)
 {
     allocateArguments(ins->argc());
     return true;
 }
 
 bool
 LIRGenerator::visitPassArg(MPassArg *arg)
--- a/js/src/ion/Lowering.h
+++ b/js/src/ion/Lowering.h
@@ -107,16 +107,17 @@ class LIRGenerator : public LIRGenerator
     bool visitBlock(MBasicBlock *block);
 
     // Visitor hooks are explicit, to give CPU-specific versions a chance to
     // intercept without a bunch of explicit gunk in the .cpp.
     bool visitParameter(MParameter *param);
     bool visitCallee(MCallee *callee);
     bool visitGoto(MGoto *ins);
     bool visitNewArray(MNewArray *ins);
+    bool visitNewObject(MNewObject *ins);
     bool visitCheckOverRecursed(MCheckOverRecursed *ins);
     bool visitDefVar(MDefVar *ins);
     bool visitPrepareCall(MPrepareCall *ins);
     bool visitPassArg(MPassArg *arg);
     bool visitCall(MCall *call);
     bool visitTest(MTest *test);
     bool visitCompare(MCompare *comp);
     bool visitTypeOf(MTypeOf *ins);
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -965,16 +965,42 @@ class MNewArray : public MNullaryInstruc
         return count_;
     }
 
     types::TypeObject *type() const {
         return type_;
     }
 };
 
+class MNewObject : public MNullaryInstruction
+{
+    HeapPtrObject baseObj_;
+    HeapPtr<types::TypeObject> type_;
+
+    MNewObject(JSObject *baseObj, types::TypeObject *type)
+      : baseObj_(baseObj), type_(type)
+    {
+        setResultType(MIRType_Object);
+    }
+
+  public:
+    INSTRUCTION_HEADER(NewObject);
+
+    static MNewObject *New(JSObject *baseObj, types::TypeObject *type) {
+        return new MNewObject(baseObj, type);
+    }
+
+    JSObject *baseObj() const {
+        return baseObj_;
+    }
+    types::TypeObject *type() const {
+        return type_;
+    }
+};
+
 // Designates the start of call frame construction.
 // Generates code to adjust the stack pointer for the argument vector.
 // Argc is inferred by checking the use chain during lowering.
 class MPrepareCall : public MNullaryInstruction
 {
   public:
     INSTRUCTION_HEADER(PrepareCall);
 
--- a/js/src/ion/MOpcodes.h
+++ b/js/src/ion/MOpcodes.h
@@ -87,16 +87,17 @@ namespace ion {
     _(Box)                                                                  \
     _(Unbox)                                                                \
     _(GuardObject)                                                          \
     _(ToDouble)                                                             \
     _(ToInt32)                                                              \
     _(TruncateToInt32)                                                      \
     _(ToString)                                                             \
     _(NewArray)                                                             \
+    _(NewObject)                                                            \
     _(Start)                                                                \
     _(OsrEntry)                                                             \
     _(RegExp)                                                               \
     _(Lambda)                                                               \
     _(LambdaJoinableForCall)                                                \
     _(LambdaJoinableForSet)                                                 \
     _(ImplicitThis)                                                         \
     _(Slots)                                                                \