tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XPCMaps.cpp (6634B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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/MemoryReporting.h"
     10 #include "xpcprivate.h"
     11 #include "XPCMaps.h"
     12 
     13 #include "js/HashTable.h"
     14 
     15 using namespace mozilla;
     16 
     17 /***************************************************************************/
     18 // implement JSObject2WrappedJSMap...
     19 
     20 void JSObject2WrappedJSMap::UpdateWeakPointersAfterGC(JSTracer* trc) {
     21  // Check all wrappers and update their JSObject pointer if it has been
     22  // moved. Release any wrappers whose weakly held JSObject has died.
     23 
     24  nsTArray<RefPtr<nsXPCWrappedJS>> dying;
     25  for (auto iter = mTable.modIter(); !iter.done(); iter.next()) {
     26    nsXPCWrappedJS* wrapper = iter.get().value();
     27    MOZ_ASSERT(wrapper, "found a null JS wrapper!");
     28 
     29    // There's no need to walk the entire chain, because only the root can be
     30    // subject to finalization due to the double release behavior in Release.
     31    // See the comment at the top of XPCWrappedJS.cpp about nsXPCWrappedJS
     32    // lifetime.
     33    if (wrapper && wrapper->IsSubjectToFinalization()) {
     34      wrapper->UpdateObjectPointerAfterGC(trc);
     35      if (!wrapper->GetJSObjectPreserveColor()) {
     36        dying.AppendElement(dont_AddRef(wrapper));
     37      }
     38    }
     39 
     40    // Remove or update the JSObject key in the table if necessary.
     41    if (!JS_UpdateWeakPointerAfterGC(trc, &iter.get().mutableKey())) {
     42      iter.remove();
     43    }
     44  }
     45 }
     46 
     47 void JSObject2WrappedJSMap::ShutdownMarker() {
     48  for (auto iter = mTable.iter(); !iter.done(); iter.next()) {
     49    nsXPCWrappedJS* wrapper = iter.get().value();
     50    MOZ_ASSERT(wrapper, "found a null JS wrapper!");
     51    MOZ_ASSERT(wrapper->IsValid(), "found an invalid JS wrapper!");
     52    wrapper->SystemIsBeingShutDown();
     53  }
     54 }
     55 
     56 size_t JSObject2WrappedJSMap::SizeOfIncludingThis(
     57    mozilla::MallocSizeOf mallocSizeOf) const {
     58  size_t n = mallocSizeOf(this);
     59  n += mTable.shallowSizeOfExcludingThis(mallocSizeOf);
     60  return n;
     61 }
     62 
     63 size_t JSObject2WrappedJSMap::SizeOfWrappedJS(
     64    mozilla::MallocSizeOf mallocSizeOf) const {
     65  size_t n = 0;
     66  for (auto iter = mTable.iter(); !iter.done(); iter.next()) {
     67    n += iter.get().value()->SizeOfIncludingThis(mallocSizeOf);
     68  }
     69  return n;
     70 }
     71 
     72 /***************************************************************************/
     73 // implement Native2WrappedNativeMap...
     74 
     75 Native2WrappedNativeMap::Native2WrappedNativeMap()
     76    : mMap(XPC_NATIVE_MAP_LENGTH) {}
     77 
     78 size_t Native2WrappedNativeMap::SizeOfIncludingThis(
     79    mozilla::MallocSizeOf mallocSizeOf) const {
     80  size_t n = mallocSizeOf(this);
     81  n += mMap.shallowSizeOfExcludingThis(mallocSizeOf);
     82  for (auto iter = mMap.iter(); !iter.done(); iter.next()) {
     83    n += mallocSizeOf(iter.get().value());
     84  }
     85  return n;
     86 }
     87 
     88 /***************************************************************************/
     89 // implement IID2NativeInterfaceMap...
     90 
     91 IID2NativeInterfaceMap::IID2NativeInterfaceMap()
     92    : mMap(XPC_NATIVE_INTERFACE_MAP_LENGTH) {}
     93 
     94 size_t IID2NativeInterfaceMap::SizeOfIncludingThis(
     95    mozilla::MallocSizeOf mallocSizeOf) const {
     96  size_t n = mallocSizeOf(this);
     97  n += mMap.shallowSizeOfExcludingThis(mallocSizeOf);
     98  for (auto iter = mMap.iter(); !iter.done(); iter.next()) {
     99    n += iter.get().value()->SizeOfIncludingThis(mallocSizeOf);
    100  }
    101  return n;
    102 }
    103 
    104 /***************************************************************************/
    105 // implement ClassInfo2NativeSetMap...
    106 
    107 ClassInfo2NativeSetMap::ClassInfo2NativeSetMap()
    108    : mMap(XPC_NATIVE_SET_MAP_LENGTH) {}
    109 
    110 size_t ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(
    111    mozilla::MallocSizeOf mallocSizeOf) {
    112  size_t n = mallocSizeOf(this);
    113  n += mMap.shallowSizeOfExcludingThis(mallocSizeOf);
    114  return n;
    115 }
    116 
    117 /***************************************************************************/
    118 // implement ClassInfo2WrappedNativeProtoMap...
    119 
    120 ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap()
    121    : mMap(XPC_NATIVE_PROTO_MAP_LENGTH) {}
    122 
    123 size_t ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(
    124    mozilla::MallocSizeOf mallocSizeOf) const {
    125  size_t n = mallocSizeOf(this);
    126  n += mMap.shallowSizeOfExcludingThis(mallocSizeOf);
    127  for (auto iter = mMap.iter(); !iter.done(); iter.next()) {
    128    n += mallocSizeOf(iter.get().value());
    129  }
    130  return n;
    131 }
    132 
    133 /***************************************************************************/
    134 // implement NativeSetMap...
    135 
    136 bool NativeSetHasher::match(Key key, Lookup lookup) {
    137  // The |key| argument is for the existing table entry and |lookup| is the
    138  // value passed by the caller that is being compared with it.
    139  XPCNativeSet* SetInTable = key;
    140  XPCNativeSet* Set = lookup->GetBaseSet();
    141  XPCNativeInterface* Addition = lookup->GetAddition();
    142 
    143  if (!Set) {
    144    // This is a special case to deal with the invariant that says:
    145    // "All sets have exactly one nsISupports interface and it comes first."
    146    // See XPCNativeSet::NewInstance for details.
    147    //
    148    // Though we might have a key that represents only one interface, we
    149    // know that if that one interface were contructed into a set then
    150    // it would end up really being a set with two interfaces (except for
    151    // the case where the one interface happened to be nsISupports).
    152 
    153    return (SetInTable->GetInterfaceCount() == 1 &&
    154            SetInTable->GetInterfaceAt(0) == Addition) ||
    155           (SetInTable->GetInterfaceCount() == 2 &&
    156            SetInTable->GetInterfaceAt(1) == Addition);
    157  }
    158 
    159  if (!Addition && Set == SetInTable) {
    160    return true;
    161  }
    162 
    163  uint16_t count = Set->GetInterfaceCount();
    164  if (count + (Addition ? 1 : 0) != SetInTable->GetInterfaceCount()) {
    165    return false;
    166  }
    167 
    168  XPCNativeInterface** CurrentInTable = SetInTable->GetInterfaceArray();
    169  XPCNativeInterface** Current = Set->GetInterfaceArray();
    170  for (uint16_t i = 0; i < count; i++) {
    171    if (*(Current++) != *(CurrentInTable++)) {
    172      return false;
    173    }
    174  }
    175  return !Addition || Addition == *(CurrentInTable++);
    176 }
    177 
    178 NativeSetMap::NativeSetMap() : mSet(XPC_NATIVE_SET_MAP_LENGTH) {}
    179 
    180 size_t NativeSetMap::SizeOfIncludingThis(
    181    mozilla::MallocSizeOf mallocSizeOf) const {
    182  size_t n = mallocSizeOf(this);
    183  n += mSet.shallowSizeOfExcludingThis(mallocSizeOf);
    184  for (auto iter = mSet.iter(); !iter.done(); iter.next()) {
    185    n += iter.get()->SizeOfIncludingThis(mallocSizeOf);
    186  }
    187  return n;
    188 }
    189 
    190 /***************************************************************************/