LCOV - code coverage report
Current view: top level - js/xpconnect/src - XPCMaps.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 70 146 47.9 %
Date: 2017-07-14 16:53:18 Functions: 22 33 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* Private maps (hashtables). */
       8             : 
       9             : #include "mozilla/MathAlgorithms.h"
      10             : #include "mozilla/MemoryReporting.h"
      11             : #include "xpcprivate.h"
      12             : 
      13             : #include "js/HashTable.h"
      14             : 
      15             : using namespace mozilla;
      16             : 
      17             : /***************************************************************************/
      18             : // static shared...
      19             : 
      20             : // Note this is returning the bit pattern of the first part of the nsID, not
      21             : // the pointer to the nsID.
      22             : 
      23             : static PLDHashNumber
      24       20347 : HashIIDPtrKey(const void* key)
      25             : {
      26       20347 :     return *((js::HashNumber*)key);
      27             : }
      28             : 
      29             : static bool
      30       15302 : MatchIIDPtrKey(const PLDHashEntryHdr* entry, const void* key)
      31             : {
      32             :     return ((const nsID*)key)->
      33       15302 :                 Equals(*((const nsID*)((PLDHashEntryStub*)entry)->key));
      34             : }
      35             : 
      36             : static PLDHashNumber
      37        3255 : HashNativeKey(const void* data)
      38             : {
      39        3255 :     return static_cast<const XPCNativeSetKey*>(data)->Hash();
      40             : }
      41             : 
      42             : /***************************************************************************/
      43             : // implement JSObject2WrappedJSMap...
      44             : 
      45             : void
      46           0 : JSObject2WrappedJSMap::UpdateWeakPointersAfterGC()
      47             : {
      48             :     // Check all wrappers and update their JSObject pointer if it has been
      49             :     // moved. Release any wrappers whose weakly held JSObject has died.
      50             : 
      51           0 :     nsTArray<RefPtr<nsXPCWrappedJS>> dying;
      52           0 :     for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
      53           0 :         nsXPCWrappedJS* wrapper = e.front().value();
      54           0 :         MOZ_ASSERT(wrapper, "found a null JS wrapper!");
      55             : 
      56             :         // Walk the wrapper chain and update all JSObjects.
      57           0 :         while (wrapper) {
      58           0 :             if (wrapper->IsSubjectToFinalization()) {
      59           0 :                 wrapper->UpdateObjectPointerAfterGC();
      60           0 :                 if (!wrapper->GetJSObjectPreserveColor())
      61           0 :                     dying.AppendElement(dont_AddRef(wrapper));
      62             :             }
      63           0 :             wrapper = wrapper->GetNextWrapper();
      64             :         }
      65             : 
      66             :         // Remove or update the JSObject key in the table if necessary.
      67           0 :         JSObject* obj = e.front().key().unbarrieredGet();
      68           0 :         JS_UpdateWeakPointerAfterGCUnbarriered(&obj);
      69           0 :         if (!obj)
      70           0 :             e.removeFront();
      71             :         else
      72           0 :             e.front().mutableKey() = obj;
      73             :     }
      74           0 : }
      75             : 
      76             : void
      77           0 : JSObject2WrappedJSMap::ShutdownMarker()
      78             : {
      79           0 :     for (Map::Range r = mTable.all(); !r.empty(); r.popFront()) {
      80           0 :         nsXPCWrappedJS* wrapper = r.front().value();
      81           0 :         MOZ_ASSERT(wrapper, "found a null JS wrapper!");
      82           0 :         MOZ_ASSERT(wrapper->IsValid(), "found an invalid JS wrapper!");
      83           0 :         wrapper->SystemIsBeingShutDown();
      84             :     }
      85           0 : }
      86             : 
      87             : size_t
      88           0 : JSObject2WrappedJSMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
      89             : {
      90           0 :     size_t n = mallocSizeOf(this);
      91           0 :     n += mTable.sizeOfExcludingThis(mallocSizeOf);
      92           0 :     return n;
      93             : }
      94             : 
      95             : size_t
      96           0 : JSObject2WrappedJSMap::SizeOfWrappedJS(mozilla::MallocSizeOf mallocSizeOf) const
      97             : {
      98           0 :     size_t n = 0;
      99           0 :     for (Map::Range r = mTable.all(); !r.empty(); r.popFront())
     100           0 :         n += r.front().value()->SizeOfIncludingThis(mallocSizeOf);
     101           0 :     return n;
     102             : }
     103             : 
     104             : /***************************************************************************/
     105             : // implement Native2WrappedNativeMap...
     106             : 
     107             : // static
     108             : Native2WrappedNativeMap*
     109         293 : Native2WrappedNativeMap::newMap(int length)
     110             : {
     111         293 :     return new Native2WrappedNativeMap(length);
     112             : }
     113             : 
     114         293 : Native2WrappedNativeMap::Native2WrappedNativeMap(int length)
     115         293 :   : mTable(PLDHashTable::StubOps(), sizeof(Entry), length)
     116             : {
     117         293 : }
     118             : 
     119             : size_t
     120           0 : Native2WrappedNativeMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
     121             : {
     122           0 :     size_t n = mallocSizeOf(this);
     123           0 :     n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
     124           0 :     for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
     125           0 :         auto entry = static_cast<Native2WrappedNativeMap::Entry*>(iter.Get());
     126           0 :         n += mallocSizeOf(entry->value);
     127             :     }
     128           0 :     return n;
     129             : }
     130             : 
     131             : /***************************************************************************/
     132             : // implement IID2WrappedJSClassMap...
     133             : 
     134             : const struct PLDHashTableOps IID2WrappedJSClassMap::Entry::sOps =
     135             : {
     136             :     HashIIDPtrKey,
     137             :     MatchIIDPtrKey,
     138             :     PLDHashTable::MoveEntryStub,
     139             :     PLDHashTable::ClearEntryStub
     140             : };
     141             : 
     142             : // static
     143             : IID2WrappedJSClassMap*
     144           3 : IID2WrappedJSClassMap::newMap(int length)
     145             : {
     146           3 :     return new IID2WrappedJSClassMap(length);
     147             : }
     148             : 
     149           3 : IID2WrappedJSClassMap::IID2WrappedJSClassMap(int length)
     150           3 :   : mTable(&Entry::sOps, sizeof(Entry), length)
     151             : {
     152           3 : }
     153             : 
     154             : /***************************************************************************/
     155             : // implement IID2NativeInterfaceMap...
     156             : 
     157             : const struct PLDHashTableOps IID2NativeInterfaceMap::Entry::sOps =
     158             : {
     159             :     HashIIDPtrKey,
     160             :     MatchIIDPtrKey,
     161             :     PLDHashTable::MoveEntryStub,
     162             :     PLDHashTable::ClearEntryStub
     163             : };
     164             : 
     165             : // static
     166             : IID2NativeInterfaceMap*
     167           3 : IID2NativeInterfaceMap::newMap(int length)
     168             : {
     169           3 :     return new IID2NativeInterfaceMap(length);
     170             : }
     171             : 
     172           3 : IID2NativeInterfaceMap::IID2NativeInterfaceMap(int length)
     173           3 :   : mTable(&Entry::sOps, sizeof(Entry), length)
     174             : {
     175           3 : }
     176             : 
     177             : size_t
     178           0 : IID2NativeInterfaceMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
     179             : {
     180           0 :     size_t n = mallocSizeOf(this);
     181           0 :     n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
     182           0 :     for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
     183           0 :         auto entry = static_cast<IID2NativeInterfaceMap::Entry*>(iter.Get());
     184           0 :         n += entry->value->SizeOfIncludingThis(mallocSizeOf);
     185             :     }
     186           0 :     return n;
     187             : }
     188             : 
     189             : /***************************************************************************/
     190             : // implement ClassInfo2NativeSetMap...
     191             : 
     192             : // static
     193         755 : bool ClassInfo2NativeSetMap::Entry::Match(const PLDHashEntryHdr* aEntry,
     194             :                                           const void* aKey)
     195             : {
     196         755 :     return static_cast<const Entry*>(aEntry)->key == aKey;
     197             : }
     198             : 
     199             : // static
     200           0 : void ClassInfo2NativeSetMap::Entry::Clear(PLDHashTable* aTable,
     201             :                                           PLDHashEntryHdr* aEntry)
     202             : {
     203           0 :     auto entry = static_cast<Entry*>(aEntry);
     204           0 :     NS_RELEASE(entry->value);
     205             : 
     206           0 :     entry->key = nullptr;
     207           0 :     entry->value = nullptr;
     208           0 : }
     209             : 
     210             : const PLDHashTableOps ClassInfo2NativeSetMap::Entry::sOps =
     211             : {
     212             :     PLDHashTable::HashVoidPtrKeyStub,
     213             :     Match,
     214             :     PLDHashTable::MoveEntryStub,
     215             :     Clear,
     216             :     nullptr
     217             : };
     218             : 
     219             : // static
     220             : ClassInfo2NativeSetMap*
     221           3 : ClassInfo2NativeSetMap::newMap(int length)
     222             : {
     223           3 :     return new ClassInfo2NativeSetMap(length);
     224             : }
     225             : 
     226           3 : ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length)
     227           3 :   : mTable(&ClassInfo2NativeSetMap::Entry::sOps, sizeof(Entry), length)
     228             : {
     229           3 : }
     230             : 
     231             : size_t
     232           0 : ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
     233             : {
     234           0 :     size_t n = mallocSizeOf(this);
     235           0 :     n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
     236           0 :     return n;
     237             : }
     238             : 
     239             : /***************************************************************************/
     240             : // implement ClassInfo2WrappedNativeProtoMap...
     241             : 
     242             : // static
     243             : ClassInfo2WrappedNativeProtoMap*
     244         293 : ClassInfo2WrappedNativeProtoMap::newMap(int length)
     245             : {
     246         293 :     return new ClassInfo2WrappedNativeProtoMap(length);
     247             : }
     248             : 
     249         293 : ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int length)
     250         293 :   : mTable(PLDHashTable::StubOps(), sizeof(Entry), length)
     251             : {
     252         293 : }
     253             : 
     254             : size_t
     255           0 : ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
     256             : {
     257           0 :     size_t n = mallocSizeOf(this);
     258           0 :     n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
     259           0 :     for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
     260           0 :         auto entry = static_cast<ClassInfo2WrappedNativeProtoMap::Entry*>(iter.Get());
     261           0 :         n += mallocSizeOf(entry->value);
     262             :     }
     263           0 :     return n;
     264             : }
     265             : 
     266             : /***************************************************************************/
     267             : // implement NativeSetMap...
     268             : 
     269             : bool
     270        2407 : NativeSetMap::Entry::Match(const PLDHashEntryHdr* entry, const void* key)
     271             : {
     272        2407 :     auto Key = static_cast<const XPCNativeSetKey*>(key);
     273        2407 :     XPCNativeSet*       SetInTable = ((Entry*)entry)->key_value;
     274        2407 :     XPCNativeSet*       Set        = Key->GetBaseSet();
     275        2407 :     XPCNativeInterface* Addition   = Key->GetAddition();
     276             : 
     277        2407 :     if (!Set) {
     278             :         // This is a special case to deal with the invariant that says:
     279             :         // "All sets have exactly one nsISupports interface and it comes first."
     280             :         // See XPCNativeSet::NewInstance for details.
     281             :         //
     282             :         // Though we might have a key that represents only one interface, we
     283             :         // know that if that one interface were contructed into a set then
     284             :         // it would end up really being a set with two interfaces (except for
     285             :         // the case where the one interface happened to be nsISupports).
     286             : 
     287        2283 :         return (SetInTable->GetInterfaceCount() == 1 &&
     288        3793 :                 SetInTable->GetInterfaceAt(0) == Addition) ||
     289        1510 :                (SetInTable->GetInterfaceCount() == 2 &&
     290        2274 :                 SetInTable->GetInterfaceAt(1) == Addition);
     291             :     }
     292             : 
     293         888 :     if (!Addition && Set == SetInTable)
     294          47 :         return true;
     295             : 
     296         841 :     uint16_t count = Set->GetInterfaceCount();
     297         841 :     if (count + (Addition ? 1 : 0) != SetInTable->GetInterfaceCount())
     298           0 :         return false;
     299             : 
     300         841 :     XPCNativeInterface** CurrentInTable = SetInTable->GetInterfaceArray();
     301         841 :     XPCNativeInterface** Current = Set->GetInterfaceArray();
     302        2371 :     for (uint16_t i = 0; i < count; i++) {
     303        1535 :         if (*(Current++) != *(CurrentInTable++))
     304           5 :             return false;
     305             :     }
     306         836 :     return !Addition || Addition == *(CurrentInTable++);
     307             : }
     308             : 
     309             : const struct PLDHashTableOps NativeSetMap::Entry::sOps =
     310             : {
     311             :     HashNativeKey,
     312             :     Match,
     313             :     PLDHashTable::MoveEntryStub,
     314             :     PLDHashTable::ClearEntryStub
     315             : };
     316             : 
     317             : // static
     318             : NativeSetMap*
     319           3 : NativeSetMap::newMap(int length)
     320             : {
     321           3 :     return new NativeSetMap(length);
     322             : }
     323             : 
     324           3 : NativeSetMap::NativeSetMap(int length)
     325           3 :   : mTable(&Entry::sOps, sizeof(Entry), length)
     326             : {
     327           3 : }
     328             : 
     329             : size_t
     330           0 : NativeSetMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
     331             : {
     332           0 :     size_t n = mallocSizeOf(this);
     333           0 :     n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
     334           0 :     for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
     335           0 :         auto entry = static_cast<NativeSetMap::Entry*>(iter.Get());
     336           0 :         n += entry->key_value->SizeOfIncludingThis(mallocSizeOf);
     337             :     }
     338           0 :     return n;
     339             : }
     340             : 
     341             : /***************************************************************************/
     342             : // implement IID2ThisTranslatorMap...
     343             : 
     344             : bool
     345          20 : IID2ThisTranslatorMap::Entry::Match(const PLDHashEntryHdr* entry,
     346             :                                     const void* key)
     347             : {
     348          20 :     return ((const nsID*)key)->Equals(((Entry*)entry)->key);
     349             : }
     350             : 
     351             : void
     352           0 : IID2ThisTranslatorMap::Entry::Clear(PLDHashTable* table, PLDHashEntryHdr* entry)
     353             : {
     354           0 :     static_cast<Entry*>(entry)->value = nullptr;
     355           0 :     memset(entry, 0, table->EntrySize());
     356           0 : }
     357             : 
     358             : const struct PLDHashTableOps IID2ThisTranslatorMap::Entry::sOps =
     359             : {
     360             :     HashIIDPtrKey,
     361             :     Match,
     362             :     PLDHashTable::MoveEntryStub,
     363             :     Clear
     364             : };
     365             : 
     366             : // static
     367             : IID2ThisTranslatorMap*
     368           3 : IID2ThisTranslatorMap::newMap(int length)
     369             : {
     370           3 :     return new IID2ThisTranslatorMap(length);
     371             : }
     372             : 
     373           3 : IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length)
     374           3 :   : mTable(&Entry::sOps, sizeof(Entry), length)
     375             : {
     376           3 : }
     377             : 
     378             : /***************************************************************************/
     379             : // implement XPCWrappedNativeProtoMap...
     380             : 
     381             : // static
     382             : XPCWrappedNativeProtoMap*
     383           3 : XPCWrappedNativeProtoMap::newMap(int length)
     384             : {
     385           3 :     return new XPCWrappedNativeProtoMap(length);
     386             : }
     387             : 
     388           3 : XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int length)
     389           3 :   : mTable(PLDHashTable::StubOps(), sizeof(PLDHashEntryStub), length)
     390             : {
     391           3 : }
     392             : 
     393             : /***************************************************************************/

Generated by: LCOV version 1.13