DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsWrapperCacheInline_h___
#define nsWrapperCacheInline_h___

#include "nsWrapperCache.h"
#include "js/TracingAPI.h"

inline JSObject* nsWrapperCache::GetWrapperPreserveColor() const {
  JSObject* obj = mWrapper;
  if (obj && js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
    // The object has been found to be dead and is in the process of being
    // finalized, so don't let the caller see it. As an optimisation, remove it
    // from the cache so we don't have to do this check in future.
    const_cast<nsWrapperCache*>(this)->ClearWrapper();
    return nullptr;
  }
  MOZ_ASSERT(obj == mWrapper);
  return obj;
}

inline JSObject* nsWrapperCache::GetWrapper() const {
  JSObject* obj = GetWrapperPreserveColor();
  if (obj) {
    JS::ExposeObjectToActiveJS(obj);
  }
  return obj;
}

inline bool nsWrapperCache::HasKnownLiveWrapper() const {
  // If we have a wrapper and it's not gray in the GC-marking sense, that means
  // that we can't be cycle-collected.  That's because the wrapper is being kept
  // alive by the JS engine (and not just due to being traced from some
  // cycle-collectable thing), and the wrapper holds us alive, so we know we're
  // not collectable.
  JSObject* o = GetWrapperPreserveColor();
  return o && !JS::ObjectIsMarkedGray(o);
}

static void SearchGray(JS::GCCellPtr aGCThing, const char* aName,
                       void* aClosure) {
  bool* hasGrayObjects = static_cast<bool*>(aClosure);
  if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing)) {
    *hasGrayObjects = true;
  }
}

inline bool nsWrapperCache::HasNothingToTrace(nsISupports* aThis) {
  nsXPCOMCycleCollectionParticipant* participant = nullptr;
  CallQueryInterface(aThis, &participant);
  bool hasGrayObjects = false;
  participant->Trace(aThis, TraceCallbackFunc(SearchGray), &hasGrayObjects);
  return !hasGrayObjects;
}

inline bool nsWrapperCache::HasKnownLiveWrapperAndDoesNotNeedTracing(
    nsISupports* aThis) {
  return HasKnownLiveWrapper() && HasNothingToTrace(aThis);
}

inline void nsWrapperCache::MarkWrapperLive() {
  // Just call GetWrapper and ignore the return value.  It will do the
  // gray-unmarking for us.
  GetWrapper();
}

#endif /* nsWrapperCache_h___ */