bug 1562309 - add protected data checks to check for context-local thread data r=jonco
authorkriswright <kwright@mozilla.com>
Wed, 03 Jul 2019 17:27:08 +0000
changeset 540802 636ffcf7e25184078c20c6323d8e42bf4a68b7d4
parent 540801 0af1dfabc22b28f26d56440fe04c91fca5461d40
child 540803 dc1ad84da67e3a3e51326c59cbe9bffdca6e0e1e
push id11529
push userarchaeopteryx@coole-files.de
push dateThu, 04 Jul 2019 15:22:33 +0000
treeherdermozilla-beta@ebb510a784b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1562309
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1562309 - add protected data checks to check for context-local thread data r=jonco Adds CheckContextLocal protected data checks and a data type to check a JSContext against the TlsContext of the thread. Objects must specify the JSContext in which they are created in to check against. Differential Revision: https://phabricator.services.mozilla.com/D36518
js/src/threading/ProtectedData.cpp
js/src/threading/ProtectedData.h
--- a/js/src/threading/ProtectedData.cpp
+++ b/js/src/threading/ProtectedData.cpp
@@ -41,16 +41,24 @@ static inline bool OnHelperThread() {
 void CheckThreadLocal::check() const {
   JSContext* cx = TlsContext.get();
   MOZ_ASSERT(cx);
   MOZ_ASSERT_IF(cx->isMainThreadContext(),
                 CurrentThreadCanAccessRuntime(cx->runtime()));
   MOZ_ASSERT(id == ThisThread::GetId());
 }
 
+void CheckContextLocal::check() const {
+  JSContext* cx = TlsContext.get();
+  MOZ_ASSERT(cx);
+  MOZ_ASSERT_IF(cx->isMainThreadContext(),
+                CurrentThreadCanAccessRuntime(cx->runtime()));
+  MOZ_ASSERT(cx_ == cx);
+}
+
 template <AllowedHelperThread Helper>
 void CheckMainThread<Helper>::check() const {
   if (OnHelperThread<Helper>()) {
     return;
   }
 
   JSContext* cx = TlsContext.get();
   MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
--- a/js/src/threading/ProtectedData.h
+++ b/js/src/threading/ProtectedData.h
@@ -183,16 +183,29 @@ class ProtectedDataZoneArg : public Prot
  public:
   template <typename... Args>
   explicit ProtectedDataZoneArg(JS::Zone* zone, Args&&... args)
       : ProtectedData<Check, T>(Check(zone), std::forward<Args>(args)...) {}
 
   using Base::operator=;
 };
 
+// Intermediate class for protected data whose checks take a JSContext.
+template <typename Check, typename T>
+class ProtectedDataContextArg : public ProtectedData<Check, T> {
+  using Base = ProtectedData<Check, T>;
+
+ public:
+  template <typename... Args>
+  explicit ProtectedDataContextArg(JSContext* cx, Args&&... args)
+      : ProtectedData<Check, T>(Check(cx), std::forward<Args>(args)...) {}
+
+  using Base::operator=;
+};
+
 class CheckUnprotected {
 #ifdef JS_HAS_PROTECTED_DATA_CHECKS
  public:
   inline void check() const {}
 #endif
 };
 
 // Data with a no-op check that permits all accesses. This is tantamount to not
@@ -207,20 +220,40 @@ class CheckThreadLocal {
 
  public:
   CheckThreadLocal() : id(ThisThread::GetId()) {}
 
   void check() const;
 #endif
 };
 
+class CheckContextLocal {
+#ifdef JS_HAS_PROTECTED_DATA_CHECKS
+  JSContext* cx_;
+
+ public:
+  explicit CheckContextLocal(JSContext* cx) : cx_(cx) {}
+
+  void check() const;
+#else
+ public:
+  explicit CheckContextLocal(JSContext* cx) {}
+#endif
+};
+
 // Data which may only be accessed by the thread on which it is created.
 template <typename T>
 using ThreadData = ProtectedDataNoCheckArgs<CheckThreadLocal, T>;
 
+// Data which belongs to a JSContext and should only be accessed from that
+// JSContext's thread. Note that a JSContext may not have a thread currently
+// associated with it and any associated thread may change over time.
+template <typename T>
+using ContextData = ProtectedDataContextArg<CheckContextLocal, T>;
+
 // Enum describing which helper threads (GC tasks or Ion compilations) may
 // access data even though they do not have exclusive access to any zone.
 enum class AllowedHelperThread { None, GCTask, IonCompile, GCTaskOrIonCompile };
 
 template <AllowedHelperThread Helper>
 class CheckMainThread {
  public:
   void check() const;