LCOV - code coverage report
Current view: directory - js/src/assembler/assembler - LinkBuffer.h (source / functions) Found Hit Coverage
Test: app.info Lines: 58 58 100.0 %
Date: 2012-06-02 Functions: 18 18 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) 2009 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 LinkBuffer_h
      31                 : #define LinkBuffer_h
      32                 : 
      33                 : #include "assembler/wtf/Platform.h"
      34                 : 
      35                 : #if ENABLE_ASSEMBLER
      36                 : 
      37                 : #include <assembler/MacroAssembler.h>
      38                 : 
      39                 : namespace JSC {
      40                 : 
      41                 : // LinkBuffer:
      42                 : //
      43                 : // This class assists in linking code generated by the macro assembler, once code generation
      44                 : // has been completed, and the code has been copied to is final location in memory.  At this
      45                 : // time pointers to labels within the code may be resolved, and relative offsets to external
      46                 : // addresses may be fixed.
      47                 : //
      48                 : // Specifically:
      49                 : //   * Jump objects may be linked to external targets,
      50                 : //   * The address of Jump objects may taken, such that it can later be relinked.
      51                 : //   * The return address of a Call may be acquired.
      52                 : //   * The address of a Label pointing into the code may be resolved.
      53                 : //   * The value referenced by a DataLabel may be set.
      54                 : //
      55                 : class LinkBuffer {
      56                 :     typedef MacroAssemblerCodeRef CodeRef;
      57                 :     typedef MacroAssembler::Label Label;
      58                 :     typedef MacroAssembler::Jump Jump;
      59                 :     typedef MacroAssembler::JumpList JumpList;
      60                 :     typedef MacroAssembler::Call Call;
      61                 :     typedef MacroAssembler::DataLabel32 DataLabel32;
      62                 :     typedef MacroAssembler::DataLabelPtr DataLabelPtr;
      63                 : 
      64                 : public:
      65                 :     // 'ok' should be checked after this constructor is called;  it's false if OOM occurred.
      66           67095 :     LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator,
      67                 :                ExecutablePool** poolp, bool* ok, CodeKind codeKind)
      68                 :     {
      69           67095 :         m_codeKind = codeKind;
      70           67095 :         m_code = executableAllocAndCopy(*masm, executableAllocator, poolp);
      71           67095 :         m_executablePool = *poolp;
      72           67095 :         m_size = masm->m_assembler.size();  // must come after call to executableAllocAndCopy()!
      73                 : #ifndef NDEBUG
      74           67095 :         m_completed = false;
      75                 : #endif
      76           67095 :         *ok = !!m_code;
      77           67095 :     }
      78                 : 
      79          306058 :     LinkBuffer(CodeKind kind)
      80                 :         : m_executablePool(NULL)
      81                 :         , m_code(NULL)
      82                 :         , m_size(0)
      83                 :         , m_codeKind(kind)
      84                 : #ifndef NDEBUG
      85          306058 :         , m_completed(false)
      86                 : #endif
      87                 :     {
      88          306058 :     }
      89                 : 
      90          515389 :     LinkBuffer(uint8_t* ncode, size_t size, CodeKind kind)
      91                 :         : m_executablePool(NULL)
      92                 :         , m_code(ncode)
      93                 :         , m_size(size)
      94                 :         , m_codeKind(kind)
      95                 : #ifndef NDEBUG
      96          515389 :         , m_completed(false)
      97                 : #endif
      98                 :     {
      99          515389 :     }
     100                 : 
     101          888542 :     ~LinkBuffer()
     102                 :     {
     103          888542 :         ASSERT(!m_executablePool || m_completed);
     104          888542 :     }
     105                 : 
     106                 :     // These methods are used to link or set values at code generation time.
     107                 : 
     108         4905105 :     void link(Call call, FunctionPtr function)
     109                 :     {
     110         4905105 :         ASSERT(call.isFlagSet(Call::Linkable));
     111         4905105 :         MacroAssembler::linkCall(code(), call, function);
     112         4905105 :     }
     113                 :     
     114         9954223 :     void link(Jump jump, CodeLocationLabel label)
     115                 :     {
     116         9954223 :         MacroAssembler::linkJump(code(), jump, label);
     117         9954223 :     }
     118                 : 
     119                 :     void link(JumpList list, CodeLocationLabel label)
     120                 :     {
     121                 :         for (unsigned i = 0; i < list.m_jumps.length(); ++i)
     122                 :             MacroAssembler::linkJump(code(), list.m_jumps[i], label);
     123                 :     }
     124                 : 
     125         1879984 :     void patch(DataLabelPtr label, void* value)
     126                 :     {
     127         1879984 :         MacroAssembler::linkPointer(code(), label.m_label, value);
     128         1879984 :     }
     129                 : 
     130          445049 :     void patch(DataLabelPtr label, CodeLocationLabel value)
     131                 :     {
     132          445049 :         MacroAssembler::linkPointer(code(), label.m_label, value.executableAddress());
     133          445049 :     }
     134                 : 
     135                 :     // These methods are used to obtain handles to allow the code to be relinked / repatched later.
     136                 : 
     137         1419654 :     CodeLocationCall locationOf(Call call)
     138                 :     {
     139         1419654 :         ASSERT(call.isFlagSet(Call::Linkable));
     140         1419654 :         ASSERT(!call.isFlagSet(Call::Near));
     141         1419654 :         return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));
     142                 :     }
     143                 : 
     144          617666 :     CodeLocationJump locationOf(Jump j)
     145                 :     {
     146          617666 :         return CodeLocationJump(MacroAssembler::getLinkerAddress(code(), j.m_jmp));
     147                 :     }
     148                 : 
     149                 :     CodeLocationNearCall locationOfNearCall(Call call)
     150                 :     {
     151                 :         ASSERT(call.isFlagSet(Call::Linkable));
     152                 :         ASSERT(call.isFlagSet(Call::Near));
     153                 :         return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));
     154                 :     }
     155                 : 
     156        14959196 :     CodeLocationLabel locationOf(Label label)
     157                 :     {
     158        14959196 :         return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), label.m_label));
     159                 :     }
     160                 : 
     161          998224 :     CodeLocationDataLabelPtr locationOf(DataLabelPtr label)
     162                 :     {
     163          998224 :         return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), label.m_label));
     164                 :     }
     165                 : 
     166           30761 :     CodeLocationDataLabel32 locationOf(DataLabel32 label)
     167                 :     {
     168           30761 :         return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), label.m_label));
     169                 :     }
     170                 : 
     171                 :     // This method obtains the return address of the call, given as an offset from
     172                 :     // the start of the code.
     173                 :     unsigned returnAddressOffset(Call call)
     174                 :     {
     175                 :         return MacroAssembler::getLinkerCallReturnOffset(call);
     176                 :     }
     177                 : 
     178                 :     // Upon completion of all patching either 'finalizeCode()' or 'finalizeCodeAddendum()' should be called
     179                 :     // once to complete generation of the code.  'finalizeCode()' is suited to situations
     180                 :     // where the executable pool must also be retained, the lighter-weight 'finalizeCodeAddendum()' is
     181                 :     // suited to adding to an existing allocation.
     182           55269 :     CodeRef finalizeCode()
     183                 :     {
     184           55269 :         performFinalization();
     185                 : 
     186           55269 :         return CodeRef(m_code, m_executablePool, m_size);
     187                 :     }
     188          317884 :     CodeLocationLabel finalizeCodeAddendum()
     189                 :     {
     190          317884 :         performFinalization();
     191                 : 
     192          317884 :         return CodeLocationLabel(code());
     193                 :     }
     194                 : 
     195                 : protected:
     196                 :     // Keep this private! - the underlying code should only be obtained externally via 
     197                 :     // finalizeCode() or finalizeCodeAddendum().
     198        36274052 :     void* code()
     199                 :     {
     200        36274052 :         return m_code;
     201                 :     }
     202                 : 
     203          373153 :     void *executableAllocAndCopy(MacroAssembler &masm, ExecutableAllocator *allocator,
     204                 :                                  ExecutablePool **poolp)
     205                 :     {
     206          373153 :         return masm.m_assembler.executableAllocAndCopy(allocator, poolp, m_codeKind);
     207                 :     }
     208                 : 
     209          373153 :     void performFinalization()
     210                 :     {
     211                 : #ifndef NDEBUG
     212          373153 :         ASSERT(!m_completed);
     213          373153 :         m_completed = true;
     214                 : #endif
     215                 : 
     216          373153 :         ExecutableAllocator::makeExecutable(code(), m_size);
     217          373153 :         ExecutableAllocator::cacheFlush(code(), m_size);
     218          373153 :     }
     219                 : 
     220                 :     ExecutablePool* m_executablePool;
     221                 :     void* m_code;
     222                 :     size_t m_size;
     223                 :     CodeKind m_codeKind;
     224                 : #ifndef NDEBUG
     225                 :     bool m_completed;
     226                 : #endif
     227                 : };
     228                 : 
     229                 : } // namespace JSC
     230                 : 
     231                 : #endif // ENABLE(ASSEMBLER)
     232                 : 
     233                 : #endif // LinkBuffer_h

Generated by: LCOV version 1.7