зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1456494 - Initialize Zone::helperThreadUse_ first to avoid accessing uninitialized memory in debug builds. r=jonco
--HG-- extra : rebase_source : 9abb7cecd084e7f8c4bbe7ce1ff3e34c10e024ce
This commit is contained in:
Родитель
37bc3aaed9
Коммит
4da56c6d15
|
@ -26,6 +26,10 @@ Zone * const Zone::NotOnList = reinterpret_cast<Zone*>(1);
|
||||||
|
|
||||||
JS::Zone::Zone(JSRuntime* rt)
|
JS::Zone::Zone(JSRuntime* rt)
|
||||||
: JS::shadow::Zone(rt, &rt->gc.marker),
|
: JS::shadow::Zone(rt, &rt->gc.marker),
|
||||||
|
// Note: don't use |this| before initializing helperThreadUse_!
|
||||||
|
// ProtectedData checks in CheckZone::check may read this field.
|
||||||
|
helperThreadUse_(HelperThreadUse::None),
|
||||||
|
helperThreadOwnerContext_(nullptr),
|
||||||
debuggers(this, nullptr),
|
debuggers(this, nullptr),
|
||||||
uniqueIds_(this),
|
uniqueIds_(this),
|
||||||
suppressAllocationMetadataBuilder(this, false),
|
suppressAllocationMetadataBuilder(this, false),
|
||||||
|
@ -54,8 +58,6 @@ JS::Zone::Zone(JSRuntime* rt)
|
||||||
nurseryShapes_(this),
|
nurseryShapes_(this),
|
||||||
data(this, nullptr),
|
data(this, nullptr),
|
||||||
isSystem(this, false),
|
isSystem(this, false),
|
||||||
helperThreadOwnerContext_(nullptr),
|
|
||||||
helperThreadUse(HelperThreadUse::None),
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
gcLastSweepGroupIndex(this, 0),
|
gcLastSweepGroupIndex(this, 0),
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,7 +80,7 @@ JS::Zone::Zone(JSRuntime* rt)
|
||||||
|
|
||||||
Zone::~Zone()
|
Zone::~Zone()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(helperThreadUse == HelperThreadUse::None);
|
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None);
|
||||||
|
|
||||||
JSRuntime* rt = runtimeFromAnyThread();
|
JSRuntime* rt = runtimeFromAnyThread();
|
||||||
if (this == rt->gc.systemZone)
|
if (this == rt->gc.systemZone)
|
||||||
|
|
|
@ -151,6 +151,44 @@ struct Zone : public JS::shadow::Zone,
|
||||||
MOZ_MUST_USE bool init(bool isSystem);
|
MOZ_MUST_USE bool init(bool isSystem);
|
||||||
void destroy(js::FreeOp *fop);
|
void destroy(js::FreeOp *fop);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class HelperThreadUse : uint32_t {
|
||||||
|
None,
|
||||||
|
Pending,
|
||||||
|
Active
|
||||||
|
};
|
||||||
|
mozilla::Atomic<HelperThreadUse> helperThreadUse_;
|
||||||
|
|
||||||
|
// The helper thread context with exclusive access to this zone, if
|
||||||
|
// usedByHelperThread(), or nullptr when on the main thread.
|
||||||
|
js::UnprotectedData<JSContext*> helperThreadOwnerContext_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool ownedByCurrentHelperThread();
|
||||||
|
void setHelperThreadOwnerContext(JSContext* cx);
|
||||||
|
|
||||||
|
// Whether this zone was created for use by a helper thread.
|
||||||
|
bool createdForHelperThread() const {
|
||||||
|
return helperThreadUse_ != HelperThreadUse::None;
|
||||||
|
}
|
||||||
|
// Whether this zone is currently in use by a helper thread.
|
||||||
|
bool usedByHelperThread() {
|
||||||
|
MOZ_ASSERT_IF(isAtomsZone(), helperThreadUse_ == HelperThreadUse::None);
|
||||||
|
return helperThreadUse_ == HelperThreadUse::Active;
|
||||||
|
}
|
||||||
|
void setCreatedForHelperThread() {
|
||||||
|
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None);
|
||||||
|
helperThreadUse_ = HelperThreadUse::Pending;
|
||||||
|
}
|
||||||
|
void setUsedByHelperThread() {
|
||||||
|
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::Pending);
|
||||||
|
helperThreadUse_ = HelperThreadUse::Active;
|
||||||
|
}
|
||||||
|
void clearUsedByHelperThread() {
|
||||||
|
MOZ_ASSERT(helperThreadUse_ != HelperThreadUse::None);
|
||||||
|
helperThreadUse_ = HelperThreadUse::None;
|
||||||
|
}
|
||||||
|
|
||||||
void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
|
void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
|
||||||
|
|
||||||
void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true);
|
void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true);
|
||||||
|
@ -513,48 +551,6 @@ struct Zone : public JS::shadow::Zone,
|
||||||
|
|
||||||
js::ZoneData<bool> isSystem;
|
js::ZoneData<bool> isSystem;
|
||||||
|
|
||||||
private:
|
|
||||||
// The helper thread context with exclusive access to this zone, if
|
|
||||||
// usedByHelperThread(), or nullptr when on the main thread.
|
|
||||||
js::UnprotectedData<JSContext*> helperThreadOwnerContext_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool ownedByCurrentHelperThread();
|
|
||||||
void setHelperThreadOwnerContext(JSContext* cx);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class HelperThreadUse : uint32_t
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Pending,
|
|
||||||
Active
|
|
||||||
};
|
|
||||||
|
|
||||||
mozilla::Atomic<HelperThreadUse> helperThreadUse;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Whether this zone was created for use by a helper thread.
|
|
||||||
bool createdForHelperThread() const {
|
|
||||||
return helperThreadUse != HelperThreadUse::None;
|
|
||||||
}
|
|
||||||
// Whether this zone is currently in use by a helper thread.
|
|
||||||
bool usedByHelperThread() {
|
|
||||||
MOZ_ASSERT_IF(isAtomsZone(), helperThreadUse == HelperThreadUse::None);
|
|
||||||
return helperThreadUse == HelperThreadUse::Active;
|
|
||||||
}
|
|
||||||
void setCreatedForHelperThread() {
|
|
||||||
MOZ_ASSERT(helperThreadUse == HelperThreadUse::None);
|
|
||||||
helperThreadUse = HelperThreadUse::Pending;
|
|
||||||
}
|
|
||||||
void setUsedByHelperThread() {
|
|
||||||
MOZ_ASSERT(helperThreadUse == HelperThreadUse::Pending);
|
|
||||||
helperThreadUse = HelperThreadUse::Active;
|
|
||||||
}
|
|
||||||
void clearUsedByHelperThread() {
|
|
||||||
MOZ_ASSERT(helperThreadUse != HelperThreadUse::None);
|
|
||||||
helperThreadUse = HelperThreadUse::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
js::ZoneData<unsigned> gcLastSweepGroupIndex;
|
js::ZoneData<unsigned> gcLastSweepGroupIndex;
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче