LCOV - code coverage report
Current view: top level - js/src/jit/x86-shared - AssemblerBuffer-x86-shared.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 51 64.7 %
Date: 2017-07-14 16:53:18 Functions: 20 24 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  *
       4             :  * ***** BEGIN LICENSE BLOCK *****
       5             :  * Copyright (C) 2008 Apple Inc. All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
      17             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      18             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      19             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
      20             :  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      21             :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      22             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      23             :  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
      24             :  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             :  *
      28             :  * ***** END LICENSE BLOCK ***** */
      29             : 
      30             : #ifndef jit_x86_shared_AssemblerBuffer_x86_shared_h
      31             : #define jit_x86_shared_AssemblerBuffer_x86_shared_h
      32             : 
      33             : #include <stdarg.h>
      34             : #include <string.h>
      35             : 
      36             : #include "ds/PageProtectingVector.h"
      37             : #include "jit/ExecutableAllocator.h"
      38             : #include "jit/JitSpewer.h"
      39             : 
      40             : // Spew formatting helpers.
      41             : #define PRETTYHEX(x)                       (((x)<0)?"-":""),(((x)<0)?-(x):(x))
      42             : 
      43             : #define MEM_o     "%s0x%x"
      44             : #define MEM_os    MEM_o   "(,%s,%d)"
      45             : #define MEM_ob    MEM_o   "(%s)"
      46             : #define MEM_obs   MEM_o   "(%s,%s,%d)"
      47             : 
      48             : #define MEM_o32   "%s0x%04x"
      49             : #define MEM_o32s  MEM_o32 "(,%s,%d)"
      50             : #define MEM_o32b  MEM_o32 "(%s)"
      51             : #define MEM_o32bs MEM_o32 "(%s,%s,%d)"
      52             : #define MEM_o32r  ".Lfrom%d(%%rip)"
      53             : 
      54             : #define ADDR_o(offset)                       PRETTYHEX(offset)
      55             : #define ADDR_os(offset, index, scale)        ADDR_o(offset), GPRegName((index)), (1<<(scale))
      56             : #define ADDR_ob(offset, base)                ADDR_o(offset), GPRegName((base))
      57             : #define ADDR_obs(offset, base, index, scale) ADDR_ob(offset, base), GPRegName((index)), (1<<(scale))
      58             : 
      59             : #define ADDR_o32(offset)                       ADDR_o(offset)
      60             : #define ADDR_o32s(offset, index, scale)        ADDR_os(offset, index, scale)
      61             : #define ADDR_o32b(offset, base)                ADDR_ob(offset, base)
      62             : #define ADDR_o32bs(offset, base, index, scale) ADDR_obs(offset, base, index, scale)
      63             : #define ADDR_o32r(offset)                      (offset)
      64             : 
      65             : namespace js {
      66             : 
      67             :     class Sprinter;
      68             : 
      69             : namespace jit {
      70             : 
      71        4503 :     class AssemblerBuffer
      72             :     {
      73             :         template<size_t size, typename T>
      74     3724296 :         MOZ_ALWAYS_INLINE void sizedAppendUnchecked(T value)
      75             :         {
      76     3724296 :             m_buffer.infallibleAppend(reinterpret_cast<unsigned char*>(&value), size);
      77     3724853 :         }
      78             : 
      79             :         template<size_t size, typename T>
      80         306 :         MOZ_ALWAYS_INLINE void sizedAppend(T value)
      81             :         {
      82         306 :             if (MOZ_UNLIKELY(!m_buffer.append(reinterpret_cast<unsigned char*>(&value), size)))
      83           0 :                 oomDetected();
      84         306 :         }
      85             : 
      86             :     public:
      87        4503 :         AssemblerBuffer() : m_oom(false) {}
      88             : 
      89     1119893 :         void ensureSpace(size_t space)
      90             :         {
      91     1119893 :             if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space)))
      92           0 :                 oomDetected();
      93     1119939 :         }
      94             : 
      95       25908 :         bool isAligned(size_t alignment) const
      96             :         {
      97       25908 :             return !(m_buffer.length() & (alignment - 1));
      98             :         }
      99             : 
     100     3338469 :         MOZ_ALWAYS_INLINE void putByteUnchecked(int value) { sizedAppendUnchecked<1>(value); }
     101        1040 :         MOZ_ALWAYS_INLINE void putShortUnchecked(int value) { sizedAppendUnchecked<2>(value); }
     102      303320 :         MOZ_ALWAYS_INLINE void putIntUnchecked(int value) { sizedAppendUnchecked<4>(value); }
     103       81378 :         MOZ_ALWAYS_INLINE void putInt64Unchecked(int64_t value) { sizedAppendUnchecked<8>(value); }
     104             : 
     105         306 :         MOZ_ALWAYS_INLINE void putByte(int value) { sizedAppend<1>(value); }
     106             :         MOZ_ALWAYS_INLINE void putShort(int value) { sizedAppend<2>(value); }
     107             :         MOZ_ALWAYS_INLINE void putInt(int value) { sizedAppend<4>(value); }
     108             :         MOZ_ALWAYS_INLINE void putInt64(int64_t value) { sizedAppend<8>(value); }
     109             : 
     110           0 :         MOZ_MUST_USE bool append(const unsigned char* values, size_t size)
     111             :         {
     112           0 :             if (MOZ_UNLIKELY(!m_buffer.append(values, size))) {
     113           0 :                 oomDetected();
     114           0 :                 return false;
     115             :             }
     116           0 :             return true;
     117             :         }
     118             : 
     119      636903 :         size_t size() const
     120             :         {
     121      636903 :             return m_buffer.length();
     122             :         }
     123             : 
     124      256035 :         bool oom() const
     125             :         {
     126      256035 :             return m_oom;
     127             :         }
     128             : 
     129        4499 :         const unsigned char* buffer() const
     130             :         {
     131        4499 :             MOZ_RELEASE_ASSERT(!m_oom);
     132        4499 :             return m_buffer.begin();
     133             :         }
     134             : 
     135      142599 :         unsigned char* data()
     136             :         {
     137      142599 :             return m_buffer.begin();
     138             :         }
     139             : 
     140             : #ifndef RELEASE_OR_BETA
     141           0 :         void disableProtection() { m_buffer.disableProtection(); }
     142             :         void enableProtection() { m_buffer.enableProtection(); }
     143             :         void setLowerBoundForProtection(size_t size)
     144             :         {
     145             :             m_buffer.setLowerBoundForProtection(size);
     146             :         }
     147             :         void unprotectRegion(unsigned char* first, size_t size)
     148             :         {
     149             :             m_buffer.unprotectRegion(first, size);
     150             :         }
     151             :         void reprotectRegion(unsigned char* first, size_t size)
     152             :         {
     153             :             m_buffer.reprotectRegion(first, size);
     154             :         }
     155             : #else
     156             :         void disableProtection() {}
     157             :         void enableProtection() {}
     158             :         void setLowerBoundForProtection(size_t) {}
     159             :         void unprotectRegion(unsigned char*, size_t) {}
     160             :         void reprotectRegion(unsigned char*, size_t) {}
     161             : #endif
     162             : 
     163             :     protected:
     164             :         /*
     165             :          * OOM handling: This class can OOM in the ensureSpace() method trying
     166             :          * to allocate a new buffer. In response to an OOM, we need to avoid
     167             :          * crashing and report the error. We also want to make it so that
     168             :          * users of this class need to check for OOM only at certain points
     169             :          * and not after every operation.
     170             :          *
     171             :          * Our strategy for handling an OOM is to set m_oom, and then clear (but
     172             :          * not free) m_buffer, preserving the current buffer. This way, the user
     173             :          * can continue assembling into the buffer, deferring OOM checking
     174             :          * until the user wants to read code out of the buffer.
     175             :          *
     176             :          * See also the |buffer| method.
     177             :          */
     178           0 :         void oomDetected()
     179             :         {
     180           0 :             m_oom = true;
     181           0 :             m_buffer.clear();
     182           0 :         }
     183             : 
     184             : #ifndef RELEASE_OR_BETA
     185             :         PageProtectingVector<unsigned char, 256, ProtectedReallocPolicy,
     186             :                              /* ProtectUsed = */ false, /* ProtectUnused = */ false> m_buffer;
     187             : #else
     188             :         mozilla::Vector<unsigned char, 256, SystemAllocPolicy> m_buffer;
     189             : #endif
     190             :         bool m_oom;
     191             :     };
     192             : 
     193             :     class GenericAssembler
     194             :     {
     195             : #ifdef JS_JITSPEW
     196             :         Sprinter* printer;
     197             : #endif
     198             :       public:
     199             : 
     200        4503 :         GenericAssembler()
     201             : #ifdef JS_JITSPEW
     202        4503 :           : printer(nullptr)
     203             : #endif
     204        4503 :         {}
     205             : 
     206           0 :         void setPrinter(Sprinter* sp)
     207             :         {
     208             : #ifdef JS_JITSPEW
     209           0 :             printer = sp;
     210             : #endif
     211           0 :         }
     212             : 
     213             : #ifdef JS_JITSPEW
     214     1367819 :         inline void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3)
     215             :         {
     216     1367819 :             if (MOZ_UNLIKELY(printer || JitSpewEnabled(JitSpew_Codegen))) {
     217             :                 va_list va;
     218           0 :                 va_start(va, fmt);
     219           0 :                 spew(fmt, va);
     220           0 :                 va_end(va);
     221             :             }
     222     1367817 :         }
     223             : #else
     224             :         MOZ_ALWAYS_INLINE void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3)
     225             :         { }
     226             : #endif
     227             : 
     228             : #ifdef JS_JITSPEW
     229             :         MOZ_COLD void spew(const char* fmt, va_list va) MOZ_FORMAT_PRINTF(2, 0);
     230             : #endif
     231             :     };
     232             : 
     233             : } // namespace jit
     234             : } // namespace js
     235             : 
     236             : #endif /* jit_x86_shared_AssemblerBuffer_x86_shared_h */

Generated by: LCOV version 1.13