LCOV - code coverage report
Current view: top level - js/src/jit - IonIC.h (source / functions) Hit Total Coverage
Test: output.info Lines: 89 122 73.0 %
Date: 2017-07-14 16:53:18 Functions: 49 72 68.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_IonIC_h
       8             : #define jit_IonIC_h
       9             : 
      10             : #include "jit/CacheIR.h"
      11             : 
      12             : namespace js {
      13             : namespace jit {
      14             : 
      15             : class CacheIRStubInfo;
      16             : 
      17             : // An optimized stub attached to an IonIC.
      18             : class IonICStub
      19             : {
      20             :     // Code to jump to when this stub fails. This is either the next optimized
      21             :     // stub or the OOL fallback path.
      22             :     uint8_t* nextCodeRaw_;
      23             : 
      24             :     // The next optimized stub in this chain, or nullptr if this is the last
      25             :     // one.
      26             :     IonICStub* next_;
      27             : 
      28             :     // Info about this stub.
      29             :     CacheIRStubInfo* stubInfo_;
      30             : 
      31             :   public:
      32          21 :     IonICStub(uint8_t* fallbackCode, CacheIRStubInfo* stubInfo)
      33          21 :       : nextCodeRaw_(fallbackCode), next_(nullptr), stubInfo_(stubInfo)
      34          21 :     {}
      35             : 
      36           0 :     uint8_t* nextCodeRaw() const { return nextCodeRaw_; }
      37          32 :     uint8_t** nextCodeRawPtr() { return &nextCodeRaw_; }
      38          16 :     CacheIRStubInfo* stubInfo() const { return stubInfo_; }
      39          38 :     IonICStub* next() const { return next_; }
      40             : 
      41             :     uint8_t* stubDataStart();
      42             : 
      43           6 :     void setNext(IonICStub* next, JitCode* nextCode) {
      44           6 :         MOZ_ASSERT(!next_);
      45           6 :         MOZ_ASSERT(next && nextCode);
      46           6 :         next_ = next;
      47           6 :         nextCodeRaw_ = nextCode->raw();
      48           6 :     }
      49             : 
      50             :     // Null out pointers when we unlink stubs, to ensure we never use
      51             :     // discarded stubs.
      52           6 :     void poison() {
      53           6 :         nextCodeRaw_ = nullptr;
      54           6 :         next_ = nullptr;
      55           6 :         stubInfo_ = nullptr;
      56           6 :     }
      57             : };
      58             : 
      59             : class IonGetPropertyIC;
      60             : class IonSetPropertyIC;
      61             : class IonGetNameIC;
      62             : class IonBindNameIC;
      63             : class IonHasOwnIC;
      64             : class IonInIC;
      65             : 
      66             : class IonIC
      67             : {
      68             :     // This either points at the OOL path for the fallback path, or the code for
      69             :     // the first stub.
      70             :     uint8_t* codeRaw_;
      71             : 
      72             :     // The first optimized stub, or nullptr.
      73             :     IonICStub* firstStub_;
      74             : 
      75             :     // The address stubs should jump to when done.
      76             :     CodeLocationLabel rejoinLabel_;
      77             : 
      78             :     // The OOL path that calls the IC's update function.
      79             :     CodeLocationLabel fallbackLabel_;
      80             : 
      81             :     // Location of this IC, nullptr for idempotent caches.
      82             :     JSScript* script_;
      83             :     jsbytecode* pc_;
      84             : 
      85             :     CacheKind kind_;
      86             :     bool idempotent_ : 1;
      87             :     ICState state_;
      88             : 
      89             :   protected:
      90          35 :     explicit IonIC(CacheKind kind)
      91          35 :       : codeRaw_(nullptr),
      92             :         firstStub_(nullptr),
      93             :         rejoinLabel_(),
      94             :         fallbackLabel_(),
      95             :         script_(nullptr),
      96             :         pc_(nullptr),
      97             :         kind_(kind),
      98             :         idempotent_(false),
      99          35 :         state_()
     100          35 :     {}
     101             : 
     102             :     void attachStub(IonICStub* newStub, JitCode* code);
     103             : 
     104             :   public:
     105          32 :     void setScriptedLocation(JSScript* script, jsbytecode* pc) {
     106          32 :         MOZ_ASSERT(!script_ && !pc_);
     107          32 :         MOZ_ASSERT(script && pc);
     108          32 :         script_ = script;
     109          32 :         pc_ = pc;
     110          32 :     }
     111             : 
     112           1 :     JSScript* script() const { MOZ_ASSERT(script_); return script_; }
     113          36 :     jsbytecode* pc() const { MOZ_ASSERT(pc_); return pc_; }
     114             : 
     115          21 :     CodeLocationLabel rejoinLabel() const { return rejoinLabel_; }
     116             : 
     117             :     // Discard all stubs.
     118             :     void discardStubs(Zone* zone);
     119             : 
     120             :     // Discard all stubs and reset the ICState.
     121             :     void reset(Zone* zone);
     122             : 
     123          63 :     ICState& state() {
     124          63 :         return state_;
     125             :     }
     126             : 
     127         111 :     CacheKind kind() const { return kind_; }
     128          14 :     uint8_t** codeRawPtr() { return &codeRaw_; }
     129             : 
     130          80 :     bool idempotent() const { return idempotent_; }
     131           3 :     void setIdempotent() { idempotent_ = true; }
     132             : 
     133          35 :     void setFallbackLabel(CodeOffset fallbackLabel) { fallbackLabel_ = fallbackLabel; }
     134          35 :     void setRejoinLabel(CodeOffset rejoinLabel) { rejoinLabel_ = rejoinLabel; }
     135             : 
     136         148 :     IonGetPropertyIC* asGetPropertyIC() {
     137         148 :         MOZ_ASSERT(kind_ == CacheKind::GetProp || kind_ == CacheKind::GetElem);
     138         148 :         return (IonGetPropertyIC*)this;
     139             :     }
     140          12 :     IonSetPropertyIC* asSetPropertyIC() {
     141          12 :         MOZ_ASSERT(kind_ == CacheKind::SetProp || kind_ == CacheKind::SetElem);
     142          12 :         return (IonSetPropertyIC*)this;
     143             :     }
     144           8 :     IonGetNameIC* asGetNameIC() {
     145           8 :         MOZ_ASSERT(kind_ == CacheKind::GetName);
     146           8 :         return (IonGetNameIC*)this;
     147             :     }
     148           0 :     IonBindNameIC* asBindNameIC() {
     149           0 :         MOZ_ASSERT(kind_ == CacheKind::BindName);
     150           0 :         return (IonBindNameIC*)this;
     151             :     }
     152           0 :     IonHasOwnIC* asHasOwnIC() {
     153           0 :         MOZ_ASSERT(kind_ == CacheKind::HasOwn);
     154           0 :         return (IonHasOwnIC*)this;
     155             :     }
     156           7 :     IonInIC* asInIC() {
     157           7 :         MOZ_ASSERT(kind_ == CacheKind::In);
     158           7 :         return (IonInIC*)this;
     159             :     }
     160             : 
     161             :     void updateBaseAddress(JitCode* code, MacroAssembler& masm);
     162             : 
     163             :     // Returns the Register to use as scratch when entering IC stubs. This
     164             :     // should either be an output register or a temp.
     165             :     Register scratchRegisterForEntryJump();
     166             : 
     167             :     void trace(JSTracer* trc);
     168             : 
     169             :     void attachCacheIRStub(JSContext* cx, const CacheIRWriter& writer, CacheKind kind,
     170             :                            IonScript* ionScript, bool* attached,
     171             :                            const PropertyTypeCheckInfo* typeCheckInfo = nullptr);
     172             : };
     173             : 
     174          23 : class IonGetPropertyIC : public IonIC
     175             : {
     176             :     LiveRegisterSet liveRegs_;
     177             : 
     178             :     TypedOrValueRegister value_;
     179             :     ConstantOrRegister id_;
     180             :     TypedOrValueRegister output_;
     181             :     Register maybeTemp_; // Might be InvalidReg.
     182             : 
     183             :     bool monitoredResult_ : 1;
     184             :     bool allowDoubleResult_ : 1;
     185             : 
     186             :   public:
     187          23 :     IonGetPropertyIC(CacheKind kind, LiveRegisterSet liveRegs, TypedOrValueRegister value,
     188             :                      const ConstantOrRegister& id, TypedOrValueRegister output, Register maybeTemp,
     189             :                      bool monitoredResult, bool allowDoubleResult)
     190          23 :       : IonIC(kind),
     191             :         liveRegs_(liveRegs),
     192             :         value_(value),
     193             :         id_(id),
     194             :         output_(output),
     195             :         maybeTemp_(maybeTemp),
     196             :         monitoredResult_(monitoredResult),
     197          23 :         allowDoubleResult_(allowDoubleResult)
     198          23 :     { }
     199             : 
     200          40 :     bool monitoredResult() const { return monitoredResult_; }
     201          43 :     TypedOrValueRegister value() const { return value_; }
     202          38 :     ConstantOrRegister id() const { return id_; }
     203         118 :     TypedOrValueRegister output() const { return output_; }
     204          73 :     Register maybeTemp() const { return maybeTemp_; }
     205          20 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     206          20 :     bool allowDoubleResult() const { return allowDoubleResult_; }
     207             : 
     208             :     static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonGetPropertyIC* ic,
     209             :                                     HandleValue val, HandleValue idVal, MutableHandleValue res);
     210             : };
     211             : 
     212           6 : class IonSetPropertyIC : public IonIC
     213             : {
     214             :     LiveRegisterSet liveRegs_;
     215             : 
     216             :     Register object_;
     217             :     Register temp_;
     218             :     FloatRegister maybeTempDouble_;
     219             :     FloatRegister maybeTempFloat32_;
     220             :     ConstantOrRegister id_;
     221             :     ConstantOrRegister rhs_;
     222             :     bool strict_ : 1;
     223             :     bool needsPostBarrier_ : 1;
     224             :     bool needsTypeBarrier_ : 1;
     225             :     bool guardHoles_ : 1;
     226             : 
     227             :   public:
     228           6 :     IonSetPropertyIC(CacheKind kind, LiveRegisterSet liveRegs, Register object, Register temp,
     229             :                      FloatRegister maybeTempDouble, FloatRegister maybeTempFloat32,
     230             :                      const ConstantOrRegister& id, const ConstantOrRegister& rhs, bool strict,
     231             :                      bool needsPostBarrier, bool needsTypeBarrier, bool guardHoles)
     232           6 :       : IonIC(kind),
     233             :         liveRegs_(liveRegs),
     234             :         object_(object),
     235             :         temp_(temp),
     236             :         maybeTempDouble_(maybeTempDouble),
     237             :         maybeTempFloat32_(maybeTempFloat32),
     238             :         id_(id),
     239             :         rhs_(rhs),
     240             :         strict_(strict),
     241             :         needsPostBarrier_(needsPostBarrier),
     242             :         needsTypeBarrier_(needsTypeBarrier),
     243           6 :         guardHoles_(guardHoles)
     244           6 :     { }
     245             : 
     246           0 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     247           6 :     Register object() const { return object_; }
     248           6 :     ConstantOrRegister id() const { return id_; }
     249           6 :     ConstantOrRegister rhs() const { return rhs_; }
     250             : 
     251           6 :     Register temp() const { return temp_; }
     252           0 :     FloatRegister maybeTempDouble() const { return maybeTempDouble_; }
     253           0 :     FloatRegister maybeTempFloat32() const { return maybeTempFloat32_; }
     254             : 
     255           0 :     bool strict() const { return strict_; }
     256           0 :     bool needsPostBarrier() const { return needsPostBarrier_; }
     257           0 :     bool needsTypeBarrier() const { return needsTypeBarrier_; }
     258           0 :     bool guardHoles() const { return guardHoles_; }
     259             : 
     260             :     static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonSetPropertyIC* ic,
     261             :                                     HandleObject obj, HandleValue idVal, HandleValue rhs);
     262             : };
     263             : 
     264           4 : class IonGetNameIC : public IonIC
     265             : {
     266             :     LiveRegisterSet liveRegs_;
     267             : 
     268             :     Register environment_;
     269             :     ValueOperand output_;
     270             :     Register temp_;
     271             : 
     272             :   public:
     273           4 :     IonGetNameIC(LiveRegisterSet liveRegs, Register environment, ValueOperand output,
     274             :                  Register temp)
     275           4 :       : IonIC(CacheKind::GetName),
     276             :         liveRegs_(liveRegs),
     277             :         environment_(environment),
     278             :         output_(output),
     279           4 :         temp_(temp)
     280           4 :     { }
     281             : 
     282           4 :     Register environment() const { return environment_; }
     283           8 :     ValueOperand output() const { return output_; }
     284           4 :     Register temp() const { return temp_; }
     285           0 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     286             : 
     287             :     static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonGetNameIC* ic,
     288             :                                     HandleObject envChain, MutableHandleValue res);
     289             : };
     290             : 
     291           0 : class IonBindNameIC : public IonIC
     292             : {
     293             :     LiveRegisterSet liveRegs_;
     294             : 
     295             :     Register environment_;
     296             :     Register output_;
     297             :     Register temp_;
     298             : 
     299             :   public:
     300           0 :     IonBindNameIC(LiveRegisterSet liveRegs, Register environment, Register output, Register temp)
     301           0 :       : IonIC(CacheKind::BindName),
     302             :         liveRegs_(liveRegs),
     303             :         environment_(environment),
     304             :         output_(output),
     305           0 :         temp_(temp)
     306           0 :     { }
     307             : 
     308           0 :     Register environment() const { return environment_; }
     309           0 :     Register output() const { return output_; }
     310           0 :     Register temp() const { return temp_; }
     311           0 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     312             : 
     313             :     static JSObject* update(JSContext* cx, HandleScript outerScript, IonBindNameIC* ic,
     314             :                             HandleObject envChain);
     315             : };
     316             : 
     317           0 : class IonHasOwnIC : public IonIC
     318             : {
     319             :     LiveRegisterSet liveRegs_;
     320             : 
     321             :     TypedOrValueRegister value_;
     322             :     TypedOrValueRegister id_;
     323             :     Register output_;
     324             : 
     325             :   public:
     326           0 :     IonHasOwnIC(LiveRegisterSet liveRegs, TypedOrValueRegister value,
     327             :                 TypedOrValueRegister id, Register output)
     328           0 :       : IonIC(CacheKind::HasOwn),
     329             :         liveRegs_(liveRegs),
     330             :         value_(value),
     331             :         id_(id),
     332           0 :         output_(output)
     333           0 :     { }
     334             : 
     335           0 :     TypedOrValueRegister value() const { return value_; }
     336           0 :     TypedOrValueRegister id() const { return id_; }
     337           0 :     Register output() const { return output_; }
     338           0 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     339             : 
     340             :     static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonHasOwnIC* ic,
     341             :                                     HandleValue val, HandleValue idVal, int32_t* res);
     342             : };
     343             : 
     344           2 : class IonInIC : public IonIC
     345             : {
     346             :     LiveRegisterSet liveRegs_;
     347             : 
     348             :     ConstantOrRegister key_;
     349             :     Register object_;
     350             :     Register output_;
     351             :     Register temp_;
     352             : 
     353             :   public:
     354           2 :     IonInIC(LiveRegisterSet liveRegs, const ConstantOrRegister& key,
     355             :             Register object, Register output, Register temp)
     356           2 :       : IonIC(CacheKind::In),
     357             :         liveRegs_(liveRegs),
     358             :         key_(key),
     359             :         object_(object),
     360             :         output_(output),
     361           2 :         temp_(temp)
     362           2 :     { }
     363             : 
     364           3 :     ConstantOrRegister key() const { return key_; }
     365           3 :     Register object() const { return object_; }
     366           5 :     Register output() const { return output_; }
     367           4 :     Register temp() const { return temp_; }
     368           1 :     LiveRegisterSet liveRegs() const { return liveRegs_; }
     369             : 
     370             :     static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonInIC* ic,
     371             :                                     HandleValue key, HandleObject obj, bool* res);
     372             : };
     373             : 
     374             : } // namespace jit
     375             : } // namespace js
     376             : 
     377             : #endif /* jit_IonIC_h */

Generated by: LCOV version 1.13