mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
Bug 1417123 - Move barrier function declarations to public/HeapAPI.h r=sfink
This commit is contained in:
parent
97baa05333
commit
08052a293d
@ -4,6 +4,10 @@
|
||||
* 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/. */
|
||||
|
||||
/*
|
||||
* High-level interface to the JS garbage collector.
|
||||
*/
|
||||
|
||||
#ifndef js_GCAPI_h
|
||||
#define js_GCAPI_h
|
||||
|
||||
@ -11,10 +15,13 @@
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include "js/GCAnnotations.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
struct JSContext;
|
||||
class JSObject;
|
||||
struct JSRuntime;
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
class GCRuntime;
|
||||
@ -51,6 +58,8 @@ typedef enum JSGCInvocationKind {
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct Zone;
|
||||
|
||||
#define GCREASONS(D) \
|
||||
/* Reasons internal to the JS engine */ \
|
||||
D(API) \
|
||||
@ -442,29 +451,6 @@ IsIncrementalGCInProgress(JSContext* cx);
|
||||
extern JS_PUBLIC_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime* rt);
|
||||
|
||||
/*
|
||||
* Returns true when writes to GC thing pointers (and reads from weak pointers)
|
||||
* must call an incremental barrier. This is generally only true when running
|
||||
* mutator code in-between GC slices. At other times, the barrier may be elided
|
||||
* for performance.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext* cx);
|
||||
|
||||
/*
|
||||
* Notify the GC that a reference to a JSObject is about to be overwritten.
|
||||
* This method must be called if IsIncrementalBarrierNeeded.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
IncrementalPreWriteBarrier(JSObject* obj);
|
||||
|
||||
/*
|
||||
* Notify the GC that a weak reference to a GC thing has been read.
|
||||
* This method must be called if IsIncrementalBarrierNeeded.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
IncrementalReadBarrier(GCCellPtr thing);
|
||||
|
||||
/**
|
||||
* Returns true if the most recent GC ran incrementally.
|
||||
*/
|
||||
@ -613,88 +599,6 @@ class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC
|
||||
} JS_HAZ_GC_INVALIDATED;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
* JS::TraceKind::Shape. |thing| should be non-null. The return value indicates
|
||||
* if anything was unmarked.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
UnmarkGrayGCThingRecursively(GCCellPtr thing);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeGCThingToActiveJS(JS::GCCellPtr thing)
|
||||
{
|
||||
// GC things residing in the nursery cannot be gray: they have no mark bits.
|
||||
// All live objects in the nursery are moved to tenured at the beginning of
|
||||
// each GC slice, so the gray marker never sees nursery things.
|
||||
if (IsInsideNursery(thing.asCell()))
|
||||
return;
|
||||
|
||||
// There's nothing to do for permanent GC things that might be owned by
|
||||
// another runtime.
|
||||
if (thing.mayBeOwnedByOtherRuntime())
|
||||
return;
|
||||
|
||||
if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
|
||||
JS::IncrementalReadBarrier(thing);
|
||||
else if (js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()))
|
||||
JS::UnmarkGrayGCThingRecursively(thing);
|
||||
|
||||
MOZ_ASSERT(!js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
extern JS_PUBLIC_API(bool)
|
||||
EdgeNeedsSweepUnbarrieredSlow(T* thingp);
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
EdgeNeedsSweepUnbarriered(JSObject** objp)
|
||||
{
|
||||
// This function does not handle updating nursery pointers. Raw JSObject
|
||||
// pointers should be updated separately or replaced with
|
||||
// JS::Heap<JSObject*> which handles this automatically.
|
||||
MOZ_ASSERT(!JS::CurrentThreadIsHeapMinorCollecting());
|
||||
if (IsInsideNursery(reinterpret_cast<Cell*>(*objp)))
|
||||
return false;
|
||||
|
||||
auto zone = JS::shadow::Zone::asShadowZone(detail::GetGCThingZone(uintptr_t(*objp)));
|
||||
if (!zone->isGCSweepingOrCompacting())
|
||||
return false;
|
||||
|
||||
return EdgeNeedsSweepUnbarrieredSlow(objp);
|
||||
}
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* This should be called when an object that is marked gray is exposed to the JS
|
||||
* engine (by handing it to running JS code or writing it into live JS
|
||||
* data). During incremental GC, since the gray bits haven't been computed yet,
|
||||
* we conservatively mark the object black.
|
||||
*/
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeObjectToActiveJS(JSObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(obj);
|
||||
MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&obj));
|
||||
js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeScriptToActiveJS(JSScript* script)
|
||||
{
|
||||
MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&script));
|
||||
js::gc::ExposeGCThingToActiveJS(GCCellPtr(script));
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal to Firefox.
|
||||
*/
|
||||
@ -709,4 +613,18 @@ NotifyDidPaint(JSContext* cx);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
/**
|
||||
* Create an object providing access to the garbage collector's internal notion
|
||||
* of the current state of memory (both GC heap memory and GCthing-controlled
|
||||
* malloc memory.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
NewMemoryInfoObject(JSContext* cx);
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* js_GCAPI_h */
|
||||
|
@ -467,7 +467,38 @@ GCThingIsMarkedGray(GCCellPtr thing)
|
||||
extern JS_PUBLIC_API(JS::TraceKind)
|
||||
GCThingTraceKind(void* thing);
|
||||
|
||||
} /* namespace JS */
|
||||
/*
|
||||
* Returns true when writes to GC thing pointers (and reads from weak pointers)
|
||||
* must call an incremental barrier. This is generally only true when running
|
||||
* mutator code in-between GC slices. At other times, the barrier may be elided
|
||||
* for performance.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext* cx);
|
||||
|
||||
/*
|
||||
* Notify the GC that a reference to a JSObject is about to be overwritten.
|
||||
* This method must be called if IsIncrementalBarrierNeeded.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
IncrementalPreWriteBarrier(JSObject* obj);
|
||||
|
||||
/*
|
||||
* Notify the GC that a weak reference to a GC thing has been read.
|
||||
* This method must be called if IsIncrementalBarrierNeeded.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
IncrementalReadBarrier(GCCellPtr thing);
|
||||
|
||||
/**
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
* JS::TraceKind::Shape. |thing| should be non-null. The return value indicates
|
||||
* if anything was unmarked.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
UnmarkGrayGCThingRecursively(GCCellPtr thing);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
@ -487,15 +518,75 @@ IsIncrementalBarrierNeededOnTenuredGCThing(const JS::GCCellPtr thing)
|
||||
return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an object providing access to the garbage collector's internal notion
|
||||
* of the current state of memory (both GC heap memory and GCthing-controlled
|
||||
* malloc memory.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
NewMemoryInfoObject(JSContext* cx);
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeGCThingToActiveJS(JS::GCCellPtr thing)
|
||||
{
|
||||
// GC things residing in the nursery cannot be gray: they have no mark bits.
|
||||
// All live objects in the nursery are moved to tenured at the beginning of
|
||||
// each GC slice, so the gray marker never sees nursery things.
|
||||
if (IsInsideNursery(thing.asCell()))
|
||||
return;
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
// There's nothing to do for permanent GC things that might be owned by
|
||||
// another runtime.
|
||||
if (thing.mayBeOwnedByOtherRuntime())
|
||||
return;
|
||||
|
||||
if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
|
||||
JS::IncrementalReadBarrier(thing);
|
||||
else if (js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()))
|
||||
JS::UnmarkGrayGCThingRecursively(thing);
|
||||
|
||||
MOZ_ASSERT(!js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
extern JS_PUBLIC_API(bool)
|
||||
EdgeNeedsSweepUnbarrieredSlow(T* thingp);
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
EdgeNeedsSweepUnbarriered(JSObject** objp)
|
||||
{
|
||||
// This function does not handle updating nursery pointers. Raw JSObject
|
||||
// pointers should be updated separately or replaced with
|
||||
// JS::Heap<JSObject*> which handles this automatically.
|
||||
MOZ_ASSERT(!JS::CurrentThreadIsHeapMinorCollecting());
|
||||
if (IsInsideNursery(reinterpret_cast<Cell*>(*objp)))
|
||||
return false;
|
||||
|
||||
auto zone = JS::shadow::Zone::asShadowZone(detail::GetGCThingZone(uintptr_t(*objp)));
|
||||
if (!zone->isGCSweepingOrCompacting())
|
||||
return false;
|
||||
|
||||
return EdgeNeedsSweepUnbarrieredSlow(objp);
|
||||
}
|
||||
|
||||
} // namespace gc
|
||||
} // namesapce js
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* This should be called when an object that is marked gray is exposed to the JS
|
||||
* engine (by handing it to running JS code or writing it into live JS
|
||||
* data). During incremental GC, since the gray bits haven't been computed yet,
|
||||
* we conservatively mark the object black.
|
||||
*/
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeObjectToActiveJS(JSObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(obj);
|
||||
MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&obj));
|
||||
js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
ExposeScriptToActiveJS(JSScript* script)
|
||||
{
|
||||
MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&script));
|
||||
js::gc::ExposeGCThingToActiveJS(GCCellPtr(script));
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_HeapAPI_h */
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "jspubtd.h"
|
||||
|
||||
#include "js/GCAnnotations.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/GCPolicyAPI.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "builtin/SelfHostingDefines.h"
|
||||
#include "js/Class.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/GCHashTable.h"
|
||||
#include "vm/NativeObject.h"
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "jit/AtomicOperations.h"
|
||||
#include "jit/InlinableNatives.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/Value.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#define gc_ArenaList_h
|
||||
|
||||
#include "gc/AllocKind.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "threading/ProtectedData.h"
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "gc/AllocKind.h"
|
||||
#include "gc/GCEnum.h"
|
||||
#include "gc/Memory.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TracingAPI.h"
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "gc/GCEnum.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "js/Vector.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
#include "jscntxtinlines.h"
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "jit/mips32/Simulator-mips32.h"
|
||||
#include "jit/mips64/Simulator-mips64.h"
|
||||
#include "jit/ProcessExecutableMemory.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
@ -76,6 +75,8 @@ extern "C" void sync_instruction_memory(caddr_t v, u_int len);
|
||||
#include <libkern/OSCacheControl.h>
|
||||
#endif
|
||||
|
||||
struct JSRuntime;
|
||||
|
||||
namespace JS {
|
||||
struct CodeSizes;
|
||||
} // namespace JS
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/Value.h"
|
||||
#include "vm/String.h"
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "jit/Lowering.h"
|
||||
#include "jit/MIR.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
static unsigned gSliceCallbackCount = 0;
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "js/Class.h"
|
||||
#include "js/Date.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/Id.h"
|
||||
|
@ -71,33 +71,8 @@ class AtomStateEntry
|
||||
|
||||
struct AtomHasher
|
||||
{
|
||||
struct Lookup
|
||||
{
|
||||
union {
|
||||
const JS::Latin1Char* latin1Chars;
|
||||
const char16_t* twoByteChars;
|
||||
};
|
||||
bool isLatin1;
|
||||
size_t length;
|
||||
const JSAtom* atom; /* Optional. */
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
||||
HashNumber hash;
|
||||
|
||||
MOZ_ALWAYS_INLINE Lookup(const char16_t* chars, size_t length)
|
||||
: twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
MOZ_ALWAYS_INLINE Lookup(const JS::Latin1Char* chars, size_t length)
|
||||
: latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
inline explicit Lookup(const JSAtom* atom);
|
||||
};
|
||||
|
||||
static HashNumber hash(const Lookup& l) { return l.hash; }
|
||||
struct Lookup;
|
||||
static inline HashNumber hash(const Lookup& l);
|
||||
static MOZ_ALWAYS_INLINE bool match(const AtomStateEntry& entry, const Lookup& lookup);
|
||||
static void rekey(AtomStateEntry& k, const AtomStateEntry& newKey) { k = newKey; }
|
||||
};
|
||||
|
@ -35,6 +35,38 @@ js::AtomStateEntry::asPtrUnbarriered() const
|
||||
|
||||
namespace js {
|
||||
|
||||
struct AtomHasher::Lookup
|
||||
{
|
||||
union {
|
||||
const JS::Latin1Char* latin1Chars;
|
||||
const char16_t* twoByteChars;
|
||||
};
|
||||
bool isLatin1;
|
||||
size_t length;
|
||||
const JSAtom* atom; /* Optional. */
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
||||
HashNumber hash;
|
||||
|
||||
MOZ_ALWAYS_INLINE Lookup(const char16_t* chars, size_t length)
|
||||
: twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
MOZ_ALWAYS_INLINE Lookup(const JS::Latin1Char* chars, size_t length)
|
||||
: latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
inline explicit Lookup(const JSAtom* atom);
|
||||
};
|
||||
|
||||
inline HashNumber
|
||||
AtomHasher::hash(const Lookup& l)
|
||||
{
|
||||
return l.hash;
|
||||
}
|
||||
|
||||
inline jsid
|
||||
AtomToId(JSAtom* atom)
|
||||
{
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "vm/Printer.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "jsobj.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
@ -75,7 +75,6 @@
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/OptimizationTracking.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "js/Initialization.h"
|
||||
#include "js/StructuredClone.h"
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "jit/BaselineDebugModeOSR.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "js/Date.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/UbiNodeBreadthFirst.h"
|
||||
#include "js/Vector.h"
|
||||
#include "proxy/ScriptedProxyHandler.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/Opcodes.h"
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/UbiNode.h"
|
||||
#include "vm/GeckoProfiler.h"
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Rooting.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
#include "vm/Printer.h"
|
||||
|
Loading…
Reference in New Issue
Block a user