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-04-07 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          156654 :     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          156654 :     void reset() {
     106          156654 :         hit = false;
     107          156654 :         slowCallPatched = false;
     108          156654 :         forcedTypeBarrier = false;
     109          156654 :         stubsGenerated = 0;
     110          156654 :         secondShapeGuard = 0;
     111          156654 :     }
     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          222914 :     static bool isTagged(void *p) {
     135          222914 :         return !!(intptr_t(p) & 1);
     136                 :     }
     137                 : 
     138            2358 :     static ExecPoolVector *tag(ExecPoolVector *p) {
     139            2358 :         JS_ASSERT(!isTagged(p));
     140            2358 :         return (ExecPoolVector *)(intptr_t(p) | 1);
     141                 :     }
     142                 : 
     143            9841 :     static ExecPoolVector *detag(ExecPoolVector *p) {
     144            9841 :         JS_ASSERT(isTagged(p));
     145            9841 :         return (ExecPoolVector *)(intptr_t(p) & ~1);
     146                 :     }
     147                 : 
     148          500418 :     bool areZeroPools()     { return !u.execPool; }
     149           47565 :     bool isOnePool()        { return u.execPool && !isTagged(u.execPool); }
     150          160792 :     bool areMultiplePools() { return isTagged(u.taggedExecPools); }
     151                 : 
     152            9841 :     ExecPoolVector *multiplePools() {
     153            9841 :         JS_ASSERT(areMultiplePools());
     154            9841 :         return detag(u.taggedExecPools);
     155                 :     }
     156                 : 
     157                 :   public:
     158          150951 :     BasePolyIC() {
     159          150951 :         u.execPool = NULL;
     160          150951 :     }
     161                 : 
     162          150951 :     ~BasePolyIC() {
     163          150951 :         releasePools();
     164          150951 :         if (areMultiplePools())
     165            2358 :             Foreground::delete_(multiplePools());
     166          150951 :     }
     167                 : 
     168          150951 :     void reset() {
     169          150951 :         BaseIC::reset();
     170          150951 :         releasePools();
     171          150951 :         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          150951 :     }
     179                 : 
     180          301902 :     void releasePools() {
     181          301902 :         if (areZeroPools()) {
     182                 :             // Common case:  do nothing.
     183           40082 :         } else if (isOnePool()) {
     184           37724 :             u.execPool->release();
     185                 :         } else {
     186            2358 :             ExecPoolVector *execPools = multiplePools();
     187           12199 :             for (size_t i = 0; i < execPools->length(); i++)
     188            9841 :                 (*execPools)[i]->release();
     189                 :         }
     190          301902 :     }
     191                 : 
     192           47565 :     bool addPool(JSContext *cx, JSC::ExecutablePool *pool) {
     193           47565 :         if (areZeroPools()) {
     194           40082 :             u.execPool = pool;
     195           40082 :             return true;
     196                 :         }
     197            7483 :         if (isOnePool()) {
     198            2358 :             JSC::ExecutablePool *oldPool = u.execPool;
     199            2358 :             JS_ASSERT(!isTagged(oldPool));
     200            2358 :             ExecPoolVector *execPools = OffTheBooks::new_<ExecPoolVector>(SystemAllocPolicy()); 
     201            2358 :             if (!execPools)
     202               0 :                 return false;
     203            2358 :             if (!execPools->append(oldPool) || !execPools->append(pool)) {
     204               0 :                 Foreground::delete_(execPools);
     205               0 :                 return false;
     206                 :             }
     207            2358 :             u.taggedExecPools = tag(execPools);
     208            2358 :             return true;
     209                 :         }
     210            5125 :         return multiplePools()->append(pool); 
     211                 :     }
     212                 : };
     213                 : 
     214           21648 : struct GetElementIC : public BasePolyIC {
     215           21648 :     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           19986 :     bool hasInlineTypeGuard() const {
     280           19986 :         return !idRemat.isTypeKnown();
     281                 :     }
     282            7380 :     bool shouldPatchInlineTypeGuard() {
     283            7380 :         return hasInlineTypeGuard() && !inlineTypeGuardPatched;
     284                 :     }
     285            7429 :     bool shouldPatchUnconditionalShapeGuard() {
     286                 :         // The shape guard is only unconditional if the type is known to not
     287                 :         // be an int32.
     288            7429 :         if (idRemat.isTypeKnown() && idRemat.knownType() != JSVAL_TYPE_INT32)
     289            3420 :             return !inlineShapeGuardPatched;
     290            4009 :         return false;
     291                 :     }
     292                 : 
     293           21648 :     void reset() {
     294           21648 :         BasePolyIC::reset();
     295           21648 :         inlineTypeGuardPatched = false;
     296           21648 :         inlineShapeGuardPatched = false;
     297           21648 :         typeRegHasBaseShape = false;
     298           21648 :         hasLastStringStub = false;
     299           21648 :     }
     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 attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
     305                 :     LookupStatus disable(VMFrame &f, const char *reason);
     306                 :     LookupStatus error(JSContext *cx);
     307                 :     bool shouldUpdate(JSContext *cx);
     308                 : };
     309                 : 
     310                 : struct SetElementIC : public BaseIC {
     311            5703 :     SetElementIC() : execPool(NULL) { reset(); }
     312            5703 :     ~SetElementIC() {
     313            5703 :         if (execPool)
     314            1179 :             execPool->release();
     315            5703 :     }
     316                 : 
     317                 :     // On stub entry:
     318                 :     //   objReg contains the payload of the |obj| parameter.
     319                 :     // On stub exit:
     320                 :     //   objReg may be clobbered.
     321                 :     RegisterID objReg    : 5;
     322                 : 
     323                 :     // Information on how to rematerialize |objReg|.
     324                 :     int32_t objRemat       : MIN_STATE_REMAT_BITS;
     325                 : 
     326                 :     // Offset from the start of the fast path to the inline shape guard.
     327                 :     unsigned inlineShapeGuard : 6;
     328                 : 
     329                 :     // True if the shape guard has been patched; false otherwise.
     330                 :     bool inlineShapeGuardPatched : 1;
     331                 : 
     332                 :     // Offset from the start of the fast path to the inline hole guard.
     333                 :     unsigned inlineHoleGuard : 8;
     334                 : 
     335                 :     // True if the capacity guard has been patched; false otherwise.
     336                 :     bool inlineHoleGuardPatched : 1;
     337                 : 
     338                 :     // True if this is from a strict-mode script.
     339                 :     bool strictMode : 1;
     340                 : 
     341                 :     // A bitmask of registers that are volatile and must be preserved across
     342                 :     // stub calls inside the IC.
     343                 :     uint32_t volatileMask;
     344                 : 
     345                 :     // If true, then keyValue contains a constant index value >= 0. Otherwise,
     346                 :     // keyReg contains a dynamic integer index in any range.
     347                 :     bool hasConstantKey : 1;
     348                 :     union {
     349                 :         RegisterID keyReg;
     350                 :         int32_t    keyValue;
     351                 :     };
     352                 : 
     353                 :     // Rematerialize information about the value being stored.
     354                 :     ValueRemat vr;
     355                 : 
     356                 :     // Optional executable pool for the out-of-line hole stub.
     357                 :     JSC::ExecutablePool *execPool;
     358                 : 
     359            5703 :     void reset() {
     360            5703 :         BaseIC::reset();
     361            5703 :         if (execPool != NULL)
     362               0 :             execPool->release();
     363            5703 :         execPool = NULL;
     364            5703 :         inlineShapeGuardPatched = false;
     365            5703 :         inlineHoleGuardPatched = false;
     366            5703 :     }
     367                 :     void purge(Repatcher &repatcher);
     368                 :     LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, int32_t key);
     369                 :     LookupStatus attachHoleStub(VMFrame &f, JSObject *obj, int32_t key);
     370                 :     LookupStatus update(VMFrame &f, const Value &objval, const Value &idval);
     371                 :     LookupStatus disable(VMFrame &f, const char *reason);
     372                 :     LookupStatus error(JSContext *cx);
     373                 :     bool shouldUpdate(JSContext *cx);
     374                 : };
     375                 : 
     376          129303 : struct PICInfo : public BasePolyIC {
     377          129303 :     PICInfo() { reset(); }
     378                 : 
     379                 :     // Operation this is a PIC for.
     380                 :     enum Kind
     381                 : #ifdef _MSC_VER
     382                 :     : uint8_t
     383                 : #endif
     384                 :     {
     385                 :         GET,        // JSOP_GETPROP
     386                 :         SET,        // JSOP_SETPROP, JSOP_SETNAME
     387                 :         NAME,       // JSOP_NAME
     388                 :         BIND,       // JSOP_BINDNAME
     389                 :         XNAME       // JSOP_GETXPROP
     390                 :     };
     391                 : 
     392                 :     union {
     393                 :         struct {
     394                 :             RegisterID typeReg  : 5;  // reg used for checking type
     395                 :             bool hasTypeCheck   : 1;  // type check and reg are present
     396                 : 
     397                 :             // Reverse offset from slowPathStart to the type check slow path.
     398                 :             int32_t typeCheckOffset;
     399                 :         } get;
     400                 :         ValueRemat vr;
     401                 :     } u;
     402                 : 
     403                 :     // Address of the start of the last generated stub, if any. Note that this
     404                 :     // does not correctly overlay with the allocated memory; it does however
     405                 :     // overlay the portion that may need to be patched, which is good enough.
     406                 :     JITCode lastStubStart;
     407                 : 
     408                 :     // Return the start address of the last path in this PIC, which is the
     409                 :     // inline path if no stubs have been generated yet.
     410           39461 :     CodeLocationLabel lastPathStart() {
     411           39461 :         if (!stubsGenerated)
     412           36365 :             return fastPathStart;
     413            3096 :         return CodeLocationLabel(lastStubStart.start());
     414                 :     }
     415                 : 
     416           14654 :     CodeLocationLabel getFastShapeGuard() {
     417           14654 :         return fastPathStart.labelAtOffset(shapeGuard);
     418                 :     }
     419                 : 
     420             951 :     CodeLocationLabel getSlowTypeCheck() {
     421             951 :         JS_ASSERT(isGet());
     422             951 :         return slowPathStart.labelAtOffset(u.get.typeCheckOffset);
     423                 :     }
     424                 : 
     425                 :     // Return a JITCode block corresponding to the code memory to attach a
     426                 :     // new stub to.
     427           80987 :     JITCode lastCodeBlock(JITChunk *chunk) {
     428           80987 :         if (!stubsGenerated)
     429           74795 :             return JITCode(chunk->code.m_code.executableAddress(), chunk->code.m_size);
     430            6192 :         return lastStubStart;
     431                 :     }
     432                 : 
     433           34750 :     void updateLastPath(LinkerHelper &linker, Label label) {
     434           34750 :         CodeLocationLabel loc = linker.locationOf(label);
     435           34750 :         lastStubStart = JITCode(loc.executableAddress(), linker.size());
     436           34750 :     }
     437                 : 
     438                 :     Kind kind : 3;
     439                 : 
     440                 :     // True if register R holds the base object shape along exits from the
     441                 :     // last stub.
     442                 :     bool shapeRegHasBaseShape : 1;
     443                 : 
     444                 :     // True if can use the property cache.
     445                 :     bool usePropCache : 1;
     446                 : 
     447                 :     // State flags.
     448                 :     bool inlinePathPatched : 1;     // inline path has been patched
     449                 : 
     450                 :     RegisterID shapeReg : 5;        // also the out type reg
     451                 :     RegisterID objReg   : 5;        // also the out data reg
     452                 : 
     453                 :     // Whether type properties need to be updated to reflect generated stubs.
     454                 :     bool typeMonitored : 1;
     455                 : 
     456                 :     // Offset from start of fast path to initial shape guard.
     457                 :     uint32_t shapeGuard;
     458                 : 
     459                 :     // Possible types of the RHS, for monitored SETPROP PICs.
     460                 :     types::TypeSet *rhsTypes;
     461                 :     
     462          216412 :     inline bool isSet() const {
     463          216412 :         return kind == SET;
     464                 :     }
     465          361321 :     inline bool isGet() const {
     466          361321 :         return kind == GET;
     467                 :     }
     468           35580 :     inline bool isBind() const {
     469           35580 :         return kind == BIND;
     470                 :     }
     471           32505 :     inline bool isScopeName() const {
     472           32505 :         return kind == NAME || kind == XNAME;
     473                 :     }
     474             951 :     inline RegisterID typeReg() {
     475             951 :         JS_ASSERT(isGet());
     476             951 :         return u.get.typeReg;
     477                 :     }
     478            1072 :     inline bool hasTypeCheck() {
     479            1072 :         JS_ASSERT(isGet());
     480            1072 :         return u.get.hasTypeCheck;
     481                 :     }
     482           10403 :     inline bool shapeNeedsRemat() {
     483           10403 :         return !shapeRegHasBaseShape;
     484                 :     }
     485                 : 
     486                 :     union {
     487                 :         GetPropLabels getPropLabels_;
     488                 :         SetPropLabels setPropLabels_;
     489                 :         BindNameLabels bindNameLabels_;
     490                 :         ScopeNameLabels scopeNameLabels_;
     491                 :     };
     492           77873 :     void setLabels(const ic::GetPropLabels &labels) {
     493           77873 :         JS_ASSERT(isGet());
     494           77873 :         getPropLabels_ = labels;
     495           77873 :     }
     496           15850 :     void setLabels(const ic::SetPropLabels &labels) {
     497           15850 :         JS_ASSERT(isSet());
     498           15850 :         setPropLabels_ = labels;
     499           15850 :     }
     500            3075 :     void setLabels(const ic::BindNameLabels &labels) {
     501            3075 :         JS_ASSERT(kind == BIND);
     502            3075 :         bindNameLabels_ = labels;
     503            3075 :     }
     504           32505 :     void setLabels(const ic::ScopeNameLabels &labels) {
     505           32505 :         JS_ASSERT(kind == NAME || kind == XNAME);
     506           32505 :         scopeNameLabels_ = labels;
     507           32505 :     }
     508                 : 
     509           37718 :     GetPropLabels &getPropLabels() {
     510           37718 :         JS_ASSERT(isGet());
     511           37718 :         return getPropLabels_;
     512                 :     }
     513            6649 :     SetPropLabels &setPropLabels() {
     514            6649 :         JS_ASSERT(isSet());
     515            6649 :         return setPropLabels_;
     516                 :     }
     517            1297 :     BindNameLabels &bindNameLabels() {
     518            1297 :         JS_ASSERT(kind == BIND);
     519            1297 :         return bindNameLabels_;
     520                 :     }
     521           44579 :     ScopeNameLabels &scopeNameLabels() {
     522           44579 :         JS_ASSERT(kind == NAME || kind == XNAME);
     523           44579 :         return scopeNameLabels_;
     524                 :     }
     525                 : 
     526                 :     // Where in the script did we generate this PIC?
     527                 :     jsbytecode *pc;
     528                 :     
     529                 :     // Index into the script's atom table.
     530                 :     PropertyName *name;
     531                 : 
     532                 :     // Reset the data members to the state of a fresh PIC before any patching
     533                 :     // or stub generation was done.
     534          129303 :     void reset() {
     535          129303 :         BasePolyIC::reset();
     536          129303 :         inlinePathPatched = false;
     537          129303 :         shapeRegHasBaseShape = true;
     538          129303 :     }
     539                 : };
     540                 : 
     541                 : #ifdef JS_POLYIC
     542                 : void JS_FASTCALL GetProp(VMFrame &f, ic::PICInfo *);
     543                 : void JS_FASTCALL GetPropNoCache(VMFrame &f, ic::PICInfo *);
     544                 : void JS_FASTCALL SetProp(VMFrame &f, ic::PICInfo *);
     545                 : void JS_FASTCALL Name(VMFrame &f, ic::PICInfo *);
     546                 : void JS_FASTCALL XName(VMFrame &f, ic::PICInfo *);
     547                 : void JS_FASTCALL BindName(VMFrame &f, ic::PICInfo *);
     548                 : void JS_FASTCALL GetElement(VMFrame &f, ic::GetElementIC *);
     549            4174 : template <JSBool strict> void JS_FASTCALL SetElement(VMFrame &f, ic::SetElementIC *);
     550                 : #endif
     551                 : 
     552                 : } /* namespace ic */
     553                 : } /* namespace mjit */
     554                 : } /* namespace js */
     555                 : 
     556                 : #endif /* jsjaeger_poly_ic_h__ */
     557                 : 

Generated by: LCOV version 1.7