Bug 1501703: Move the custom section read before finishing a wasm module's metadata; r=luke
authorBenjamin Bouvier <benj@benj.me>
Wed, 24 Oct 2018 17:28:27 +0200
changeset 491254 ca965ec1bc91eb004ab8f5d89dc783e62ba04cf2
parent 491253 444ecc63baf3485f5d8448dda33592c6319e368a
child 491255 a81dc13c90897abc468e8f70647a5c73b61a6017
child 491275 3cc04ee79005058d817daf66da7963dfac3f0a3a
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersluke
bugs1501703
milestone65.0a1
Bug 1501703: Move the custom section read before finishing a wasm module's metadata; r=luke
js/src/wasm/WasmGenerator.cpp
js/src/wasm/WasmGenerator.h
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -973,17 +973,17 @@ ModuleGenerator::finishCodeTier()
     UniqueModuleSegment segment = ModuleSegment::create(tier(), masm_, *linkData_);
     if (!segment) {
         return nullptr;
     }
 
     return js::MakeUnique<CodeTier>(std::move(metadataTier_), std::move(segment));
 }
 
-bool
+SharedMetadata
 ModuleGenerator::finishMetadata(const Bytes& bytecode)
 {
     // Finish initialization of Metadata, which is only needed for constructing
     // the initial Module, not for tier-2 compilation.
     MOZ_ASSERT(mode() != CompileMode::Tier2);
 
     // Copy over data from the ModuleEnvironment.
 
@@ -1000,38 +1000,43 @@ ModuleGenerator::finishMetadata(const By
 
     // Copy over additional debug information.
 
     if (env_->debugEnabled()) {
         metadata_->debugEnabled = true;
 
         const size_t numFuncTypes = env_->funcTypes.length();
         if (!metadata_->debugFuncArgTypes.resize(numFuncTypes)) {
-            return false;
+            return nullptr;
         }
         if (!metadata_->debugFuncReturnTypes.resize(numFuncTypes)) {
-            return false;
+            return nullptr;
         }
         for (size_t i = 0; i < numFuncTypes; i++) {
             if (!metadata_->debugFuncArgTypes[i].appendAll(env_->funcTypes[i]->args())) {
-                return false;
+                return nullptr;
             }
             metadata_->debugFuncReturnTypes[i] = env_->funcTypes[i]->ret();
         }
 
         static_assert(sizeof(ModuleHash) <= sizeof(mozilla::SHA1Sum::Hash),
                       "The ModuleHash size shall not exceed the SHA1 hash size.");
         mozilla::SHA1Sum::Hash hash;
         mozilla::SHA1Sum sha1Sum;
         sha1Sum.update(bytecode.begin(), bytecode.length());
         sha1Sum.finish(hash);
         memcpy(metadata_->debugHash, hash, sizeof(ModuleHash));
     }
 
-    return true;
+    MOZ_ASSERT_IF(env_->nameCustomSectionIndex, !!metadata_->namePayload);
+
+    // Metadata shouldn't be mutably modified after finishMetadata().
+    SharedMetadata metadata = metadata_;
+    metadata_ = nullptr;
+    return metadata;
 }
 
 SharedModule
 ModuleGenerator::finishModule(const ShareableBytes& bytecode,
                               JS::OptimizedEncodingListener* maybeTier2Listener,
                               UniqueLinkData* maybeLinkDataOut)
 {
     MOZ_ASSERT(mode() == CompileMode::Once || mode() == CompileMode::Tier1);
@@ -1041,33 +1046,16 @@ ModuleGenerator::finishModule(const Shar
         return nullptr;
     }
 
     JumpTables jumpTables;
     if (!jumpTables.init(mode(), codeTier->segment(), codeTier->metadata().codeRanges)) {
         return nullptr;
     }
 
-    if (!finishMetadata(bytecode.bytes)) {
-        return nullptr;
-    }
-
-    StructTypeVector structTypes;
-    for (TypeDef& td : env_->types) {
-        if (td.isStructType() && !structTypes.append(std::move(td.structType()))) {
-            return nullptr;
-        }
-    }
-
-    MutableCode code = js_new<Code>(std::move(codeTier), *metadata_, std::move(jumpTables),
-                                    std::move(structTypes));
-    if (!code || !code->initialize(*linkData_)) {
-        return nullptr;
-    }
-
     // Copy over data from the Bytecode, which is going away at the end of
     // compilation.
 
     DataSegmentVector dataSegments;
     if (!dataSegments.reserve(env_->dataSegments.length())) {
         return nullptr;
     }
     for (const DataSegmentEnv& srcSeg : env_->dataSegments) {
@@ -1100,16 +1088,34 @@ ModuleGenerator::finishModule(const Shar
         sec.payload = std::move(payload);
         customSections.infallibleAppend(std::move(sec));
     }
 
     if (env_->nameCustomSectionIndex) {
         metadata_->namePayload = customSections[*env_->nameCustomSectionIndex].payload;
     }
 
+    SharedMetadata metadata = finishMetadata(bytecode.bytes);
+    if (!metadata) {
+        return nullptr;
+    }
+
+    StructTypeVector structTypes;
+    for (TypeDef& td : env_->types) {
+        if (td.isStructType() && !structTypes.append(std::move(td.structType()))) {
+            return nullptr;
+        }
+    }
+
+    MutableCode code = js_new<Code>(std::move(codeTier), *metadata, std::move(jumpTables),
+                                    std::move(structTypes));
+    if (!code || !code->initialize(*linkData_)) {
+        return nullptr;
+    }
+
     // See Module debugCodeClaimed_ comments for why we need to make a separate
     // debug copy.
 
     UniqueBytes debugUnlinkedCode;
     UniqueLinkData debugLinkData;
     const ShareableBytes* debugBytecode = nullptr;
     if (env_->debugEnabled()) {
         MOZ_ASSERT(mode() == CompileMode::Once);
--- a/js/src/wasm/WasmGenerator.h
+++ b/js/src/wasm/WasmGenerator.h
@@ -197,17 +197,17 @@ class MOZ_STACK_CLASS ModuleGenerator
     void noteCodeRange(uint32_t codeRangeIndex, const CodeRange& codeRange);
     bool linkCompiledCode(const CompiledCode& code);
     bool finishTask(CompileTask* task);
     bool launchBatchCompile();
     bool finishOutstandingTask();
     bool finishCodegen();
     bool finishMetadataTier();
     UniqueCodeTier finishCodeTier();
-    bool finishMetadata(const Bytes& bytecode);
+    SharedMetadata finishMetadata(const Bytes& bytecode);
 
     bool isAsmJS() const { return env_->isAsmJS(); }
     Tier tier() const { return env_->tier(); }
     CompileMode mode() const { return env_->mode(); }
     bool debugEnabled() const { return env_->debugEnabled(); }
 
   public:
     ModuleGenerator(const CompileArgs& args, ModuleEnvironment* env,