LCOV - app.info - js/src/methodjit/ICRepatcher.h

LCOV - code coverage report
| Current view: | directory - js/src/methodjit - ICRepatcher.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 19 | 19 | 100.0 %
| Date: | 2012-04-07 | Functions: | 6 | 6 | 100.0 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=4 sw=4 et tw=99:
           3                 :  *
           4                 :  * ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
          18                 :  * May 28, 2008.
          19                 :  *
          20                 :  * The Initial Developer of the Original Code is
          21                 :  *   Brendan Eich <brendan@mozilla.org>
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   David Mandelin <dmandelin@mozilla.com>
          25                 :  *   David Anderson <danderson@mozilla.com>
          26                 :  *   Chris Leary <cdleary@mozilla.com>
          27                 :  *   Jacob Bramley <Jacob.Bramely@arm.com>
          28                 :  *
          29                 :  * Alternatively, the contents of this file may be used under the terms of
          30                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          31                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          32                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          33                 :  * of those above. If you wish to allow use of your version of this file only
          34                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          35                 :  * use your version of this file under the terms of the MPL, indicate your
          36                 :  * decision by deleting the provisions above and replace them with the notice
          37                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          38                 :  * the provisions above, a recipient may use your version of this file under
          39                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          40                 :  *
          41                 :  * ***** END LICENSE BLOCK ***** */
          42                 :
          43                 : #if !defined jsjaeger_icrepatcher_h__ && defined JS_METHODJIT
          44                 : #define jsjaeger_icrepatcher_h__
          45                 :
          46                 : #include "assembler/assembler/RepatchBuffer.h"
          47                 : #include "assembler/moco/MocoStubs.h"
          48                 : #include "methodjit/ICChecker.h"
          49                 :
          50                 : namespace js {
          51                 : namespace mjit {
          52                 : namespace ic {
          53                 :
          54                 : class Repatcher : public JSC::RepatchBuffer
          55          307277 : {
          56                 :     typedef JSC::CodeLocationLabel  CodeLocationLabel;
          57                 :     typedef JSC::CodeLocationCall   CodeLocationCall;
          58                 :     typedef JSC::FunctionPtr        FunctionPtr;
          59                 :
          60                 :     CodeLocationLabel label;
          61                 :
          62                 :   public:
          63          262751 :     explicit Repatcher(JITChunk *js)
          64          262751 :       : JSC::RepatchBuffer(js->code), label(js->code.m_code.executableAddress())
          65          262751 :     { }
          66                 :
          67           44526 :     explicit Repatcher(const JSC::JITCode &code)
          68           44526 :       : JSC::RepatchBuffer(code), label(code.start())
          69           44526 :     { }
          70                 :
          71                 :     using JSC::RepatchBuffer::relink;
          72                 :
          73                 :     /* Patch a stub call. */
          74           18039 :     void relink(CodeLocationCall call, FunctionPtr stub) {
          75                 : #if defined JS_CPU_X64 || defined JS_CPU_X86 || defined JS_CPU_SPARC
          76           18039 :         JSC::RepatchBuffer::relink(call, stub);
          77                 : #elif defined JS_CPU_ARM
          78                 :         /*
          79                 :          * Stub calls on ARM look like this:
          80                 :          *
          81                 :          *                  ldr     ip, =stub
          82                 :          * call label ->    ldr     r8, =JaegerStubVeneer
          83                 :          *                  blx     r8
          84                 :          *
          85                 :          * ARM has to run stub calls through a veneer in order for THROW to
          86                 :          * work properly. The address that must be patched is the load into
          87                 :          * 'ip', not the load into 'r8'.
          88                 :          */
          89                 :         CheckIsStubCall(call.labelAtOffset(0));
          90                 :         JSC::RepatchBuffer::relink(call.callAtOffset(-4), stub);
          91                 : #elif defined JS_CPU_MIPS
          92                 :         /*
          93                 :          * Stub calls on MIPS look like this:
          94                 :          *
          95                 :          *                  lui     v0, hi(stub)
          96                 :          *                  ori     v0, v0, lo(stub)
          97                 :          *                  lui     t9, hi(JaegerStubVeneer)
          98                 :          *                  ori     t9, t9, lo(JaegerStubVeneer)
          99                 :          *                  jalr    t9
         100                 :          *                  nop
         101                 :          * call label ->    xxx
         102                 :          *
         103                 :          * MIPS has to run stub calls through a veneer in order for THROW to
         104                 :          * work properly. The address that must be patched is the load into
         105                 :          * 'v0', not the load into 't9'.
         106                 :          */
         107                 :         JSC::RepatchBuffer::relink(call.callAtOffset(-8), stub);
         108                 : #else
         109                 : # error
         110                 : #endif
         111           18039 :     }
         112                 :
         113                 :     /* Patch the offset of a Value load emitted by loadValueWithAddressOffsetPatch. */
         114          162803 :     void patchAddressOffsetForValueLoad(CodeLocationLabel label, uint32_t offset) {
         115                 : #if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC || defined JS_CPU_MIPS
         116                 :         repatch(label.dataLabel32AtOffset(0), offset);
         117                 : #elif defined JS_CPU_X86
         118                 :         static const unsigned LOAD_TYPE_OFFSET = 6;
         119                 :         static const unsigned LOAD_DATA_OFFSET = 12;
         120                 :
         121                 :         /*
         122                 :          * We have the following sequence to patch:
         123                 :          *
         124                 :          *      mov     <offset+4>($base), %<type>
         125                 :          *      mov     <offset+0>($base), %<data>
         126                 :          */
         127          162803 :         repatch(label.dataLabel32AtOffset(LOAD_DATA_OFFSET), offset);
         128          162803 :         repatch(label.dataLabel32AtOffset(LOAD_TYPE_OFFSET), offset + 4);
         129                 : #else
         130                 : # error
         131                 : #endif
         132          162803 :     }
         133                 :
         134           46408 :     void patchAddressOffsetForValueStore(CodeLocationLabel label, uint32_t offset, bool typeConst) {
         135                 : #if defined JS_CPU_ARM || defined JS_CPU_X64 || defined JS_CPU_SPARC || defined JS_CPU_MIPS
         136                 :         (void) typeConst;
         137                 :         repatch(label.dataLabel32AtOffset(0), offset);
         138                 : #elif defined JS_CPU_X86
         139                 :         static const unsigned STORE_TYPE_OFFSET = 6;
         140                 :         static const unsigned STORE_DATA_CONST_TYPE_OFFSET = 16;
         141                 :         static const unsigned STORE_DATA_TYPE_OFFSET = 12;
         142                 :
         143                 :         /*
         144                 :          * The type is stored first, then the payload. Both stores can vary in
         145                 :          * size, depending on whether or not the data is a constant in the
         146                 :          * instruction stream (though only the first store matters for the
         147                 :          * purpose of locating both offsets for patching).
         148                 :          *
         149                 :          * We have one of the following sequences to patch. Offsets are located
         150                 :          * before 6B into a given move instruction, but the mov instructions
         151                 :          * carrying constant payloads are 10B wide overall.
         152                 :          *
         153                 :          *  typeConst=false, dataConst=false
         154                 :          *      mov     %<type>, <offset+4>($base)  ; Length is 6
         155                 :          *      mov     %<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 12
         156                 :          *  typeConst=true, dataConst=false
         157                 :          *      mov     $<type>, <offset+4>($base)  ; Length is 10
         158                 :          *      mov     %<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 16
         159                 :          *  typeConst=true, dataConst=true
         160                 :          *      mov     $<type>, <offset+4>($base)  ; Length is 10
         161                 :          *      mov     $<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 16
         162                 :          *
         163                 :          * Note that we only need to know whether type is const to determine the
         164                 :          * correct patch offsets. In all cases, the label points to the start
         165                 :          * of the sequence.
         166                 :          */
         167           46408 :         repatch(label.dataLabel32AtOffset(STORE_TYPE_OFFSET), offset + 4);
         168                 :
         169           46408 :         unsigned payloadOffset = typeConst ? STORE_DATA_CONST_TYPE_OFFSET : STORE_DATA_TYPE_OFFSET;
         170           46408 :         repatch(label.dataLabel32AtOffset(payloadOffset), offset);
         171                 : #else
         172                 : # error
         173                 : #endif
         174           46408 :     }
         175                 : };
         176                 :
         177                 : } /* namespace ic */
         178                 : } /* namespace mjit */
         179                 : } /* namespace js */
         180                 :
         181                 : #endif

Generated by: LCOV version 1.7