LCOV - code coverage report
Current view: directory - js/xpconnect/src - XPCMaps.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 353 246 69.7 %
Date: 2012-06-02 Functions: 60 53 88.3 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla Communicator client code, released
      17                 :  * March 31, 1998.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  * Netscape Communications Corporation.
      21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *   John Bandhauer <jband@netscape.com> (original author)
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or 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                 : /* Private maps (hashtables). */
      42                 : 
      43                 : #include "xpcprivate.h"
      44                 : 
      45                 : #include "jshash.h"
      46                 : 
      47                 : /***************************************************************************/
      48                 : // static shared...
      49                 : 
      50                 : // Note this is returning the bit pattern of the first part of the nsID, not
      51                 : // the pointer to the nsID.
      52                 : 
      53                 : static JSDHashNumber
      54         2916826 : HashIIDPtrKey(JSDHashTable *table, const void *key)
      55                 : {
      56         2916826 :     return *((JSHashNumber*)key);
      57                 : }
      58                 : 
      59                 : static JSBool
      60         2522439 : MatchIIDPtrKey(JSDHashTable *table,
      61                 :                const JSDHashEntryHdr *entry,
      62                 :                const void *key)
      63                 : {
      64                 :     return ((const nsID*)key)->
      65         2522439 :                 Equals(*((const nsID*)((JSDHashEntryStub*)entry)->key));
      66                 : }
      67                 : 
      68                 : static JSDHashNumber
      69         1281696 : HashNativeKey(JSDHashTable *table, const void *key)
      70                 : {
      71         1281696 :     XPCNativeSetKey* Key = (XPCNativeSetKey*) key;
      72                 : 
      73         1281696 :     JSDHashNumber h = 0;
      74                 : 
      75                 :     XPCNativeSet*       Set;
      76                 :     XPCNativeInterface* Addition;
      77                 :     PRUint16            Position;
      78                 : 
      79         1281696 :     if (Key->IsAKey()) {
      80         1281696 :         Set      = Key->GetBaseSet();
      81         1281696 :         Addition = Key->GetAddition();
      82         1281696 :         Position = Key->GetPosition();
      83                 :     } else {
      84               0 :         Set      = (XPCNativeSet*) Key;
      85               0 :         Addition = nsnull;
      86               0 :         Position = 0;
      87                 :     }
      88                 : 
      89         1281696 :     if (!Set) {
      90          989461 :         NS_ASSERTION(Addition, "bad key");
      91                 :         // This would be an XOR like below.
      92                 :         // But "0 ^ x == x". So it does not matter.
      93          989461 :         h = (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
      94                 :     } else {
      95          292235 :         XPCNativeInterface** Current = Set->GetInterfaceArray();
      96          292235 :         PRUint16 count = Set->GetInterfaceCount();
      97          292235 :         if (Addition) {
      98          188077 :             count++;
      99          697875 :             for (PRUint16 i = 0; i < count; i++) {
     100          509798 :                 if (i == Position)
     101          188077 :                     h ^= (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
     102                 :                 else
     103          321721 :                     h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
     104                 :             }
     105                 :         } else {
     106          420680 :             for (PRUint16 i = 0; i < count; i++)
     107          316522 :                 h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
     108                 :         }
     109                 :     }
     110                 : 
     111         1281696 :     return h;
     112                 : }
     113                 : 
     114                 : /***************************************************************************/
     115                 : // implement JSObject2WrappedJSMap...
     116                 : 
     117                 : // static
     118                 : JSObject2WrappedJSMap*
     119            1404 : JSObject2WrappedJSMap::newMap(int size)
     120                 : {
     121            1404 :     JSObject2WrappedJSMap* map = new JSObject2WrappedJSMap(size);
     122            1404 :     if (map && map->mTable)
     123            1404 :         return map;
     124               0 :     delete map;
     125               0 :     return nsnull;
     126                 : }
     127                 : 
     128            1404 : JSObject2WrappedJSMap::JSObject2WrappedJSMap(int size)
     129                 : {
     130                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     131            1404 :                               sizeof(Entry), size);
     132            1404 : }
     133                 : 
     134            1403 : JSObject2WrappedJSMap::~JSObject2WrappedJSMap()
     135                 : {
     136            1403 :     if (mTable)
     137            1403 :         JS_DHashTableDestroy(mTable);
     138            1403 : }
     139                 : 
     140                 : size_t
     141               3 : JSObject2WrappedJSMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     142                 : {
     143               3 :     size_t n = 0;
     144               3 :     n += mallocSizeOf(this);
     145               3 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
     146               3 :     return n;
     147                 : }
     148                 : 
     149                 : /* static */ size_t
     150              81 : JSObject2WrappedJSMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
     151                 :                                                 JSMallocSizeOfFun mallocSizeOf, void *)
     152                 : {
     153              81 :     return mallocSizeOf(((JSObject2WrappedJSMap::Entry*)hdr)->value);
     154                 : }
     155                 : 
     156                 : /***************************************************************************/
     157                 : // implement Native2WrappedNativeMap...
     158                 : 
     159                 : // static
     160                 : Native2WrappedNativeMap*
     161           15475 : Native2WrappedNativeMap::newMap(int size)
     162                 : {
     163           15475 :     Native2WrappedNativeMap* map = new Native2WrappedNativeMap(size);
     164           15475 :     if (map && map->mTable)
     165           15475 :         return map;
     166               0 :     delete map;
     167               0 :     return nsnull;
     168                 : }
     169                 : 
     170           15475 : Native2WrappedNativeMap::Native2WrappedNativeMap(int size)
     171                 : {
     172                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     173           15475 :                               sizeof(Entry), size);
     174           15475 : }
     175                 : 
     176           15471 : Native2WrappedNativeMap::~Native2WrappedNativeMap()
     177                 : {
     178           15471 :     if (mTable)
     179           15471 :         JS_DHashTableDestroy(mTable);
     180           15471 : }
     181                 : 
     182                 : size_t
     183              59 : Native2WrappedNativeMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     184                 : {
     185              59 :     size_t n = 0;
     186              59 :     n += mallocSizeOf(this);
     187              59 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
     188              59 :     return n;
     189                 : }
     190                 : 
     191                 : /* static */ size_t
     192            1865 : Native2WrappedNativeMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
     193                 :                                                   JSMallocSizeOfFun mallocSizeOf, void *)
     194                 : {
     195            1865 :     return mallocSizeOf(((Native2WrappedNativeMap::Entry*)hdr)->value);
     196                 : }
     197                 : 
     198                 : /***************************************************************************/
     199                 : // implement IID2WrappedJSClassMap...
     200                 : 
     201                 : struct JSDHashTableOps IID2WrappedJSClassMap::Entry::sOps =
     202                 : {
     203                 :     JS_DHashAllocTable,
     204                 :     JS_DHashFreeTable,
     205                 :     HashIIDPtrKey,
     206                 :     MatchIIDPtrKey,
     207                 :     JS_DHashMoveEntryStub,
     208                 :     JS_DHashClearEntryStub,
     209                 :     JS_DHashFinalizeStub
     210                 : };
     211                 : 
     212                 : // static
     213                 : IID2WrappedJSClassMap*
     214            1404 : IID2WrappedJSClassMap::newMap(int size)
     215                 : {
     216            1404 :     IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(size);
     217            1404 :     if (map && map->mTable)
     218            1404 :         return map;
     219               0 :     delete map;
     220               0 :     return nsnull;
     221                 : }
     222                 : 
     223            1404 : IID2WrappedJSClassMap::IID2WrappedJSClassMap(int size)
     224                 : {
     225            1404 :     mTable = JS_NewDHashTable(&Entry::sOps, nsnull, sizeof(Entry), size);
     226            1404 : }
     227                 : 
     228            1403 : IID2WrappedJSClassMap::~IID2WrappedJSClassMap()
     229                 : {
     230            1403 :     if (mTable)
     231            1403 :         JS_DHashTableDestroy(mTable);
     232            1403 : }
     233                 : 
     234                 : 
     235                 : /***************************************************************************/
     236                 : // implement IID2NativeInterfaceMap...
     237                 : 
     238                 : struct JSDHashTableOps IID2NativeInterfaceMap::Entry::sOps =
     239                 : {
     240                 :     JS_DHashAllocTable,
     241                 :     JS_DHashFreeTable,
     242                 :     HashIIDPtrKey,
     243                 :     MatchIIDPtrKey,
     244                 :     JS_DHashMoveEntryStub,
     245                 :     JS_DHashClearEntryStub,
     246                 :     JS_DHashFinalizeStub
     247                 : };
     248                 : 
     249                 : // static
     250                 : IID2NativeInterfaceMap*
     251            1404 : IID2NativeInterfaceMap::newMap(int size)
     252                 : {
     253            1404 :     IID2NativeInterfaceMap* map = new IID2NativeInterfaceMap(size);
     254            1404 :     if (map && map->mTable)
     255            1404 :         return map;
     256               0 :     delete map;
     257               0 :     return nsnull;
     258                 : }
     259                 : 
     260            1404 : IID2NativeInterfaceMap::IID2NativeInterfaceMap(int size)
     261                 : {
     262            1404 :     mTable = JS_NewDHashTable(&Entry::sOps, nsnull, sizeof(Entry), size);
     263            1404 : }
     264                 : 
     265            1403 : IID2NativeInterfaceMap::~IID2NativeInterfaceMap()
     266                 : {
     267            1403 :     if (mTable)
     268            1403 :         JS_DHashTableDestroy(mTable);
     269            1403 : }
     270                 : 
     271                 : size_t
     272               3 : IID2NativeInterfaceMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     273                 : {
     274               3 :     size_t n = 0;
     275               3 :     n += mallocSizeOf(this);
     276               3 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
     277               3 :     return n;
     278                 : }
     279                 : 
     280                 : /* static */ size_t
     281             303 : IID2NativeInterfaceMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
     282                 :                                                  JSMallocSizeOfFun mallocSizeOf, void *)
     283                 : {
     284             303 :     XPCNativeInterface *iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value;
     285             303 :     return iface->SizeOfIncludingThis(mallocSizeOf);
     286                 : }
     287                 : 
     288                 : /***************************************************************************/
     289                 : // implement ClassInfo2NativeSetMap...
     290                 : 
     291                 : // static
     292                 : ClassInfo2NativeSetMap*
     293            1404 : ClassInfo2NativeSetMap::newMap(int size)
     294                 : {
     295            1404 :     ClassInfo2NativeSetMap* map = new ClassInfo2NativeSetMap(size);
     296            1404 :     if (map && map->mTable)
     297            1404 :         return map;
     298               0 :     delete map;
     299               0 :     return nsnull;
     300                 : }
     301                 : 
     302            1404 : ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int size)
     303                 : {
     304                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     305            1404 :                               sizeof(Entry), size);
     306            1404 : }
     307                 : 
     308            1403 : ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap()
     309                 : {
     310            1403 :     if (mTable)
     311            1403 :         JS_DHashTableDestroy(mTable);
     312            1403 : }
     313                 : 
     314                 : size_t
     315               3 : ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     316                 : {
     317               3 :     size_t n = 0;
     318               3 :     n += mallocSizeOf(this);
     319                 :     // The second arg is NULL because this is a "shallow" measurement of the map.
     320               3 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, NULL, mallocSizeOf) : 0;
     321               3 :     return n;
     322                 : }
     323                 : 
     324                 : /***************************************************************************/
     325                 : // implement ClassInfo2WrappedNativeProtoMap...
     326                 : 
     327                 : // static
     328                 : ClassInfo2WrappedNativeProtoMap*
     329           30950 : ClassInfo2WrappedNativeProtoMap::newMap(int size)
     330                 : {
     331           30950 :     ClassInfo2WrappedNativeProtoMap* map = new ClassInfo2WrappedNativeProtoMap(size);
     332           30950 :     if (map && map->mTable)
     333           30950 :         return map;
     334               0 :     delete map;
     335               0 :     return nsnull;
     336                 : }
     337                 : 
     338           30950 : ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int size)
     339                 : {
     340                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     341           30950 :                               sizeof(Entry), size);
     342           30950 : }
     343                 : 
     344           30942 : ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap()
     345                 : {
     346           30942 :     if (mTable)
     347           30942 :         JS_DHashTableDestroy(mTable);
     348           30942 : }
     349                 : 
     350                 : size_t
     351             118 : ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     352                 : {
     353             118 :     size_t n = 0;
     354             118 :     n += mallocSizeOf(this);
     355             118 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
     356             118 :     return n;
     357                 : }
     358                 : 
     359                 : /* static */ size_t
     360             469 : ClassInfo2WrappedNativeProtoMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
     361                 :                                                           JSMallocSizeOfFun mallocSizeOf, void *)
     362                 : {
     363             469 :     return mallocSizeOf(((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value);
     364                 : }
     365                 : 
     366                 : /***************************************************************************/
     367                 : // implement NativeSetMap...
     368                 : 
     369                 : JSBool
     370         1090654 : NativeSetMap::Entry::Match(JSDHashTable *table,
     371                 :                            const JSDHashEntryHdr *entry,
     372                 :                            const void *key)
     373                 : {
     374         1090654 :     XPCNativeSetKey* Key = (XPCNativeSetKey*) key;
     375                 : 
     376                 :     // See the comment in the XPCNativeSetKey declaration in xpcprivate.h.
     377         1090654 :     if (!Key->IsAKey()) {
     378               0 :         XPCNativeSet* Set1 = (XPCNativeSet*) key;
     379               0 :         XPCNativeSet* Set2 = ((Entry*)entry)->key_value;
     380                 : 
     381               0 :         if (Set1 == Set2)
     382               0 :             return true;
     383                 : 
     384               0 :         PRUint16 count = Set1->GetInterfaceCount();
     385               0 :         if (count != Set2->GetInterfaceCount())
     386               0 :             return false;
     387                 : 
     388               0 :         XPCNativeInterface** Current1 = Set1->GetInterfaceArray();
     389               0 :         XPCNativeInterface** Current2 = Set2->GetInterfaceArray();
     390               0 :         for (PRUint16 i = 0; i < count; i++) {
     391               0 :             if (*(Current1++) != *(Current2++))
     392               0 :                 return false;
     393                 :         }
     394                 : 
     395               0 :         return true;
     396                 :     }
     397                 : 
     398         1090654 :     XPCNativeSet*       SetInTable = ((Entry*)entry)->key_value;
     399         1090654 :     XPCNativeSet*       Set        = Key->GetBaseSet();
     400         1090654 :     XPCNativeInterface* Addition   = Key->GetAddition();
     401                 : 
     402         1090654 :     if (!Set) {
     403                 :         // This is a special case to deal with the invariant that says:
     404                 :         // "All sets have exactly one nsISupports interface and it comes first."
     405                 :         // See XPCNativeSet::NewInstance for details.
     406                 :         //
     407                 :         // Though we might have a key that represents only one interface, we
     408                 :         // know that if that one interface were contructed into a set then
     409                 :         // it would end up really being a set with two interfaces (except for
     410                 :         // the case where the one interface happened to be nsISupports).
     411                 : 
     412          864487 :         return ((SetInTable->GetInterfaceCount() == 1 &&
     413           69545 :                  SetInTable->GetInterfaceAt(0) == Addition) ||
     414          794942 :                 (SetInTable->GetInterfaceCount() == 2 &&
     415         1728974 :                  SetInTable->GetInterfaceAt(1) == Addition));
     416                 :     }
     417                 : 
     418          226167 :     if (!Addition && Set == SetInTable)
     419               0 :         return true;
     420                 : 
     421          226167 :     PRUint16 count = Set->GetInterfaceCount() + (Addition ? 1 : 0);
     422          226167 :     if (count != SetInTable->GetInterfaceCount())
     423               1 :         return false;
     424                 : 
     425          226166 :     PRUint16 Position = Key->GetPosition();
     426          226166 :     XPCNativeInterface** CurrentInTable = SetInTable->GetInterfaceArray();
     427          226166 :     XPCNativeInterface** Current = Set->GetInterfaceArray();
     428          824202 :     for (PRUint16 i = 0; i < count; i++) {
     429          610374 :         if (Addition && i == Position) {
     430          273630 :             if (Addition != *(CurrentInTable++))
     431               0 :                 return false;
     432                 :         } else {
     433          473559 :             if (*(Current++) != *(CurrentInTable++))
     434           12338 :                 return false;
     435                 :         }
     436                 :     }
     437                 : 
     438          213828 :     return true;
     439                 : }
     440                 : 
     441                 : struct JSDHashTableOps NativeSetMap::Entry::sOps =
     442                 : {
     443                 :     JS_DHashAllocTable,
     444                 :     JS_DHashFreeTable,
     445                 :     HashNativeKey,
     446                 :     Match,
     447                 :     JS_DHashMoveEntryStub,
     448                 :     JS_DHashClearEntryStub,
     449                 :     JS_DHashFinalizeStub
     450                 : };
     451                 : 
     452                 : // static
     453                 : NativeSetMap*
     454            1404 : NativeSetMap::newMap(int size)
     455                 : {
     456            1404 :     NativeSetMap* map = new NativeSetMap(size);
     457            1404 :     if (map && map->mTable)
     458            1404 :         return map;
     459               0 :     delete map;
     460               0 :     return nsnull;
     461                 : }
     462                 : 
     463            1404 : NativeSetMap::NativeSetMap(int size)
     464                 : {
     465            1404 :     mTable = JS_NewDHashTable(&Entry::sOps, nsnull, sizeof(Entry), size);
     466            1404 : }
     467                 : 
     468            1403 : NativeSetMap::~NativeSetMap()
     469                 : {
     470            1403 :     if (mTable)
     471            1403 :         JS_DHashTableDestroy(mTable);
     472            1403 : }
     473                 : 
     474                 : size_t
     475               3 : NativeSetMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
     476                 : {
     477               3 :     size_t n = 0;
     478               3 :     n += mallocSizeOf(this);
     479               3 :     n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
     480               3 :     return n;
     481                 : }
     482                 : 
     483                 : /* static */ size_t
     484             284 : NativeSetMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *)
     485                 : {
     486             284 :     XPCNativeSet *set = ((NativeSetMap::Entry*)hdr)->key_value;
     487             284 :     return set->SizeOfIncludingThis(mallocSizeOf);
     488                 : }
     489                 : 
     490                 : /***************************************************************************/
     491                 : // implement IID2ThisTranslatorMap...
     492                 : 
     493                 : JSBool
     494            3965 : IID2ThisTranslatorMap::Entry::Match(JSDHashTable *table,
     495                 :                                     const JSDHashEntryHdr *entry,
     496                 :                                     const void *key)
     497                 : {
     498            3965 :     return ((const nsID*)key)->Equals(((Entry*)entry)->key);
     499                 : }
     500                 : 
     501                 : void
     502             305 : IID2ThisTranslatorMap::Entry::Clear(JSDHashTable *table, JSDHashEntryHdr *entry)
     503                 : {
     504             305 :     NS_IF_RELEASE(((Entry*)entry)->value);
     505             305 :     memset(entry, 0, table->entrySize);
     506             305 : }
     507                 : 
     508                 : struct JSDHashTableOps IID2ThisTranslatorMap::Entry::sOps =
     509                 : {
     510                 :     JS_DHashAllocTable,
     511                 :     JS_DHashFreeTable,
     512                 :     HashIIDPtrKey,
     513                 :     Match,
     514                 :     JS_DHashMoveEntryStub,
     515                 :     Clear,
     516                 :     JS_DHashFinalizeStub
     517                 : };
     518                 : 
     519                 : // static
     520                 : IID2ThisTranslatorMap*
     521            1404 : IID2ThisTranslatorMap::newMap(int size)
     522                 : {
     523            1404 :     IID2ThisTranslatorMap* map = new IID2ThisTranslatorMap(size);
     524            1404 :     if (map && map->mTable)
     525            1404 :         return map;
     526               0 :     delete map;
     527               0 :     return nsnull;
     528                 : }
     529                 : 
     530            1404 : IID2ThisTranslatorMap::IID2ThisTranslatorMap(int size)
     531                 : {
     532            1404 :     mTable = JS_NewDHashTable(&Entry::sOps, nsnull, sizeof(Entry), size);
     533            1404 : }
     534                 : 
     535            1403 : IID2ThisTranslatorMap::~IID2ThisTranslatorMap()
     536                 : {
     537            1403 :     if (mTable)
     538            1403 :         JS_DHashTableDestroy(mTable);
     539            1403 : }
     540                 : 
     541                 : /***************************************************************************/
     542                 : 
     543                 : JSDHashNumber
     544          249788 : XPCNativeScriptableSharedMap::Entry::Hash(JSDHashTable *table, const void *key)
     545                 : {
     546                 :     JSDHashNumber h;
     547                 :     const unsigned char *s;
     548                 : 
     549                 :     XPCNativeScriptableShared* obj =
     550          249788 :         (XPCNativeScriptableShared*) key;
     551                 : 
     552                 :     // hash together the flags and the classname string, ignore the interfaces
     553                 :     // bitmap since it's very rare that it's different when flags and classname
     554                 :     // are the same.
     555                 : 
     556          249788 :     h = (JSDHashNumber) obj->GetFlags();
     557         3208185 :     for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++)
     558         2958397 :         h = JS_ROTATE_LEFT32(h, 4) ^ *s;
     559          249788 :     return h;
     560                 : }
     561                 : 
     562                 : JSBool
     563          228557 : XPCNativeScriptableSharedMap::Entry::Match(JSDHashTable *table,
     564                 :                                            const JSDHashEntryHdr *entry,
     565                 :                                            const void *key)
     566                 : {
     567                 :     XPCNativeScriptableShared* obj1 =
     568          228557 :         ((XPCNativeScriptableSharedMap::Entry*) entry)->key;
     569                 : 
     570                 :     XPCNativeScriptableShared* obj2 =
     571          228557 :         (XPCNativeScriptableShared*) key;
     572                 : 
     573                 :     // match the flags, the classname string and the interfaces bitmap
     574                 : 
     575          457114 :     if (obj1->GetFlags() != obj2->GetFlags() ||
     576          228557 :         obj1->GetInterfacesBitmap() != obj2->GetInterfacesBitmap())
     577               0 :         return false;
     578                 : 
     579          228557 :     const char* name1 = obj1->GetJSClass()->name;
     580          228557 :     const char* name2 = obj2->GetJSClass()->name;
     581                 : 
     582          228557 :     if (!name1 || !name2)
     583               0 :         return name1 == name2;
     584                 : 
     585          228557 :     return 0 == strcmp(name1, name2);
     586                 : }
     587                 : 
     588                 : struct JSDHashTableOps XPCNativeScriptableSharedMap::Entry::sOps =
     589                 : {
     590                 :     JS_DHashAllocTable,
     591                 :     JS_DHashFreeTable,
     592                 :     Hash,
     593                 :     Match,
     594                 :     JS_DHashMoveEntryStub,
     595                 :     JS_DHashClearEntryStub,
     596                 :     JS_DHashFinalizeStub
     597                 : };
     598                 : 
     599                 : // static
     600                 : XPCNativeScriptableSharedMap*
     601            1404 : XPCNativeScriptableSharedMap::newMap(int size)
     602                 : {
     603                 :     XPCNativeScriptableSharedMap* map =
     604            1404 :         new XPCNativeScriptableSharedMap(size);
     605            1404 :     if (map && map->mTable)
     606            1404 :         return map;
     607               0 :     delete map;
     608               0 :     return nsnull;
     609                 : }
     610                 : 
     611            1404 : XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int size)
     612                 : {
     613            1404 :     mTable = JS_NewDHashTable(&Entry::sOps, nsnull, sizeof(Entry), size);
     614            1404 : }
     615                 : 
     616            1403 : XPCNativeScriptableSharedMap::~XPCNativeScriptableSharedMap()
     617                 : {
     618            1403 :     if (mTable)
     619            1403 :         JS_DHashTableDestroy(mTable);
     620            1403 : }
     621                 : 
     622                 : JSBool
     623          249788 : XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags,
     624                 :                                            char* name,
     625                 :                                            PRUint32 interfacesBitmap,
     626                 :                                            XPCNativeScriptableInfo* si)
     627                 : {
     628          249788 :     NS_PRECONDITION(name,"bad param");
     629          249788 :     NS_PRECONDITION(si,"bad param");
     630                 : 
     631          499576 :     XPCNativeScriptableShared key(flags, name, interfacesBitmap);
     632                 :     Entry* entry = (Entry*)
     633          249788 :         JS_DHashTableOperate(mTable, &key, JS_DHASH_ADD);
     634          249788 :     if (!entry)
     635               0 :         return false;
     636                 : 
     637          249788 :     XPCNativeScriptableShared* shared = entry->key;
     638                 : 
     639          249788 :     if (!shared) {
     640                 :         entry->key = shared =
     641                 :             new XPCNativeScriptableShared(flags, key.TransferNameOwnership(),
     642           42462 :                                           interfacesBitmap);
     643           21231 :         if (!shared)
     644               0 :             return false;
     645           21231 :         shared->PopulateJSClass();
     646                 :     }
     647          249788 :     si->SetScriptableShared(shared);
     648          249788 :     return true;
     649                 : }
     650                 : 
     651                 : /***************************************************************************/
     652                 : // implement XPCWrappedNativeProtoMap...
     653                 : 
     654                 : // static
     655                 : XPCWrappedNativeProtoMap*
     656            2808 : XPCWrappedNativeProtoMap::newMap(int size)
     657                 : {
     658            2808 :     XPCWrappedNativeProtoMap* map = new XPCWrappedNativeProtoMap(size);
     659            2808 :     if (map && map->mTable)
     660            2808 :         return map;
     661               0 :     delete map;
     662               0 :     return nsnull;
     663                 : }
     664                 : 
     665            2808 : XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int size)
     666                 : {
     667                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     668            2808 :                               sizeof(JSDHashEntryStub), size);
     669            2808 : }
     670                 : 
     671            2806 : XPCWrappedNativeProtoMap::~XPCWrappedNativeProtoMap()
     672                 : {
     673            2806 :     if (mTable)
     674            2806 :         JS_DHashTableDestroy(mTable);
     675            2806 : }
     676                 : 
     677                 : /***************************************************************************/
     678                 : // implement XPCNativeWrapperMap...
     679                 : 
     680                 : // static
     681                 : XPCNativeWrapperMap*
     682            1404 : XPCNativeWrapperMap::newMap(int size)
     683                 : {
     684            1404 :     XPCNativeWrapperMap* map = new XPCNativeWrapperMap(size);
     685            1404 :     if (map && map->mTable)
     686            1404 :         return map;
     687               0 :     delete map;
     688               0 :     return nsnull;
     689                 : }
     690                 : 
     691            1404 : XPCNativeWrapperMap::XPCNativeWrapperMap(int size)
     692                 : {
     693                 :     mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
     694            1404 :                               sizeof(JSDHashEntryStub), size);
     695            1404 : }
     696                 : 
     697            1403 : XPCNativeWrapperMap::~XPCNativeWrapperMap()
     698                 : {
     699            1403 :     if (mTable)
     700            1403 :         JS_DHashTableDestroy(mTable);
     701            1403 : }
     702                 : 
     703                 : /***************************************************************************/
     704                 : // implement WrappedNative2WrapperMap...
     705                 : 
     706                 : struct JSDHashTableOps
     707                 : WrappedNative2WrapperMap::sOps = {
     708                 :     JS_DHashAllocTable,
     709                 :     JS_DHashFreeTable,
     710                 :     JS_DHashVoidPtrKeyStub,
     711                 :     JS_DHashMatchEntryStub,
     712                 :     MoveLink,
     713                 :     ClearLink,
     714                 :     JS_DHashFinalizeStub,
     715                 :     nsnull
     716                 : };
     717                 : 
     718                 : // static
     719                 : void
     720               0 : WrappedNative2WrapperMap::ClearLink(JSDHashTable* table,
     721                 :                                     JSDHashEntryHdr* entry)
     722                 : {
     723               0 :     Entry* e = static_cast<Entry*>(entry);
     724               0 :     e->key = nsnull;
     725               0 :     PR_REMOVE_LINK(&e->value);
     726               0 :     memset(e, 0, sizeof(*e));
     727               0 : }
     728                 : 
     729                 : // static
     730                 : void
     731               0 : WrappedNative2WrapperMap::MoveLink(JSDHashTable* table,
     732                 :                                    const JSDHashEntryHdr* from,
     733                 :                                    JSDHashEntryHdr* to)
     734                 : {
     735               0 :     const Entry* oldEntry = static_cast<const Entry*>(from);
     736               0 :     Entry* newEntry = static_cast<Entry*>(to);
     737                 : 
     738               0 :     newEntry->key = oldEntry->key;
     739                 : 
     740                 :     // Now update the list.
     741               0 :     if (PR_CLIST_IS_EMPTY(&oldEntry->value)) {
     742               0 :         PR_INIT_CLIST(&newEntry->value);
     743               0 :         newEntry->value.obj = oldEntry->value.obj;
     744                 :     } else {
     745               0 :         newEntry->value = oldEntry->value;
     746               0 :         newEntry->value.next->prev = &newEntry->value;
     747               0 :         newEntry->value.prev->next = &newEntry->value;
     748                 :     }
     749               0 : }
     750                 : 
     751                 : // static
     752                 : WrappedNative2WrapperMap*
     753               0 : WrappedNative2WrapperMap::newMap(int size)
     754                 : {
     755               0 :     WrappedNative2WrapperMap* map = new WrappedNative2WrapperMap(size);
     756               0 :     if (map && map->mTable)
     757               0 :         return map;
     758               0 :     delete map;
     759               0 :     return nsnull;
     760                 : }
     761                 : 
     762               0 : WrappedNative2WrapperMap::WrappedNative2WrapperMap(int size)
     763                 : {
     764               0 :     mTable = JS_NewDHashTable(&sOps, nsnull, sizeof(Entry), size);
     765               0 : }
     766                 : 
     767               0 : WrappedNative2WrapperMap::~WrappedNative2WrapperMap()
     768                 : {
     769               0 :     if (mTable)
     770               0 :         JS_DHashTableDestroy(mTable);
     771               0 : }
     772                 : 
     773                 : JSObject*
     774               0 : WrappedNative2WrapperMap::Add(WrappedNative2WrapperMap* head,
     775                 :                               JSObject* wrappedObject,
     776                 :                               JSObject* wrapper)
     777                 : {
     778               0 :     NS_PRECONDITION(wrappedObject,"bad param");
     779                 :     Entry* entry = (Entry*)
     780               0 :         JS_DHashTableOperate(mTable, wrappedObject, JS_DHASH_ADD);
     781               0 :     if (!entry)
     782               0 :         return nsnull;
     783               0 :     NS_ASSERTION(!entry->key || this == head, "dangling pointer?");
     784               0 :     entry->key = wrappedObject;
     785               0 :     Link* l = &entry->value;
     786                 : 
     787               0 :     NS_ASSERTION(!l->obj, "Uh, how'd this happen?");
     788                 : 
     789               0 :     if (!l->next) {
     790                 :         // Initialize the circular list. This case only happens when
     791                 :         // this == head.
     792               0 :         PR_INIT_CLIST(l);
     793                 :     }
     794                 : 
     795               0 :     l->obj = wrapper;
     796                 : 
     797               0 :     if (this != head) {
     798               0 :         Link* headLink = head->FindLink(wrappedObject);
     799               0 :         if (!headLink) {
     800                 :             Entry* dummy = (Entry*)
     801               0 :                 JS_DHashTableOperate(head->mTable, wrappedObject, JS_DHASH_ADD);
     802               0 :             dummy->key = wrappedObject;
     803               0 :             headLink = &dummy->value;
     804               0 :             PR_INIT_CLIST(headLink);
     805               0 :             headLink->obj = nsnull;
     806                 :         }
     807                 : 
     808               0 :         PR_INSERT_BEFORE(l, headLink);
     809                 :     }
     810                 : 
     811               0 :     return wrapper;
     812                 : }
     813                 : 
     814                 : bool
     815               0 : WrappedNative2WrapperMap::AddLink(JSObject* wrappedObject, Link* oldLink)
     816                 : {
     817                 :     Entry* entry = (Entry*)
     818               0 :         JS_DHashTableOperate(mTable, wrappedObject, JS_DHASH_ADD);
     819               0 :     if (!entry)
     820               0 :         return false;
     821               0 :     NS_ASSERTION(!entry->key, "Eh? What's happening?");
     822               0 :     entry->key = wrappedObject;
     823               0 :     Link* newLink = &entry->value;
     824                 : 
     825               0 :     PR_INSERT_LINK(newLink, oldLink);
     826               0 :     PR_REMOVE_AND_INIT_LINK(oldLink);
     827               0 :     newLink->obj = oldLink->obj;
     828                 : 
     829               0 :     return true;
     830                 : }
     831                 : 
     832                 : /***************************************************************************/
     833                 : // implement JSObject2JSObjectMap...
     834                 : 
     835                 : struct JSDHashTableOps
     836                 : JSObject2JSObjectMap::sOps = {
     837                 :     JS_DHashAllocTable,
     838                 :     JS_DHashFreeTable,
     839                 :     JS_DHashVoidPtrKeyStub,
     840                 :     JS_DHashMatchEntryStub,
     841                 :     JS_DHashMoveEntryStub,
     842                 :     JS_DHashClearEntryStub,
     843                 :     JS_DHashFinalizeStub,
     844                 :     nsnull
     845                 : };
     846                 : 
     847                 : /***************************************************************************/

Generated by: LCOV version 1.7