Bug 1541404 part 33 - Implement emitArgumentTypeChecks. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 15 May 2019 14:25:19 +0000
changeset 535836 c9834e23330c28ee333fc83dfb8ba1cf1e113688
parent 535835 03b65e2fa7f638f0089c9f64c69872940e4277f2
child 535837 e7a45a6189d2de0ba53900ca9e480ba0fc3c1d8b
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)
reviewersdjvj
bugs1541404
milestone68.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 1541404 part 33 - Implement emitArgumentTypeChecks. r=djvj Differential Revision: https://phabricator.services.mozilla.com/D31039
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineFrameInfo.cpp
js/src/jit/BaselineFrameInfo.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1396,17 +1396,69 @@ bool BaselineCompilerCodeGen::emitArgume
     }
   }
 
   return true;
 }
 
 template <>
 bool BaselineInterpreterCodeGen::emitArgumentTypeChecks() {
-  MOZ_CRASH("NYI: interpreter emitArgumentTypeChecks");
+  Register scratch1 = R1.scratchReg();
+
+  // If the script is not a function, we're done.
+  Label done;
+  masm.loadPtr(frame.addressOfCalleeToken(), scratch1);
+  masm.branchTestPtr(Assembler::NonZero, scratch1, Imm32(CalleeTokenScriptBit),
+                     &done);
+
+  // CalleeToken_Function or CalleeToken_FunctionConstructing.
+  masm.andPtr(Imm32(uint32_t(CalleeTokenMask)), scratch1);
+
+  // Store nargs in the frame's scratch slot.
+  masm.load16ZeroExtend(Address(scratch1, JSFunction::offsetOfNargs()),
+                        scratch1);
+  masm.store32(scratch1, frame.addressOfScratchValue());
+
+  // Type check |this|.
+  masm.loadValue(frame.addressOfThis(), R0);
+  if (!emitNextIC()) {
+    return false;
+  }
+  frame.bumpInterpreterICEntry();
+
+  // Type check arguments. Scratch1 holds the next argument's index.
+  masm.move32(Imm32(0), scratch1);
+
+  // Bounds check.
+  Label top;
+  masm.bind(&top);
+  masm.branch32(Assembler::Equal, frame.addressOfScratchValue(), scratch1,
+                &done);
+  {
+    // Load the argument, increment argument index. Use the frame's return value
+    // slot to store this index across the IC call.
+    BaseValueIndex addr(BaselineFrameReg, scratch1,
+                        BaselineFrame::offsetOfArg(0));
+    masm.loadValue(addr, R0);
+    masm.add32(Imm32(1), scratch1);
+    masm.store32(scratch1, frame.addressOfReturnValue());
+
+    // Type check the argument.
+    if (!emitNextIC()) {
+      return false;
+    }
+    frame.bumpInterpreterICEntry();
+
+    // Restore argument index.
+    masm.load32(frame.addressOfReturnValue(), scratch1);
+    masm.jump(&top);
+  }
+
+  masm.bind(&done);
+  return true;
 }
 
 bool BaselineCompiler::emitDebugTrap() {
   MOZ_ASSERT(compileDebugInstrumentation());
   MOZ_ASSERT(frame.numUnsyncedSlots() == 0);
 
   JSScript* script = handler.script();
   bool enabled =
@@ -6734,17 +6786,17 @@ bool BaselineInterpreterGenerator::emitI
     if (!BytecodeFallsThrough(op)) {
       // Nothing to do.
       masm.assumeUnreachable("unexpected fall through");
       return true;
     }
 
     // Bump frame->interpreterICEntry if needed.
     if (BytecodeOpHasIC(op)) {
-      masm.addPtr(Imm32(sizeof(ICEntry)), frame.addressOfInterpreterICEntry());
+      frame.bumpInterpreterICEntry();
     }
 
     // Bump frame->interpreterPC, keep pc in PCRegAtStart.
     masm.loadPtr(pcAddr, PCRegAtStart);
     masm.addPtr(Imm32(opLength), PCRegAtStart);
     masm.storePtr(PCRegAtStart, pcAddr);
 
     if (!emitDebugTrap()) {
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BaselineFrameInfo.h"
 
+#include "jit/BaselineIC.h"
 #ifdef DEBUG
 #  include "jit/BytecodeAnalysis.h"
 #endif
 
 #include "jit/BaselineFrameInfo-inl.h"
 #include "jit/MacroAssembler-inl.h"
 
 using namespace js;
@@ -156,16 +157,20 @@ void InterpreterFrameInfo::popRegsAndSyn
       popValue(R0);
       break;
     }
     default:
       MOZ_CRASH("Invalid uses");
   }
 }
 
+void InterpreterFrameInfo::bumpInterpreterICEntry() {
+  masm.addPtr(Imm32(sizeof(ICEntry)), addressOfInterpreterICEntry());
+}
+
 void CompilerFrameInfo::storeStackValue(int32_t depth, const Address& dest,
                                         const ValueOperand& scratch) {
   const StackValue* source = peek(depth);
   switch (source->kind()) {
     case StackValue::Constant:
       masm.storeValue(source->constant(), dest);
       break;
     case StackValue::Register:
--- a/js/src/jit/BaselineFrameInfo.h
+++ b/js/src/jit/BaselineFrameInfo.h
@@ -391,16 +391,18 @@ class InterpreterFrameInfo : public Fram
   void pushScratchValue() { masm.pushValue(addressOfScratchValue()); }
 
   void storeStackValue(int32_t depth, const Address& dest,
                        const ValueOperand& scratch) {
     masm.loadValue(addressOfStackValue(depth), scratch);
     masm.storeValue(scratch, dest);
   }
 
+  void bumpInterpreterICEntry();
+
   Address addressOfInterpreterScript() const {
     return Address(BaselineFrameReg,
                    BaselineFrame::reverseOffsetOfInterpreterScript());
   }
   Address addressOfInterpreterPC() const {
     return Address(BaselineFrameReg,
                    BaselineFrame::reverseOffsetOfInterpreterPC());
   }