LCOV - code coverage report
Current view: directory - js/src - jspropertycache.h (source / functions) Found Hit Coverage
Test: app.info Lines: 17 17 100.0 %
Date: 2012-06-02 Functions: 5 5 100.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=98:
       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 Communicator client code, released
      18                 :  * March 31, 1998.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  * Netscape Communications Corporation.
      22                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      23                 :  * the Initial Developer. All Rights Reserved.
      24                 :  *
      25                 :  * Contributor(s):
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * 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                 : 
      41                 : #ifndef jspropertycache_h___
      42                 : #define jspropertycache_h___
      43                 : 
      44                 : #include "jsapi.h"
      45                 : #include "jsprvtd.h"
      46                 : #include "jstypes.h"
      47                 : 
      48                 : #include "vm/String.h"
      49                 : 
      50                 : namespace js {
      51                 : 
      52                 : /*
      53                 :  * Property cache with structurally typed capabilities for invalidation, for
      54                 :  * polymorphic callsite method/get/set speedups.  For details, see
      55                 :  * <https://developer.mozilla.org/en/SpiderMonkey/Internals/Property_cache>.
      56                 :  */
      57                 : class PropertyCache;
      58                 : 
      59                 : struct PropertyCacheEntry
      60                 : {
      61                 :     jsbytecode          *kpc;           /* pc of cache-testing bytecode */
      62                 :     const Shape         *kshape;        /* shape of direct (key) object */
      63                 :     const Shape         *pshape;        /* shape of owning object */
      64                 :     const Shape         *prop;          /* shape of accessed property */
      65                 : 
      66                 :     friend class PropertyCache;
      67                 : 
      68                 :   private:
      69                 :     /* Index into scope chain; inapplicable to property lookup entries. */
      70                 :     uint8_t             scopeIndex;
      71                 :     /* Index into the prototype chain from the object for this entry. */
      72                 :     uint8_t             protoIndex;
      73                 : 
      74                 :   public:
      75                 :     static const size_t MaxScopeIndex = 15;
      76                 :     static const size_t MaxProtoIndex = 15;
      77                 : 
      78                 :     /*
      79                 :      * True iff the property lookup will find an own property on the object if
      80                 :      * the entry matches.
      81                 :      *
      82                 :      * This test is applicable only to property lookups, not to identifier
      83                 :      * lookups.  It is meaningless to ask this question of an entry for an
      84                 :      * identifier lookup.
      85                 :      */
      86        45023611 :     bool isOwnPropertyHit() const { return scopeIndex == 0 && protoIndex == 0; }
      87                 : 
      88                 :     /*
      89                 :      * True iff the property lookup will find the property on the prototype of
      90                 :      * the object if the entry matches.
      91                 :      *
      92                 :      * This test is applicable only to property lookups, not to identifier
      93                 :      * lookups.  It is meaningless to ask this question of an entry for an
      94                 :      * identifier lookup.
      95                 :      */
      96        99557093 :     bool isPrototypePropertyHit() const { return scopeIndex == 0 && protoIndex == 1; }
      97                 : 
      98        17199230 :     void assign(jsbytecode *kpc, const Shape *kshape, const Shape *pshape,
      99                 :                 const Shape *prop, unsigned scopeIndex, unsigned protoIndex) {
     100        17199230 :         JS_ASSERT(scopeIndex <= MaxScopeIndex);
     101        17199230 :         JS_ASSERT(protoIndex <= MaxProtoIndex);
     102                 : 
     103        17199230 :         this->kpc = kpc;
     104        17199230 :         this->kshape = kshape;
     105        17199230 :         this->pshape = pshape;
     106        17199230 :         this->prop = prop;
     107        17199230 :         this->scopeIndex = uint8_t(scopeIndex);
     108        17199230 :         this->protoIndex = uint8_t(protoIndex);
     109        17199230 :     }
     110                 : };
     111                 : 
     112                 : /*
     113                 :  * Special value for functions returning PropertyCacheEntry * to distinguish
     114                 :  * between failure and no no-cache-fill cases.
     115                 :  */
     116                 : #define JS_NO_PROP_CACHE_FILL ((js::PropertyCacheEntry *) NULL + 1)
     117                 : 
     118                 : #if defined DEBUG_brendan || defined DEBUG_brendaneich
     119                 : #define JS_PROPERTY_CACHE_METERING 1
     120                 : #endif
     121                 : 
     122                 : class PropertyCache
     123                 : {
     124                 :   private:
     125                 :     enum {
     126                 :         SIZE_LOG2 = 12,
     127                 :         SIZE = JS_BIT(SIZE_LOG2),
     128                 :         MASK = JS_BITMASK(SIZE_LOG2)
     129                 :     };
     130                 : 
     131                 :     PropertyCacheEntry  table[SIZE];
     132                 :     JSBool              empty;
     133                 : 
     134                 :   public:
     135                 : #ifdef JS_PROPERTY_CACHE_METERING
     136                 :     PropertyCacheEntry  *pctestentry;   /* entry of the last PC-based test */
     137                 :     uint32_t            fills;          /* number of cache entry fills */
     138                 :     uint32_t            nofills;        /* couldn't fill (e.g. default get) */
     139                 :     uint32_t            rofills;        /* set on read-only prop can't fill */
     140                 :     uint32_t            disfills;       /* fill attempts on disabled cache */
     141                 :     uint32_t            oddfills;       /* fill attempt after setter deleted */
     142                 :     uint32_t            add2dictfills;  /* fill attempt on dictionary object */
     143                 :     uint32_t            modfills;       /* fill that rehashed to a new entry */
     144                 :     uint32_t            brandfills;     /* scope brandings to type structural
     145                 :                                            method fills */
     146                 :     uint32_t            noprotos;       /* resolve-returned non-proto pobj */
     147                 :     uint32_t            longchains;     /* overlong scope and/or proto chain */
     148                 :     uint32_t            recycles;       /* cache entries recycled by fills */
     149                 :     uint32_t            tests;          /* cache probes */
     150                 :     uint32_t            pchits;         /* fast-path polymorphic op hits */
     151                 :     uint32_t            protopchits;    /* pchits hitting immediate prototype */
     152                 :     uint32_t            initests;       /* cache probes from JSOP_INITPROP */
     153                 :     uint32_t            inipchits;      /* init'ing next property pchit case */
     154                 :     uint32_t            inipcmisses;    /* init'ing next property pc misses */
     155                 :     uint32_t            settests;       /* cache probes from JOF_SET opcodes */
     156                 :     uint32_t            addpchits;      /* adding next property pchit case */
     157                 :     uint32_t            setpchits;      /* setting existing property pchit */
     158                 :     uint32_t            setpcmisses;    /* setting/adding property pc misses */
     159                 :     uint32_t            setmisses;      /* JSOP_SET{NAME,PROP} total misses */
     160                 :     uint32_t            kpcmisses;      /* slow-path key id == atom misses */
     161                 :     uint32_t            kshapemisses;   /* slow-path key object misses */
     162                 :     uint32_t            vcapmisses;     /* value capability misses */
     163                 :     uint32_t            misses;         /* cache misses */
     164                 :     uint32_t            flushes;        /* cache flushes */
     165                 :     uint32_t            pcpurges;       /* shadowing purges on proto chain */
     166                 : 
     167                 : # define PCMETER(x)     x
     168                 : #else
     169                 : # define PCMETER(x)     ((void)0)
     170                 : #endif
     171                 : 
     172           19910 :     PropertyCache() {
     173           19910 :         PodZero(this);
     174           19910 :     }
     175                 :     
     176                 :   private:
     177                 :     static inline uintptr_t
     178       155457553 :     hash(jsbytecode *pc, const Shape *kshape)
     179                 :     {
     180       155457553 :         return (((uintptr_t(pc) >> SIZE_LOG2) ^ uintptr_t(pc) ^ ((uintptr_t)kshape >> 3)) & MASK);
     181                 :     }
     182                 : 
     183                 :     static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape);
     184                 : 
     185                 :     PropertyName *
     186                 :     fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp,
     187                 :              JSObject **pobjp, PropertyCacheEntry *entry);
     188                 : 
     189                 : #ifdef DEBUG
     190                 :     void assertEmpty();
     191                 : #else
     192                 :     inline void assertEmpty() {}
     193                 : #endif
     194                 : 
     195                 :   public:
     196                 :     JS_ALWAYS_INLINE void test(JSContext *cx, jsbytecode *pc,
     197                 :                                JSObject *&obj, JSObject *&pobj,
     198                 :                                PropertyCacheEntry *&entry, PropertyName *&name);
     199                 : 
     200                 :     /*
     201                 :      * Test for cached information about a property set on *objp at pc.
     202                 :      *
     203                 :      * On a hit, set *entryp to the entry and return true.
     204                 :      *
     205                 :      * On a miss, set *namep to the name of the property being set and return false.
     206                 :      */
     207                 :     JS_ALWAYS_INLINE bool testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
     208                 :                                      PropertyCacheEntry **entryp, JSObject **obj2p,
     209                 :                                      PropertyName **namep);
     210                 : 
     211                 :     /*
     212                 :      * Fill property cache entry for key cx->fp->pc, optimized value word
     213                 :      * computed from obj and shape, and entry capability forged from 24-bit
     214                 :      * obj->shape(), 4-bit scopeIndex, and 4-bit protoIndex.
     215                 :      *
     216                 :      * Return the filled cache entry or JS_NO_PROP_CACHE_FILL if caching was
     217                 :      * not possible.
     218                 :      */
     219                 :     PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, unsigned scopeIndex,
     220                 :                              JSObject *pobj, const js::Shape *shape);
     221                 : 
     222                 :     void purge(JSRuntime *rt);
     223                 : 
     224                 :     /* Restore an entry that may have been purged during a GC. */
     225                 :     void restore(PropertyCacheEntry *entry);
     226                 : };
     227                 : 
     228                 : } /* namespace js */
     229                 : 
     230                 : #endif /* jspropertycache_h___ */

Generated by: LCOV version 1.7