LCOV - code coverage report
Current view: directory - js/src/vm - ObjectImpl-inl.h (source / functions) Found Hit Coverage
Test: app.info Lines: 177 177 100.0 %
Date: 2012-04-07 Functions: 44 44 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=78:
       3                 :  *
       4                 :  * This Source Code Form is subject to the terms of the Mozilla Public
       5                 :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       6                 :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       7                 : 
       8                 : #ifndef ObjectImpl_inl_h___
       9                 : #define ObjectImpl_inl_h___
      10                 : 
      11                 : #include "mozilla/Assertions.h"
      12                 : 
      13                 : #include "jscell.h"
      14                 : #include "jscompartment.h"
      15                 : #include "jsgc.h"
      16                 : #include "jsgcmark.h"
      17                 : #include "jsinterp.h"
      18                 : 
      19                 : #include "js/TemplateLib.h"
      20                 : 
      21                 : #include "ObjectImpl.h"
      22                 : 
      23                 : namespace js {
      24                 : 
      25                 : static MOZ_ALWAYS_INLINE void
      26         4555234 : Debug_SetSlotRangeToCrashOnTouch(HeapSlot *vec, uint32_t len)
      27                 : {
      28                 : #ifdef DEBUG
      29         4555234 :     Debug_SetValueRangeToCrashOnTouch((Value *) vec, len);
      30                 : #endif
      31         4555234 : }
      32                 : 
      33                 : static MOZ_ALWAYS_INLINE void
      34             900 : Debug_SetSlotRangeToCrashOnTouch(HeapSlot *begin, HeapSlot *end)
      35                 : {
      36                 : #ifdef DEBUG
      37             900 :     Debug_SetValueRangeToCrashOnTouch((Value *) begin, end - begin);
      38                 : #endif
      39             900 : }
      40                 : 
      41                 : } // namespace js
      42                 : 
      43                 : inline bool
      44        34793055 : js::ObjectImpl::isExtensible() const
      45                 : {
      46        34793055 :     return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
      47                 : }
      48                 : 
      49                 : inline bool
      50       577260863 : js::ObjectImpl::isDenseArray() const
      51                 : {
      52       577260863 :     bool result = hasClass(&ArrayClass);
      53       577260863 :     MOZ_ASSERT_IF(result, elements != emptyObjectElements);
      54       577260863 :     return result;
      55                 : }
      56                 : 
      57                 : inline bool
      58       176833456 : js::ObjectImpl::isSlowArray() const
      59                 : {
      60       176833456 :     bool result = hasClass(&SlowArrayClass);
      61       176833456 :     MOZ_ASSERT_IF(result, elements != emptyObjectElements);
      62       176833456 :     return result;
      63                 : }
      64                 : 
      65                 : inline bool
      66       176346391 : js::ObjectImpl::isArray() const
      67                 : {
      68       176346391 :     return isSlowArray() || isDenseArray();
      69                 : }
      70                 : 
      71                 : inline uint32_t
      72       127519804 : js::ObjectImpl::getDenseArrayInitializedLength()
      73                 : {
      74       127519804 :     MOZ_ASSERT(isDenseArray());
      75       127519804 :     return getElementsHeader()->initializedLength;
      76                 : }
      77                 : 
      78                 : inline js::HeapSlotArray
      79          839076 : js::ObjectImpl::getDenseArrayElements()
      80                 : {
      81          839076 :     MOZ_ASSERT(isDenseArray());
      82          839076 :     return HeapSlotArray(elements);
      83                 : }
      84                 : 
      85                 : inline const js::Value &
      86        61138891 : js::ObjectImpl::getDenseArrayElement(uint32_t idx)
      87                 : {
      88        61138891 :     MOZ_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
      89        61138891 :     return elements[idx];
      90                 : }
      91                 : 
      92                 : inline void
      93         4919164 : js::ObjectImpl::getSlotRangeUnchecked(uint32_t start, uint32_t length,
      94                 :                                       HeapSlot **fixedStart, HeapSlot **fixedEnd,
      95                 :                                       HeapSlot **slotsStart, HeapSlot **slotsEnd)
      96                 : {
      97         4919164 :     MOZ_ASSERT(!isDenseArray());
      98         4919164 :     MOZ_ASSERT(start + length >= start);
      99                 : 
     100         4919164 :     uint32_t fixed = numFixedSlots();
     101         4919164 :     if (start < fixed) {
     102         4892690 :         if (start + length < fixed) {
     103         1624434 :             *fixedStart = &fixedSlots()[start];
     104         1624434 :             *fixedEnd = &fixedSlots()[start + length];
     105         1624434 :             *slotsStart = *slotsEnd = NULL;
     106                 :         } else {
     107         3268256 :             uint32_t localCopy = fixed - start;
     108         3268256 :             *fixedStart = &fixedSlots()[start];
     109         3268256 :             *fixedEnd = &fixedSlots()[start + localCopy];
     110         3268256 :             *slotsStart = &slots[0];
     111         3268256 :             *slotsEnd = &slots[length - localCopy];
     112                 :         }
     113                 :     } else {
     114           26474 :         *fixedStart = *fixedEnd = NULL;
     115           26474 :         *slotsStart = &slots[start - fixed];
     116           26474 :         *slotsEnd = &slots[start - fixed + length];
     117                 :     }
     118         4919164 : }
     119                 : 
     120                 : inline void
     121          379152 : js::ObjectImpl::getSlotRange(uint32_t start, uint32_t length,
     122                 :                              HeapSlot **fixedStart, HeapSlot **fixedEnd,
     123                 :                              HeapSlot **slotsStart, HeapSlot **slotsEnd)
     124                 : {
     125          379152 :     MOZ_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
     126          379152 :     getSlotRangeUnchecked(start, length, fixedStart, fixedEnd, slotsStart, slotsEnd);
     127          379152 : }
     128                 : 
     129                 : inline bool
     130          553758 : js::ObjectImpl::hasContiguousSlots(uint32_t start, uint32_t count) const
     131                 : {
     132                 :     /*
     133                 :      * Check that the range [start, start+count) is either all inline or all
     134                 :      * out of line.
     135                 :      */
     136          553758 :     MOZ_ASSERT(slotInRange(start + count, SENTINEL_ALLOWED));
     137          553758 :     return start + count <= numFixedSlots() || start >= numFixedSlots();
     138                 : }
     139                 : 
     140                 : inline void
     141             450 : js::ObjectImpl::invalidateSlotRange(uint32_t start, uint32_t length)
     142                 : {
     143                 : #ifdef DEBUG
     144             450 :     MOZ_ASSERT(!isDenseArray());
     145                 : 
     146                 :     HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
     147             450 :     getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
     148             450 :     Debug_SetSlotRangeToCrashOnTouch(fixedStart, fixedEnd);
     149             450 :     Debug_SetSlotRangeToCrashOnTouch(slotsStart, slotsEnd);
     150                 : #endif /* DEBUG */
     151             450 : }
     152                 : 
     153                 : inline void
     154         4540012 : js::ObjectImpl::initializeSlotRange(uint32_t start, uint32_t length)
     155                 : {
     156                 :     /*
     157                 :      * No bounds check, as this is used when the object's shape does not
     158                 :      * reflect its allocated slots (updateSlotsForSpan).
     159                 :      */
     160                 :     HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
     161         4540012 :     getSlotRangeUnchecked(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
     162                 : 
     163         4540012 :     JSCompartment *comp = compartment();
     164         4540012 :     uint32_t offset = start;
     165        17637207 :     for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
     166        13097195 :         sp->init(comp, this->asObjectPtr(), offset++, UndefinedValue());
     167         7958091 :     for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
     168         3418079 :         sp->init(comp, this->asObjectPtr(), offset++, UndefinedValue());
     169         4540012 : }
     170                 : 
     171                 : inline bool
     172       293370951 : js::ObjectImpl::isNative() const
     173                 : {
     174       293370951 :     return lastProperty()->isNative();
     175                 : }
     176                 : 
     177                 : inline js::HeapSlot &
     178         8270165 : js::ObjectImpl::nativeGetSlotRef(uint32_t slot)
     179                 : {
     180         8270165 :     MOZ_ASSERT(isNative());
     181         8270165 :     MOZ_ASSERT(slot < slotSpan());
     182         8270165 :     return getSlotRef(slot);
     183                 : }
     184                 : 
     185                 : inline const js::Value &
     186        97855496 : js::ObjectImpl::nativeGetSlot(uint32_t slot) const
     187                 : {
     188        97855496 :     MOZ_ASSERT(isNative());
     189        97855496 :     MOZ_ASSERT(slot < slotSpan());
     190        97855496 :     return getSlot(slot);
     191                 : }
     192                 : 
     193                 : inline void
     194        59439646 : js::ObjectImpl::setSlot(uint32_t slot, const js::Value &value)
     195                 : {
     196        59439646 :     MOZ_ASSERT(slotInRange(slot));
     197        59439646 :     getSlotRef(slot).set(this->asObjectPtr(), slot, value);
     198        59439646 : }
     199                 : 
     200                 : inline void
     201          153351 : js::ObjectImpl::initSlot(uint32_t slot, const js::Value &value)
     202                 : {
     203          153351 :     MOZ_ASSERT(getSlot(slot).isUndefined() || getSlot(slot).isMagic(JS_ARRAY_HOLE));
     204          153351 :     MOZ_ASSERT(slotInRange(slot));
     205          153351 :     initSlotUnchecked(slot, value);
     206          153351 : }
     207                 : 
     208                 : inline void
     209        18642989 : js::ObjectImpl::initSlotUnchecked(uint32_t slot, const js::Value &value)
     210                 : {
     211        18642989 :     getSlotAddressUnchecked(slot)->init(this->asObjectPtr(), slot, value);
     212        18642989 : }
     213                 : 
     214                 : inline void
     215         4049801 : js::ObjectImpl::setFixedSlot(uint32_t slot, const js::Value &value)
     216                 : {
     217         4049801 :     MOZ_ASSERT(slot < numFixedSlots());
     218         4049801 :     fixedSlots()[slot].set(this->asObjectPtr(), slot, value);
     219         4049801 : }
     220                 : 
     221                 : inline void
     222         2215034 : js::ObjectImpl::initFixedSlot(uint32_t slot, const js::Value &value)
     223                 : {
     224         2215034 :     MOZ_ASSERT(slot < numFixedSlots());
     225         2215034 :     fixedSlots()[slot].init(this->asObjectPtr(), slot, value);
     226         2215034 : }
     227                 : 
     228                 : inline uint32_t
     229       687711998 : js::ObjectImpl::slotSpan() const
     230                 : {
     231       687711998 :     if (inDictionaryMode())
     232       218453263 :         return lastProperty()->base()->slotSpan();
     233       469258735 :     return lastProperty()->slotSpan();
     234                 : }
     235                 : 
     236                 : inline uint32_t
     237       505693457 : js::ObjectImpl::numDynamicSlots() const
     238                 : {
     239       505693457 :     return dynamicSlotsCount(numFixedSlots(), slotSpan());
     240                 : }
     241                 : 
     242                 : inline js::Class *
     243      1681562781 : js::ObjectImpl::getClass() const
     244                 : {
     245      1681562781 :     return lastProperty()->getObjectClass();
     246                 : }
     247                 : 
     248                 : inline JSClass *
     249         2323858 : js::ObjectImpl::getJSClass() const
     250                 : {
     251         2323858 :     return Jsvalify(getClass());
     252                 : }
     253                 : 
     254                 : inline bool
     255      1210191962 : js::ObjectImpl::hasClass(const Class *c) const
     256                 : {
     257      1210191962 :     return getClass() == c;
     258                 : }
     259                 : 
     260                 : inline const js::ObjectOps *
     261       155868044 : js::ObjectImpl::getOps() const
     262                 : {
     263       155868044 :     return &getClass()->ops;
     264                 : }
     265                 : 
     266                 : inline bool
     267        32607555 : js::ObjectImpl::isDelegate() const
     268                 : {
     269        32607555 :     return lastProperty()->hasObjectFlag(BaseShape::DELEGATE);
     270                 : }
     271                 : 
     272                 : inline bool
     273       827005121 : js::ObjectImpl::inDictionaryMode() const
     274                 : {
     275       827005121 :     return lastProperty()->inDictionary();
     276                 : }
     277                 : 
     278                 : /* static */ inline uint32_t
     279       560762265 : js::ObjectImpl::dynamicSlotsCount(uint32_t nfixed, uint32_t span)
     280                 : {
     281       560762265 :     if (span <= nfixed)
     282       269308014 :         return 0;
     283       291454251 :     span -= nfixed;
     284       291454251 :     if (span <= SLOT_CAPACITY_MIN)
     285        84106339 :         return SLOT_CAPACITY_MIN;
     286                 : 
     287       207347912 :     uint32_t slots = RoundUpPow2(span);
     288       207347912 :     MOZ_ASSERT(slots >= span);
     289       207347912 :     return slots;
     290                 : }
     291                 : 
     292                 : inline size_t
     293        19877247 : js::ObjectImpl::sizeOfThis() const
     294                 : {
     295        19877247 :     return arenaHeader()->getThingSize();
     296                 : }
     297                 : 
     298                 : /* static */ inline void
     299          108666 : js::ObjectImpl::readBarrier(ObjectImpl *obj)
     300                 : {
     301                 : #ifdef JSGC_INCREMENTAL
     302          108666 :     JSCompartment *comp = obj->compartment();
     303          108666 :     if (comp->needsBarrier()) {
     304             153 :         MOZ_ASSERT(!comp->rt->gcRunning);
     305             153 :         JSObject *tmp = obj->asObjectPtr();
     306             153 :         MarkObjectUnbarriered(comp->barrierTracer(), &tmp, "read barrier");
     307             153 :         MOZ_ASSERT(tmp == obj->asObjectPtr());
     308                 :     }
     309                 : #endif
     310          108666 : }
     311                 : 
     312                 : inline void
     313         2869927 : js::ObjectImpl::privateWriteBarrierPre(void **old)
     314                 : {
     315                 : #ifdef JSGC_INCREMENTAL
     316         2869927 :     JSCompartment *comp = compartment();
     317         2869927 :     if (comp->needsBarrier()) {
     318             651 :         if (*old && getClass()->trace)
     319             160 :             getClass()->trace(comp->barrierTracer(), this->asObjectPtr());
     320                 :     }
     321                 : #endif
     322         2869927 : }
     323                 : 
     324                 : inline void
     325         2869927 : js::ObjectImpl::privateWriteBarrierPost(void **old)
     326                 : {
     327         2869927 : }
     328                 : 
     329                 : /* static */ inline void
     330        13547991 : js::ObjectImpl::writeBarrierPre(ObjectImpl *obj)
     331                 : {
     332                 : #ifdef JSGC_INCREMENTAL
     333                 :     /*
     334                 :      * This would normally be a null test, but TypeScript::global uses 0x1 as a
     335                 :      * special value.
     336                 :      */
     337        13547991 :     if (uintptr_t(obj) < 32)
     338        11771551 :         return;
     339                 : 
     340         1776440 :     JSCompartment *comp = obj->compartment();
     341         1776440 :     if (comp->needsBarrier()) {
     342              95 :         MOZ_ASSERT(!comp->rt->gcRunning);
     343              95 :         JSObject *tmp = obj->asObjectPtr();
     344              95 :         MarkObjectUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
     345              95 :         MOZ_ASSERT(tmp == obj->asObjectPtr());
     346                 :     }
     347                 : #endif
     348                 : }
     349                 : 
     350                 : /* static */ inline void
     351        27619473 : js::ObjectImpl::writeBarrierPost(ObjectImpl *obj, void *addr)
     352                 : {
     353        27619473 : }
     354                 : 
     355                 : inline bool
     356        48179401 : js::ObjectImpl::hasPrivate() const
     357                 : {
     358        48179401 :     return getClass()->hasPrivate();
     359                 : }
     360                 : 
     361                 : inline void *&
     362        48161538 : js::ObjectImpl::privateRef(uint32_t nfixed) const
     363                 : {
     364                 :     /*
     365                 :      * The private pointer of an object can hold any word sized value.
     366                 :      * Private pointers are stored immediately after the last fixed slot of
     367                 :      * the object.
     368                 :      */
     369        48161538 :     MOZ_ASSERT(nfixed == numFixedSlots());
     370        48161538 :     MOZ_ASSERT(hasPrivate());
     371        48161538 :     HeapSlot *end = &fixedSlots()[nfixed];
     372        48161538 :     return *reinterpret_cast<void**>(end);
     373                 : }
     374                 : 
     375                 : inline void *
     376        43456612 : js::ObjectImpl::getPrivate() const
     377                 : {
     378        43456612 :     return privateRef(numFixedSlots());
     379                 : }
     380                 : 
     381                 : inline void *
     382           57368 : js::ObjectImpl::getPrivate(uint32_t nfixed) const
     383                 : {
     384           57368 :     return privateRef(nfixed);
     385                 : }
     386                 : 
     387                 : inline void
     388         2869927 : js::ObjectImpl::setPrivate(void *data)
     389                 : {
     390         2869927 :     void **pprivate = &privateRef(numFixedSlots());
     391                 : 
     392         2869927 :     privateWriteBarrierPre(pprivate);
     393         2869927 :     *pprivate = data;
     394         2869927 :     privateWriteBarrierPost(pprivate);
     395         2869927 : }
     396                 : 
     397                 : inline void
     398            3779 : js::ObjectImpl::setPrivateUnbarriered(void *data)
     399                 : {
     400            3779 :     void **pprivate = &privateRef(numFixedSlots());
     401            3779 :     *pprivate = data;
     402            3779 : }
     403                 : 
     404                 : inline void
     405          201545 : js::ObjectImpl::initPrivate(void *data)
     406                 : {
     407          201545 :     privateRef(numFixedSlots()) = data;
     408          201545 : }
     409                 : 
     410                 : #endif /* ObjectImpl_inl_h__ */

Generated by: LCOV version 1.7