Line data Source code
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 "nsWrapperCache.h"
11 : #include "js/GCAPI.h"
12 : #include "js/TracingAPI.h"
13 :
14 : inline JSObject*
15 35645 : nsWrapperCache::GetWrapperPreserveColor() const
16 : {
17 35645 : JSObject* obj = mWrapper;
18 35645 : if (obj && js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
19 : // The object has been found to be dead and is in the process of being
20 : // finalized, so don't let the caller see it. As an optimisation, remove it
21 : // from the cache so we don't have to do this check in future.
22 0 : const_cast<nsWrapperCache*>(this)->ClearWrapper();
23 0 : return nullptr;
24 : }
25 35646 : MOZ_ASSERT(obj == mWrapper);
26 35646 : return obj;
27 : }
28 :
29 : inline JSObject*
30 17739 : nsWrapperCache::GetWrapper() const
31 : {
32 17739 : JSObject* obj = GetWrapperPreserveColor();
33 17739 : if (obj) {
34 10085 : JS::ExposeObjectToActiveJS(obj);
35 : }
36 17739 : return obj;
37 : }
38 :
39 : inline bool
40 0 : nsWrapperCache::HasKnownLiveWrapper() const
41 : {
42 : // If we have a wrapper and it's not gray in the GC-marking sense, that means
43 : // that we can't be cycle-collected. That's because the wrapper is being kept
44 : // alive by the JS engine (and not just due to being traced from some
45 : // cycle-collectable thing), and the wrapper holds us alive, so we know we're
46 : // not collectable.
47 0 : JSObject* o = GetWrapperPreserveColor();
48 0 : return o && !JS::ObjectIsMarkedGray(o);
49 : }
50 :
51 : static void
52 0 : SearchGray(JS::GCCellPtr aGCThing, const char* aName, void* aClosure)
53 : {
54 0 : bool* hasGrayObjects = static_cast<bool*>(aClosure);
55 0 : if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing)) {
56 0 : *hasGrayObjects = true;
57 : }
58 0 : }
59 :
60 : inline bool
61 0 : nsWrapperCache::HasNothingToTrace(nsISupports* aThis)
62 : {
63 0 : nsXPCOMCycleCollectionParticipant* participant = nullptr;
64 0 : CallQueryInterface(aThis, &participant);
65 0 : bool hasGrayObjects = false;
66 0 : participant->Trace(aThis, TraceCallbackFunc(SearchGray), &hasGrayObjects);
67 0 : return !hasGrayObjects;
68 : }
69 :
70 : inline bool
71 0 : nsWrapperCache::HasKnownLiveWrapperAndDoesNotNeedTracing(nsISupports* aThis)
72 : {
73 0 : return HasKnownLiveWrapper() && HasNothingToTrace(aThis);
74 : }
75 :
76 : inline void
77 0 : nsWrapperCache::MarkWrapperLive()
78 : {
79 : // Just call GetWrapper and ignore the return value. It will do the
80 : // gray-unmarking for us.
81 0 : GetWrapper();
82 0 : }
83 :
84 : #endif /* nsWrapperCache_h___ */
|