LCOV - code coverage report
Current view: top level - js/src/wasm - WasmModule.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 30 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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/TypeDecls.h"
      23             : 
      24             : #include "wasm/WasmCode.h"
      25             : #include "wasm/WasmTable.h"
      26             : 
      27             : namespace js {
      28             : namespace wasm {
      29             : 
      30             : // LinkData contains all the metadata necessary to patch all the locations
      31             : // that depend on the absolute address of a CodeSegment.
      32             : //
      33             : // LinkData is built incrementing by ModuleGenerator and then stored immutably
      34             : // in Module.
      35             : 
      36             : struct LinkDataTierCacheablePod
      37             : {
      38             :     uint32_t functionCodeLength;
      39             :     uint32_t interruptOffset;
      40             :     uint32_t outOfBoundsOffset;
      41             :     uint32_t unalignedAccessOffset;
      42             : 
      43           0 :     LinkDataTierCacheablePod() { mozilla::PodZero(this); }
      44             : };
      45             : 
      46           0 : struct LinkDataTier : LinkDataTierCacheablePod
      47             : {
      48             :     const Tier tier;
      49             : 
      50           0 :     explicit LinkDataTier(Tier tier)
      51           0 :       : tier(tier)
      52             :     {
      53           0 :         MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
      54           0 :     }
      55             : 
      56           0 :     LinkDataTierCacheablePod& pod() { return *this; }
      57           0 :     const LinkDataTierCacheablePod& pod() const { return *this; }
      58             : 
      59             :     struct InternalLink {
      60             :         enum Kind {
      61             :             RawPointer,
      62             :             CodeLabel,
      63             :             InstructionImmediate
      64             :         };
      65             :         MOZ_INIT_OUTSIDE_CTOR uint32_t patchAtOffset;
      66             :         MOZ_INIT_OUTSIDE_CTOR uint32_t targetOffset;
      67             : 
      68             :         InternalLink() = default;
      69             :         explicit InternalLink(Kind kind);
      70             :         bool isRawPointerPatch();
      71             :     };
      72             :     typedef Vector<InternalLink, 0, SystemAllocPolicy> InternalLinkVector;
      73             : 
      74           0 :     struct SymbolicLinkArray : EnumeratedArray<SymbolicAddress, SymbolicAddress::Limit, Uint32Vector> {
      75             :         WASM_DECLARE_SERIALIZABLE(SymbolicLinkArray)
      76             :     };
      77             : 
      78             :     InternalLinkVector  internalLinks;
      79             :     SymbolicLinkArray   symbolicLinks;
      80             : 
      81             :     WASM_DECLARE_SERIALIZABLE(LinkData)
      82             : };
      83             : 
      84             : typedef UniquePtr<LinkDataTier> UniqueLinkDataTier;
      85             : 
      86           0 : struct LinkData
      87             : {
      88             :     // `tier_` will become more complicated once tiering is implemented.
      89             :     UniqueLinkDataTier tier_;
      90             : 
      91           0 :     LinkData() : tier_(nullptr) {}
      92             : 
      93             :     // Construct the tier_ object.
      94             :     bool initTier(Tier tier);
      95             : 
      96             :     Tiers tiers() const;
      97             :     const LinkDataTier& linkData(Tier tier) const;
      98             :     LinkDataTier& linkData(Tier tier);
      99             : 
     100             :     WASM_DECLARE_SERIALIZABLE(LinkData)
     101             : };
     102             : 
     103             : // Module represents a compiled wasm module and primarily provides two
     104             : // operations: instantiation and serialization. A Module can be instantiated any
     105             : // number of times to produce new Instance objects. A Module can be serialized
     106             : // any number of times such that the serialized bytes can be deserialized later
     107             : // to produce a new, equivalent Module.
     108             : //
     109             : // Fully linked-and-instantiated code (represented by Code and its owned
     110             : // CodeSegment) can be shared between instances, provided none of those
     111             : // instances are being debugged. If patchable code is needed then each instance
     112             : // must have its own Code. Module eagerly creates a new Code and gives it to the
     113             : // first instance; it then instantiates new Code objects from a copy of the
     114             : // unlinked code that it keeps around for that purpose.
     115             : 
     116             : class Module : public JS::WasmModule
     117             : {
     118             :     const Assumptions       assumptions_;
     119             :     const SharedCode        code_;
     120             :     const UniqueConstBytes  unlinkedCodeForDebugging_;
     121             :     const LinkData          linkData_;
     122             :     const ImportVector      imports_;
     123             :     const ExportVector      exports_;
     124             :     const DataSegmentVector dataSegments_;
     125             :     const ElemSegmentVector elemSegments_;
     126             :     const SharedBytes       bytecode_;
     127             : 
     128             :     // `codeIsBusy_` is set to false initially and then to true when `code_` is
     129             :     // already being used for an instance and can't be shared because it may be
     130             :     // patched by the debugger. Subsequent instances must then create copies
     131             :     // by linking the `unlinkedCodeForDebugging_`.
     132             : 
     133             :     mutable mozilla::Atomic<bool> codeIsBusy_;
     134             : 
     135             :     bool instantiateFunctions(JSContext* cx, Handle<FunctionVector> funcImports) const;
     136             :     bool instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) const;
     137             :     bool instantiateTable(JSContext* cx,
     138             :                           MutableHandleWasmTableObject table,
     139             :                           SharedTableVector* tables) const;
     140             :     bool initSegments(JSContext* cx,
     141             :                       HandleWasmInstanceObject instance,
     142             :                       Handle<FunctionVector> funcImports,
     143             :                       HandleWasmMemoryObject memory,
     144             :                       const ValVector& globalImports) const;
     145             : 
     146             :   public:
     147           0 :     Module(Assumptions&& assumptions,
     148             :            const Code& code,
     149             :            UniqueConstBytes unlinkedCodeForDebugging,
     150             :            LinkData&& linkData,
     151             :            ImportVector&& imports,
     152             :            ExportVector&& exports,
     153             :            DataSegmentVector&& dataSegments,
     154             :            ElemSegmentVector&& elemSegments,
     155             :            const ShareableBytes& bytecode)
     156           0 :       : assumptions_(Move(assumptions)),
     157             :         code_(&code),
     158           0 :         unlinkedCodeForDebugging_(Move(unlinkedCodeForDebugging)),
     159           0 :         linkData_(Move(linkData)),
     160           0 :         imports_(Move(imports)),
     161           0 :         exports_(Move(exports)),
     162           0 :         dataSegments_(Move(dataSegments)),
     163           0 :         elemSegments_(Move(elemSegments)),
     164             :         bytecode_(&bytecode),
     165           0 :         codeIsBusy_(false)
     166             :     {
     167           0 :         MOZ_ASSERT_IF(metadata().debugEnabled, unlinkedCodeForDebugging_);
     168           0 :     }
     169           0 :     ~Module() override { /* Note: can be called on any thread */ }
     170             : 
     171           0 :     const Code& code() const { return *code_; }
     172           0 :     const Metadata& metadata() const { return code_->metadata(); }
     173           0 :     const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
     174           0 :     const ImportVector& imports() const { return imports_; }
     175           0 :     const ExportVector& exports() const { return exports_; }
     176           0 :     const Bytes& bytecode() const { return bytecode_->bytes; }
     177           0 :     uint32_t codeLength(Tier t) const { return code_->segment(t).length(); }
     178             : 
     179             :     // Instantiate this module with the given imports:
     180             : 
     181             :     bool instantiate(JSContext* cx,
     182             :                      Handle<FunctionVector> funcImports,
     183             :                      HandleWasmTableObject tableImport,
     184             :                      HandleWasmMemoryObject memoryImport,
     185             :                      const ValVector& globalImports,
     186             :                      HandleObject instanceProto,
     187             :                      MutableHandleWasmInstanceObject instanceObj) const;
     188             : 
     189             :     // Structured clone support:
     190             : 
     191             :     void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const override;
     192             :     void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize,
     193             :                    uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const override;
     194             :     static bool assumptionsMatch(const Assumptions& current, const uint8_t* compiledBegin,
     195             :                                  size_t remain);
     196             :     static RefPtr<Module> deserialize(const uint8_t* bytecodeBegin, size_t bytecodeSize,
     197             :                                       const uint8_t* compiledBegin, size_t compiledSize,
     198             :                                       Metadata* maybeMetadata = nullptr);
     199             :     JSObject* createObject(JSContext* cx) override;
     200             : 
     201             :     // about:memory reporting:
     202             : 
     203             :     void addSizeOfMisc(MallocSizeOf mallocSizeOf,
     204             :                        Metadata::SeenSet* seenMetadata,
     205             :                        ShareableBytes::SeenSet* seenBytes,
     206             :                        Code::SeenSet* seenCode,
     207             :                        size_t* code, size_t* data) const;
     208             : 
     209             :     // Generated code analysis support:
     210             : 
     211             :     bool extractCode(JSContext* cx, MutableHandleValue vp) const;
     212             : };
     213             : 
     214             : typedef RefPtr<Module> SharedModule;
     215             : 
     216             : // JS API implementations:
     217             : 
     218             : bool
     219             : CompiledModuleAssumptionsMatch(PRFileDesc* compiled, JS::BuildIdCharVector&& buildId);
     220             : 
     221             : SharedModule
     222             : DeserializeModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, JS::BuildIdCharVector&& buildId,
     223             :                   UniqueChars filename, unsigned line, unsigned column);
     224             : 
     225             : } // namespace wasm
     226             : } // namespace js
     227             : 
     228             : #endif // wasm_module_h

Generated by: LCOV version 1.13