tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WasmModule.h (8436B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 *
      4 * Copyright 2015 Mozilla Foundation
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *     http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 #ifndef wasm_module_h
     20 #define wasm_module_h
     21 
     22 #include "js/WasmModule.h"
     23 #include "js/BuildId.h"
     24 
     25 #include "wasm/WasmCode.h"
     26 #include "wasm/WasmException.h"
     27 #include "wasm/WasmJS.h"
     28 #include "wasm/WasmSerialize.h"
     29 #include "wasm/WasmTable.h"
     30 
     31 using mozilla::Maybe;
     32 
     33 namespace JS {
     34 class OptimizedEncodingListener;
     35 }
     36 
     37 namespace js {
     38 namespace wasm {
     39 
     40 struct CompileArgs;
     41 
     42 // In the context of wasm, the OptimizedEncodingListener specifically is
     43 // listening for the completion of complete tier-2.
     44 
     45 using CompleteTier2Listener = RefPtr<JS::OptimizedEncodingListener>;
     46 
     47 // Report tier-2 compilation results off-thread.  If `maybeFuncIndex` is
     48 // `Some`, this report is for a partial tier-2 compilation of the specified
     49 // function.  Otherwise it's for a complete tier-2 compilation.
     50 
     51 void ReportTier2ResultsOffThread(bool cancelled, bool success,
     52                                 Maybe<uint32_t> maybeFuncIndex,
     53                                 const ScriptedCaller& scriptedCaller,
     54                                 const UniqueChars& error,
     55                                 const UniqueCharsVector& warnings);
     56 
     57 // A struct containing the typed, imported values that are harvested from the
     58 // import object and passed to Module::instantiate(). This struct must be
     59 // stored in a (Persistent)Rooted, not in the heap due to its use of TraceRoot()
     60 // and complete lack of barriers.
     61 
     62 struct ImportValues {
     63  JSObjectVector funcs;
     64  WasmTableObjectVector tables;
     65  WasmMemoryObjectVector memories;
     66  WasmTagObjectVector tagObjs;
     67  WasmGlobalObjectVector globalObjs;
     68  ValVector globalValues;
     69 
     70  ImportValues() {}
     71 
     72  void trace(JSTracer* trc) {
     73    funcs.trace(trc);
     74    tables.trace(trc);
     75    memories.trace(trc);
     76    tagObjs.trace(trc);
     77    globalObjs.trace(trc);
     78    globalValues.trace(trc);
     79  }
     80 };
     81 
     82 // Module represents a compiled wasm module and primarily provides three
     83 // operations: instantiation, tiered compilation, serialization. A Module can be
     84 // instantiated any number of times to produce new Instance objects. A Module
     85 // can have a single tier-2 task initiated to augment a Module's code with a
     86 // higher tier. A Module can have its optimized code serialized at any point
     87 // where the LinkData is also available, which is primarily (1) at the end of
     88 // module generation, (2) at the end of tier-2 compilation.
     89 //
     90 // Fully linked-and-instantiated code (represented by SharedCode) can be shared
     91 // between instances.
     92 
     93 class Module : public JS::WasmModule {
     94  // This has the same lifetime end as Module itself -- it can be dropped when
     95  // Module itself is dropped.
     96  const SharedModuleMetadata moduleMeta_;
     97 
     98  // This contains all compilation artifacts for the module.
     99  const SharedCode code_;
    100 
    101  // This field is set during complete tier-2 compilation and cleared on
    102  // success or failure. These happen on different threads and are serialized
    103  // by the control flow of helper tasks.
    104 
    105  mutable CompleteTier2Listener completeTier2Listener_;
    106 
    107  // This flag is used for logging (and testing) purposes to indicate
    108  // whether the module was deserialized (from a cache).
    109 
    110  const bool loggingDeserialized_;
    111 
    112  // This flag is only used for testing purposes and is cleared on success or
    113  // failure. The field is racily polled from various threads.
    114 
    115  mutable mozilla::Atomic<bool> testingTier2Active_;
    116 
    117  // Cached malloc allocation size for GC memory tracking.
    118 
    119  size_t gcMallocBytesExcludingCode_;
    120 
    121  bool instantiateFunctions(JSContext* cx,
    122                            const JSObjectVector& funcImports) const;
    123  bool instantiateMemories(
    124      JSContext* cx, const WasmMemoryObjectVector& memoryImports,
    125      MutableHandle<WasmMemoryObjectVector> memoryObjs) const;
    126  bool instantiateTags(JSContext* cx, WasmTagObjectVector& tagObjs) const;
    127  bool instantiateImportedTable(JSContext* cx, const TableDesc& td,
    128                                Handle<WasmTableObject*> table,
    129                                WasmTableObjectVector* tableObjs,
    130                                SharedTableVector* tables) const;
    131  bool instantiateLocalTable(JSContext* cx, const TableDesc& td,
    132                             WasmTableObjectVector* tableObjs,
    133                             SharedTableVector* tables) const;
    134  bool instantiateTables(JSContext* cx,
    135                         const WasmTableObjectVector& tableImports,
    136                         MutableHandle<WasmTableObjectVector> tableObjs,
    137                         SharedTableVector* tables) const;
    138  bool instantiateGlobals(JSContext* cx, const ValVector& globalImportValues,
    139                          WasmGlobalObjectVector& globalObjs) const;
    140 
    141  class CompleteTier2GeneratorTaskImpl;
    142 
    143 public:
    144  class PartialTier2CompileTaskImpl;
    145 
    146  Module(const ModuleMetadata& moduleMeta, const Code& code,
    147         bool loggingDeserialized = false)
    148      : moduleMeta_(&moduleMeta),
    149        code_(&code),
    150        loggingDeserialized_(loggingDeserialized),
    151        testingTier2Active_(false) {
    152    initGCMallocBytesExcludingCode();
    153  }
    154  ~Module() override;
    155 
    156  const Code& code() const { return *code_; }
    157  const ModuleMetadata& moduleMeta() const { return *moduleMeta_; }
    158  const CodeMetadata& codeMeta() const { return code_->codeMeta(); }
    159  const CodeTailMetadata& codeTailMeta() const { return code_->codeTailMeta(); }
    160  const CodeMetadataForAsmJS* codeMetaForAsmJS() const {
    161    return code_->codeMetaForAsmJS();
    162  }
    163  const BytecodeSource& debugBytecode() const {
    164    return codeTailMeta().debugBytecode.source();
    165  }
    166  uint32_t tier1CodeMemoryUsed() const { return code_->tier1CodeMemoryUsed(); }
    167 
    168  // Instantiate this module with the given imports:
    169 
    170  bool instantiate(JSContext* cx, ImportValues& imports,
    171                   HandleObject instanceProto,
    172                   MutableHandle<WasmInstanceObject*> instanceObj) const;
    173 
    174  // Tier-2 compilation may be initiated after the Module is constructed at
    175  // most once. When tier-2 compilation completes, ModuleGenerator calls
    176  // finishTier2() from a helper thread, passing tier-variant data which will
    177  // be installed and made visible.
    178 
    179  void startTier2(const ShareableBytes* codeSection,
    180                  JS::OptimizedEncodingListener* listener);
    181  bool finishTier2(UniqueCodeBlock tier2CodeBlock, UniqueLinkData tier2LinkData,
    182                   const CompileAndLinkStats& tier2Stats) const;
    183 
    184  void testingBlockOnTier2Complete() const;
    185  bool testingTier2Active() const { return testingTier2Active_; }
    186 
    187  // Code caching support.
    188 
    189  bool canSerialize() const;
    190  [[nodiscard]] bool serialize(Bytes* bytes) const;
    191  static RefPtr<Module> deserialize(const uint8_t* begin, size_t size);
    192  bool loggingDeserialized() const { return loggingDeserialized_; }
    193 
    194  // JS API and JS::WasmModule implementation:
    195 
    196  JSObject* createObject(JSContext* cx) const override;
    197  JSObject* createObjectForAsmJS(JSContext* cx) const override;
    198 
    199  // about:memory reporting:
    200 
    201  void addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf,
    202                     CodeMetadata::SeenSet* seenCodeMeta,
    203                     CodeMetadataForAsmJS::SeenSet* seenCodeMetaForAsmJS,
    204                     Code::SeenSet* seenCode, size_t* code, size_t* data) const;
    205 
    206  // GC malloc memory tracking:
    207 
    208  void initGCMallocBytesExcludingCode();
    209  size_t gcMallocBytesExcludingCode() const {
    210    return gcMallocBytesExcludingCode_;
    211  }
    212 
    213  // Generated code analysis support:
    214 
    215  bool extractCode(JSContext* cx, Tier tier, MutableHandleValue vp) const;
    216 
    217  WASM_DECLARE_FRIEND_SERIALIZE(Module);
    218 };
    219 
    220 using MutableModule = RefPtr<Module>;
    221 using SharedModule = RefPtr<const Module>;
    222 
    223 // JS API implementations:
    224 
    225 [[nodiscard]] bool GetOptimizedEncodingBuildId(JS::BuildIdCharVector* buildId);
    226 
    227 }  // namespace wasm
    228 }  // namespace js
    229 
    230 #endif  // wasm_module_h