LCOV - app.info - js/src/assembler/assembler/AssemblerBuffer.h

LCOV - code coverage report
| Current view: | directory - js/src/assembler/assembler - AssemblerBuffer.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 67 | 56 | 83.6 %
| Date: | 2012-04-07 | Functions: | 13 | 13 | 100.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=79:
           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 AssemblerBuffer_h
          31                 : #define AssemblerBuffer_h
          32                 :
          33                 : #include "assembler/wtf/Platform.h"
          34                 :
          35                 : #if ENABLE_ASSEMBLER
          36                 :
          37                 : #include <string.h>
          38                 : #include "assembler/jit/ExecutableAllocator.h"
          39                 : #include "assembler/wtf/Assertions.h"
          40                 :
          41                 : namespace JSC {
          42                 :
          43                 :     class AssemblerBuffer {
          44                 :         static const int inlineCapacity = 256;
          45                 :     public:
          46          384107 :         AssemblerBuffer()
          47                 :             : m_buffer(m_inlineBuffer)
          48                 :             , m_capacity(inlineCapacity)
          49                 :             , m_size(0)
          50          384107 :             , m_oom(false)
          51                 :         {
          52          384107 :         }
          53                 :
          54          384107 :         ~AssemblerBuffer()
          55                 :         {
          56          384107 :             if (m_buffer != m_inlineBuffer)
          57          140380 :                 free(m_buffer);
          58          384107 :         }
          59                 :
          60        70355661 :         void ensureSpace(int space)
          61                 :         {
          62        70355661 :             if (m_size > m_capacity - space)
          63          311219 :                 grow();
          64        70355661 :         }
          65                 :
          66                 :         bool isAligned(int alignment) const
          67                 :         {
          68                 :             return !(m_size & (alignment - 1));
          69                 :         }
          70                 :
          71       190828974 :         void putByteUnchecked(int value)
          72                 :         {
          73       190828974 :             ASSERT(!(m_size > m_capacity - 4));
          74       190828974 :             m_buffer[m_size] = char(value);
          75       190828974 :             m_size++;
          76       190828974 :         }
          77                 :
          78         3610374 :         void putByte(int value)
          79                 :         {
          80         3610374 :             if (m_size > m_capacity - 4)
          81               0 :                 grow();
          82         3610374 :             putByteUnchecked(value);
          83         3610374 :         }
          84                 :
          85             281 :         void putShortUnchecked(int value)
          86                 :         {
          87             281 :             ASSERT(!(m_size > m_capacity - 4));
          88             281 :             *reinterpret_cast<short*>(&m_buffer[m_size]) = short(value);
          89             281 :             m_size += 2;
          90             281 :         }
          91                 :
          92                 :         void putShort(int value)
          93                 :         {
          94                 :             if (m_size > m_capacity - 4)
          95                 :                 grow();
          96                 :             putShortUnchecked(value);
          97                 :         }
          98                 :
          99        29874914 :         void putIntUnchecked(int value)
         100                 :         {
         101        29874914 :             ASSERT(!(m_size > m_capacity - 4));
         102        29874914 :             *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
         103        29874914 :             m_size += 4;
         104        29874914 :         }
         105                 :
         106                 :         void putInt64Unchecked(int64_t value)
         107                 :         {
         108                 :             ASSERT(!(m_size > m_capacity - 8));
         109                 :             *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value;
         110                 :             m_size += 8;
         111                 :         }
         112                 :
         113                 :         void putInt(int value)
         114                 :         {
         115                 :             if (m_size > m_capacity - 4)
         116                 :                 grow();
         117                 :             putIntUnchecked(value);
         118                 :         }
         119                 :
         120         4764764 :         void* data() const
         121                 :         {
         122         4764764 :             return m_buffer;
         123                 :         }
         124                 :
         125        45139401 :         int size() const
         126                 :         {
         127        45139401 :             return m_size;
         128                 :         }
         129                 :
         130          669360 :         bool oom() const
         131                 :         {
         132          669360 :             return m_oom;
         133                 :         }
         134                 :
         135                 :         /*
         136                 :          * The user must check for a NULL return value, which means
         137                 :          * no code was generated, or there was an OOM.
         138                 :          */
         139          104165 :         void* executableAllocAndCopy(ExecutableAllocator* allocator, ExecutablePool** poolp, CodeKind kind)
         140                 :         {
         141          104165 :             if (m_oom || m_size == 0) {
         142               0 :                 *poolp = NULL;
         143               0 :                 return 0;
         144                 :             }
         145                 :
         146          104165 :             void* result = allocator->alloc(m_size, poolp, kind);
         147          104165 :             if (!result) {
         148               0 :                 *poolp = NULL;
         149               0 :                 return 0;
         150                 :             }
         151          104165 :             JS_ASSERT(*poolp);
         152                 :
         153          104165 :             ExecutableAllocator::makeWritable(result, m_size);
         154                 :
         155          104165 :             return memcpy(result, m_buffer, m_size);
         156                 :         }
         157                 :
         158          187304 :         unsigned char *buffer() const {
         159          187304 :             ASSERT(!m_oom);
         160          187304 :             return reinterpret_cast<unsigned char *>(m_buffer);
         161                 :         }
         162                 :
         163                 :     protected:
         164                 :         void append(const char* data, int size)
         165                 :         {
         166                 :             if (m_size > m_capacity - size)
         167                 :                 grow(size);
         168                 :
         169                 :             // If we OOM and size > inlineCapacity, this would crash.
         170                 :             if (m_oom)
         171                 :                 return;
         172                 :             memcpy(m_buffer + m_size, data, size);
         173                 :             m_size += size;
         174                 :         }
         175                 :
         176                 :         /*
         177                 :          * OOM handling: This class can OOM in the grow() method trying to
         178                 :          * allocate a new buffer. In response to an OOM, we need to avoid
         179                 :          * crashing and report the error. We also want to make it so that
         180                 :          * users of this class need to check for OOM only at certain points
         181                 :          * and not after every operation.
         182                 :          *
         183                 :          * Our strategy for handling an OOM is to set m_oom, and then set
         184                 :          * m_size to 0, preserving the current buffer. This way, the user
         185                 :          * can continue assembling into the buffer, deferring OOM checking
         186                 :          * until the user wants to read code out of the buffer.
         187                 :          *
         188                 :          * See also the |executableAllocAndCopy| and |buffer| methods.
         189                 :          */
         190                 :
         191          311219 :         void grow(int extraCapacity = 0)
         192                 :         {
         193                 :             /*
         194                 :              * If |extraCapacity| is zero (as it almost always is) this is an
         195                 :              * allocator-friendly doubling growth strategy.
         196                 :              */
         197          311219 :             int newCapacity = m_capacity + m_capacity + extraCapacity;
         198                 :             char* newBuffer;
         199                 :
         200          311219 :             if (m_buffer == m_inlineBuffer) {
         201          140380 :                 newBuffer = static_cast<char*>(malloc(newCapacity));
         202          140380 :                 if (!newBuffer) {
         203               0 :                     m_size = 0;
         204               0 :                     m_oom = true;
         205               0 :                     return;
         206                 :                 }
         207          140380 :                 memcpy(newBuffer, m_buffer, m_size);
         208                 :             } else {
         209          170839 :                 newBuffer = static_cast<char*>(realloc(m_buffer, newCapacity));
         210          170839 :                 if (!newBuffer) {
         211               0 :                     m_size = 0;
         212               0 :                     m_oom = true;
         213               0 :                     return;
         214                 :                 }
         215                 :             }
         216                 :
         217          311219 :             m_buffer = newBuffer;
         218          311219 :             m_capacity = newCapacity;
         219                 :         }
         220                 :
         221                 :         char m_inlineBuffer[inlineCapacity];
         222                 :         char* m_buffer;
         223                 :         int m_capacity;
         224                 :         int m_size;
         225                 :         bool m_oom;
         226                 :     };
         227                 :
         228                 : } // namespace JSC
         229                 :
         230                 : #endif // ENABLE(ASSEMBLER)
         231                 :
         232                 : #endif // AssemblerBuffer_h

Generated by: LCOV version 1.7