From 4da56c6d157a90530927d190f1e1f67423dea8f1 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 26 Apr 2018 09:57:15 +0200 Subject: [PATCH] Bug 1456494 - Initialize Zone::helperThreadUse_ first to avoid accessing uninitialized memory in debug builds. r=jonco --HG-- extra : rebase_source : 9abb7cecd084e7f8c4bbe7ce1ff3e34c10e024ce --- js/src/gc/Zone.cpp | 8 +++-- js/src/gc/Zone.h | 80 ++++++++++++++++++++++------------------------ 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 4159e1c4d2a7..8f006d194ccd 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -26,6 +26,10 @@ Zone * const Zone::NotOnList = reinterpret_cast(1); JS::Zone::Zone(JSRuntime* rt) : 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), uniqueIds_(this), suppressAllocationMetadataBuilder(this, false), @@ -54,8 +58,6 @@ JS::Zone::Zone(JSRuntime* rt) nurseryShapes_(this), data(this, nullptr), isSystem(this, false), - helperThreadOwnerContext_(nullptr), - helperThreadUse(HelperThreadUse::None), #ifdef DEBUG gcLastSweepGroupIndex(this, 0), #endif @@ -78,7 +80,7 @@ JS::Zone::Zone(JSRuntime* rt) Zone::~Zone() { - MOZ_ASSERT(helperThreadUse == HelperThreadUse::None); + MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None); JSRuntime* rt = runtimeFromAnyThread(); if (this == rt->gc.systemZone) diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index bfbab9b05319..1f3cd9aecb93 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -151,6 +151,44 @@ struct Zone : public JS::shadow::Zone, MOZ_MUST_USE bool init(bool isSystem); void destroy(js::FreeOp *fop); + private: + enum class HelperThreadUse : uint32_t { + None, + Pending, + Active + }; + mozilla::Atomic helperThreadUse_; + + // The helper thread context with exclusive access to this zone, if + // usedByHelperThread(), or nullptr when on the main thread. + js::UnprotectedData 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 discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true); @@ -513,48 +551,6 @@ struct Zone : public JS::shadow::Zone, js::ZoneData isSystem; - private: - // The helper thread context with exclusive access to this zone, if - // usedByHelperThread(), or nullptr when on the main thread. - js::UnprotectedData helperThreadOwnerContext_; - - public: - bool ownedByCurrentHelperThread(); - void setHelperThreadOwnerContext(JSContext* cx); - - private: - enum class HelperThreadUse : uint32_t - { - None, - Pending, - Active - }; - - mozilla::Atomic 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 js::ZoneData gcLastSweepGroupIndex; #endif