| Index: src/mips64/builtins-mips64.cc
 | 
| diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc
 | 
| index c63d92d69d1d820e60454b4091e6647c757f2b7b..8243c5d81309398ea537be996d58999de1433cf4 100644
 | 
| --- a/src/mips64/builtins-mips64.cc
 | 
| +++ b/src/mips64/builtins-mips64.cc
 | 
| @@ -347,6 +347,7 @@ static void Generate_Runtime_NewObject(MacroAssembler* masm,
 | 
|  
 | 
|  static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|                                             bool is_api_function,
 | 
| +                                           bool use_new_target,
 | 
|                                             bool create_memento) {
 | 
|    // ----------- S t a t e -------------
 | 
|    //  -- a0     : number of arguments
 | 
| @@ -378,10 +379,13 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|        __ push(a2);
 | 
|      }
 | 
|  
 | 
| -    // Preserve the two incoming parameters on the stack.
 | 
| -    // Tag arguments count.
 | 
| -    __ dsll32(a0, a0, 0);
 | 
| -    __ MultiPushReversed(a0.bit() | a1.bit());
 | 
| +    // Preserve the incoming parameters on the stack.
 | 
| +    __ SmiTag(a0);
 | 
| +    if (use_new_target) {
 | 
| +      __ Push(a0, a1, a3);
 | 
| +    } else {
 | 
| +      __ Push(a0, a1);
 | 
| +    }
 | 
|  
 | 
|      Label rt_call, allocated, normal_new, count_incremented;
 | 
|      __ Branch(&normal_new, eq, a1, Operand(a3));
 | 
| @@ -636,7 +640,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|      __ bind(&allocated);
 | 
|  
 | 
|      if (create_memento) {
 | 
| -      __ ld(a2, MemOperand(sp, kPointerSize * 2));
 | 
| +      int offset = (use_new_target ? 3 : 2) * kPointerSize;
 | 
| +      __ ld(a2, MemOperand(sp, offset));
 | 
|        __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
 | 
|        __ Branch(&count_incremented, eq, a2, Operand(t1));
 | 
|        // a2 is an AllocationSite. We are creating a memento from it, so we
 | 
| @@ -649,22 +654,24 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|        __ bind(&count_incremented);
 | 
|      }
 | 
|  
 | 
| +    // Restore the parameters.
 | 
| +    if (use_new_target) {
 | 
| +      __ Pop(a3);  // new.target
 | 
| +    }
 | 
|      __ Pop(a1);
 | 
|  
 | 
| -    __ Push(t0, t0);
 | 
| +    __ ld(a0, MemOperand(sp));
 | 
| +    __ SmiUntag(a0);
 | 
|  
 | 
| -    // Reload the number of arguments from the stack.
 | 
| -    // sp[0]: receiver
 | 
| -    // sp[1]: receiver
 | 
| -    // sp[2]: number of arguments (smi-tagged)
 | 
| -    __ ld(a3, MemOperand(sp, 2 * kPointerSize));
 | 
| +    if (use_new_target) {
 | 
| +      __ Push(a3, t0, t0);
 | 
| +    } else {
 | 
| +      __ Push(t0, t0);
 | 
| +    }
 | 
|  
 | 
|      // Set up pointer to last argument.
 | 
|      __ Daddu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
 | 
|  
 | 
| -    // Set up number of arguments for function call below.
 | 
| -    __ SmiUntag(a0, a3);
 | 
| -
 | 
|      // Copy arguments and receiver to the expression stack.
 | 
|      // a0: number of arguments
 | 
|      // a1: constructor function
 | 
| @@ -672,9 +679,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|      // a3: number of arguments (smi-tagged)
 | 
|      // sp[0]: receiver
 | 
|      // sp[1]: receiver
 | 
| -    // sp[2]: number of arguments (smi-tagged)
 | 
| +    // sp[2]: new.target (if used)
 | 
| +    // sp[2/3]: number of arguments (smi-tagged)
 | 
|      Label loop, entry;
 | 
| -    __ SmiUntag(a3);
 | 
| +    __ mov(a3, a0);
 | 
|      __ jmp(&entry);
 | 
|      __ bind(&loop);
 | 
|      __ dsll(a4, a3, kPointerSizeLog2);
 | 
| @@ -699,7 +707,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|      }
 | 
|  
 | 
|      // Store offset of return address for deoptimizer.
 | 
| -    if (!is_api_function) {
 | 
| +    // TODO(arv): Remove the "!use_new_target" before supporting optimization
 | 
| +    // of functions that reference new.target
 | 
| +    if (!is_api_function && !use_new_target) {
 | 
|        masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
 | 
|      }
 | 
|  
 | 
| @@ -714,7 +724,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|      // If the result is a smi, it is *not* an object in the ECMA sense.
 | 
|      // v0: result
 | 
|      // sp[0]: receiver (newly allocated object)
 | 
| -    // sp[1]: number of arguments (smi-tagged)
 | 
| +    // sp[1]: new.target (if used)
 | 
| +    // sp[1/2]: number of arguments (smi-tagged)
 | 
|      __ JumpIfSmi(v0, &use_receiver);
 | 
|  
 | 
|      // If the type of the result (stored in its map) is less than
 | 
| @@ -732,8 +743,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|      __ bind(&exit);
 | 
|      // v0: result
 | 
|      // sp[0]: receiver (newly allocated object)
 | 
| -    // sp[1]: number of arguments (smi-tagged)
 | 
| -    __ ld(a1, MemOperand(sp, kPointerSize));
 | 
| +    // sp[1]: new.target (if used)
 | 
| +    // sp[1/2]: number of arguments (smi-tagged)
 | 
| +    int offset = (use_new_target ? 2 : 1) * kPointerSize;
 | 
| +    __ ld(a1, MemOperand(sp, offset));
 | 
|  
 | 
|      // Leave construct frame.
 | 
|    }
 | 
| @@ -747,12 +760,17 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 | 
|  
 | 
|  
 | 
|  void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
 | 
| -  Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
 | 
| +  Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
 | 
|  }
 | 
|  
 | 
|  
 | 
|  void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
 | 
| -  Generate_JSConstructStubHelper(masm, true, false);
 | 
| +  Generate_JSConstructStubHelper(masm, true, false, false);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
 | 
| +  Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |