Bug 1057082 - 4/7 - Add assembler helpers for later patches. r=jandem
authorKannan Vijayan <kvijayan@mozilla.com>
Thu, 15 Jan 2015 20:11:21 -0500
changeset 224225 acb40b02b52de2cdea2b43bdc98d47cbc5562147
parent 224224 70a8168c7d24fafac7b10f42069d257519999bd4
child 224226 ea8cce9f66303f415a8bc27693bca6582efd3cca
push id54160
push userkvijayan@mozilla.com
push dateFri, 16 Jan 2015 16:05:00 +0000
treeherdermozilla-inbound@809520c9cb0a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1057082
milestone38.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 1057082 - 4/7 - Add assembler helpers for later patches. r=jandem
js/src/jit/MacroAssembler.cpp
js/src/jit/MacroAssembler.h
js/src/jit/shared/Assembler-shared.h
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1921,16 +1921,40 @@ MacroAssembler::finish()
         bind(&failureLabel_);
         handleFailure();
     }
 
     MacroAssemblerSpecific::finish();
 }
 
 void
+MacroAssembler::link(JitCode *code)
+{
+    MOZ_ASSERT(!oom());
+    // If this code can transition to C++ code and witness a GC, then we need to store
+    // the JitCode onto the stack in order to GC it correctly.  exitCodePatch should
+    // be unset if the code never needed to push its JitCode*.
+    if (hasEnteredExitFrame()) {
+        exitCodePatch_.fixup(this);
+        PatchDataWithValueCheck(CodeLocationLabel(code, exitCodePatch_),
+                                ImmPtr(code),
+                                ImmPtr((void*)-1));
+    }
+
+    // Fix up the code pointers to be written for locations where profilerCallSite
+    // emitted moves of RIP to a register.
+    for (size_t i = 0; i < profilerCallSites_.length(); i++) {
+        CodeOffsetLabel offset = profilerCallSites_[i];
+        offset.fixup(this);
+        CodeLocationLabel location(code, offset);
+        PatchDataWithValueCheck(location, ImmPtr(location.raw()), ImmPtr((void*)-1));
+    }
+}
+
+void
 MacroAssembler::branchIfNotInterpretedConstructor(Register fun, Register scratch, Label *label)
 {
     // 16-bit loads are slow and unaligned 32-bit loads may be too so
     // perform an aligned 32-bit load and adjust the bitmask accordingly.
     MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
     MOZ_ASSERT(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2);
 
     // Emit code for the following test:
@@ -2045,8 +2069,33 @@ MacroAssembler::spsUnmarkJit(SPSProfiler
     Label spsNotEnabled;
     pop(temp); // -4: Was the profiler enabled.
     branchTest32(Assembler::Equal, temp, temp, &spsNotEnabled);
 
     spsPopFrameSafe(p, temp);
 
     bind(&spsNotEnabled);
 }
+
+void
+MacroAssembler::profilerPreCallImpl()
+{
+    Register reg = CallTempReg0;
+    Register reg2 = CallTempReg1;
+    push(reg);
+    push(reg2);
+    profilerPreCallImpl(reg, reg2);
+    pop(reg2);
+    pop(reg);
+}
+
+void
+MacroAssembler::profilerPreCallImpl(Register reg, Register reg2)
+{
+    JitContext *icx = GetJitContext();
+    AbsoluteAddress profilingActivation(icx->runtime->addressOfProfilingActivation());
+
+    CodeOffsetLabel label = movWithPatch(ImmWord(uintptr_t(-1)), reg);
+    loadPtr(profilingActivation, reg2);
+    storePtr(reg, Address(reg2, JitActivation::offsetOfLastProfilingCallSite()));
+
+    appendProfilerCallSite(label);
+}
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -859,30 +859,16 @@ class MacroAssembler : public MacroAssem
     void leaveExitFrame() {
         freeStack(ExitFooterFrame::Size());
     }
 
     bool hasEnteredExitFrame() const {
         return exitCodePatch_.offset() != 0;
     }
 
-    void link(JitCode *code) {
-        MOZ_ASSERT(!oom());
-        // If this code can transition to C++ code and witness a GC, then we need to store
-        // the JitCode onto the stack in order to GC it correctly.  exitCodePatch should
-        // be unset if the code never needed to push its JitCode*.
-        if (hasEnteredExitFrame()) {
-            exitCodePatch_.fixup(this);
-            PatchDataWithValueCheck(CodeLocationLabel(code, exitCodePatch_),
-                                    ImmPtr(code),
-                                    ImmPtr((void*)-1));
-        }
-
-    }
-
     // Generates code used to complete a bailout.
     void generateBailoutTail(Register scratch, Register bailoutInfo);
 
     // These functions exist as small wrappers around sites where execution can
     // leave the currently running stream of instructions. They exist so that
     // instrumentation may be put in place around them if necessary and the
     // instrumentation is enabled. For the functions that return a uint32_t,
     // they are returning the offset of the assembler just after the call has
@@ -1146,16 +1132,17 @@ class MacroAssembler : public MacroAssem
         return &failureLabel_;
     }
 
     Label *failureLabel() {
         return &failureLabel_;
     }
 
     void finish();
