Bug 749822 - Pass original argc to uncompiled functions. r=pierron
authorSean Stangl <sstangl@mozilla.com>
Fri, 27 Apr 2012 16:55:12 -0700
changeset 112428 fb7572ed4bc6832b84b14670c490b61c9db2d278
parent 112427 1b954a5da88ce0fea80b84993a8136c05baa3f6c
child 112429 44911569fb04d891073656cac1f794495723f573
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspierron
bugs749822
milestone14.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 749822 - Pass original argc to uncompiled functions. r=pierron
js/src/ion/CodeGenerator.cpp
js/src/ion/IonBuilder.cpp
js/src/ion/LIR-Common.h
js/src/ion/MIR.cpp
js/src/ion/MIR.h
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -611,19 +611,19 @@ CodeGenerator::visitCallGeneric(LCallGen
 
         typedef bool (*pf)(JSContext *, JSFunction *, uint32, Value *, Value *);
         static const VMFunction InvokeFunctionInfo = FunctionInfo<pf>(InvokeFunction);
 
         // Nestle %esp up to the argument vector.
         // Each path must account for framePushed_ separately, for callVM to be valid.
         masm.freeStack(unusedStack);
 
-        pushArg(StackPointer);          // argv.
-        pushArg(Imm32(call->nargs()));  // argc.
-        pushArg(calleereg);             // JSFunction *.
+        pushArg(StackPointer);                 // argv.
+        pushArg(Imm32(call->bytecodeArgc()));  // argc.
+        pushArg(calleereg);                    // JSFunction *.
 
         if (!callVM(InvokeFunctionInfo, call))
             return false;
 
         // Un-nestle %esp from the argument vector. No prefix was pushed.
         masm.reserveStack(unusedStack);
     }
 
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -2621,17 +2621,17 @@ IonBuilder::makeCall(HandleFunction targ
 
     uint32 targetArgs = argc;
 
     // Collect number of missing arguments provided that the target is
     // scripted. Native functions are passed an explicit 'argc' parameter.
     if (target && !target->isNative())
         targetArgs = Max<uint32>(target->nargs, argc);
 
-    MCall *call = MCall::New(targetArgs + 1, constructing); // +1 for implicit this.
+    MCall *call = MCall::New(targetArgs + 1, argc, constructing); // +1 for implicit this.
     if (!call)
         return false;
 
     // Explicitly pad any missing arguments with |undefined|.
     // This permits skipping the argumentsRectifier.
     for (int i = targetArgs; i > (int)argc; i--) {
         JS_ASSERT_IF(target, !target->isNative());
         MConstant *undef = MConstant::New(UndefinedValue());
--- a/js/src/ion/LIR-Common.h
+++ b/js/src/ion/LIR-Common.h
@@ -414,16 +414,19 @@ class LCallGeneric : public LCallInstruc
     MCall *mir() const {
         return mir_->toCall();
     }
 
     uint32 nargs() const {
         JS_ASSERT(mir()->argc() >= 1);
         return mir()->argc() - 1; // |this| is not a formal argument.
     }
+    uint32 bytecodeArgc() const {
+        return mir()->bytecodeArgc();
+    }
 
     bool hasSingleTarget() const {
         return getSingleTarget() != NULL;
     }
     JSFunction *getSingleTarget() const {
         return mir()->getSingleTarget();
     }
 
--- a/js/src/ion/MIR.cpp
+++ b/js/src/ion/MIR.cpp
@@ -379,19 +379,19 @@ MParameter::congruentTo(MDefinition * co
 {
     if (!ins->isParameter())
         return false;
 
     return ins->toParameter()->index() == index_;
 }
 
 MCall *
-MCall::New(size_t argc, bool construct)
+MCall::New(size_t argc, size_t bytecodeArgc, bool construct)
 {
-    MCall *ins = new MCall(construct);
+    MCall *ins = new MCall(construct, bytecodeArgc);
     if (!ins->init(argc + NumNonArgumentOperands))
         return NULL;
     return ins;
 }
 
 MTest *
 MTest::New(MDefinition *ins, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
 {
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -1118,27 +1118,30 @@ class MCall
     static const size_t FunctionOperandIndex   = 1;
     static const size_t NumNonArgumentOperands = 2;
 
   protected:
     // True if the call is for JSOP_NEW.
     bool construct_;
     // Monomorphic cache of single target from TI, or NULL.
     JSFunction *target_;
-
-    MCall(bool construct)
+    // Original value of argc from the bytecode.
+    uint32 bytecodeArgc_;
+
+    MCall(bool construct, uint32 bytecodeArgc)
       : construct_(construct),
-        target_(NULL)
+        target_(NULL),
+        bytecodeArgc_(bytecodeArgc)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(Call);
-    static MCall *New(size_t argc, bool construct);
+    static MCall *New(size_t argc, size_t bytecodeArgc, bool construct);
 
     void initPrepareCall(MDefinition *start) {
         JS_ASSERT(start->isPrepareCall());
         return initOperand(PrepareCallOperandIndex, start);
     }
     void initFunction(MDefinition *func) {
         JS_ASSERT(!func->isPassArg());
         return initOperand(FunctionOperandIndex, func);
@@ -1169,16 +1172,21 @@ class MCall
         return construct_;
     }
 
     // Includes |this|.
     uint32 argc() const {
         return numOperands() - NumNonArgumentOperands;
     }
 
+    // Includes |this|. Does not include any callsite-added Undefined values.
+    uint32 bytecodeArgc() const {
+        return bytecodeArgc_;
+    }
+
     TypePolicy *typePolicy() {
         return this;
     }
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::Any);
     }
 };