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

LCOV - code coverage report
| Current view: | directory - js/src/methodjit - BaseCompiler.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 41 | 39 | 95.1 %
| Date: | 2012-04-21 | Functions: | 13 | 13 | 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 Anderson <danderson@mozilla.com>
          25                 :  *   David Mandelin <dmandelin@mozilla.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 : #if !defined jsjaeger_compilerbase_h__ && defined JS_METHODJIT
          41                 : #define jsjaeger_compilerbase_h__
          42                 :
          43                 : #include "jscntxt.h"
          44                 : #include "assembler/assembler/MacroAssembler.h"
          45                 : #include "assembler/assembler/LinkBuffer.h"
          46                 : #include "assembler/assembler/RepatchBuffer.h"
          47                 : #include "assembler/jit/ExecutableAllocator.h"
          48                 : #include <limits.h>
          49                 :
          50                 : #if defined JS_CPU_ARM
          51                 : # define POST_INST_OFFSET(__expr) ((__expr) - sizeof(ARMWord))
          52                 : #else
          53                 : # define POST_INST_OFFSET(__expr) (__expr)
          54                 : #endif
          55                 :
          56                 : namespace js {
          57                 : namespace mjit {
          58                 :
          59         2073976 : struct MacroAssemblerTypedefs {
          60                 :     typedef JSC::MacroAssembler::Label Label;
          61                 :     typedef JSC::MacroAssembler::Imm32 Imm32;
          62                 :     typedef JSC::MacroAssembler::ImmPtr ImmPtr;
          63                 :     typedef JSC::MacroAssembler::RegisterID RegisterID;
          64                 :     typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
          65                 :     typedef JSC::MacroAssembler::Address Address;
          66                 :     typedef JSC::MacroAssembler::BaseIndex BaseIndex;
          67                 :     typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
          68                 :     typedef JSC::MacroAssembler MacroAssembler;
          69                 :     typedef JSC::MacroAssembler::Jump Jump;
          70                 :     typedef JSC::MacroAssembler::JumpList JumpList;
          71                 :     typedef JSC::MacroAssembler::Call Call;
          72                 :     typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
          73                 :     typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
          74                 :     typedef JSC::FunctionPtr FunctionPtr;
          75                 :     typedef JSC::RepatchBuffer RepatchBuffer;
          76                 :     typedef JSC::CodeLocationLabel CodeLocationLabel;
          77                 :     typedef JSC::CodeLocationDataLabel32 CodeLocationDataLabel32;
          78                 :     typedef JSC::CodeLocationDataLabelPtr CodeLocationDataLabelPtr;
          79                 :     typedef JSC::CodeLocationJump CodeLocationJump;
          80                 :     typedef JSC::CodeLocationCall CodeLocationCall;
          81                 :     typedef JSC::CodeLocationInstruction CodeLocationInstruction;
          82                 :     typedef JSC::ReturnAddressPtr ReturnAddressPtr;
          83                 :     typedef JSC::MacroAssemblerCodePtr MacroAssemblerCodePtr;
          84                 :     typedef JSC::JITCode JITCode;
          85                 : #if defined JS_CPU_ARM
          86                 :     typedef JSC::ARMWord ARMWord;
          87                 : #endif
          88                 : };
          89                 :
          90                 : class BaseCompiler : public MacroAssemblerTypedefs
          91                 : {
          92                 :   protected:
          93                 :     JSContext *cx;
          94                 :
          95                 :   public:
          96                 :     BaseCompiler() : cx(NULL)
          97                 :     { }
          98                 :
          99         1185717 :     BaseCompiler(JSContext *cx) : cx(cx)
         100         1185717 :     { }
         101                 : };
         102                 :
         103                 : #ifdef JS_CPU_X64
         104                 : inline bool
         105                 : VerifyRange(void *start1, size_t size1, void *start2, size_t size2)
         106                 : {
         107                 :     uintptr_t end1 = uintptr_t(start1) + size1;
         108                 :     uintptr_t end2 = uintptr_t(start2) + size2;
         109                 :
         110                 :     uintptr_t lowest = JS_MIN(uintptr_t(start1), uintptr_t(start2));
         111                 :     uintptr_t highest = JS_MAX(end1, end2);
         112                 :
         113                 :     return (highest - lowest < INT_MAX);
         114                 : }
         115                 : #endif
         116                 :
         117                 : // This class wraps JSC::LinkBuffer for Mozilla-specific memory handling.
         118                 : // Every return |false| guarantees an OOM that has been correctly propagated,
         119                 : // and should continue to propagate.
         120                 : class LinkerHelper : public JSC::LinkBuffer
         121                 : {
         122                 :   protected:
         123                 :     Assembler &masm;
         124                 : #ifdef DEBUG
         125                 :     bool verifiedRange;
         126                 : #endif
         127                 :
         128                 :   public:
         129          307070 :     LinkerHelper(Assembler &masm, JSC::CodeKind kind) : JSC::LinkBuffer(kind)
         130                 :         , masm(masm)
         131                 : #ifdef DEBUG
         132          307070 :         , verifiedRange(false)
         133                 : #endif
         134          307070 :     { }
         135                 :
         136          614140 :     ~LinkerHelper() {
         137          307070 :         JS_ASSERT(verifiedRange);
         138          307070 :     }
         139                 :
         140          568283 :     bool verifyRange(const JSC::JITCode &other) {
         141                 : #ifdef DEBUG
         142          568283 :         verifiedRange = true;
         143                 : #endif
         144                 : #ifdef JS_CPU_X64
         145                 :         return VerifyRange(m_code, m_size, other.start(), other.size());
         146                 : #else
         147          568283 :         return true;
         148                 : #endif
         149                 :     }
         150                 :
         151          306836 :     bool verifyRange(JITChunk *chunk) {
         152                 :         return verifyRange(JSC::JITCode(chunk->code.m_code.executableAddress(),
         153          306836 :                                         chunk->code.m_size));
         154                 :     }
         155                 :
         156          307070 :     JSC::ExecutablePool *init(JSContext *cx) {
         157                 :         // The pool is incref'd after this call, so it's necessary to release()
         158                 :         // on any failure.
         159          307070 :         JSScript *script = cx->fp()->script();
         160          307070 :         JSC::ExecutableAllocator *allocator = script->compartment()->jaegerCompartment()->execAlloc();
         161          307070 :         allocator->setDestroyCallback(Probes::discardExecutableRegion);
         162                 :         JSC::ExecutablePool *pool;
         163          307070 :         m_code = executableAllocAndCopy(masm, allocator, &pool);
         164          307070 :         if (!m_code) {
         165               0 :             js_ReportOutOfMemory(cx);
         166               0 :             return NULL;
         167                 :         }
         168          307070 :         m_size = masm.size();   // must come after call to executableAllocAndCopy()!
         169          307070 :         return pool;
         170                 :     }
         171                 :
         172          304947 :     JSC::CodeLocationLabel finalize(VMFrame &f) {
         173          304947 :         masm.finalize(*this);
         174          304947 :         JSC::CodeLocationLabel label = finalizeCodeAddendum();
         175                 :         Probes::registerICCode(f.cx, f.jit(), f.script(), f.pc(),
         176          304947 :                                label.executableAddress(), masm.size());
         177                 :         return label;
         178                 :     }
         179                 :
         180           17856 :     void maybeLink(MaybeJump jump, JSC::CodeLocationLabel label) {
         181           17856 :         if (!jump.isSet())
         182           11083 :             return;
         183            6773 :         link(jump.get(), label);
         184                 :     }
         185                 :
         186          246823 :     size_t size() const {
         187          246823 :         return m_size;
         188                 :     }
         189                 : };
         190                 :
         191                 : class NativeStubLinker : public LinkerHelper
         192           35561 : {
         193                 :   public:
         194                 : #ifdef JS_CPU_X64
         195                 :     typedef JSC::MacroAssembler::DataLabelPtr FinalJump;
         196                 : #else
         197                 :     typedef JSC::MacroAssembler::Jump FinalJump;
         198                 : #endif
         199                 :
         200           35561 :     NativeStubLinker(Assembler &masm, JITChunk *chunk, jsbytecode *pc, FinalJump done)
         201           35561 :         : LinkerHelper(masm, JSC::METHOD_CODE), chunk(chunk), pc(pc), done(done)
         202           35561 :     {}
         203                 :
         204                 :     bool init(JSContext *cx);
         205                 :
         206           35561 :     void patchJump(JSC::CodeLocationLabel target) {
         207                 : #ifdef JS_CPU_X64
         208                 :         patch(done, target);
         209                 : #else
         210           35561 :         link(done, target);
         211                 : #endif
         212           35561 :     }
         213                 :
         214                 :   private:
         215                 :     JITChunk *chunk;
         216                 :     jsbytecode *pc;
         217                 :     FinalJump done;
         218                 : };
         219                 :
         220                 : bool
         221                 : NativeStubEpilogue(VMFrame &f, Assembler &masm, NativeStubLinker::FinalJump *result,
         222                 :                    int32_t initialFrameDepth, int32_t vpOffset,
         223                 :                    MaybeRegisterID typeReg, MaybeRegisterID dataReg);
         224                 :
         225                 : /*
         226                 :  * On ARM, we periodically flush a constant pool into the instruction stream
         227                 :  * where constants are found using PC-relative addressing. This is necessary
         228                 :  * because the fixed-width instruction set doesn't support wide immediates.
         229                 :  *
         230                 :  * ICs perform repatching on the inline (fast) path by knowing small and
         231                 :  * generally fixed code location offset values where the patchable instructions
         232                 :  * live. Dumping a huge constant pool into the middle of an IC's inline path
         233                 :  * makes the distance between emitted instructions potentially variable and/or
         234                 :  * large, which makes the IC offsets invalid. We must reserve contiguous space
         235                 :  * up front to prevent this from happening.
         236                 :  */
         237                 : #ifdef JS_CPU_ARM
         238                 : template <size_t reservedSpace>
         239                 : class AutoReserveICSpace {
         240                 :     typedef Assembler::Label Label;
         241                 :
         242                 :     Assembler           &masm;
         243                 :     bool                didCheck;
         244                 :     bool                *overflowSpace;
         245                 :     int                 flushCount;
         246                 :
         247                 :   public:
         248                 :     AutoReserveICSpace(Assembler &masm, bool *overflowSpace)
         249                 :         : masm(masm), didCheck(false), overflowSpace(overflowSpace)
         250                 :     {
         251                 :         masm.ensureSpace(reservedSpace);
         252                 :         flushCount = masm.flushCount();
         253                 :     }
         254                 :
         255                 :     /* Allow manual IC space checks so that non-patchable code at the end of an IC section can be
         256                 :      * free to use constant pools. */
         257                 :     void check() {
         258                 :         JS_ASSERT(!didCheck);
         259                 :         didCheck = true;
         260                 :
         261                 :         if (masm.flushCount() != flushCount)
         262                 :             *overflowSpace = true;
         263                 :     }
         264                 :
         265                 :     ~AutoReserveICSpace() {
         266                 :         /* Automatically check the IC space if we didn't already do it manually. */
         267                 :         if (!didCheck) {
         268                 :             check();
         269                 :         }
         270                 :     }
         271                 : };
         272                 :
         273                 : # define RESERVE_IC_SPACE(__masm)       AutoReserveICSpace<256> arics(__masm, &this->overflowICSpace)
         274                 : # define CHECK_IC_SPACE()               arics.check()
         275                 :
         276                 : /* The OOL path can need a lot of space because we save and restore a lot of registers. The actual
         277                 :  * sequene varies. However, dumping the literal pool before an OOL block is probably a good idea
         278                 :  * anyway, as we branch directly to the start of the block from the fast path. */
         279                 : # define RESERVE_OOL_SPACE(__masm)      AutoReserveICSpace<2048> arics_ool(__masm, &this->overflowICSpace)
         280                 :
         281                 : /* Allow the OOL patch to be checked before object destruction. Often, non-patchable epilogues or
         282                 :  * rejoining sequences are emitted, and it isn't necessary to protect these from literal pools. */
         283                 : # define CHECK_OOL_SPACE()              arics_ool.check()
         284                 : #else
         285                 : # define RESERVE_IC_SPACE(__masm)       /* Do nothing. */
         286                 : # define CHECK_IC_SPACE()               /* Do nothing. */
         287                 : # define RESERVE_OOL_SPACE(__masm)      /* Do nothing. */
         288                 : # define CHECK_OOL_SPACE()              /* Do nothing. */
         289                 : #endif
         290                 :
         291                 : } /* namespace js */
         292                 : } /* namespace mjit */
         293                 :
         294                 : #endif

Generated by: LCOV version 1.7