Bug 1557791 - Split |ScriptSource::{Unc,C}ompressed| into a |*Data| class identical to the current class, and fresh classes of identical name that inherit from it -- anticipating when those fresh classes will statically encode retrievability. r=arai
authorJeff Walden <jwalden@mit.edu>
Thu, 06 Jun 2019 13:06:40 -0700
changeset 478268 a289b17746ee5e69ed22dca2d54f0f6c1b59d728
parent 478267 cdd58bdd070214af0a98d56266864008099b1466
child 478269 53f1e230255dd7419fdc6b934d5d15faa276df73
push id5
push uservporof@mozilla.com
push dateWed, 12 Jun 2019 10:24:37 +0000
reviewersarai
bugs1557791
milestone69.0a1
Bug 1557791 - Split |ScriptSource::{Unc,C}ompressed| into a |*Data| class identical to the current class, and fresh classes of identical name that inherit from it -- anticipating when those fresh classes will statically encode retrievability. r=arai Differential Revision: https://phabricator.services.mozilla.com/D34199
js/src/vm/JSScript.cpp
js/src/vm/JSScript.h
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -1836,17 +1836,17 @@ size_t UncompressedSourceCache::sizeOfEx
   }
   return n;
 }
 
 template <typename Unit>
 const Unit* ScriptSource::chunkUnits(
     JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holder,
     size_t chunk) {
-  const Compressed<Unit>& c = data.as<Compressed<Unit>>();
+  const CompressedData<Unit>& c = data.as<Compressed<Unit>>();
 
   ScriptSourceChunk ssc(this, chunk);
   if (const Unit* decompressed =
           cx->caches().uncompressedSourceCache.lookup<Unit>(ssc, holder)) {
     return decompressed;
   }
 
   size_t totalLengthInBytes = length() * sizeof(Unit);
@@ -1879,23 +1879,24 @@ const Unit* ScriptSource::chunkUnits(
 }
 
 template <typename Unit>
 void ScriptSource::movePendingCompressedSource() {
   if (pendingCompressed_.empty()) {
     return;
   }
 
-  Compressed<Unit>& pending = pendingCompressed_.ref<Compressed<Unit>>();
+  CompressedData<Unit>& pending =
+      pendingCompressed_.ref<CompressedData<Unit>>();
 
   MOZ_ASSERT(!hasCompressedSource());
   MOZ_ASSERT_IF(hasUncompressedSource(),
                 pending.uncompressedLength == length());
 
-  data = SourceType(std::move(pending));
+  data = SourceType(Compressed<Unit>(std::move(pending)));
   pendingCompressed_.destroy();
 }
 
 template <typename Unit>
 ScriptSource::PinnedUnits<Unit>::~PinnedUnits() {
   if (units_) {
     MOZ_ASSERT(*stack_ == this);
     *stack_ = prev_;
@@ -2230,18 +2231,18 @@ void ScriptSource::convertToCompressedSo
                                              size_t uncompressedLength) {
   MOZ_ASSERT(data.is<Uncompressed<Unit>>(),
              "should only be converting uncompressed source to compressed "
              "source identically encoded");
   MOZ_ASSERT(length() == uncompressedLength);
 
   if (pinnedUnitsStack_) {
     MOZ_ASSERT(pendingCompressed_.empty());
-    pendingCompressed_.construct<Compressed<Unit>>(std::move(compressed),
-                                                   uncompressedLength);
+    pendingCompressed_.construct<CompressedData<Unit>>(std::move(compressed),
+                                                       uncompressedLength);
   } else {
     data =
         SourceType(Compressed<Unit>(std::move(compressed), uncompressedLength));
   }
 }
 
 template <typename Unit>
 MOZ_MUST_USE bool ScriptSource::initializeWithCompressedSource(
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -514,43 +514,62 @@ class ScriptSource {
       refs;
 
   // Note: while ScriptSources may be compressed off thread, they are only
   // modified by the main thread, and all members are always safe to access
   // on the main thread.
 
   // Indicate which field in the |data| union is active.
 
-  // Uncompressed source text.
   template <typename Unit>
-  class Uncompressed {
+  class UncompressedData {
     typename SourceTypeTraits<Unit>::SharedImmutableString string_;
 
    public:
-    explicit Uncompressed(
+    explicit UncompressedData(
         typename SourceTypeTraits<Unit>::SharedImmutableString str)
         : string_(std::move(str)) {}
 
     const Unit* units() const { return SourceTypeTraits<Unit>::units(string_); }
 
     size_t length() const { return string_.length(); }
   };
 
-  // Compressed source text.
+  // Uncompressed source text.
   template <typename Unit>
-  struct Compressed {
+  class Uncompressed : public UncompressedData<Unit> {
+    using Base = UncompressedData<Unit>;
+
+   public:
+    using Base::Base;
+  };
+
+  template <typename Unit>
+  struct CompressedData {
     // Single-byte compressed text, regardless whether the original text
     // was single-byte or two-byte.
     SharedImmutableString raw;
     size_t uncompressedLength;
 
-    Compressed(SharedImmutableString raw, size_t uncompressedLength)
+    CompressedData(SharedImmutableString raw, size_t uncompressedLength)
         : raw(std::move(raw)), uncompressedLength(uncompressedLength) {}
   };
 
+  // Compressed source text.
+  template <typename Unit>
+  struct Compressed : public CompressedData<Unit> {
+    using Base = CompressedData<Unit>;
+
+   public:
+    using Base::Base;
+
+    explicit Compressed(CompressedData<Unit>&& data)
+        : Base(std::move(data.raw), data.uncompressedLength) {}
+  };
+
   // Source that can be retrieved using the registered source hook.  |Unit|
   // records the source type so that source-text coordinates in functions and
   // scripts that depend on this |ScriptSource| are correct.
   template <typename Unit>
   struct Retrievable {
     // The source hook and script URL required to retrieve source are stored
     // elsewhere, so nothing is needed here.  It'd be better hygiene to store
     // something source-hook-like in each |ScriptSource| that needs it, but that
@@ -579,17 +598,18 @@ class ScriptSource {
                        Uncompressed<char16_t>, Retrievable<mozilla::Utf8Unit>,
                        Retrievable<char16_t>, Missing, BinAST>;
   SourceType data;
 
   // If the GC attempts to call convertToCompressedSource with PinnedUnits
   // present, the first PinnedUnits (that is, bottom of the stack) will set
   // the compressed chars upon destruction.
   PinnedUnitsBase* pinnedUnitsStack_;
-  mozilla::MaybeOneOf<Compressed<mozilla::Utf8Unit>, Compressed<char16_t>>
+  mozilla::MaybeOneOf<CompressedData<mozilla::Utf8Unit>,
+                      CompressedData<char16_t>>
       pendingCompressed_;
 
   // The filename of this script.
   UniqueChars filename_;
 
   UniqueTwoByteChars displayURL_;
   UniqueTwoByteChars sourceMapURL_;
   bool mutedErrors_;