LCOV - code coverage report
Current view: top level - src/compiler - wasm-compiler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 17 17 100.0 %
Date: 2017-04-26 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_COMPILER_WASM_COMPILER_H_
       6             : #define V8_COMPILER_WASM_COMPILER_H_
       7             : 
       8             : #include <memory>
       9             : 
      10             : // Clients of this interface shouldn't depend on lots of compiler internals.
      11             : // Do not include anything from src/compiler here!
      12             : #include "src/compilation-info.h"
      13             : #include "src/compiler.h"
      14             : #include "src/trap-handler/trap-handler.h"
      15             : #include "src/wasm/function-body-decoder.h"
      16             : #include "src/wasm/wasm-module.h"
      17             : #include "src/wasm/wasm-opcodes.h"
      18             : #include "src/wasm/wasm-result.h"
      19             : #include "src/zone/zone.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : namespace compiler {
      25             : // Forward declarations for some compiler data structures.
      26             : class Node;
      27             : class JSGraph;
      28             : class Graph;
      29             : class Operator;
      30             : class SourcePositionTable;
      31             : }  // namespace compiler
      32             : 
      33             : namespace wasm {
      34             : // Forward declarations for some WASM data structures.
      35             : struct ModuleBytesEnv;
      36             : struct ModuleEnv;
      37             : struct WasmFunction;
      38             : struct WasmModule;
      39             : class ErrorThrower;
      40             : struct DecodeStruct;
      41             : 
      42             : // Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
      43             : typedef compiler::Node TFNode;
      44             : typedef compiler::JSGraph TFGraph;
      45             : }  // namespace wasm
      46             : 
      47             : namespace compiler {
      48      142506 : class WasmCompilationUnit final {
      49             :  public:
      50             :   WasmCompilationUnit(Isolate* isolate, wasm::ModuleBytesEnv* module_env,
      51             :                       const wasm::WasmFunction* function);
      52             :   WasmCompilationUnit(Isolate* isolate, wasm::ModuleEnv* module_env,
      53             :                       wasm::FunctionBody body, wasm::WasmName name, int index);
      54             : 
      55             :   Zone* graph_zone() { return graph_zone_.get(); }
      56             :   int func_index() const { return func_index_; }
      57             : 
      58             :   void InitializeHandles();
      59             :   void ExecuteCompilation();
      60             :   Handle<Code> FinishCompilation(wasm::ErrorThrower* thrower);
      61             : 
      62             :   static Handle<Code> CompileWasmFunction(wasm::ErrorThrower* thrower,
      63             :                                           Isolate* isolate,
      64             :                                           wasm::ModuleBytesEnv* module_env,
      65             :                                           const wasm::WasmFunction* function);
      66             : 
      67             :  private:
      68             :   SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
      69             : 
      70             :   Isolate* isolate_;
      71             :   wasm::ModuleEnv* module_env_;
      72             :   wasm::FunctionBody func_body_;
      73             :   wasm::WasmName func_name_;
      74             :   // The graph zone is deallocated at the end of ExecuteCompilation.
      75             :   std::unique_ptr<Zone> graph_zone_;
      76             :   JSGraph* jsgraph_;
      77             :   Zone compilation_zone_;
      78             :   CompilationInfo info_;
      79             :   std::unique_ptr<CompilationJob> job_;
      80             :   int func_index_;
      81             :   wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
      82             :   bool ok_ = true;
      83             : #if DEBUG
      84             :   bool handles_initialized_ = false;
      85             : #endif  // DEBUG
      86             :   ZoneVector<trap_handler::ProtectedInstructionData>
      87             :       protected_instructions_;  // Instructions that are protected by the signal
      88             :                                 // handler.
      89             : 
      90             :   DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit);
      91             : };
      92             : 
      93             : // Wraps a JS function, producing a code object that can be called from WASM.
      94             : Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
      95             :                                     wasm::FunctionSig* sig, uint32_t index,
      96             :                                     Handle<String> module_name,
      97             :                                     MaybeHandle<String> import_name,
      98             :                                     wasm::ModuleOrigin origin);
      99             : 
     100             : // Wraps a given wasm code object, producing a code object.
     101             : Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
     102             :                                     const wasm::WasmModule* module,
     103             :                                     Handle<Code> wasm_code, uint32_t index);
     104             : 
     105             : // Compiles a stub that redirects a call to a wasm function to the wasm
     106             : // interpreter. It's ABI compatible with the compiled wasm function.
     107             : Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index,
     108             :                                          wasm::FunctionSig* sig,
     109             :                                          Handle<WasmInstanceObject> instance);
     110             : 
     111             : // Abstracts details of building TurboFan graph nodes for WASM to separate
     112             : // the WASM decoder from the internal details of TurboFan.
     113             : class WasmTrapHelper;
     114             : typedef ZoneVector<Node*> NodeVector;
     115             : class WasmGraphBuilder {
     116             :  public:
     117             :   WasmGraphBuilder(
     118             :       wasm::ModuleEnv* module_env, Zone* z, JSGraph* g, wasm::FunctionSig* sig,
     119             :       compiler::SourcePositionTable* source_position_table = nullptr);
     120             : 
     121      462295 :   Node** Buffer(size_t count) {
     122      462295 :     if (count > cur_bufsize_) {
     123        1088 :       size_t new_size = count + cur_bufsize_ + 5;
     124             :       cur_buffer_ =
     125        1088 :           reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
     126        1088 :       cur_bufsize_ = new_size;
     127             :     }
     128      462295 :     return cur_buffer_;
     129             :   }
     130             : 
     131             :   //-----------------------------------------------------------------------
     132             :   // Operations independent of {control} or {effect}.
     133             :   //-----------------------------------------------------------------------
     134             :   Node* Error();
     135             :   Node* Start(unsigned params);
     136             :   Node* Param(unsigned index);
     137             :   Node* Loop(Node* entry);
     138             :   Node* Terminate(Node* effect, Node* control);
     139             :   Node* Merge(unsigned count, Node** controls);
     140             :   Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control);
     141             :   Node* EffectPhi(unsigned count, Node** effects, Node* control);
     142             :   Node* NumberConstant(int32_t value);
     143             :   Node* Uint32Constant(uint32_t value);
     144             :   Node* Int32Constant(int32_t value);
     145             :   Node* Int64Constant(int64_t value);
     146             :   Node* Float32Constant(float value);
     147             :   Node* Float64Constant(double value);
     148             :   Node* HeapConstant(Handle<HeapObject> value);
     149             :   Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
     150             :               wasm::WasmCodePosition position = wasm::kNoCodePosition);
     151             :   Node* Unop(wasm::WasmOpcode opcode, Node* input,
     152             :              wasm::WasmCodePosition position = wasm::kNoCodePosition);
     153             :   Node* GrowMemory(Node* input);
     154             :   Node* Throw(Node* input);
     155             :   Node* Catch(Node* input, wasm::WasmCodePosition position);
     156             :   unsigned InputCount(Node* node);
     157             :   bool IsPhiWithMerge(Node* phi, Node* merge);
     158             :   bool ThrowsException(Node* node, Node** if_success, Node** if_exception);
     159             :   void AppendToMerge(Node* merge, Node* from);
     160             :   void AppendToPhi(Node* phi, Node* from);
     161             : 
     162             :   void StackCheck(wasm::WasmCodePosition position, Node** effect = nullptr,
     163             :                   Node** control = nullptr);
     164             : 
     165             :   //-----------------------------------------------------------------------
     166             :   // Operations that read and/or write {control} and {effect}.
     167             :   //-----------------------------------------------------------------------
     168             :   Node* BranchNoHint(Node* cond, Node** true_node, Node** false_node);
     169             :   Node* BranchExpectTrue(Node* cond, Node** true_node, Node** false_node);
     170             :   Node* BranchExpectFalse(Node* cond, Node** true_node, Node** false_node);
     171             : 
     172             :   Node* TrapIfTrue(wasm::TrapReason reason, Node* cond,
     173             :                    wasm::WasmCodePosition position);
     174             :   Node* TrapIfFalse(wasm::TrapReason reason, Node* cond,
     175             :                     wasm::WasmCodePosition position);
     176             :   Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val,
     177             :                    wasm::WasmCodePosition position);
     178             :   Node* ZeroCheck32(wasm::TrapReason reason, Node* node,
     179             :                     wasm::WasmCodePosition position);
     180             :   Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val,
     181             :                    wasm::WasmCodePosition position);
     182             :   Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
     183             :                     wasm::WasmCodePosition position);
     184             : 
     185             :   Node* Switch(unsigned count, Node* key);
     186             :   Node* IfValue(int32_t value, Node* sw);
     187             :   Node* IfDefault(Node* sw);
     188             :   Node* Return(unsigned count, Node** nodes);
     189             :   template <typename... Nodes>
     190             :   Node* Return(Node* fst, Nodes*... more) {
     191       67566 :     Node* arr[] = {fst, more...};
     192       67566 :     return Return(arraysize(arr), arr);
     193             :   }
     194             :   Node* ReturnVoid();
     195             :   Node* Unreachable(wasm::WasmCodePosition position);
     196             : 
     197             :   Node* CallDirect(uint32_t index, Node** args, Node*** rets,
     198             :                    wasm::WasmCodePosition position);
     199             :   Node* CallIndirect(uint32_t index, Node** args, Node*** rets,
     200             :                      wasm::WasmCodePosition position);
     201             : 
     202             :   void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig);
     203             :   void BuildWasmToJSWrapper(Handle<JSReceiver> target, wasm::FunctionSig* sig);
     204             :   void BuildWasmInterpreterEntry(uint32_t func_index, wasm::FunctionSig* sig,
     205             :                                  Handle<WasmInstanceObject> instance);
     206             : 
     207             :   Node* ToJS(Node* node, wasm::ValueType type);
     208             :   Node* FromJS(Node* node, Node* context, wasm::ValueType type);
     209             :   Node* Invert(Node* node);
     210             :   void EnsureFunctionTableNodes();
     211             : 
     212             :   //-----------------------------------------------------------------------
     213             :   // Operations that concern the linear memory.
     214             :   //-----------------------------------------------------------------------
     215             :   Node* CurrentMemoryPages();
     216             :   Node* GetGlobal(uint32_t index);
     217             :   Node* SetGlobal(uint32_t index, Node* val);
     218             :   Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index,
     219             :                 uint32_t offset, uint32_t alignment,
     220             :                 wasm::WasmCodePosition position);
     221             :   Node* StoreMem(MachineType type, Node* index, uint32_t offset,
     222             :                  uint32_t alignment, Node* val,
     223             :                  wasm::WasmCodePosition position);
     224             : 
     225             :   static void PrintDebugName(Node* node);
     226             : 
     227       16600 :   Node* Control() { return *control_; }
     228       16600 :   Node* Effect() { return *effect_; }
     229             : 
     230      743735 :   void set_control_ptr(Node** control) { this->control_ = control; }
     231             : 
     232      743735 :   void set_effect_ptr(Node** effect) { this->effect_ = effect; }
     233             : 
     234             :   wasm::FunctionSig* GetFunctionSignature() { return sig_; }
     235             : 
     236             :   void Int64LoweringForTesting();
     237             : 
     238             :   void SimdScalarLoweringForTesting();
     239             : 
     240             :   void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
     241             : 
     242             :   Node* S128Zero();
     243             :   Node* S1x4Zero();
     244             :   Node* S1x8Zero();
     245             :   Node* S1x16Zero();
     246             : 
     247             :   Node* SimdOp(wasm::WasmOpcode opcode, const NodeVector& inputs);
     248             : 
     249             :   Node* SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane,
     250             :                    const NodeVector& inputs);
     251             : 
     252             :   Node* SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
     253             :                     const NodeVector& inputs);
     254             : 
     255             :   Node* SimdConcatOp(uint8_t bytes, const NodeVector& inputs);
     256             : 
     257             :   bool has_simd() const { return has_simd_; }
     258             : 
     259             :   wasm::ModuleEnv* module_env() const { return module_; }
     260             : 
     261             :  private:
     262             :   static const int kDefaultBufferSize = 16;
     263             :   friend class WasmTrapHelper;
     264             : 
     265             :   Zone* zone_;
     266             :   JSGraph* jsgraph_;
     267             :   wasm::ModuleEnv* module_ = nullptr;
     268             :   Node* mem_buffer_ = nullptr;
     269             :   Node* mem_size_ = nullptr;
     270             :   NodeVector signature_tables_;
     271             :   NodeVector function_tables_;
     272             :   NodeVector function_table_sizes_;
     273             :   Node** control_ = nullptr;
     274             :   Node** effect_ = nullptr;
     275             :   Node** cur_buffer_;
     276             :   size_t cur_bufsize_;
     277             :   Node* def_buffer_[kDefaultBufferSize];
     278             :   bool has_simd_ = false;
     279             : 
     280             :   wasm::FunctionSig* sig_;
     281             :   SetOncePointer<const Operator> allocate_heap_number_operator_;
     282             : 
     283             :   compiler::SourcePositionTable* source_position_table_ = nullptr;
     284             : 
     285             :   // Internal helper methods.
     286             :   JSGraph* jsgraph() { return jsgraph_; }
     287             :   Graph* graph();
     288             : 
     289             :   Node* String(const char* string);
     290             :   Node* MemSize();
     291             :   Node* MemBuffer(uint32_t offset);
     292             :   void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset,
     293             :                       wasm::WasmCodePosition position);
     294             : 
     295             :   Node* BuildChangeEndianness(Node* node, MachineType type,
     296             :                               wasm::ValueType wasmtype = wasm::kWasmStmt);
     297             : 
     298             :   Node* MaskShiftCount32(Node* node);
     299             :   Node* MaskShiftCount64(Node* node);
     300             : 
     301             :   Node* BuildCCall(MachineSignature* sig, Node** args);
     302             :   Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
     303             :                       wasm::WasmCodePosition position);
     304             : 
     305             :   Node* BuildF32CopySign(Node* left, Node* right);
     306             :   Node* BuildF64CopySign(Node* left, Node* right);
     307             :   Node* BuildI32SConvertF32(Node* input, wasm::WasmCodePosition position);
     308             :   Node* BuildI32SConvertF64(Node* input, wasm::WasmCodePosition position);
     309             :   Node* BuildI32UConvertF32(Node* input, wasm::WasmCodePosition position);
     310             :   Node* BuildI32UConvertF64(Node* input, wasm::WasmCodePosition position);
     311             :   Node* BuildI32Ctz(Node* input);
     312             :   Node* BuildI32Popcnt(Node* input);
     313             :   Node* BuildI64Ctz(Node* input);
     314             :   Node* BuildI64Popcnt(Node* input);
     315             :   Node* BuildBitCountingCall(Node* input, ExternalReference ref,
     316             :                              MachineRepresentation input_type);
     317             : 
     318             :   Node* BuildCFuncInstruction(ExternalReference ref, MachineType type,
     319             :                               Node* input0, Node* input1 = nullptr);
     320             :   Node* BuildF32Trunc(Node* input);
     321             :   Node* BuildF32Floor(Node* input);
     322             :   Node* BuildF32Ceil(Node* input);
     323             :   Node* BuildF32NearestInt(Node* input);
     324             :   Node* BuildF64Trunc(Node* input);
     325             :   Node* BuildF64Floor(Node* input);
     326             :   Node* BuildF64Ceil(Node* input);
     327             :   Node* BuildF64NearestInt(Node* input);
     328             :   Node* BuildI32Rol(Node* left, Node* right);
     329             :   Node* BuildI64Rol(Node* left, Node* right);
     330             : 
     331             :   Node* BuildF64Acos(Node* input);
     332             :   Node* BuildF64Asin(Node* input);
     333             :   Node* BuildF64Pow(Node* left, Node* right);
     334             :   Node* BuildF64Mod(Node* left, Node* right);
     335             : 
     336             :   Node* BuildIntToFloatConversionInstruction(
     337             :       Node* input, ExternalReference ref,
     338             :       MachineRepresentation parameter_representation,
     339             :       const MachineType result_type);
     340             :   Node* BuildF32SConvertI64(Node* input);
     341             :   Node* BuildF32UConvertI64(Node* input);
     342             :   Node* BuildF64SConvertI64(Node* input);
     343             :   Node* BuildF64UConvertI64(Node* input);
     344             : 
     345             :   Node* BuildFloatToIntConversionInstruction(
     346             :       Node* input, ExternalReference ref,
     347             :       MachineRepresentation parameter_representation,
     348             :       const MachineType result_type, wasm::WasmCodePosition position);
     349             :   Node* BuildI64SConvertF32(Node* input, wasm::WasmCodePosition position);
     350             :   Node* BuildI64UConvertF32(Node* input, wasm::WasmCodePosition position);
     351             :   Node* BuildI64SConvertF64(Node* input, wasm::WasmCodePosition position);
     352             :   Node* BuildI64UConvertF64(Node* input, wasm::WasmCodePosition position);
     353             : 
     354             :   Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
     355             :   Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
     356             :   Node* BuildI32DivU(Node* left, Node* right, wasm::WasmCodePosition position);
     357             :   Node* BuildI32RemU(Node* left, Node* right, wasm::WasmCodePosition position);
     358             : 
     359             :   Node* BuildI64DivS(Node* left, Node* right, wasm::WasmCodePosition position);
     360             :   Node* BuildI64RemS(Node* left, Node* right, wasm::WasmCodePosition position);
     361             :   Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
     362             :   Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
     363             :   Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
     364             :                        MachineType result_type, int trap_zero,
     365             :                        wasm::WasmCodePosition position);
     366             : 
     367             :   Node* BuildJavaScriptToNumber(Node* node, Node* context);
     368             : 
     369             :   Node* BuildChangeInt32ToTagged(Node* value);
     370             :   Node* BuildChangeFloat64ToTagged(Node* value);
     371             :   Node* BuildChangeTaggedToFloat64(Node* value);
     372             : 
     373             :   Node* BuildChangeInt32ToSmi(Node* value);
     374             :   Node* BuildChangeSmiToInt32(Node* value);
     375             :   Node* BuildChangeUint32ToSmi(Node* value);
     376             :   Node* BuildChangeSmiToFloat64(Node* value);
     377             :   Node* BuildTestNotSmi(Node* value);
     378             :   Node* BuildSmiShiftBitsConstant();
     379             : 
     380             :   Node* BuildAllocateHeapNumberWithValue(Node* value, Node* control);
     381             :   Node* BuildLoadHeapNumberValue(Node* value, Node* control);
     382             :   Node* BuildHeapNumberValueIndexConstant();
     383             : 
     384             :   // Asm.js specific functionality.
     385             :   Node* BuildI32AsmjsSConvertF32(Node* input);
     386             :   Node* BuildI32AsmjsSConvertF64(Node* input);
     387             :   Node* BuildI32AsmjsUConvertF32(Node* input);
     388             :   Node* BuildI32AsmjsUConvertF64(Node* input);
     389             :   Node* BuildI32AsmjsDivS(Node* left, Node* right);
     390             :   Node* BuildI32AsmjsRemS(Node* left, Node* right);
     391             :   Node* BuildI32AsmjsDivU(Node* left, Node* right);
     392             :   Node* BuildI32AsmjsRemU(Node* left, Node* right);
     393             :   Node* BuildAsmjsLoadMem(MachineType type, Node* index);
     394             :   Node* BuildAsmjsStoreMem(MachineType type, Node* index, Node* val);
     395             : 
     396      199692 :   Node** Realloc(Node** buffer, size_t old_count, size_t new_count) {
     397      199692 :     Node** buf = Buffer(new_count);
     398      199698 :     if (buf != buffer) memcpy(buf, buffer, old_count * sizeof(Node*));
     399      199698 :     return buf;
     400             :   }
     401             : 
     402             :   int AddParameterNodes(Node** args, int pos, int param_count,
     403             :                         wasm::FunctionSig* sig);
     404             : };
     405             : }  // namespace compiler
     406             : }  // namespace internal
     407             : }  // namespace v8
     408             : 
     409             : #endif  // V8_COMPILER_WASM_COMPILER_H_

Generated by: LCOV version 1.10