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

LCOV - code coverage report
| Current view: | directory - js/src/methodjit - Compiler.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 138 | 135 | 97.8 %
| Date: | 2012-04-07 | Functions: | 59 | 58 | 98.3 %

           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_compiler_h__ && defined JS_METHODJIT
          41                 : #define jsjaeger_compiler_h__
          42                 :
          43                 : #include "jsanalyze.h"
          44                 : #include "jscntxt.h"
          45                 : #include "MethodJIT.h"
          46                 : #include "CodeGenIncludes.h"
          47                 : #include "BaseCompiler.h"
          48                 : #include "StubCompiler.h"
          49                 : #include "MonoIC.h"
          50                 : #include "PolyIC.h"
          51                 :
          52                 : namespace js {
          53                 : namespace mjit {
          54                 :
          55                 : /*
          56                 :  * Patch for storing call site and rejoin site return addresses at, for
          57                 :  * redirecting the return address in InvariantFailure.
          58                 :  */
          59                 : struct InvariantCodePatch {
          60                 :     bool hasPatch;
          61                 :     JSC::MacroAssembler::DataLabelPtr codePatch;
          62         2780483 :     InvariantCodePatch() : hasPatch(false) {}
          63                 : };
          64                 :
          65                 : struct JSActiveFrame {
          66                 :     JSActiveFrame *parent;
          67                 :     jsbytecode *parentPC;
          68                 :     JSScript *script;
          69                 :
          70                 :     /*
          71                 :      * Index into inlineFrames or OUTER_FRAME, matches this frame's index in
          72                 :      * the cross script SSA.
          73                 :      */
          74                 :     uint32_t inlineIndex;
          75                 :
          76                 :     /* JIT code generation tracking state */
          77                 :     size_t mainCodeStart;
          78                 :     size_t stubCodeStart;
          79                 :     size_t mainCodeEnd;
          80                 :     size_t stubCodeEnd;
          81                 :     size_t inlinePCOffset;
          82                 :
          83                 :     JSActiveFrame();
          84                 : };
          85                 :
          86                 : class Compiler : public BaseCompiler
          87                 : {
          88                 :     friend class StubCompiler;
          89                 :
          90          158595 :     struct BranchPatch {
          91          117507 :         BranchPatch(const Jump &j, jsbytecode *pc, uint32_t inlineIndex)
          92          117507 :           : jump(j), pc(pc), inlineIndex(inlineIndex)
          93          117507 :         { }
          94                 :
          95                 :         Jump jump;
          96                 :         jsbytecode *pc;
          97                 :         uint32_t inlineIndex;
          98                 :     };
          99                 :
         100                 : #if defined JS_MONOIC
         101          420321 :     struct GlobalNameICInfo {
         102                 :         Label fastPathStart;
         103                 :         Call slowPathCall;
         104                 :         DataLabelPtr shape;
         105                 :         DataLabelPtr addrLabel;
         106                 :
         107          420302 :         void copyTo(ic::GlobalNameIC &to, JSC::LinkBuffer &full, JSC::LinkBuffer &stub) {
         108          420302 :             to.fastPathStart = full.locationOf(fastPathStart);
         109                 :
         110          420302 :             int offset = full.locationOf(shape) - to.fastPathStart;
         111          420302 :             to.shapeOffset = offset;
         112          420302 :             JS_ASSERT(to.shapeOffset == offset);
         113                 :
         114          420302 :             to.slowPathCall = stub.locationOf(slowPathCall);
         115          420302 :         }
         116                 :     };
         117                 :
         118         1382026 :     struct GetGlobalNameICInfo : public GlobalNameICInfo {
         119                 :         Label load;
         120                 :     };
         121                 :
         122           81106 :     struct SetGlobalNameICInfo : public GlobalNameICInfo {
         123                 :         Label slowPathStart;
         124                 :         Label fastPathRejoin;
         125                 :         DataLabel32 store;
         126                 :         Jump shapeGuardJump;
         127                 :         ValueRemat vr;
         128                 :         RegisterID objReg;
         129                 :         RegisterID shapeReg;
         130                 :         bool objConst;
         131                 :     };
         132                 :
         133           10483 :     struct EqualityGenInfo {
         134                 :         DataLabelPtr addrLabel;
         135                 :         Label stubEntry;
         136                 :         Call stubCall;
         137                 :         BoolStub stub;
         138                 :         MaybeJump jumpToStub;
         139                 :         Label fallThrough;
         140                 :         jsbytecode *jumpTarget;
         141                 :         bool trampoline;
         142                 :         Label trampolineStart;
         143                 :         ValueRemat lvr, rvr;
         144                 :         Assembler::Condition cond;
         145                 :         JSC::MacroAssembler::RegisterID tempReg;
         146                 :     };
         147                 :
         148                 :     /* InlineFrameAssembler wants to see this. */
         149                 :   public:
         150          236672 :     struct CallGenInfo {
         151                 :         /*
         152                 :          * These members map to members in CallICInfo. See that structure for
         153                 :          * more comments.
         154                 :          */
         155                 :         uint32_t     callIndex;
         156                 :         DataLabelPtr funGuard;
         157                 :         Jump         funJump;
         158                 :         Jump         hotJump;
         159                 :         Call         oolCall;
         160                 :         Label        joinPoint;
         161                 :         Label        slowJoinPoint;
         162                 :         Label        slowPathStart;
         163                 :         Label        hotPathLabel;
         164                 :         DataLabelPtr addrLabel1;
         165                 :         DataLabelPtr addrLabel2;
         166                 :         Jump         oolJump;
         167                 :         Label        icCall;
         168                 :         RegisterID   funObjReg;
         169                 :         FrameSize    frameSize;
         170                 :         bool         typeMonitored;
         171                 :     };
         172                 :
         173                 :   private:
         174                 : #endif
         175                 :
         176                 :     /*
         177                 :      * Writes of call return addresses which needs to be delayed until the final
         178                 :      * absolute address of the join point is known.
         179                 :      */
         180          190509 :     struct CallPatchInfo {
         181          264777 :         CallPatchInfo() : hasFastNcode(false), hasSlowNcode(false), joinSlow(false) {}
         182                 :         Label joinPoint;
         183                 :         DataLabelPtr fastNcodePatch;
         184                 :         DataLabelPtr slowNcodePatch;
         185                 :         bool hasFastNcode;
         186                 :         bool hasSlowNcode;
         187                 :         bool joinSlow;
         188                 :     };
         189                 :
         190                 :     struct BaseICInfo {
         191          156730 :         BaseICInfo(JSOp op) : op(op), canCallHook(false), forcedTypeBarrier(false)
         192          156730 :         { }
         193                 :         Label fastPathStart;
         194                 :         Label fastPathRejoin;
         195                 :         Label slowPathStart;
         196                 :         Call slowPathCall;
         197                 :         DataLabelPtr paramAddr;
         198                 :         JSOp op;
         199                 :         bool canCallHook;
         200                 :         bool forcedTypeBarrier;
         201                 :
         202          156654 :         void copyTo(ic::BaseIC &to, JSC::LinkBuffer &full, JSC::LinkBuffer &stub) {
         203          156654 :             to.fastPathStart = full.locationOf(fastPathStart);
         204          156654 :             to.fastPathRejoin = full.locationOf(fastPathRejoin);
         205          156654 :             to.slowPathStart = stub.locationOf(slowPathStart);
         206          156654 :             to.slowPathCall = stub.locationOf(slowPathCall);
         207          156654 :             to.canCallHook = canCallHook;
         208          156654 :             to.forcedTypeBarrier = forcedTypeBarrier;
         209          156654 :             to.op = op;
         210          156654 :             JS_ASSERT(to.op == op);
         211          156654 :         }
         212                 :     };
         213                 :
         214           24306 :     struct GetElementICInfo : public BaseICInfo {
         215           21656 :         GetElementICInfo(JSOp op) : BaseICInfo(op)
         216           21656 :         { }
         217                 :         RegisterID  typeReg;
         218                 :         RegisterID  objReg;
         219                 :         ValueRemat  id;
         220                 :         MaybeJump   typeGuard;
         221                 :         Jump        shapeGuard;
         222                 :     };
         223                 :
         224            6255 :     struct SetElementICInfo : public BaseICInfo {
         225            5703 :         SetElementICInfo(JSOp op) : BaseICInfo(op)
         226            5703 :         { }
         227                 :         RegisterID  objReg;
         228                 :         StateRemat  objRemat;
         229                 :         ValueRemat  vr;
         230                 :         Jump        capacityGuard;
         231                 :         Jump        shapeGuard;
         232                 :         Jump        holeGuard;
         233                 :         Int32Key    key;
         234                 :         uint32_t    volatileMask;
         235                 :     };
         236                 :
         237          182359 :     struct PICGenInfo : public BaseICInfo {
         238          129371 :         PICGenInfo(ic::PICInfo::Kind kind, JSOp op)
         239          129371 :           : BaseICInfo(op), kind(kind), typeMonitored(false)
         240          129371 :         { }
         241                 :         ic::PICInfo::Kind kind;
         242                 :         Label typeCheck;
         243                 :         RegisterID shapeReg;
         244                 :         RegisterID objReg;
         245                 :         RegisterID typeReg;
         246                 :         Label shapeGuard;
         247                 :         jsbytecode *pc;
         248                 :         PropertyName *name;
         249                 :         bool hasTypeCheck;
         250                 :         bool typeMonitored;
         251                 :         types::TypeSet *rhsTypes;
         252                 :         ValueRemat vr;
         253                 :         union {
         254                 :             ic::GetPropLabels getPropLabels_;
         255                 :             ic::SetPropLabels setPropLabels_;
         256                 :             ic::BindNameLabels bindNameLabels_;
         257                 :             ic::ScopeNameLabels scopeNameLabels_;
         258                 :         };
         259                 :
         260          155799 :         ic::GetPropLabels &getPropLabels() {
         261          155799 :             JS_ASSERT(kind == ic::PICInfo::GET);
         262          155799 :             return getPropLabels_;
         263                 :         }
         264           31700 :         ic::SetPropLabels &setPropLabels() {
         265           31700 :             JS_ASSERT(kind == ic::PICInfo::SET);
         266           31700 :             return setPropLabels_;
         267                 :         }
         268            6150 :         ic::BindNameLabels &bindNameLabels() {
         269            6150 :             JS_ASSERT(kind == ic::PICInfo::BIND);
         270            6150 :             return bindNameLabels_;
         271                 :         }
         272           65025 :         ic::ScopeNameLabels &scopeNameLabels() {
         273               0 :             JS_ASSERT(kind == ic::PICInfo::NAME ||
         274           65025 :                       kind == ic::PICInfo::XNAME);
         275           65025 :             return scopeNameLabels_;
         276                 :         }
         277                 :
         278          129303 :         void copySimpleMembersTo(ic::PICInfo &ic) {
         279          129303 :             ic.kind = kind;
         280          129303 :             ic.shapeReg = shapeReg;
         281          129303 :             ic.objReg = objReg;
         282          129303 :             ic.name = name;
         283          129303 :             if (ic.isSet()) {
         284           15850 :                 ic.u.vr = vr;
         285          113453 :             } else if (ic.isGet()) {
         286           77873 :                 ic.u.get.typeReg = typeReg;
         287           77873 :                 ic.u.get.hasTypeCheck = hasTypeCheck;
         288                 :             }
         289          129303 :             ic.typeMonitored = typeMonitored;
         290          129303 :             ic.rhsTypes = rhsTypes;
         291          129303 :             if (ic.isGet())
         292           77873 :                 ic.setLabels(getPropLabels());
         293           51430 :             else if (ic.isSet())
         294           15850 :                 ic.setLabels(setPropLabels());
         295           35580 :             else if (ic.isBind())
         296            3075 :                 ic.setLabels(bindNameLabels());
         297           32505 :             else if (ic.isScopeName())
         298           32505 :                 ic.setLabels(scopeNameLabels());
         299          129303 :         }
         300                 :
         301                 :     };
         302                 :
         303                 :     struct Defs {
         304                 :         Defs(uint32_t ndefs)
         305                 :           : ndefs(ndefs)
         306                 :         { }
         307                 :         uint32_t ndefs;
         308                 :     };
         309                 :
         310         5701195 :     struct InternalCallSite {
         311                 :         uint32_t returnOffset;
         312                 :         DataLabelPtr inlinePatch;
         313                 :         uint32_t inlineIndex;
         314                 :         jsbytecode *inlinepc;
         315                 :         RejoinState rejoin;
         316                 :         bool ool;
         317                 :         Label loopJumpLabel;
         318                 :         InvariantCodePatch loopPatch;
         319                 :
         320         2780483 :         InternalCallSite(uint32_t returnOffset,
         321                 :                          uint32_t inlineIndex, jsbytecode *inlinepc,
         322                 :                          RejoinState rejoin, bool ool)
         323                 :           : returnOffset(returnOffset),
         324                 :             inlineIndex(inlineIndex), inlinepc(inlinepc),
         325         2780483 :             rejoin(rejoin), ool(ool)
         326         2780483 :         { }
         327                 :     };
         328                 :
         329               0 :     struct DoublePatch {
         330                 :         double d;
         331                 :         DataLabelPtr label;
         332                 :         bool ool;
         333                 :     };
         334                 :
         335             524 :     struct JumpTable {
         336                 :         DataLabelPtr label;
         337                 :         size_t offsetIndex;
         338                 :     };
         339                 :
         340            2038 :     struct JumpTableEdge {
         341                 :         uint32_t source;
         342                 :         uint32_t target;
         343                 :     };
         344                 :
         345              10 :     struct ChunkJumpTableEdge {
         346                 :         JumpTableEdge edge;
         347                 :         void **jumpTableEntry;
         348                 :     };
         349                 :
         350           68964 :     struct LoopEntry {
         351                 :         uint32_t pcOffset;
         352                 :         Label label;
         353                 :     };
         354                 :
         355                 :     /*
         356                 :      * Information about the current type of an argument or local in the
         357                 :      * script. The known type tag of these types is cached when possible to
         358                 :      * avoid generating duplicate dependency constraints.
         359                 :      */
         360                 :     class VarType {
         361                 :         JSValueType type;
         362                 :         types::TypeSet *types;
         363                 :
         364                 :       public:
         365          375947 :         void setTypes(types::TypeSet *types) {
         366          375947 :             this->types = types;
         367          375947 :             this->type = JSVAL_TYPE_MISSING;
         368          375947 :         }
         369                 :
         370                 :         types::TypeSet *getTypes() { return types; }
         371                 :
         372          644567 :         JSValueType getTypeTag(JSContext *cx) {
         373          644567 :             if (type == JSVAL_TYPE_MISSING)
         374          213733 :                 type = types ? types->getKnownTypeTag(cx) : JSVAL_TYPE_UNKNOWN;
         375          644567 :             return type;
         376                 :         }
         377                 :     };
         378                 :
         379            3592 :     struct OutgoingChunkEdge {
         380                 :         uint32_t source;
         381                 :         uint32_t target;
         382                 :
         383                 : #ifdef JS_CPU_X64
         384                 :         Label sourceTrampoline;
         385                 : #endif
         386                 :
         387                 :         Jump fastJump;
         388                 :         MaybeJump slowJump;
         389                 :     };
         390                 :
         391                 :     struct SlotType
         392                 :     {
         393                 :         uint32_t slot;
         394                 :         VarType vt;
         395                 :         SlotType(uint32_t slot, VarType vt) : slot(slot), vt(vt) {}
         396                 :     };
         397                 :
         398                 :     JSScript *outerScript;
         399                 :     unsigned chunkIndex;
         400                 :     bool isConstructing;
         401                 :     ChunkDescriptor outerChunk;
         402                 :
         403                 :     /* SSA information for the outer script and all frames we will be inlining. */
         404                 :     analyze::CrossScriptSSA ssa;
         405                 :
         406                 :     GlobalObject *globalObj;
         407                 :     const HeapSlot *globalSlots;  /* Original slots pointer. */
         408                 :
         409                 :     Assembler masm;
         410                 :     FrameState frame;
         411                 :
         412                 :     /*
         413                 :      * State for the current stack frame, and links to its parents going up to
         414                 :      * the outermost script.
         415                 :      */
         416                 :
         417                 : public:
         418                 :     struct ActiveFrame : public JSActiveFrame {
         419                 :         Label *jumpMap;
         420                 :
         421                 :         /* Current types for non-escaping vars in the script. */
         422                 :         VarType *varTypes;
         423                 :
         424                 :         /* State for managing return from inlined frames. */
         425                 :         bool needReturnValue;          /* Return value will be used. */
         426                 :         bool syncReturnValue;          /* Return value should be fully synced. */
         427                 :         bool returnValueDouble;        /* Return value should be a double. */
         428                 :         bool returnSet;                /* Whether returnRegister is valid. */
         429                 :         AnyRegisterID returnRegister;  /* Register holding return value. */
         430                 :         const FrameEntry *returnEntry; /* Entry copied by return value. */
         431                 :         Vector<Jump, 4, CompilerAllocPolicy> *returnJumps;
         432                 :
         433                 :         /*
         434                 :          * Snapshot of the heap state to use after the call, in case
         435                 :          * there are multiple return paths the inlined frame could take.
         436                 :          */
         437                 :         RegisterAllocation *exitState;
         438                 :
         439                 :         ActiveFrame(JSContext *cx);
         440                 :         ~ActiveFrame();
         441                 :     };
         442                 :
         443                 : private:
         444                 :     ActiveFrame *a;
         445                 :     ActiveFrame *outer;
         446                 :
         447                 :     JSScript *script;
         448                 :     analyze::ScriptAnalysis *analysis;
         449                 :     jsbytecode *PC;
         450                 :
         451                 :     LoopState *loop;
         452                 :
         453                 :     /* State spanning all stack frames. */
         454                 :
         455                 :     js::Vector<ActiveFrame*, 4, CompilerAllocPolicy> inlineFrames;
         456                 :     js::Vector<BranchPatch, 64, CompilerAllocPolicy> branchPatches;
         457                 : #if defined JS_MONOIC
         458                 :     js::Vector<GetGlobalNameICInfo, 16, CompilerAllocPolicy> getGlobalNames;
         459                 :     js::Vector<SetGlobalNameICInfo, 16, CompilerAllocPolicy> setGlobalNames;
         460                 :     js::Vector<CallGenInfo, 64, CompilerAllocPolicy> callICs;
         461                 :     js::Vector<EqualityGenInfo, 64, CompilerAllocPolicy> equalityICs;
         462                 : #endif
         463                 : #if defined JS_POLYIC
         464                 :     js::Vector<PICGenInfo, 16, CompilerAllocPolicy> pics;
         465                 :     js::Vector<GetElementICInfo, 16, CompilerAllocPolicy> getElemICs;
         466                 :     js::Vector<SetElementICInfo, 16, CompilerAllocPolicy> setElemICs;
         467                 : #endif
         468                 :     js::Vector<CallPatchInfo, 64, CompilerAllocPolicy> callPatches;
         469                 :     js::Vector<InternalCallSite, 64, CompilerAllocPolicy> callSites;
         470                 :     js::Vector<DoublePatch, 16, CompilerAllocPolicy> doubleList;
         471                 :     js::Vector<uint32_t> fixedIntToDoubleEntries;
         472                 :     js::Vector<uint32_t> fixedDoubleToAnyEntries;
         473                 :     js::Vector<JumpTable, 16> jumpTables;
         474                 :     js::Vector<JumpTableEdge, 16> jumpTableEdges;
         475                 :     js::Vector<LoopEntry, 16> loopEntries;
         476                 :     js::Vector<OutgoingChunkEdge, 16> chunkEdges;
         477                 :     StubCompiler stubcc;
         478                 :     Label invokeLabel;
         479                 :     Label arityLabel;
         480                 :     Label argsCheckLabel;
         481                 : #ifdef JS_MONOIC
         482                 :     Label argsCheckStub;
         483                 :     Label argsCheckFallthrough;
         484                 :     Jump argsCheckJump;
         485                 : #endif
         486                 :     bool debugMode_;
         487                 :     bool inlining_;
         488                 :     bool hasGlobalReallocation;
         489                 :     bool oomInVector;       // True if we have OOM'd appending to a vector.
         490                 :     bool overflowICSpace;   // True if we added a constant pool in a reserved space.
         491                 :     uint64_t gcNumber;
         492                 :     enum { NoApplyTricks, LazyArgsObj } applyTricks;
         493                 :     PCLengthEntry *pcLengths;
         494                 :
         495         1917240 :     Compiler *thisFromCtor() { return this; }
         496                 :
         497                 :     friend class CompilerAllocPolicy;
         498                 :   public:
         499                 :     Compiler(JSContext *cx, JSScript *outerScript, unsigned chunkIndex, bool isConstructing);
         500                 :     ~Compiler();
         501                 :
         502                 :     CompileStatus compile();
         503                 :
         504         1944055 :     Label getLabel() { return masm.label(); }
         505                 :     bool knownJump(jsbytecode *pc);
         506                 :     Label labelOf(jsbytecode *target, uint32_t inlineIndex);
         507                 :     void addCallSite(const InternalCallSite &callSite);
         508                 :     void addReturnSite();
         509                 :     void inlineStubCall(void *stub, RejoinState rejoin, Uses uses);
         510                 :
         511          756888 :     bool debugMode() { return debugMode_; }
         512          593824 :     bool inlining() { return inlining_; }
         513            4937 :     bool constructing() { return isConstructing; }
         514                 :
         515         2606267 :     jsbytecode *outerPC() {
         516         2606267 :         if (a == outer)
         517         2579229 :             return PC;
         518           27038 :         ActiveFrame *scan = a;
         519           68095 :         while (scan && scan->parent != outer)
         520           14019 :             scan = static_cast<ActiveFrame *>(scan->parent);
         521           27038 :         return scan->parentPC;
         522                 :     }
         523                 :
         524          944030 :     JITScript *outerJIT() {
         525          944030 :         return outerScript->getJIT(isConstructing);
         526                 :     }
         527                 :
         528          376818 :     ChunkDescriptor &outerChunkRef() {
         529          376818 :         return outerJIT()->chunkDescriptor(chunkIndex);
         530                 :     }
         531                 :
         532          490900 :     bool bytecodeInChunk(jsbytecode *pc) {
         533                 :         return (unsigned(pc - outerScript->code) >= outerChunk.begin)
         534          490900 :             && (unsigned(pc - outerScript->code) < outerChunk.end);
         535                 :     }
         536                 :
         537         2095663 :     jsbytecode *inlinePC() { return PC; }
         538         2234289 :     uint32_t inlineIndex() { return a->inlineIndex; }
         539                 :
         540           31930 :     Assembler &getAssembler(bool ool) { return ool ? stubcc.masm : masm; }
         541                 :
         542            8351 :     InvariantCodePatch *getInvariantPatch(unsigned index) {
         543            8351 :         return &callSites[index].loopPatch;
         544                 :     }
         545            8740 :     jsbytecode *getInvariantPC(unsigned index) {
         546            8740 :         return callSites[index].inlinepc;
         547                 :     }
         548                 :
         549           16509 :     bool activeFrameHasMultipleExits() {
         550           16509 :         ActiveFrame *na = a;
         551           33196 :         while (na->parent) {
         552             199 :             if (na->exitState)
         553              21 :                 return true;
         554             178 :             na = static_cast<ActiveFrame *>(na->parent);
         555                 :         }
         556           16488 :         return false;
         557                 :     }
         558                 :
         559                 :   private:
         560                 :     CompileStatus performCompilation();
         561                 :     CompileStatus generatePrologue();
         562                 :     CompileStatus generateMethod();
         563                 :     CompileStatus generateEpilogue();
         564                 :     CompileStatus finishThisUp();
         565                 :     CompileStatus pushActiveFrame(JSScript *script, uint32_t argc);
         566                 :     void popActiveFrame();
         567                 :     void updatePCCounts(jsbytecode *pc, Label *start, bool *updated);
         568                 :     void updatePCTypes(jsbytecode *pc, FrameEntry *fe);
         569                 :     void updateArithCounts(jsbytecode *pc, FrameEntry *fe,
         570                 :                              JSValueType firstUseType, JSValueType secondUseType);
         571                 :     void updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
         572                 :     void bumpPropCount(jsbytecode *pc, int count);
         573                 :
         574                 :     /* Analysis helpers. */
         575                 :     CompileStatus prepareInferenceTypes(JSScript *script, ActiveFrame *a);
         576                 :     void ensureDoubleArguments();
         577                 :     void markUndefinedLocal(uint32_t offset, uint32_t i);
         578                 :     void markUndefinedLocals();
         579                 :     void fixDoubleTypes(jsbytecode *target);
         580                 :     void watchGlobalReallocation();
         581                 :     void updateVarType();
         582                 :     void updateJoinVarTypes();
         583                 :     void restoreVarType();
         584                 :     JSValueType knownPushedType(uint32_t pushed);
         585                 :     bool mayPushUndefined(uint32_t pushed);
         586                 :     types::TypeSet *pushedTypeSet(uint32_t which);
         587                 :     bool monitored(jsbytecode *pc);
         588                 :     bool hasTypeBarriers(jsbytecode *pc);
         589                 :     bool testSingletonProperty(JSObject *obj, jsid id);
         590                 :     bool testSingletonPropertyTypes(FrameEntry *top, jsid id, bool *testObject);
         591                 :     CompileStatus addInlineFrame(JSScript *script, uint32_t depth, uint32_t parent, jsbytecode *parentpc);
         592                 :     CompileStatus scanInlineCalls(uint32_t index, uint32_t depth);
         593                 :     CompileStatus checkAnalysis(JSScript *script);
         594                 :
         595          850917 :     struct BarrierState {
         596                 :         MaybeJump jump;
         597                 :         RegisterID typeReg;
         598                 :         RegisterID dataReg;
         599                 :     };
         600                 :
         601                 :     MaybeJump trySingleTypeTest(types::TypeSet *types, RegisterID typeReg);
         602                 :     Jump addTypeTest(types::TypeSet *types, RegisterID typeReg, RegisterID dataReg);
         603                 :     BarrierState pushAddressMaybeBarrier(Address address, JSValueType type, bool reuseBase,
         604                 :                                          bool testUndefined = false);
         605                 :     BarrierState testBarrier(RegisterID typeReg, RegisterID dataReg,
         606                 :                              bool testUndefined = false, bool testReturn = false,
         607                 :                              bool force = false);
         608                 :     void finishBarrier(const BarrierState &barrier, RejoinState rejoin, uint32_t which);
         609                 :
         610                 :     void testPushedType(RejoinState rejoin, int which, bool ool = true);
         611                 :
         612                 :     /* Non-emitting helpers. */
         613                 :     void pushSyncedEntry(uint32_t pushed);
         614                 :     bool jumpInScript(Jump j, jsbytecode *pc);
         615                 :     bool compareTwoValues(JSContext *cx, JSOp op, const Value &lhs, const Value &rhs);
         616                 :     bool canUseApplyTricks();
         617                 :
         618                 :     /* Emitting helpers. */
         619                 :     bool constantFoldBranch(jsbytecode *target, bool taken);
         620                 :     bool emitStubCmpOp(BoolStub stub, jsbytecode *target, JSOp fused);
         621                 :     bool iter(unsigned flags);
         622                 :     void iterNext(ptrdiff_t offset);
         623                 :     bool iterMore(jsbytecode *target);
         624                 :     void iterEnd();
         625                 :     MaybeJump loadDouble(FrameEntry *fe, FPRegisterID *fpReg, bool *allocated);
         626                 : #ifdef JS_POLYIC
         627                 :     void passICAddress(BaseICInfo *ic);
         628                 : #endif
         629                 : #ifdef JS_MONOIC
         630                 :     void passMICAddress(GlobalNameICInfo &mic);
         631                 : #endif
         632                 :     bool constructThis();
         633                 :     void ensureDouble(FrameEntry *fe);
         634                 :
         635                 :     /*
         636                 :      * Ensure fe is an integer, truncating from double if necessary, or jump to
         637                 :      * the slow path per uses.
         638                 :      */
         639                 :     void ensureInteger(FrameEntry *fe, Uses uses);
         640                 :
         641                 :     /* Convert fe from a double to integer (per ValueToECMAInt32) in place. */
         642                 :     void truncateDoubleToInt32(FrameEntry *fe, Uses uses);
         643                 :
         644                 :     /*
         645                 :      * Try to convert a double fe to an integer, with no truncation performed,
         646                 :      * or jump to the slow path per uses.
         647                 :      */
         648                 :     void tryConvertInteger(FrameEntry *fe, Uses uses);
         649                 :
         650                 :     /* Opcode handlers. */
         651                 :     bool jumpAndRun(Jump j, jsbytecode *target,
         652                 :                     Jump *slow = NULL, bool *trampoline = NULL,
         653                 :                     bool fallthrough = false);
         654                 :     bool startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
         655                 :     bool finishLoop(jsbytecode *head);
         656                 :     inline bool shouldStartLoop(jsbytecode *head);
         657                 :     void jsop_bindname(PropertyName *name);
         658                 :     void jsop_setglobal(uint32_t index);
         659                 :     void jsop_getprop_slow(PropertyName *name, bool forPrototype = false);
         660                 :     void jsop_getarg(uint32_t slot);
         661                 :     void jsop_setarg(uint32_t slot, bool popped);
         662                 :     void jsop_this();
         663                 :     void emitReturn(FrameEntry *fe);
         664                 :     void emitFinalReturn(Assembler &masm);
         665                 :     void loadReturnValue(Assembler *masm, FrameEntry *fe);
         666                 :     void emitReturnValue(Assembler *masm, FrameEntry *fe);
         667                 :     void emitInlineReturnValue(FrameEntry *fe);
         668                 :     void dispatchCall(VoidPtrStubUInt32 stub, uint32_t argc);
         669                 :     void interruptCheckHelper();
         670                 :     void recompileCheckHelper();
         671                 :     void emitUncachedCall(uint32_t argc, bool callingNew);
         672                 :     void checkCallApplySpeculation(uint32_t callImmArgc, uint32_t speculatedArgc,
         673                 :                                    FrameEntry *origCallee, FrameEntry *origThis,
         674                 :                                    MaybeRegisterID origCalleeType, RegisterID origCalleeData,
         675                 :                                    MaybeRegisterID origThisType, RegisterID origThisData,
         676                 :                                    Jump *uncachedCallSlowRejoin, CallPatchInfo *uncachedCallPatch);
         677                 :     bool inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &callFrameSize);
         678                 :     void fixPrimitiveReturn(Assembler *masm, FrameEntry *fe);
         679                 :     void jsop_getgname(uint32_t index);
         680                 :     void jsop_getgname_slow(uint32_t index);
         681                 :     void jsop_setgname(PropertyName *name, bool popGuaranteed);
         682                 :     void jsop_setgname_slow(PropertyName *name);
         683                 :     void jsop_bindgname();
         684                 :     void jsop_setelem_slow();
         685                 :     void jsop_getelem_slow();
         686                 :     bool jsop_getprop(PropertyName *name, JSValueType type,
         687                 :                       bool typeCheck = true, bool forPrototype = false);
         688                 :     bool jsop_getprop_dispatch(PropertyName *name);
         689                 :     bool jsop_setprop(PropertyName *name, bool popGuaranteed);
         690                 :     void jsop_setprop_slow(PropertyName *name);
         691                 :     bool jsop_instanceof();
         692                 :     void jsop_name(PropertyName *name, JSValueType type);
         693                 :     bool jsop_xname(PropertyName *name);
         694                 :     void enterBlock(StaticBlockObject *block);
         695                 :     void leaveBlock();
         696                 :     void emitEval(uint32_t argc);
         697                 :     void jsop_arguments(RejoinState rejoin);
         698                 :     bool jsop_tableswitch(jsbytecode *pc);
         699                 :
         700                 :     /* Fast arithmetic. */
         701                 :     bool jsop_binary_slow(JSOp op, VoidStub stub, JSValueType type, FrameEntry *lhs, FrameEntry *rhs);
         702                 :     bool jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::TypeSet *typeSet);
         703                 :     void jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op, VoidStub stub,
         704                 :                           JSValueType type, bool cannotOverflow, bool ignoreOverflow);
         705                 :     void jsop_binary_full_simple(FrameEntry *fe, JSOp op, VoidStub stub,
         706                 :                                  JSValueType type);
         707                 :     void jsop_binary_double(FrameEntry *lhs, FrameEntry *rhs, JSOp op, VoidStub stub,
         708                 :                             JSValueType type);
         709                 :     void slowLoadConstantDouble(Assembler &masm, FrameEntry *fe,
         710                 :                                 FPRegisterID fpreg);
         711                 :     void maybeJumpIfNotInt32(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
         712                 :                              MaybeRegisterID &mreg);
         713                 :     void maybeJumpIfNotDouble(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
         714                 :                               MaybeRegisterID &mreg);
         715                 :     bool jsop_relational(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
         716                 :     bool jsop_relational_full(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
         717                 :     bool jsop_relational_double(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
         718                 :     bool jsop_relational_int(JSOp op, jsbytecode *target, JSOp fused);
         719                 :
         720                 :     void emitLeftDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
         721                 :                             MaybeJump &lhsNotDouble, MaybeJump &rhsNotNumber,
         722                 :                             MaybeJump &lhsUnknownDone);
         723                 :     void emitRightDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
         724                 :                              MaybeJump &rhsNotNumber2);
         725                 :     bool tryBinaryConstantFold(JSContext *cx, FrameState &frame, JSOp op,
         726                 :                                FrameEntry *lhs, FrameEntry *rhs, Value *vp);
         727                 :
         728                 :     /* Fast opcodes. */
         729                 :     void jsop_bitop(JSOp op);
         730                 :     bool jsop_mod();
         731                 :     void jsop_neg();
         732                 :     void jsop_bitnot();
         733                 :     void jsop_not();
         734                 :     void jsop_typeof();
         735                 :     bool booleanJumpScript(JSOp op, jsbytecode *target);
         736                 :     bool jsop_ifneq(JSOp op, jsbytecode *target);
         737                 :     bool jsop_andor(JSOp op, jsbytecode *target);
         738                 :     bool jsop_arginc(JSOp op, uint32_t slot);
         739                 :     bool jsop_localinc(JSOp op, uint32_t slot);
         740                 :     bool jsop_newinit();
         741                 :     bool jsop_regexp();
         742                 :     void jsop_initmethod();
         743                 :     void jsop_initprop();
         744                 :     void jsop_initelem();
         745                 :     void jsop_setelem_dense();
         746                 : #ifdef JS_METHODJIT_TYPED_ARRAY
         747                 :     void jsop_setelem_typed(int atype);
         748                 :     void convertForTypedArray(int atype, ValueRemat *vr, bool *allocated);
         749                 : #endif
         750                 :     bool jsop_setelem(bool popGuaranteed);
         751                 :     bool jsop_getelem();
         752                 :     void jsop_getelem_dense(bool isPacked);
         753                 :     void jsop_getelem_args();
         754                 : #ifdef JS_METHODJIT_TYPED_ARRAY
         755                 :     bool jsop_getelem_typed(int atype);
         756                 : #endif
         757                 :     void jsop_toid();
         758                 :     bool isCacheableBaseAndIndex(FrameEntry *obj, FrameEntry *id);
         759                 :     void jsop_stricteq(JSOp op);
         760                 :     bool jsop_equality(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
         761                 :     CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused);
         762                 :     bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
         763                 :     void jsop_pos();
         764                 :     void jsop_in();
         765                 :
         766                 :     static inline Assembler::Condition
         767           42727 :     GetCompareCondition(JSOp op, JSOp fused)
         768                 :     {
         769           42727 :         bool ifeq = fused == JSOP_IFEQ;
         770           42727 :         switch (op) {
         771                 :           case JSOP_GT:
         772            2704 :             return ifeq ? Assembler::LessThanOrEqual : Assembler::GreaterThan;
         773                 :           case JSOP_GE:
         774            1832 :             return ifeq ? Assembler::LessThan : Assembler::GreaterThanOrEqual;
         775                 :           case JSOP_LT:
         776           36515 :             return ifeq ? Assembler::GreaterThanOrEqual : Assembler::LessThan;
         777                 :           case JSOP_LE:
         778            1264 :             return ifeq ? Assembler::GreaterThan : Assembler::LessThanOrEqual;
         779                 :           case JSOP_STRICTEQ:
         780                 :           case JSOP_EQ:
         781             287 :             return ifeq ? Assembler::NotEqual : Assembler::Equal;
         782                 :           case JSOP_STRICTNE:
         783                 :           case JSOP_NE:
         784             125 :             return ifeq ? Assembler::Equal : Assembler::NotEqual;
         785                 :           default:
         786               0 :             JS_NOT_REACHED("unrecognized op");
         787                 :             return Assembler::Equal;
         788                 :         }
         789                 :     }
         790                 :
         791                 :     static inline Assembler::Condition
         792           48168 :     GetStubCompareCondition(JSOp fused)
         793                 :     {
         794           48168 :         return fused == JSOP_IFEQ ? Assembler::Zero : Assembler::NonZero;
         795                 :     }
         796                 :
         797                 :     /* Fast builtins. */
         798                 :     JSObject *pushedSingleton(unsigned pushed);
         799                 :     CompileStatus callArrayBuiltin(uint32_t argc, bool callingNew);
         800                 :     CompileStatus inlineNativeFunction(uint32_t argc, bool callingNew);
         801                 :     CompileStatus inlineScriptedFunction(uint32_t argc, bool callingNew);
         802                 :     CompileStatus compileMathAbsInt(FrameEntry *arg);
         803                 :     CompileStatus compileMathAbsDouble(FrameEntry *arg);
         804                 :     CompileStatus compileMathSqrt(FrameEntry *arg);
         805                 :     CompileStatus compileMathMinMaxDouble(FrameEntry *arg1, FrameEntry *arg2,
         806                 :                                           Assembler::DoubleCondition cond);
         807                 :     CompileStatus compileMathMinMaxInt(FrameEntry *arg1, FrameEntry *arg2,
         808                 :                                        Assembler::Condition cond);
         809                 :     CompileStatus compileMathPowSimple(FrameEntry *arg1, FrameEntry *arg2);
         810                 :     CompileStatus compileArrayPush(FrameEntry *thisv, FrameEntry *arg);
         811                 :     CompileStatus compileArrayConcat(types::TypeSet *thisTypes, types::TypeSet *argTypes,
         812                 :                                      FrameEntry *thisValue, FrameEntry *argValue);
         813                 :     CompileStatus compileArrayPopShift(FrameEntry *thisv, bool isPacked, bool isArrayPop);
         814                 :     CompileStatus compileArrayWithLength(uint32_t argc);
         815                 :     CompileStatus compileArrayWithArgs(uint32_t argc);
         816                 :
         817                 :     enum RoundingMode { Floor, Round };
         818                 :     CompileStatus compileRound(FrameEntry *arg, RoundingMode mode);
         819                 :
         820                 :     enum GetCharMode { GetChar, GetCharCode };
         821                 :     CompileStatus compileGetChar(FrameEntry *thisValue, FrameEntry *arg, GetCharMode mode);
         822                 :
         823                 :     CompileStatus compileStringFromCode(FrameEntry *arg);
         824                 :     CompileStatus compileParseInt(JSValueType argType, uint32_t argc);
         825                 :
         826                 :     void prepareStubCall(Uses uses);
         827                 :     Call emitStubCall(void *ptr, DataLabelPtr *pinline);
         828                 : };
         829                 :
         830                 : // Given a stub call, emits the call into the inline assembly path. rejoin
         831                 : // indicates how to rejoin should this call trigger expansion/discarding.
         832                 : #define INLINE_STUBCALL(stub, rejoin)                                       \
         833                 :     inlineStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0))
         834                 : #define INLINE_STUBCALL_USES(stub, rejoin, uses)                            \
         835                 :     inlineStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, uses)
         836                 :
         837                 : // Given a stub call, emits the call into the out-of-line assembly path.
         838                 : // Unlike the INLINE_STUBCALL variant, this returns the Call offset.
         839                 : #define OOL_STUBCALL(stub, rejoin)                                          \
         840                 :     stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0))
         841                 : #define OOL_STUBCALL_USES(stub, rejoin, uses)                               \
         842                 :     stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, uses)
         843                 :
         844                 : // Same as OOL_STUBCALL, but specifies a slot depth.
         845                 : #define OOL_STUBCALL_LOCAL_SLOTS(stub, rejoin, slots)                       \
         846                 :     stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0), (slots))
         847                 :
         848                 : } /* namespace js */
         849                 : } /* namespace mjit */
         850                 :
         851                 : #endif
         852                 :

Generated by: LCOV version 1.7