tor-browser

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

nsWrapperCacheInlines.h (3362B)


      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 #ifndef nsWrapperCacheInline_h___
      8 #define nsWrapperCacheInline_h___
      9 
     10 #include "js/RootingAPI.h"
     11 #include "js/TracingAPI.h"
     12 #include "nsWrapperCache.h"
     13 
     14 inline JSObject* nsWrapperCache::GetWrapperPreserveColor() const {
     15  JSObject* obj = GetWrapperMaybeDead();
     16  if (obj && js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
     17    // The object has been found to be dead and is in the process of being
     18    // finalized, so don't let the caller see it.
     19    // Don't clear the cache though: this happens when a new wrapper is created
     20    // for this native or when the wrapper is finalized.
     21    return nullptr;
     22  }
     23  MOZ_ASSERT(obj == mWrapper);
     24  return obj;
     25 }
     26 
     27 inline JSObject* nsWrapperCache::GetWrapper() const {
     28  JSObject* obj = GetWrapperPreserveColor();
     29  if (obj) {
     30    JS::ExposeObjectToActiveJS(obj);
     31  }
     32  return obj;
     33 }
     34 
     35 inline bool nsWrapperCache::HasKnownLiveWrapper() const {
     36  // If we have a wrapper and it's not gray in the GC-marking sense, that means
     37  // that we can't be cycle-collected.  That's because the wrapper is being kept
     38  // alive by the JS engine (and not just due to being traced from some
     39  // cycle-collectable thing), and the wrapper holds us alive, so we know we're
     40  // not collectable.
     41  JSObject* o = GetWrapperPreserveColor();
     42  return o && !JS::ObjectIsMarkedGray(o);
     43 }
     44 
     45 static void SearchGray(JS::GCCellPtr aGCThing, const char* aName,
     46                       void* aClosure) {
     47  bool* hasGrayObjects = static_cast<bool*>(aClosure);
     48  if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing)) {
     49    *hasGrayObjects = true;
     50  }
     51 }
     52 
     53 inline bool nsWrapperCache::HasNothingToTrace(nsISupports* aThis) {
     54  nsXPCOMCycleCollectionParticipant* participant = nullptr;
     55  CallQueryInterface(aThis, &participant);
     56  bool hasGrayObjects = false;
     57  participant->Trace(aThis, TraceCallbackFunc(SearchGray), &hasGrayObjects);
     58  return !hasGrayObjects;
     59 }
     60 
     61 inline bool nsWrapperCache::HasKnownLiveWrapperAndDoesNotNeedTracing(
     62    nsISupports* aThis) {
     63  return HasKnownLiveWrapper() && HasNothingToTrace(aThis);
     64 }
     65 
     66 inline void nsWrapperCache::MarkWrapperLive() {
     67  // Just call GetWrapper and ignore the return value.  It will do the
     68  // gray-unmarking for us.
     69  GetWrapper();
     70 }
     71 
     72 template <typename T>
     73 inline void nsWrapperCache::UpdateWrapperForNewGlobal(T* aScriptObjectHolder,
     74                                                      JSObject* aNewWrapper) {
     75  // If the new wrapper is in a different zone we must ensure the
     76  // DropJSObjects/HoldJSObjects are called to move the holder to the new zone.
     77 
     78  bool preserving = PreservingWrapper();
     79  bool zoneChanged =
     80      preserving && (JS::GetObjectZone(GetWrapperPreserveColor()) !=
     81                     JS::GetObjectZone(aNewWrapper));
     82 
     83  if (zoneChanged) {
     84    ReleaseWrapper(aScriptObjectHolder);
     85  } else if (preserving) {
     86    SetPreservingWrapper(false);
     87  }
     88 
     89  SetWrapper(aNewWrapper);
     90 
     91  if (zoneChanged) {
     92    PreserveWrapper(aScriptObjectHolder);
     93  } else if (preserving) {
     94    SetPreservingWrapper(true);
     95  }
     96 }
     97 
     98 #endif /* nsWrapperCache_h___ */