+    void link(JitCode *code);
 
     void assumeUnreachable(const char *output);
     void printf(const char *output);
     void printf(const char *output, Register value);
 
 #ifdef JS_TRACE_LOGGING
     void tracelogStartId(Register logger, uint32_t textId, bool force = false);
     void tracelogStartId(Register logger, Register textId);
@@ -1417,16 +1404,20 @@ class MacroAssembler : public MacroAssem
 #ifdef DEBUG
         Label ok;
         MOZ_ASSERT(IsPowerOfTwo(alignment));
         branchTestPtr(Assembler::Zero, StackPointer, Imm32(alignment - 1), &ok);
         breakpoint();
         bind(&ok);
 #endif
     }
+
+    void profilerPreCallImpl();
+    void profilerPreCallImpl(Register reg, Register reg2);
+    void profilerPostReturnImpl() {}
 };
 
 static inline Assembler::DoubleCondition
 JSOpToDoubleCondition(JSOp op)
 {
     switch (op) {
       case JSOP_EQ:
       case JSOP_STRICTEQ:
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -892,16 +892,17 @@ struct AsmJSAbsoluteLink
 class AssemblerShared
 {
     Vector<CallSite, 0, SystemAllocPolicy> callsites_;
     Vector<AsmJSHeapAccess, 0, SystemAllocPolicy> asmJSHeapAccesses_;
     Vector<AsmJSGlobalAccess, 0, SystemAllocPolicy> asmJSGlobalAccesses_;
     Vector<AsmJSAbsoluteLink, 0, SystemAllocPolicy> asmJSAbsoluteLinks_;
 
   protected:
+    Vector<CodeOffsetLabel, 0, SystemAllocPolicy> profilerCallSites_;
     bool enoughMemory_;
     bool embedsNurseryPointers_;
 
   public:
     AssemblerShared()
      : enoughMemory_(true),
        embedsNurseryPointers_(false)
     {}
@@ -913,16 +914,20 @@ class AssemblerShared
     void setOOM() {
         enoughMemory_ = false;
     }
 
     bool oom() const {
         return !enoughMemory_;
     }
 
+    void appendProfilerCallSite(CodeOffsetLabel label) {
+        enoughMemory_ &= profilerCallSites_.append(label);
+    }
+
     bool embedsNurseryPointers() const {
         return embedsNurseryPointers_;
     }
 
     ImmGCPtr noteMaybeNurseryPtr(ImmMaybeNurseryPtr ptr) {
         if (ptr.value && gc::IsInsideNursery(ptr.value)) {
             // PJS FIXME bug 1121435
             // FIXME: Ideally we'd assert this in all cases, but PJS needs to