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

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-04-21 | 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           67196 :     LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator,
          67                 :                ExecutablePool** poolp, bool* ok, CodeKind codeKind)
          68                 :     {
          69           67196 :         m_codeKind = codeKind;
          70           67196 :         m_code = executableAllocAndCopy(*masm, executableAllocator, poolp);
          71           67196 :         m_executablePool = *poolp;
          72           67196 :         m_size = masm->m_assembler.size();  // must come after call to executableAllocAndCopy()!
          73                 : #ifndef NDEBUG
          74           67196 :         m_completed = false;
          75                 : #endif
          76           67196 :         *ok = !!m_code;
          77           67196 :     }
          78                 :
          79          307070 :     LinkBuffer(CodeKind kind)
          80                 :         : m_executablePool(NULL)
          81                 :         , m_code(NULL)
          82                 :         , m_size(0)
          83                 :         , m_codeKind(kind)
          84                 : #ifndef NDEBUG
          85          307070 :         , m_completed(false)
          86                 : #endif
          87                 :     {
          88          307070 :     }
          89                 :
          90          516097 :     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          516097 :         , m_completed(false)
          97                 : #endif
          98                 :     {
          99          516097 :     }
         100                 :
         101          890363 :     ~LinkBuffer()
         102                 :     {
         103          890363 :         ASSERT(!m_executablePool || m_completed);
         104          890363 :     }
         105                 :
         106                 :     // These methods are used to link or set values at code generation time.
         107                 :
         108         4919357 :     void link(Call call, FunctionPtr function)
         109                 :     {
         110         4919357 :         ASSERT(call.isFlagSet(Call::Linkable));
         111         4919357 :         MacroAssembler::linkCall(code(), call, function);
         112         4919357 :     }
         113                 :
         114         9976997 :     void link(Jump jump, CodeLocationLabel label)
         115                 :     {
         116         9976997 :         MacroAssembler::linkJump(code(), jump, label);
         117         9976997 :     }
         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         1882796 :     void patch(DataLabelPtr label, void* value)
         126                 :     {
         127         1882796 :         MacroAssembler::linkPointer(code(), label.m_label, value);
         128         1882796 :     }
         129                 :
         130          446202 :     void patch(DataLabelPtr label, CodeLocationLabel value)
         131                 :     {
         132          446202 :         MacroAssembler::linkPointer(code(), label.m_label, value.executableAddress());
         133          446202 :     }
         134                 :
         135                 :     // These methods are used to obtain handles to allow the code to be relinked / repatched later.
         136                 :
         137         1424164 :     CodeLocationCall locationOf(Call call)
         138                 :     {
         139         1424164 :         ASSERT(call.isFlagSet(Call::Linkable));
         140         1424164 :         ASSERT(!call.isFlagSet(Call::Near));
         141         1424164 :         return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));
         142                 :     }
         143                 :
         144          618983 :     CodeLocationJump locationOf(Jump j)
         145                 :     {
         146          618983 :         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        14997839 :     CodeLocationLabel locationOf(Label label)
         157                 :     {
         158        14997839 :         return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), label.m_label));
         159                 :     }
         160                 :
         161          999729 :     CodeLocationDataLabelPtr locationOf(DataLabelPtr label)
         162                 :     {
         163          999729 :         return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), label.m_label));
         164                 :     }
         165                 :
         166           30759 :     CodeLocationDataLabel32 locationOf(DataLabel32 label)
         167                 :     {
         168           30759 :         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           55367 :     CodeRef finalizeCode()
         183                 :     {
         184           55367 :         performFinalization();
         185                 :
         186           55367 :         return CodeRef(m_code, m_executablePool, m_size);
         187                 :     }
         188          318899 :     CodeLocationLabel finalizeCodeAddendum()
         189                 :     {
         190          318899 :         performFinalization();
         191                 :
         192          318899 :         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        36364257 :     void* code()
         199                 :     {
         200        36364257 :         return m_code;
         201                 :     }
         202                 :
         203          374266 :     void *executableAllocAndCopy(MacroAssembler &masm, ExecutableAllocator *allocator,
         204                 :                                  ExecutablePool **poolp)
         205                 :     {
         206          374266 :         return masm.m_assembler.executableAllocAndCopy(allocator, poolp, m_codeKind);
         207                 :     }
         208                 :
         209          374266 :     void performFinalization()
         210                 :     {
         211                 : #ifndef NDEBUG
         212          374266 :         ASSERT(!m_completed);
         213          374266 :         m_completed = true;
         214                 : #endif
         215                 :
         216          374266 :         ExecutableAllocator::makeExecutable(code(), m_size);
         217          374266 :         ExecutableAllocator::cacheFlush(code(), m_size);
         218          374266 :     }
         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