11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#if !V8_ENABLE_WEBASSEMBLY
61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled.
71cb0ef41Sopenharmony_ci#endif  // !V8_ENABLE_WEBASSEMBLY
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef V8_WASM_FUNCTION_COMPILER_H_
101cb0ef41Sopenharmony_ci#define V8_WASM_FUNCTION_COMPILER_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <memory>
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h"
151cb0ef41Sopenharmony_ci#include "src/codegen/code-desc.h"
161cb0ef41Sopenharmony_ci#include "src/trap-handler/trap-handler.h"
171cb0ef41Sopenharmony_ci#include "src/wasm/compilation-environment.h"
181cb0ef41Sopenharmony_ci#include "src/wasm/function-body-decoder.h"
191cb0ef41Sopenharmony_ci#include "src/wasm/wasm-limits.h"
201cb0ef41Sopenharmony_ci#include "src/wasm/wasm-module.h"
211cb0ef41Sopenharmony_ci#include "src/wasm/wasm-tier.h"
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cinamespace v8 {
241cb0ef41Sopenharmony_cinamespace internal {
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciclass Counters;
271cb0ef41Sopenharmony_ciclass TurbofanCompilationJob;
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_cinamespace wasm {
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciclass NativeModule;
321cb0ef41Sopenharmony_ciclass WasmCode;
331cb0ef41Sopenharmony_ciclass WasmEngine;
341cb0ef41Sopenharmony_cistruct WasmFunction;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cistruct WasmCompilationResult {
371cb0ef41Sopenharmony_ci public:
381cb0ef41Sopenharmony_ci  MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  enum Kind : int8_t {
411cb0ef41Sopenharmony_ci    kFunction,
421cb0ef41Sopenharmony_ci    kWasmToJsWrapper,
431cb0ef41Sopenharmony_ci  };
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  bool succeeded() const { return code_desc.buffer != nullptr; }
461cb0ef41Sopenharmony_ci  bool failed() const { return !succeeded(); }
471cb0ef41Sopenharmony_ci  operator bool() const { return succeeded(); }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  CodeDesc code_desc;
501cb0ef41Sopenharmony_ci  std::unique_ptr<AssemblerBuffer> instr_buffer;
511cb0ef41Sopenharmony_ci  uint32_t frame_slot_count = 0;
521cb0ef41Sopenharmony_ci  uint32_t tagged_parameter_slots = 0;
531cb0ef41Sopenharmony_ci  base::OwnedVector<byte> source_positions;
541cb0ef41Sopenharmony_ci  base::OwnedVector<byte> protected_instructions_data;
551cb0ef41Sopenharmony_ci  int func_index = kAnonymousFuncIndex;
561cb0ef41Sopenharmony_ci  ExecutionTier requested_tier;
571cb0ef41Sopenharmony_ci  ExecutionTier result_tier;
581cb0ef41Sopenharmony_ci  Kind kind = kFunction;
591cb0ef41Sopenharmony_ci  ForDebugging for_debugging = kNoDebugging;
601cb0ef41Sopenharmony_ci  int feedback_vector_slots = 0;
611cb0ef41Sopenharmony_ci};
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE WasmCompilationUnit final {
641cb0ef41Sopenharmony_ci public:
651cb0ef41Sopenharmony_ci  static ExecutionTier GetBaselineExecutionTier(const WasmModule*);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
681cb0ef41Sopenharmony_ci      : func_index_(index), tier_(tier), for_debugging_(for_debugging) {}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  WasmCompilationResult ExecuteCompilation(CompilationEnv*,
711cb0ef41Sopenharmony_ci                                           const WireBytesStorage*, Counters*,
721cb0ef41Sopenharmony_ci                                           WasmFeatures* detected);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  ExecutionTier tier() const { return tier_; }
751cb0ef41Sopenharmony_ci  ForDebugging for_debugging() const { return for_debugging_; }
761cb0ef41Sopenharmony_ci  int func_index() const { return func_index_; }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  static void CompileWasmFunction(Isolate*, NativeModule*,
791cb0ef41Sopenharmony_ci                                  WasmFeatures* detected, const WasmFunction*,
801cb0ef41Sopenharmony_ci                                  ExecutionTier);
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci private:
831cb0ef41Sopenharmony_ci  WasmCompilationResult ExecuteFunctionCompilation(CompilationEnv*,
841cb0ef41Sopenharmony_ci                                                   const WireBytesStorage*,
851cb0ef41Sopenharmony_ci                                                   Counters*,
861cb0ef41Sopenharmony_ci                                                   WasmFeatures* detected);
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  WasmCompilationResult ExecuteImportWrapperCompilation(CompilationEnv*);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  int func_index_;
911cb0ef41Sopenharmony_ci  ExecutionTier tier_;
921cb0ef41Sopenharmony_ci  ForDebugging for_debugging_;
931cb0ef41Sopenharmony_ci};
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci// {WasmCompilationUnit} should be trivially copyable and small enough so we can
961cb0ef41Sopenharmony_ci// efficiently pass it by value.
971cb0ef41Sopenharmony_ciASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
981cb0ef41Sopenharmony_ciSTATIC_ASSERT(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
1011cb0ef41Sopenharmony_ci public:
1021cb0ef41Sopenharmony_ci  // A flag to mark whether the compilation unit can skip the compilation
1031cb0ef41Sopenharmony_ci  // and return the builtin (generic) wrapper, when available.
1041cb0ef41Sopenharmony_ci  enum AllowGeneric : bool { kAllowGeneric = true, kDontAllowGeneric = false };
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  JSToWasmWrapperCompilationUnit(Isolate* isolate, const FunctionSig* sig,
1071cb0ef41Sopenharmony_ci                                 const wasm::WasmModule* module, bool is_import,
1081cb0ef41Sopenharmony_ci                                 const WasmFeatures& enabled_features,
1091cb0ef41Sopenharmony_ci                                 AllowGeneric allow_generic);
1101cb0ef41Sopenharmony_ci  ~JSToWasmWrapperCompilationUnit();
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  Isolate* isolate() const { return isolate_; }
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  void Execute();
1151cb0ef41Sopenharmony_ci  Handle<Code> Finalize();
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  bool is_import() const { return is_import_; }
1181cb0ef41Sopenharmony_ci  const FunctionSig* sig() const { return sig_; }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  // Run a compilation unit synchronously.
1211cb0ef41Sopenharmony_ci  static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
1221cb0ef41Sopenharmony_ci                                             const FunctionSig* sig,
1231cb0ef41Sopenharmony_ci                                             const WasmModule* module,
1241cb0ef41Sopenharmony_ci                                             bool is_import);
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  // Run a compilation unit synchronously, but ask for the specific
1271cb0ef41Sopenharmony_ci  // wrapper.
1281cb0ef41Sopenharmony_ci  static Handle<Code> CompileSpecificJSToWasmWrapper(Isolate* isolate,
1291cb0ef41Sopenharmony_ci                                                     const FunctionSig* sig,
1301cb0ef41Sopenharmony_ci                                                     const WasmModule* module);
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci private:
1331cb0ef41Sopenharmony_ci  // Wrapper compilation is bound to an isolate. Concurrent accesses to the
1341cb0ef41Sopenharmony_ci  // isolate (during the "Execute" phase) must be audited carefully, i.e. we
1351cb0ef41Sopenharmony_ci  // should only access immutable information (like the root table). The isolate
1361cb0ef41Sopenharmony_ci  // is guaranteed to be alive when this unit executes.
1371cb0ef41Sopenharmony_ci  Isolate* isolate_;
1381cb0ef41Sopenharmony_ci  bool is_import_;
1391cb0ef41Sopenharmony_ci  const FunctionSig* sig_;
1401cb0ef41Sopenharmony_ci  bool use_generic_wrapper_;
1411cb0ef41Sopenharmony_ci  std::unique_ptr<TurbofanCompilationJob> job_;
1421cb0ef41Sopenharmony_ci};
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci}  // namespace wasm
1451cb0ef41Sopenharmony_ci}  // namespace internal
1461cb0ef41Sopenharmony_ci}  // namespace v8
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci#endif  // V8_WASM_FUNCTION_COMPILER_H_
149