LCOV - code coverage report
Current view: directory - js/src/methodjit - PolyIC.h (source / functions) Found Hit Coverage
Test: app.info Lines: 161 154 95.7 %
Date: 2012-06-02 Functions: 48 48 100.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=4 sw=4 et tw=99:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
      18                 :  * May 28, 2008.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  *   Brendan Eich <brendan@mozilla.org>
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   David Mandelin <dmandelin@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #if !defined jsjaeger_poly_ic_h__ && defined JS_METHODJIT
      41                 : #define jsjaeger_poly_ic_h__
      42                 : 
      43                 : #include "jscntxt.h"
      44                 : #include "assembler/assembler/MacroAssembler.h"
      45                 : #include "assembler/assembler/CodeLocation.h"
      46                 : #include "js/Vector.h"
      47                 : #include "methodjit/MethodJIT.h"
      48                 : #include "methodjit/ICRepatcher.h"
      49                 : #include "BaseAssembler.h"
      50                 : #include "RematInfo.h"
      51                 : #include "BaseCompiler.h"
      52                 : #include "methodjit/ICLabels.h"
      53                 : #include "assembler/moco/MocoStubs.h"
      54                 : 
      55                 : namespace js {
      56                 : namespace mjit {
      57                 : namespace ic {
      58                 : 
      59                 : /* Maximum number of stubs for a given callsite. */
      60                 : static const uint32_t MAX_PIC_STUBS = 16;
      61                 : static const uint32_t MAX_GETELEM_IC_STUBS = 17;
      62                 : 
      63                 : enum LookupStatus {
      64                 :     Lookup_Error = 0,
      65                 :     Lookup_Uncacheable,
      66                 :     Lookup_Cacheable
      67                 : };
      68                 : 
      69                 : struct BaseIC : public MacroAssemblerTypedefs {
      70          850596 :     BaseIC() { }
      71                 : 
      72                 :     // Address of inline fast-path.
      73                 :     CodeLocationLabel fastPathStart;
      74                 : 
      75                 :     // Address to rejoin to the fast-path.
      76                 :     CodeLocationLabel fastPathRejoin;
      77                 : 
      78                 :     // Start of the slow path.
      79                 :     CodeLocationLabel slowPathStart;
      80                 : 
      81                 :     // Slow path stub call.
      82                 :     CodeLocationCall slowPathCall;
      83                 : 
      84                 :     // Offset from start of stub to jump target of second shape guard as Nitro
      85                 :     // asm data location. This is 0 if there is only one shape guard in the
      86                 :     // last stub.
      87                 :     int32_t secondShapeGuard;
      88                 : 
      89                 :     // Whether or not the callsite has been hit at least once.
      90                 :     bool hit : 1;
      91                 :     bool slowCallPatched : 1;
      92                 : 
      93                 :     // Whether getter/setter hooks can be called from IC stubs.
      94                 :     bool canCallHook : 1;
      95                 : 
      96                 :     // Whether a type barrier is in place for the result of the op.
      97                 :     bool forcedTypeBarrier : 1;
      98                 : 
      99                 :     // Number of stubs generated.
     100                 :     uint32_t stubsGenerated : 5;
     101                 : 
     102                 :     // Opcode this was compiled for.
     103                 :     JSOp op : 9;
     104                 : 
     105          850596 :     void reset() {
     106          850596 :         hit = false;
     107          850596 :         slowCallPatched = false;
     108          850596 :         forcedTypeBarrier = false;
     109          850596 :         stubsGenerated = 0;
     110          850596 :         secondShapeGuard = 0;
     111          850596 :     }
     112                 :     bool shouldUpdate(JSContext *cx);
     113                 :     void spew(JSContext *cx, const char *event, const char *reason);
     114                 :     LookupStatus disable(VMFrame &f, const char *reason, void *stub);
     115                 :     void updatePCCounters(VMFrame &f, Assembler &masm);
     116                 :     bool isCallOp();
     117                 : };
     118                 : 
     119                 : class BasePolyIC : public BaseIC {
     120                 :     typedef Vector<JSC::ExecutablePool *, 2, SystemAllocPolicy> ExecPoolVector;
     121                 : 
     122                 :     // ExecutablePools that IC stubs were generated into.  Very commonly (eg.
     123                 :     // 99.5% of BasePolyICs) there are 0 or 1, and there are lots of
     124                 :     // BasePolyICs, so we space-optimize for that case.  If the bottom bit of
     125                 :     // the pointer is 0, execPool should be used, and it will be NULL (for 0
     126                 :     // pools) or non-NULL (for 1 pool).  If the bottom bit of the
     127                 :     // pointer is 1, taggedExecPools should be used, but only after de-tagging
     128                 :     // (for 2 or more pools).
     129                 :     union {
     130                 :         JSC::ExecutablePool *execPool;      // valid when bottom bit is a 0
     131                 :         ExecPoolVector *taggedExecPools;    // valid when bottom bit is a 1
     132                 :     } u;
     133                 : 
     134         1235147 :     static bool isTagged(void *p) {
     135         1235147 :         return !!(intptr_t(p) & 1);
     136                 :     }
     137                 : 
     138           14307 :     static ExecPoolVector *tag(ExecPoolVector *p) {
     139           14307 :         JS_ASSERT(!isTagged(p));
     140           14307 :         return (ExecPoolVector *)(intptr_t(p) | 1);
     141                 :     }
     142                 : 
     143           50078 :     static ExecPoolVector *detag(ExecPoolVector *p) {
     144           50078 :         JS_ASSERT(isTagged(p));
     145           50078 :         return (ExecPoolVector *)(intptr_t(p) & ~1);
     146                 :     }
     147                 : 
     148         2796185 :     bool areZeroPools()     { return !u.execPool; }
     149          261473 :     bool isOnePool()        { return u.execPool && !isTagged(u.execPool); }
     150          894982 :     bool areMultiplePools() { return isTagged(u.taggedExecPools); }
     151                 : 
     152           50078 :     ExecPoolVector *multiplePools() {
     153           50078 :         JS_ASSERT(areMultiplePools());
     154           50078 :         return detag(u.taggedExecPools);
     155                 :     }
     156                 : 
     157                 :   public:
     158          844904 :     BasePolyIC() {
     159          844904 :         u.execPool = NULL;
     160          844904 :     }
     161                 : 
     162          844904 :     ~BasePolyIC() {
     163          844904 :         releasePools();
     164          844904 :         if (areMultiplePools())
     165           14307 :             Foreground::delete_(multiplePools());
     166          844904 :     }
     167                 : 
     168          844904 :     void reset() {
     169          844904 :         BaseIC::reset();
     170          844904 :         releasePools();
     171          844904 :         if (areZeroPools()) {
     172                 :             // Common case:  do nothing.
     173               0 :         } else if (isOnePool()) {
     174               0 :             u.execPool = NULL;
     175                 :         } else {
     176               0 :             multiplePools()->clear();
     177                 :         }
     178          844904 :     }
     179                 : 
     180         1689808 :     void releasePools() {
     181         1689808 :         if (areZeroPools()) {
     182                 :             // Common case:  do nothing.
     183          225702 :         } else if (isOnePool()) {
     184          211395 :             u.execPool->release();
     185                 :         } else {
     186           14307 :             ExecPoolVector *execPools = multiplePools();
     187           64385 :             for (size_t i = 0; i < execPools->length(); i++)
     188           50078 :                 (*execPools)[i]->release();
     189                 :         }
     190         1689808 :     }
     191                 : 
     192          261473 :     bool addPool(JSContext *cx, JSC::ExecutablePool *pool) {
     193          261473 :         if (areZeroPools()) {
     194          225702 :             u.execPool = pool;
     195          225702 :             return true;
     196                 :         }
     197           35771 :         if (isOnePool()) {
     198           14307 :             JSC::ExecutablePool *oldPool = u.execPool;
     199           14307 :             JS_ASSERT(!isTagged(oldPool));
     200           14307 :             ExecPoolVector *execPools = OffTheBooks::new_<ExecPoolVector>(SystemAllocPolicy()); 
     201           14307 :             if (!execPools)
     202               0 :                 return false;
     203           14307 :             if (!execPools->append(oldPool) || !execPools->append(pool)) {
     204               0 :                 Foreground::delete_(execPools);
     205               0 :                 return false;
     206                 :             }
     207           14307 :             u.taggedExecPools = tag(execPools);
     208           14307 :             return true;
     209                 :         }
     210           21464 :         return multiplePools()->append(pool); 
     211                 :     }
     212                 : };
     213                 : 
     214           21695 : struct GetElementIC : public BasePolyIC {
     215           21695 :     GetElementIC() { reset(); }
     216                 : 
     217                 :     // On stub entry:
     218                 :     //   If hasInlineTypeCheck() is true, and inlineTypeCheckPatched is false,
     219                 :     //     - typeReg contains the type of the |id| parameter.
     220                 :     //   If hasInlineTypeCheck() is true, and inlineTypeCheckPatched is true,
     221                 :     //     - typeReg contains the shape of |objReg| iff typeRegHasBaseShape
     222                 :     //       is true.
     223                 :     //   Otherwise, typeReg is garbage.
     224                 :     //
     225                 :     // On stub exit, typeReg must contain the type of the result value.
     226                 :     RegisterID typeReg   : 5;
     227                 : 
     228                 :     // On stub entry, objReg contains the object pointer for the |obj| parameter.
     229                 :     // On stub exit, objReg must contain the payload of the result value.
     230                 :     RegisterID objReg    : 5;
     231                 : 
     232                 :     // Offset from the fast path to the inline type check.
     233                 :     // This is only set if hasInlineTypeCheck() is true.
     234                 :     unsigned inlineTypeGuard  : 8;
     235                 : 
     236                 :     // Offset from the fast path to the inline shape guard. This is always
     237                 :     // set; if |id| is known to not be int32, then it's an unconditional
     238                 :     // jump to the slow path.
     239                 :     unsigned inlineShapeGuard : 8;
     240                 : 
     241                 :     // This is usable if hasInlineTypeGuard() returns true, which implies
     242                 :     // that a dense array fast path exists. The inline type guard serves as
     243                 :     // the head of the chain of all string-based element stubs.
     244                 :     bool inlineTypeGuardPatched : 1;
     245                 : 
     246                 :     // This is always usable, and specifies whether the inline shape guard
     247                 :     // has been patched. If hasInlineTypeGuard() is true, it guards against
     248                 :     // a dense array, and guarantees the inline type guard has passed.
     249                 :     // Otherwise, there is no inline type guard, and the shape guard is just
     250                 :     // an unconditional jump.
     251                 :     bool inlineShapeGuardPatched : 1;
     252                 : 
     253                 :     ////////////////////////////////////////////
     254                 :     // State for string-based property stubs. //
     255                 :     ////////////////////////////////////////////
     256                 : 
     257                 :     // True if typeReg is guaranteed to have the shape of objReg.
     258                 :     bool typeRegHasBaseShape : 1;
     259                 : 
     260                 :     // These offsets are used for string-key dependent stubs, such as named
     261                 :     // property accesses. They are separated from the int-key dependent stubs,
     262                 :     // in order to guarantee that the id type needs only one guard per type.
     263                 :     int32_t atomGuard : 8;          // optional, non-zero if present
     264                 :     int32_t firstShapeGuard : 11;    // always set
     265                 :     int32_t secondShapeGuard : 11;   // optional, non-zero if present
     266                 : 
     267                 :     bool hasLastStringStub : 1;
     268                 :     JITCode lastStringStub;
     269                 : 
     270                 :     // A limited ValueRemat instance. It may contains either:
     271                 :     //  1) A constant, or
     272                 :     //  2) A known type and data reg, or
     273                 :     //  3) A data reg.
     274                 :     // The sync bits are not set, and the type reg is never set and should not
     275                 :     // be used, as it is encapsulated more accurately in |typeReg|. Also, note
     276                 :     // carefully that the data reg is immutable.
     277                 :     ValueRemat idRemat;
     278                 : 
     279           20456 :     bool hasInlineTypeGuard() const {
     280           20456 :         return !idRemat.isTypeKnown();
     281                 :     }
     282            7396 :     bool shouldPatchInlineTypeGuard() {
     283            7396 :         return hasInlineTypeGuard() && !inlineTypeGuardPatched;
     284                 :     }
     285            7875 :     bool shouldPatchUnconditionalShapeGuard() {
     286                 :         // The shape guard is only unconditional if the type is known to not
     287                 :         // be an int32.
     288            7875 :         if (idRemat.isTypeKnown() && idRemat.knownType() != JSVAL_TYPE_INT32)
     289            3431 :             return !inlineShapeGuardPatched;
     290            4444 :         return false;
     291                 :     }
     292                 : 
     293           21695 :     void reset() {
     294           21695 :         BasePolyIC::reset();
     295           21695 :         inlineTypeGuardPatched = false;
     296           21695 :         inlineShapeGuardPatched = false;
     297           21695 :         typeRegHasBaseShape = false;
     298           21695 :         hasLastStringStub = false;
     299           21695 :     }
     300                 :     void purge(Repatcher &repatcher);
     301                 :     LookupStatus update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
     302                 :     LookupStatus attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyName *name,
     303                 :                                Value *vp);
     304                 :     LookupStatus attachArguments(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
     305                 :     LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
     306                 :     LookupStatus disable(VMFrame &f, const char *reason);
     307                 :     LookupStatus error(JSContext *cx);
     308                 :     bool shouldUpdate(JSContext *cx);
     309                 : };
     310                 : 
     311                 : struct SetElementIC : public BaseIC {
     312            5692 :     SetElementIC() : execPool(NULL) { reset(); }
     313            5692 :     ~SetElementIC() {
     314            5692 :         if (execPool)
     315            1179 :             execPool->release();
     316            5692 :     }
     317                 : 
     318                 :     // On stub entry:
     319                 :     //   objReg contains the payload of the |obj| parameter.
     320                 :     // On stub exit:
     321                 :     //   objReg may be clobbered.
     322                 :     RegisterID objReg    : 5;
     323                 : 
     324                 :     // Information on how to rematerialize |objReg|.
     325                 :     int32_t objRemat       : MIN_STATE_REMAT_BITS;
     326                 : 
     327                 :     // Offset from the start of the fast path to the inline shape guard.
     328                 :     unsigned inlineShapeGuard : 6;
     329                 : 
     330                 :     // True if the shape guard has been patched; false otherwise.
     331                 :     bool inlineShapeGuardPatched : 1;
     332                 : 
     333                 :     // Offset from the start of the fast path to the inline hole guard.
     334                 :     unsigned inlineHoleGuard : 8;
     335                 : 
     336                 :     // True if the capacity guard has been patched; false otherwise.
     337                 :     bool inlineHoleGuardPatched : 1;
     338                 : 
     339                 :     // True if this is from a strict-mode script.
     340                 :     bool strictMode : 1;
     341                 : 
     342                 :     // A bitmask of registers that are volatile and must be preserved across
     343                 :     // stub calls inside the IC.
     344                 :     uint32_t volatileMask;
     345                 : 
     346                 :     // If true, then keyValue contains a constant index value >= 0. Otherwise,
     347                 :     // keyReg contains a dynamic integer index in any range.
     348                 :     bool hasConstantKey : 1;
     349                 :     union {
     350                 :         RegisterID keyReg;
     351                 :         int32_t    keyValue;
     352                 :     };
     353                 : 
     354                 :     // Rematerialize information about the value being stored.
     355                 :     ValueRemat vr;
     356                 : 
     357                 :     // Optional executable pool for the out-of-line hole stub.
     358                 :     JSC::ExecutablePool *execPool;
     359                 : 
     360            5692 :     void reset() {
     361            5692 :         BaseIC::reset();
     362            5692 :         if (execPool != NULL)
     363               0 :             execPool->release();
     364            5692 :         execPool = NULL;
     365            5692 :         inlineShapeGuardPatched = false;
     366            5692 :         inlineHoleGuardPatched = false;
     367            5692 :     }
     368                 :     void purge(Repatcher &repatcher);
     369                 :     LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, int32_t key);
     370                 :     LookupStatus attachHoleStub(VMFrame &f, JSObject *obj, int32_t key);
     371                 :     LookupStatus update(VMFrame &f, const Value &objval, const Value &idval);
     372                 :     LookupStatus disable(VMFrame &f, const char *reason);
     373                 :     LookupStatus error(JSContext *cx);
     374                 :     bool shouldUpdate(JSContext *cx);
     375                 : };
     376                 : 
     377          823209 : struct PICInfo : public BasePolyIC {
     378          823209 :     PICInfo() { reset(); }
     379                 : 
     380                 :     // Operation this is a PIC for.
     381                 :     enum Kind
     382                 : #ifdef _MSC_VER
     383                 :     : uint8_t
     384                 : #endif
     385                 :     {
     386                 :         GET,        // JSOP_GETPROP
     387                 :         SET,        // JSOP_SETPROP, JSOP_SETNAME
     388                 :         SETMETHOD,  // JSOP_SETMETHOD
     389                 :         NAME,       // JSOP_NAME
     390                 :         BIND,       // JSOP_BINDNAME
     391                 :         XNAME       // JSOP_GETXPROP
     392                 :     };
     393                 : 
     394                 :     union {
     395                 :         struct {
     396                 :             RegisterID typeReg  : 5;  // reg used for checking type
     397                 :             bool hasTypeCheck   : 1;  // type check and reg are present
     398                 : 
     399                 :             // Reverse offset from slowPathStart to the type check slow path.
     400                 :             int32_t typeCheckOffset;
     401                 :         } get;
     402                 :         ValueRemat vr;
     403                 :     } u;
     404                 : 
     405                 :     // Address of the start of the last generated stub, if any. Note that this
     406                 :     // does not correctly overlay with the allocated memory; it does however
     407                 :     // overlay the portion that may need to be patched, which is good enough.
     408                 :     JITCode lastStubStart;
     409                 : 
     410                 :     // Return the start address of the last path in this PIC, which is the
     411                 :     // inline path if no stubs have been generated yet.
     412          246991 :     CodeLocationLabel lastPathStart() {
     413          246991 :         if (!stubsGenerated)
     414          214832 :             return fastPathStart;
     415           32159 :         return CodeLocationLabel(lastStubStart.start());
     416                 :     }
     417                 : 
     418          139363 :     CodeLocationLabel getFastShapeGuard() {
     419          139363 :         return fastPathStart.labelAtOffset(shapeGuard);
     420                 :     }
     421                 : 
     422            7670 :     CodeLocationLabel getSlowTypeCheck() {
     423            7670 :         JS_ASSERT(isGet());
     424            7670 :         return slowPathStart.labelAtOffset(u.get.typeCheckOffset);
     425                 :     }
     426                 : 
     427                 :     // Return a JITCode block corresponding to the code memory to attach a
     428                 :     // new stub to.
     429          503626 :     JITCode lastCodeBlock(JITChunk *chunk) {
     430          503626 :         if (!stubsGenerated)
     431          439308 :             return JITCode(chunk->code.m_code.executableAddress(), chunk->code.m_size);
     432           64318 :         return lastStubStart;
     433                 :     }
     434                 : 
     435          239893 :     void updateLastPath(LinkerHelper &linker, Label label) {
     436          239893 :         CodeLocationLabel loc = linker.locationOf(label);
     437          239893 :         lastStubStart = JITCode(loc.executableAddress(), linker.size());
     438          239893 :     }
     439                 : 
     440                 :     Kind kind : 3;
     441                 : 
     442                 :     // True if register R holds the base object shape along exits from the
     443                 :     // last stub.
     444                 :     bool shapeRegHasBaseShape : 1;
     445                 : 
     446                 :     // True if can use the property cache.
     447                 :     bool usePropCache : 1;
     448                 : 
     449                 :     // State flags.
     450                 :     bool inlinePathPatched : 1;     // inline path has been patched
     451                 : 
     452                 :     RegisterID shapeReg : 5;        // also the out type reg
     453                 :     RegisterID objReg   : 5;        // also the out data reg
     454                 : 
     455                 :     // Whether type properties need to be updated to reflect generated stubs.
     456                 :     bool typeMonitored : 1;
     457                 : 
     458                 :     // Offset from start of fast path to initial shape guard.
     459                 :     uint32_t shapeGuard;
     460                 : 
     461                 :     // Possible types of the RHS, for monitored SETPROP PICs.
     462                 :     types::TypeSet *rhsTypes;
     463                 :     
     464         1283981 :     inline bool isSet() const {
     465         1283981 :         return kind == SET || kind == SETMETHOD;
     466                 :     }
     467         2340113 :     inline bool isGet() const {
     468         2340113 :         return kind == GET;
     469                 :     }
     470          346522 :     inline bool isBind() const {
     471          346522 :         return kind == BIND;
     472                 :     }
     473          339411 :     inline bool isScopeName() const {
     474          339411 :         return kind == NAME || kind == XNAME;
     475                 :     }
     476            7670 :     inline RegisterID typeReg() {
     477            7670 :         JS_ASSERT(isGet());
     478            7670 :         return u.get.typeReg;
     479                 :     }
     480           14512 :     inline bool hasTypeCheck() {
     481           14512 :         JS_ASSERT(isGet());
     482           14512 :         return u.get.hasTypeCheck;
     483                 :     }
     484           50969 :     inline bool shapeNeedsRemat() {
     485           50969 :         return !shapeRegHasBaseShape;
     486                 :     }
     487                 : 
     488                 :     union {
     489                 :         GetPropLabels getPropLabels_;
     490                 :         SetPropLabels setPropLabels_;
     491                 :         BindNameLabels bindNameLabels_;
     492                 :         ScopeNameLabels scopeNameLabels_;
     493                 :     };
     494          443609 :     void setLabels(const ic::GetPropLabels &labels) {
     495          443609 :         JS_ASSERT(isGet());
     496          443609 :         getPropLabels_ = labels;
     497          443609 :     }
     498           33078 :     void setLabels(const ic::SetPropLabels &labels) {
     499           33078 :         JS_ASSERT(isSet());
     500           33078 :         setPropLabels_ = labels;
     501           33078 :     }
     502            7111 :     void setLabels(const ic::BindNameLabels &labels) {
     503            7111 :         JS_ASSERT(kind == BIND);
     504            7111 :         bindNameLabels_ = labels;
     505            7111 :     }
     506          339411 :     void setLabels(const ic::ScopeNameLabels &labels) {
     507          339411 :         JS_ASSERT(kind == NAME || kind == XNAME);
     508          339411 :         scopeNameLabels_ = labels;
     509          339411 :     }
     510                 : 
     511          253312 :     GetPropLabels &getPropLabels() {
     512          253312 :         JS_ASSERT(isGet());
     513          253312 :         return getPropLabels_;
     514                 :     }
     515           16887 :     SetPropLabels &setPropLabels() {
     516           16887 :         JS_ASSERT(isSet());
     517           16887 :         return setPropLabels_;
     518                 :     }
     519            2189 :     BindNameLabels &bindNameLabels() {
     520            2189 :         JS_ASSERT(kind == BIND);
     521            2189 :         return bindNameLabels_;
     522                 :     }
     523          360148 :     ScopeNameLabels &scopeNameLabels() {
     524          360148 :         JS_ASSERT(kind == NAME || kind == XNAME);
     525          360148 :         return scopeNameLabels_;
     526                 :     }
     527                 : 
     528                 :     // Where in the script did we generate this PIC?
     529                 :     jsbytecode *pc;
     530                 :     
     531                 :     // Index into the script's atom table.
     532                 :     PropertyName *name;
     533                 : 
     534                 :     // Reset the data members to the state of a fresh PIC before any patching
     535                 :     // or stub generation was done.
     536          823209 :     void reset() {
     537          823209 :         BasePolyIC::reset();
     538          823209 :         inlinePathPatched = false;
     539          823209 :         shapeRegHasBaseShape = true;
     540          823209 :     }
     541                 : };
     542                 : 
     543                 : #ifdef JS_POLYIC
     544                 : void JS_FASTCALL GetProp(VMFrame &f, ic::PICInfo *);
     545                 : void JS_FASTCALL GetPropNoCache(VMFrame &f, ic::PICInfo *);
     546                 : void JS_FASTCALL SetProp(VMFrame &f, ic::PICInfo *);
     547                 : void JS_FASTCALL Name(VMFrame &f, ic::PICInfo *);
     548                 : void JS_FASTCALL XName(VMFrame &f, ic::PICInfo *);
     549                 : void JS_FASTCALL BindName(VMFrame &f, ic::PICInfo *);
     550                 : void JS_FASTCALL GetElement(VMFrame &f, ic::GetElementIC *);
     551            4160 : template <JSBool strict> void JS_FASTCALL SetElement(VMFrame &f, ic::SetElementIC *);
     552                 : #endif
     553                 : 
     554                 : } /* namespace ic */
     555                 : } /* namespace mjit */
     556                 : } /* namespace js */
     557                 : 
     558                 : #endif /* jsjaeger_poly_ic_h__ */
     559                 : 

Generated by: LCOV version 1.7