LCOV - code coverage report
Current view: top level - js/src/wasm - WasmGenerator.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 102 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 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_generator_h
      20             : #define wasm_generator_h
      21             : 
      22             : #include "jit/MacroAssembler.h"
      23             : #include "wasm/WasmModule.h"
      24             : #include "wasm/WasmValidate.h"
      25             : 
      26             : namespace js {
      27             : namespace wasm {
      28             : 
      29             : struct ModuleEnvironment;
      30             : 
      31             : typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
      32             : typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
      33             : typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
      34             : 
      35             : struct CompileArgs;
      36             : 
      37             : class FunctionGenerator;
      38             : 
      39             : // The FuncBytes class represents a single, concurrently-compilable function.
      40             : // A FuncBytes object is composed of the wasm function body bytes along with the
      41             : // ambient metadata describing the function necessary to compile it.
      42             : 
      43           0 : class FuncBytes
      44             : {
      45             :     Bytes            bytes_;
      46             :     uint32_t         index_;
      47             :     const SigWithId* sig_;
      48             :     uint32_t         lineOrBytecode_;
      49             :     Uint32Vector     callSiteLineNums_;
      50             : 
      51             :   public:
      52           0 :     FuncBytes()
      53           0 :       : index_(UINT32_MAX),
      54             :         sig_(nullptr),
      55           0 :         lineOrBytecode_(UINT32_MAX)
      56           0 :     {}
      57             : 
      58           0 :     Bytes& bytes() {
      59           0 :         return bytes_;
      60             :     }
      61           0 :     MOZ_MUST_USE bool addCallSiteLineNum(uint32_t lineno) {
      62           0 :         return callSiteLineNums_.append(lineno);
      63             :     }
      64           0 :     void setLineOrBytecode(uint32_t lineOrBytecode) {
      65           0 :         MOZ_ASSERT(lineOrBytecode_ == UINT32_MAX);
      66           0 :         lineOrBytecode_ = lineOrBytecode;
      67           0 :     }
      68           0 :     void setFunc(uint32_t index, const SigWithId* sig) {
      69           0 :         MOZ_ASSERT(index_ == UINT32_MAX);
      70           0 :         MOZ_ASSERT(sig_ == nullptr);
      71           0 :         index_ = index;
      72           0 :         sig_ = sig;
      73           0 :     }
      74           0 :     void reset() {
      75           0 :         bytes_.clear();
      76           0 :         index_ = UINT32_MAX;
      77           0 :         sig_ = nullptr;
      78           0 :         lineOrBytecode_ = UINT32_MAX;
      79           0 :         callSiteLineNums_.clear();
      80           0 :     }
      81             : 
      82           0 :     const Bytes& bytes() const { return bytes_; }
      83           0 :     uint32_t index() const { return index_; }
      84           0 :     const SigWithId& sig() const { return *sig_; }
      85           0 :     uint32_t lineOrBytecode() const { return lineOrBytecode_; }
      86           0 :     const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
      87             : };
      88             : 
      89             : typedef UniquePtr<FuncBytes> UniqueFuncBytes;
      90             : typedef Vector<UniqueFuncBytes, 8, SystemAllocPolicy> UniqueFuncBytesVector;
      91             : 
      92             : // FuncCompileUnit contains all the data necessary to produce and store the
      93             : // results of a single function's compilation.
      94             : 
      95           0 : class FuncCompileUnit
      96             : {
      97             :     UniqueFuncBytes func_;
      98             :     FuncOffsets offsets_;
      99             :     DebugOnly<bool> finished_;
     100             : 
     101             :   public:
     102           0 :     explicit FuncCompileUnit(UniqueFuncBytes func)
     103           0 :       : func_(Move(func)),
     104           0 :         finished_(false)
     105           0 :     {}
     106             : 
     107           0 :     const FuncBytes& func() const { return *func_; }
     108           0 :     FuncOffsets offsets() const { MOZ_ASSERT(finished_); return offsets_; }
     109             : 
     110           0 :     void finish(FuncOffsets offsets) {
     111           0 :         MOZ_ASSERT(!finished_);
     112           0 :         offsets_ = offsets;
     113           0 :         finished_ = true;
     114           0 :     }
     115             : 
     116           0 :     UniqueFuncBytes recycle() {
     117           0 :         MOZ_ASSERT(finished_);
     118           0 :         func_->reset();
     119           0 :         return Move(func_);
     120             :     }
     121             : };
     122             : 
     123             : typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
     124             : 
     125             : // A CompileTask represents the task of compiling a batch of functions. It is
     126             : // filled with a certain number of function's bodies that are sent off to a
     127             : // compilation helper thread, which fills in the resulting code offsets, and
     128             : // finally sent back to the validation thread. To save time allocating and
     129             : // freeing memory, CompileTasks are reset() and reused.
     130             : 
     131           0 : class CompileTask
     132             : {
     133             :     const ModuleEnvironment&   env_;
     134             :     Tier                       tier_;
     135             :     LifoAlloc                  lifo_;
     136             :     Maybe<jit::TempAllocator>  alloc_;
     137             :     Maybe<jit::MacroAssembler> masm_;
     138             :     FuncCompileUnitVector      units_;
     139             :     bool                       debugEnabled_;
     140             : 
     141             :     CompileTask(const CompileTask&) = delete;
     142             :     CompileTask& operator=(const CompileTask&) = delete;
     143             : 
     144           0 :     void init() {
     145           0 :         alloc_.emplace(&lifo_);
     146           0 :         masm_.emplace(jit::MacroAssembler::WasmToken(), *alloc_);
     147           0 :         debugEnabled_ = false;
     148           0 :     }
     149             : 
     150             :   public:
     151           0 :     CompileTask(const ModuleEnvironment& env, Tier tier, size_t defaultChunkSize)
     152           0 :       : env_(env),
     153             :         tier_(tier),
     154           0 :         lifo_(defaultChunkSize)
     155             :     {
     156           0 :         MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
     157           0 :         init();
     158           0 :     }
     159             :     LifoAlloc& lifo() {
     160             :         return lifo_;
     161             :     }
     162           0 :     jit::TempAllocator& alloc() {
     163           0 :         return *alloc_;
     164             :     }
     165           0 :     const ModuleEnvironment& env() const {
     166           0 :         return env_;
     167             :     }
     168           0 :     jit::MacroAssembler& masm() {
     169           0 :         return *masm_;
     170             :     }
     171           0 :     FuncCompileUnitVector& units() {
     172           0 :         return units_;
     173             :     }
     174           0 :     Tier tier() const {
     175           0 :         return tier_;
     176             :     }
     177           0 :     bool debugEnabled() const {
     178           0 :         return debugEnabled_;
     179             :     }
     180           0 :     void setDebugEnabled(bool enabled) {
     181           0 :         debugEnabled_ = enabled;
     182           0 :     }
     183           0 :     bool reset(UniqueFuncBytesVector* freeFuncBytes) {
     184           0 :         for (FuncCompileUnit& unit : units_) {
     185           0 :             if (!freeFuncBytes->emplaceBack(Move(unit.recycle())))
     186           0 :                 return false;
     187             :         }
     188             : 
     189           0 :         units_.clear();
     190           0 :         masm_.reset();
     191           0 :         alloc_.reset();
     192           0 :         lifo_.releaseAll();
     193             : 
     194           0 :         init();
     195           0 :         return true;
     196             :     }
     197             : };
     198             : 
     199             : // A ModuleGenerator encapsulates the creation of a wasm module. During the
     200             : // lifetime of a ModuleGenerator, a sequence of FunctionGenerators are created
     201             : // and destroyed to compile the individual function bodies. After generating all
     202             : // functions, ModuleGenerator::finish() must be called to complete the
     203             : // compilation and extract the resulting wasm module.
     204             : 
     205             : class MOZ_STACK_CLASS ModuleGenerator
     206             : {
     207             :     typedef HashSet<uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy> Uint32Set;
     208             :     typedef Vector<CompileTask, 0, SystemAllocPolicy> CompileTaskVector;
     209             :     typedef Vector<CompileTask*, 0, SystemAllocPolicy> CompileTaskPtrVector;
     210             :     typedef EnumeratedArray<Trap, Trap::Limit, CallableOffsets> TrapExitOffsetArray;
     211             : 
     212             :     // Constant parameters
     213             :     Tier                            tier_;
     214             :     UniqueChars*                    error_;
     215             : 
     216             :     // Data that is moved into the result of finish()
     217             :     Assumptions                     assumptions_;
     218             :     LinkDataTier*                   linkDataTier_; // Owned by linkData_
     219             :     LinkData                        linkData_;
     220             :     MetadataTier*                   metadataTier_; // Owned by metadata_
     221             :     MutableMetadata                 metadata_;
     222             : 
     223             :     // Data scoped to the ModuleGenerator's lifetime
     224             :     UniqueModuleEnvironment         env_;
     225             :     uint32_t                        numSigs_;
     226             :     uint32_t                        numTables_;
     227             :     LifoAlloc                       lifo_;
     228             :     jit::JitContext                 jcx_;
     229             :     jit::TempAllocator              masmAlloc_;
     230             :     jit::MacroAssembler             masm_;
     231             :     Uint32Vector                    funcToCodeRange_;
     232             :     Uint32Set                       exportedFuncs_;
     233             :     uint32_t                        lastPatchedCallsite_;
     234             :     uint32_t                        startOfUnpatchedCallsites_;
     235             :     Uint32Vector                    debugTrapFarJumps_;
     236             :     FuncArgTypesVector              debugFuncArgTypes_;
     237             :     FuncReturnTypesVector           debugFuncReturnTypes_;
     238             : 
     239             :     // Parallel compilation
     240             :     bool                            parallel_;
     241             :     uint32_t                        outstanding_;
     242             :     CompileTaskVector               tasks_;
     243             :     CompileTaskPtrVector            freeTasks_;
     244             :     UniqueFuncBytesVector           freeFuncBytes_;
     245             :     CompileTask*                    currentTask_;
     246             :     uint32_t                        batchedBytecode_;
     247             : 
     248             :     // Assertions
     249             :     DebugOnly<FunctionGenerator*>   activeFuncDef_;
     250             :     DebugOnly<bool>                 startedFuncDefs_;
     251             :     DebugOnly<bool>                 finishedFuncDefs_;
     252             :     DebugOnly<uint32_t>             numFinishedFuncDefs_;
     253             : 
     254             :     bool funcIsCompiled(uint32_t funcIndex) const;
     255             :     const CodeRange& funcCodeRange(uint32_t funcIndex) const;
     256             :     uint32_t numFuncImports() const;
     257             :     MOZ_MUST_USE bool patchCallSites();
     258             :     MOZ_MUST_USE bool patchFarJumps(const TrapExitOffsetArray& trapExits, const Offsets& debugTrapStub);
     259             :     MOZ_MUST_USE bool finishTask(CompileTask* task);
     260             :     MOZ_MUST_USE bool finishOutstandingTask();
     261             :     MOZ_MUST_USE bool finishFuncExports();
     262             :     MOZ_MUST_USE bool finishCodegen();
     263             :     MOZ_MUST_USE bool finishLinkData();
     264             :     void generateBytecodeHash(const ShareableBytes& bytecode);
     265             :     MOZ_MUST_USE bool addFuncImport(const Sig& sig, uint32_t globalDataOffset);
     266             :     MOZ_MUST_USE bool allocateGlobalBytes(uint32_t bytes, uint32_t align, uint32_t* globalDataOff);
     267             :     MOZ_MUST_USE bool allocateGlobal(GlobalDesc* global);
     268             : 
     269             :     MOZ_MUST_USE bool launchBatchCompile();
     270             : 
     271             :     MOZ_MUST_USE bool initAsmJS(Metadata* asmJSMetadata);
     272             :     MOZ_MUST_USE bool initWasm(const CompileArgs& args);
     273             : 
     274             :   public:
     275             :     explicit ModuleGenerator(UniqueChars* error);
     276             :     ~ModuleGenerator();
     277             : 
     278             :     MOZ_MUST_USE bool init(UniqueModuleEnvironment env, const CompileArgs& args,
     279             :                            Metadata* maybeAsmJSMetadata = nullptr);
     280             : 
     281           0 :     const ModuleEnvironment& env() const { return *env_; }
     282             :     ModuleEnvironment& mutableEnv();
     283             : 
     284           0 :     bool isAsmJS() const { return metadata_->kind == ModuleKind::AsmJS; }
     285             :     jit::MacroAssembler& masm() { return masm_; }
     286             : 
     287             :     // Memory:
     288             :     bool usesMemory() const { return env_->usesMemory(); }
     289           0 :     uint32_t minMemoryLength() const { return env_->minMemoryLength; }
     290             : 
     291             :     // Tables:
     292             :     uint32_t numTables() const { return numTables_; }
     293             :     const TableDescVector& tables() const { return env_->tables; }
     294             : 
     295             :     // Signatures:
     296           0 :     uint32_t numSigs() const { return numSigs_; }
     297             :     const SigWithId& sig(uint32_t sigIndex) const;
     298             :     const SigWithId& funcSig(uint32_t funcIndex) const;
     299             :     const SigWithIdPtrVector& funcSigs() const { return env_->funcSigs; }
     300             : 
     301             :     // Globals:
     302             :     const GlobalDescVector& globals() const { return env_->globals; }
     303             : 
     304             :     // Function definitions:
     305             :     MOZ_MUST_USE bool startFuncDefs();
     306             :     MOZ_MUST_USE bool startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg);
     307             :     MOZ_MUST_USE bool finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg);
     308             :     MOZ_MUST_USE bool finishFuncDefs();
     309             : 
     310             :     // asm.js lazy initialization:
     311             :     void initSig(uint32_t sigIndex, Sig&& sig);
     312             :     void initFuncSig(uint32_t funcIndex, uint32_t sigIndex);
     313             :     MOZ_MUST_USE bool initImport(uint32_t funcIndex, uint32_t sigIndex);
     314             :     MOZ_MUST_USE bool initSigTableLength(uint32_t sigIndex, uint32_t length);
     315             :     MOZ_MUST_USE bool initSigTableElems(uint32_t sigIndex, Uint32Vector&& elemFuncIndices);
     316             :     void initMemoryUsage(MemoryUsage memoryUsage);
     317             :     void bumpMinMemoryLength(uint32_t newMinMemoryLength);
     318             :     MOZ_MUST_USE bool addGlobal(ValType type, bool isConst, uint32_t* index);
     319             :     MOZ_MUST_USE bool addExport(CacheableChars&& fieldChars, uint32_t funcIndex);
     320             : 
     321             :     // Finish compilation of the given bytecode.
     322             :     SharedModule finish(const ShareableBytes& bytecode);
     323             : };
     324             : 
     325             : // A FunctionGenerator encapsulates the generation of a single function body.
     326             : // ModuleGenerator::startFuncDef must be called after construction and before
     327             : // doing anything else.
     328             : //
     329             : // After the body is complete, ModuleGenerator::finishFuncDef must be called
     330             : // before the FunctionGenerator is destroyed and the next function is started.
     331             : 
     332           0 : class MOZ_STACK_CLASS FunctionGenerator
     333             : {
     334             :     friend class ModuleGenerator;
     335             : 
     336             :     ModuleGenerator* m_;
     337             :     bool             usesSimd_;
     338             :     bool             usesAtomics_;
     339             : 
     340             :     UniqueFuncBytes  funcBytes_;
     341             : 
     342             :   public:
     343           0 :     FunctionGenerator()
     344           0 :       : m_(nullptr), usesSimd_(false), usesAtomics_(false), funcBytes_(nullptr)
     345           0 :     {}
     346             : 
     347             :     bool usesSimd() const {
     348             :         return usesSimd_;
     349             :     }
     350           0 :     void setUsesSimd() {
     351           0 :         usesSimd_ = true;
     352           0 :     }
     353             : 
     354             :     bool usesAtomics() const {
     355             :         return usesAtomics_;
     356             :     }
     357           0 :     void setUsesAtomics() {
     358           0 :         usesAtomics_ = true;
     359           0 :     }
     360             : 
     361             :     bool isAsmJS() const {
     362             :       return m_->isAsmJS();
     363             :     }
     364             : 
     365           0 :     Bytes& bytes() {
     366           0 :         return funcBytes_->bytes();
     367             :     }
     368           0 :     MOZ_MUST_USE bool addCallSiteLineNum(uint32_t lineno) {
     369           0 :         return funcBytes_->addCallSiteLineNum(lineno);
     370             :     }
     371             : };
     372             : 
     373             : } // namespace wasm
     374             : } // namespace js
     375             : 
     376             : #endif // wasm_generator_h

Generated by: LCOV version 1.13