зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1421319 - Split out GCManagedDeletePolicy into its own header r=sfink
This commit is contained in:
Родитель
63739feac3
Коммит
295da27e19
|
@ -0,0 +1,79 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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 gc_DeletePolicy_h
|
||||
#define gc_DeletePolicy_h
|
||||
|
||||
#include "js/TracingAPI.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
struct ClearEdgesTracer : public JS::CallbackTracer
|
||||
{
|
||||
ClearEdgesTracer();
|
||||
|
||||
#ifdef DEBUG
|
||||
TracerKind getTracerKind() const override { return TracerKind::ClearEdges; }
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void clearEdge(T** thingp);
|
||||
|
||||
void onObjectEdge(JSObject** objp) override;
|
||||
void onStringEdge(JSString** strp) override;
|
||||
void onSymbolEdge(JS::Symbol** symp) override;
|
||||
void onScriptEdge(JSScript** scriptp) override;
|
||||
void onShapeEdge(js::Shape** shapep) override;
|
||||
void onObjectGroupEdge(js::ObjectGroup** groupp) override;
|
||||
void onBaseShapeEdge(js::BaseShape** basep) override;
|
||||
void onJitCodeEdge(js::jit::JitCode** codep) override;
|
||||
void onLazyScriptEdge(js::LazyScript** lazyp) override;
|
||||
void onScopeEdge(js::Scope** scopep) override;
|
||||
void onRegExpSharedEdge(js::RegExpShared** sharedp) override;
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
inline bool
|
||||
IsClearEdgesTracer(JSTracer *trc)
|
||||
{
|
||||
return trc->isCallbackTracer() &&
|
||||
trc->asCallbackTracer()->getTracerKind() == JS::CallbackTracer::TracerKind::ClearEdges;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gc
|
||||
|
||||
/*
|
||||
* Provides a delete policy that can be used for objects which have their
|
||||
* lifetime managed by the GC so they can be safely destroyed outside of GC.
|
||||
*
|
||||
* This is necessary for example when initializing such an object may fail after
|
||||
* the initial allocation. The partially-initialized object must be destroyed,
|
||||
* but it may not be safe to do so at the current time as the store buffer may
|
||||
* contain pointers into it.
|
||||
*
|
||||
* This policy traces GC pointers in the object and clears them, making sure to
|
||||
* trigger barriers while doing so. This will remove any store buffer pointers
|
||||
* into the object and make it safe to delete.
|
||||
*/
|
||||
template <typename T>
|
||||
struct GCManagedDeletePolicy
|
||||
{
|
||||
void operator()(const T* constPtr) {
|
||||
if (constPtr) {
|
||||
auto ptr = const_cast<T*>(constPtr);
|
||||
gc::ClearEdgesTracer trc;
|
||||
ptr->trace(&trc);
|
||||
js_delete(ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // gc_DeletePolicy_h
|
|
@ -9,21 +9,20 @@
|
|||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "ds/SplayTree.h"
|
||||
#include "gc/FindSCCs.h"
|
||||
#include "gc/GCRuntime.h"
|
||||
#include "js/GCHashTable.h"
|
||||
#include "js/TracingAPI.h"
|
||||
#include "vm/MallocProvider.h"
|
||||
#include "vm/RegExpShared.h"
|
||||
#include "vm/TypeInference.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
struct JSContext;
|
||||
|
||||
namespace js {
|
||||
|
||||
class Debugger;
|
||||
|
||||
namespace jit {
|
||||
class JitZone;
|
||||
} // namespace jit
|
||||
|
@ -987,92 +986,6 @@ ZoneAllocPolicy::pod_realloc(T* p, size_t oldSize, size_t newSize)
|
|||
return zone->pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provides a delete policy that can be used for objects which have their
|
||||
* lifetime managed by the GC so they can be safely destroyed outside of GC.
|
||||
*
|
||||
* This is necessary for example when initializing such an object may fail after
|
||||
* the initial allocation. The partially-initialized object must be destroyed,
|
||||
* but it may not be safe to do so at the current time as the store buffer may
|
||||
* contain pointers into it.
|
||||
*
|
||||
* This policy traces GC pointers in the object and clears them, making sure to
|
||||
* trigger barriers while doing so. This will remove any store buffer pointers
|
||||
* into the object and make it safe to delete.
|
||||
*/
|
||||
template <typename T>
|
||||
struct GCManagedDeletePolicy
|
||||
{
|
||||
struct ClearEdgesTracer : public JS::CallbackTracer
|
||||
{
|
||||
explicit ClearEdgesTracer(JSContext* cx) : CallbackTracer(cx, TraceWeakMapKeysValues) {}
|
||||
#ifdef DEBUG
|
||||
TracerKind getTracerKind() const override { return TracerKind::ClearEdges; }
|
||||
#endif
|
||||
|
||||
template <typename S>
|
||||
void clearEdge(S** thingp) {
|
||||
InternalBarrierMethods<S*>::preBarrier(*thingp);
|
||||
InternalBarrierMethods<S*>::postBarrier(thingp, *thingp, nullptr);
|
||||
*thingp = nullptr;
|
||||
}
|
||||
|
||||
void onObjectEdge(JSObject** objp) override { clearEdge(objp); }
|
||||
void onStringEdge(JSString** strp) override { clearEdge(strp); }
|
||||
void onSymbolEdge(JS::Symbol** symp) override { clearEdge(symp); }
|
||||
void onScriptEdge(JSScript** scriptp) override { clearEdge(scriptp); }
|
||||
void onShapeEdge(js::Shape** shapep) override { clearEdge(shapep); }
|
||||
void onObjectGroupEdge(js::ObjectGroup** groupp) override { clearEdge(groupp); }
|
||||
void onBaseShapeEdge(js::BaseShape** basep) override { clearEdge(basep); }
|
||||
void onJitCodeEdge(js::jit::JitCode** codep) override { clearEdge(codep); }
|
||||
void onLazyScriptEdge(js::LazyScript** lazyp) override { clearEdge(lazyp); }
|
||||
void onScopeEdge(js::Scope** scopep) override { clearEdge(scopep); }
|
||||
void onRegExpSharedEdge(js::RegExpShared** sharedp) override { clearEdge(sharedp); }
|
||||
void onChild(const JS::GCCellPtr& thing) override { MOZ_CRASH(); }
|
||||
};
|
||||
|
||||
void operator()(const T* constPtr) {
|
||||
if (constPtr) {
|
||||
auto ptr = const_cast<T*>(constPtr);
|
||||
ClearEdgesTracer trc(TlsContext.get());
|
||||
ptr->trace(&trc);
|
||||
js_delete(ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
inline bool
|
||||
IsClearEdgesTracer(JSTracer *trc)
|
||||
{
|
||||
return trc->isCallbackTracer() &&
|
||||
trc->asCallbackTracer()->getTracerKind() == JS::CallbackTracer::TracerKind::ClearEdges;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace js
|
||||
|
||||
namespace JS {
|
||||
|
||||
// Scope data that contain GCPtrs must use the correct DeletePolicy.
|
||||
//
|
||||
// This is defined here because vm/Scope.h cannot #include "vm/Runtime.h"
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::FunctionScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::FunctionScope::Data>
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::ModuleScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::ModuleScope::Data>
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::WasmInstanceScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::WasmInstanceScope::Data>
|
||||
{ };
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // gc_Zone_h
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "js/Vector.h"
|
||||
#include "threading/ProtectedData.h"
|
||||
#include "vm/ErrorReporting.h"
|
||||
#include "vm/MallocProvider.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -9047,3 +9047,29 @@ js::gc::detail::CellIsNotGray(const Cell* cell)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
js::gc::ClearEdgesTracer::ClearEdgesTracer()
|
||||
: CallbackTracer(TlsContext.get(), TraceWeakMapKeysValues)
|
||||
{}
|
||||
|
||||
template <typename S>
|
||||
inline void
|
||||
js::gc::ClearEdgesTracer::clearEdge(S** thingp)
|
||||
{
|
||||
InternalBarrierMethods<S*>::preBarrier(*thingp);
|
||||
InternalBarrierMethods<S*>::postBarrier(thingp, *thingp, nullptr);
|
||||
*thingp = nullptr;
|
||||
}
|
||||
|
||||
void js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) { clearEdge(objp); }
|
||||
void js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) { clearEdge(strp); }
|
||||
void js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) { clearEdge(symp); }
|
||||
void js::gc::ClearEdgesTracer::onScriptEdge(JSScript** scriptp) { clearEdge(scriptp); }
|
||||
void js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) { clearEdge(shapep); }
|
||||
void js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) { clearEdge(groupp); }
|
||||
void js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape** basep) { clearEdge(basep); }
|
||||
void js::gc::ClearEdgesTracer::onJitCodeEdge(js::jit::JitCode** codep) { clearEdge(codep); }
|
||||
void js::gc::ClearEdgesTracer::onLazyScriptEdge(js::LazyScript** lazyp) { clearEdge(lazyp); }
|
||||
void js::gc::ClearEdgesTracer::onScopeEdge(js::Scope** scopep) { clearEdge(scopep); }
|
||||
void js::gc::ClearEdgesTracer::onRegExpSharedEdge(js::RegExpShared** sharedp) { clearEdge(sharedp); }
|
||||
void js::gc::ClearEdgesTracer::onChild(const JS::GCCellPtr& thing) { MOZ_CRASH(); }
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "jsfriendapi.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "gc/DeletePolicy.h"
|
||||
#include "gc/StoreBuffer.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "jsobj.h"
|
||||
#include "jsopcode.h"
|
||||
|
||||
#include "gc/DeletePolicy.h"
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Policy.h"
|
||||
#include "js/UbiNode.h"
|
||||
|
@ -1538,6 +1539,23 @@ DEFINE_SCOPE_DATA_GCPOLICY(js::WasmFunctionScope::Data);
|
|||
|
||||
#undef DEFINE_SCOPE_DATA_GCPOLICY
|
||||
|
||||
// Scope data that contain GCPtrs must use the correct DeletePolicy.
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::FunctionScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::FunctionScope::Data>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::ModuleScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::ModuleScope::Data>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct DeletePolicy<js::WasmInstanceScope::Data>
|
||||
: public js::GCManagedDeletePolicy<js::WasmInstanceScope::Data>
|
||||
{ };
|
||||
|
||||
namespace ubi {
|
||||
|
||||
template <>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "gc/DeletePolicy.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "vm/Runtime.h"
|
||||
#include "vm/TypeInference.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче