dom/xbl/nsXBLMaybeCompiled.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsXBLMaybeCompiled_h__
michael@0 7 #define nsXBLMaybeCompiled_h__
michael@0 8
michael@0 9 #include "js/GCAPI.h"
michael@0 10
michael@0 11 /*
michael@0 12 * A union containing either a pointer representing uncompiled source or a
michael@0 13 * JSObject* representing the compiled result. The class is templated on the
michael@0 14 * source object type.
michael@0 15 *
michael@0 16 * The purpose of abstracting this as a separate class is to allow it to be
michael@0 17 * wrapped in a JS::Heap<T> to correctly handle post-barriering of the JSObject
michael@0 18 * pointer, when present.
michael@0 19 */
michael@0 20 template <class UncompiledT>
michael@0 21 class nsXBLMaybeCompiled
michael@0 22 {
michael@0 23 public:
michael@0 24 nsXBLMaybeCompiled() : mUncompiled(BIT_UNCOMPILED) {}
michael@0 25
michael@0 26 nsXBLMaybeCompiled(UncompiledT* uncompiled)
michael@0 27 : mUncompiled(reinterpret_cast<uintptr_t>(uncompiled) | BIT_UNCOMPILED) {}
michael@0 28
michael@0 29 nsXBLMaybeCompiled(JSObject* compiled) : mCompiled(compiled) {}
michael@0 30
michael@0 31 bool IsCompiled() const
michael@0 32 {
michael@0 33 return !(mUncompiled & BIT_UNCOMPILED);
michael@0 34 }
michael@0 35
michael@0 36 UncompiledT* GetUncompiled() const
michael@0 37 {
michael@0 38 MOZ_ASSERT(!IsCompiled(), "Attempt to get compiled function as uncompiled");
michael@0 39 uintptr_t unmasked = mUncompiled & ~BIT_UNCOMPILED;
michael@0 40 return reinterpret_cast<UncompiledT*>(unmasked);
michael@0 41 }
michael@0 42
michael@0 43 JSObject* GetJSFunction() const
michael@0 44 {
michael@0 45 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
michael@0 46 if (mCompiled) {
michael@0 47 JS::ExposeObjectToActiveJS(mCompiled);
michael@0 48 }
michael@0 49 return mCompiled;
michael@0 50 }
michael@0 51
michael@0 52 // This is appropriate for use in tracing methods, etc.
michael@0 53 JSObject* GetJSFunctionPreserveColor() const
michael@0 54 {
michael@0 55 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
michael@0 56 return mCompiled;
michael@0 57 }
michael@0 58
michael@0 59 private:
michael@0 60 JSObject*& UnsafeGetJSFunction()
michael@0 61 {
michael@0 62 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
michael@0 63 return mCompiled;
michael@0 64 }
michael@0 65
michael@0 66 enum { BIT_UNCOMPILED = 1 << 0 };
michael@0 67
michael@0 68 union
michael@0 69 {
michael@0 70 // An pointer that represents the function before being compiled, with
michael@0 71 // BIT_UNCOMPILED set.
michael@0 72 uintptr_t mUncompiled;
michael@0 73
michael@0 74 // The JS object for the compiled result.
michael@0 75 JSObject* mCompiled;
michael@0 76 };
michael@0 77
michael@0 78 friend class js::GCMethods<nsXBLMaybeCompiled<UncompiledT> >;
michael@0 79 };
michael@0 80
michael@0 81 /* Add support for JS::Heap<nsXBLMaybeCompiled>. */
michael@0 82 namespace js {
michael@0 83
michael@0 84 template <class UncompiledT>
michael@0 85 struct GCMethods<nsXBLMaybeCompiled<UncompiledT> > : public GCMethods<JSObject *>
michael@0 86 {
michael@0 87 typedef struct GCMethods<JSObject *> Base;
michael@0 88
michael@0 89 static nsXBLMaybeCompiled<UncompiledT> initial() { return nsXBLMaybeCompiled<UncompiledT>(); }
michael@0 90
michael@0 91 static bool poisoned(nsXBLMaybeCompiled<UncompiledT> function)
michael@0 92 {
michael@0 93 return function.IsCompiled() && Base::poisoned(function.GetJSFunction());
michael@0 94 }
michael@0 95
michael@0 96 static bool needsPostBarrier(nsXBLMaybeCompiled<UncompiledT> function)
michael@0 97 {
michael@0 98 return function.IsCompiled() && Base::needsPostBarrier(function.GetJSFunction());
michael@0 99 }
michael@0 100
michael@0 101 #ifdef JSGC_GENERATIONAL
michael@0 102 static void postBarrier(nsXBLMaybeCompiled<UncompiledT>* functionp)
michael@0 103 {
michael@0 104 Base::postBarrier(&functionp->UnsafeGetJSFunction());
michael@0 105 }
michael@0 106
michael@0 107 static void relocate(nsXBLMaybeCompiled<UncompiledT>* functionp)
michael@0 108 {
michael@0 109 Base::relocate(&functionp->UnsafeGetJSFunction());
michael@0 110 }
michael@0 111 #endif
michael@0 112 };
michael@0 113
michael@0 114 template <class UncompiledT>
michael@0 115 class HeapBase<nsXBLMaybeCompiled<UncompiledT> >
michael@0 116 {
michael@0 117 const JS::Heap<nsXBLMaybeCompiled<UncompiledT> >& wrapper() const {
michael@0 118 return *static_cast<const JS::Heap<nsXBLMaybeCompiled<UncompiledT> >*>(this);
michael@0 119 }
michael@0 120
michael@0 121 JS::Heap<nsXBLMaybeCompiled<UncompiledT> >& wrapper() {
michael@0 122 return *static_cast<JS::Heap<nsXBLMaybeCompiled<UncompiledT> >*>(this);
michael@0 123 }
michael@0 124
michael@0 125 const nsXBLMaybeCompiled<UncompiledT>* extract() const {
michael@0 126 return wrapper().address();
michael@0 127 }
michael@0 128
michael@0 129 nsXBLMaybeCompiled<UncompiledT>* extract() {
michael@0 130 return wrapper().unsafeGet();
michael@0 131 }
michael@0 132
michael@0 133 public:
michael@0 134 bool IsCompiled() const { return extract()->IsCompiled(); }
michael@0 135 UncompiledT* GetUncompiled() const { return extract()->GetUncompiled(); }
michael@0 136 JSObject* GetJSFunction() const { return extract()->GetJSFunction(); }
michael@0 137 JSObject* GetJSFunctionPreserveColor() const { return extract()->GetJSFunctionPreserveColor(); }
michael@0 138
michael@0 139 void SetUncompiled(UncompiledT* source) {
michael@0 140 wrapper().set(nsXBLMaybeCompiled<UncompiledT>(source));
michael@0 141 }
michael@0 142
michael@0 143 void SetJSFunction(JSObject* function) {
michael@0 144 wrapper().set(nsXBLMaybeCompiled<UncompiledT>(function));
michael@0 145 }
michael@0 146
michael@0 147 JS::Heap<JSObject*>& AsHeapObject()
michael@0 148 {
michael@0 149 MOZ_ASSERT(extract()->IsCompiled());
michael@0 150 return *reinterpret_cast<JS::Heap<JSObject*>*>(this);
michael@0 151 }
michael@0 152 };
michael@0 153
michael@0 154 } /* namespace js */
michael@0 155
michael@0 156 #endif // nsXBLMaybeCompiled_h__

mercurial