#ifndef V8_WASM_FUNCTION_COMPILER_H_
#define V8_WASM_FUNCTION_COMPILER_H_
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif
#include <memory>
#include "src/codegen/assembler.h"
#include "src/codegen/code-desc.h"
#include "src/codegen/compiler.h"
#include "src/wasm/compilation-environment.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-deopt-data.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-tier.h"
namespace v8::internal {
class Counters;
class TurbofanCompilationJob;
}
namespace v8::internal::wasm {
class NativeModule;
class WasmCode;
class WasmEngine;
struct WasmFunction;
class AssumptionsJournal {
public:
AssumptionsJournal() = default;
void RecordAssumption(uint32_t func_index, WellKnownImport status) {
imports_.push_back(std::make_pair(func_index, status));
}
const std::vector<std::pair<uint32_t, WellKnownImport>>& import_statuses() {
return imports_;
}
bool empty() const { return imports_.empty(); }
private:
std::vector<std::pair<uint32_t, WellKnownImport>> imports_;
};
struct WasmCompilationResult {
public:
MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);
enum Kind : int8_t {
kFunction,
kWasmToJsWrapper,
kStackEntryWrapper,
#if V8_ENABLE_DRUMBRAKE
kInterpreterEntry,
#endif
};
bool succeeded() const { return code_desc.buffer != nullptr; }
bool failed() const { return !succeeded(); }
explicit operator bool() const { return succeeded(); }
CodeDesc code_desc;
std::unique_ptr<AssemblerBuffer> instr_buffer;
uint32_t frame_slot_count = 0;
uint32_t ool_spill_count = 0;
uint32_t tagged_parameter_slots = 0;
base::OwnedVector<uint8_t> source_positions;
base::OwnedVector<uint8_t> inlining_positions;
base::OwnedVector<uint8_t> protected_instructions_data;
base::OwnedVector<uint8_t> deopt_data;
std::unique_ptr<AssumptionsJournal> assumptions;
std::unique_ptr<LiftoffFrameDescriptionForDeopt> liftoff_frame_descriptions;
int func_index = kAnonymousFuncIndex;
ExecutionTier result_tier = ExecutionTier::kNone;
Kind kind = kFunction;
ForDebugging for_debugging = kNotForDebugging;
bool frame_has_feedback_slot = false;
base::OwnedVector<const WasmCode::EffectHandler> effect_handlers;
};
class V8_EXPORT_PRIVATE WasmCompilationUnit final {
public:
WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
: func_index_(index), tier_(tier), for_debugging_(for_debugging) {
DCHECK_IMPLIES(for_debugging != ForDebugging::kNotForDebugging,
tier_ == ExecutionTier::kLiftoff);
}
WasmCompilationResult ExecuteCompilation(CompilationEnv*,
const WireBytesStorage*,
DelayedCounterUpdates*,
WasmDetectedFeatures*);
ExecutionTier tier() const { return tier_; }
ForDebugging for_debugging() const { return for_debugging_; }
int func_index() const { return func_index_; }
static void CompileWasmFunction(NativeModule*, WasmDetectedFeatures*,
const WasmFunction*, ExecutionTier);
private:
int func_index_;
ExecutionTier tier_;
ForDebugging for_debugging_;
};
ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
static_assert(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
public:
JSToWasmWrapperCompilationUnit(Isolate* isolate, const CanonicalSig* sig,
bool receiver_is_first_param);
~JSToWasmWrapperCompilationUnit();
JSToWasmWrapperCompilationUnit(JSToWasmWrapperCompilationUnit&&)
V8_NOEXCEPT = default;
JSToWasmWrapperCompilationUnit& operator=(JSToWasmWrapperCompilationUnit&&)
V8_NOEXCEPT = default;
Isolate* isolate() const { return isolate_; }
void Execute();
DirectHandle<Code> Finalize();
const CanonicalSig* sig() const { return sig_; }
static DirectHandle<Code> CompileJSToWasmWrapper(
Isolate* isolate, const CanonicalSig* sig, bool receiver_is_first_param);
private:
Isolate* isolate_;
const CanonicalSig* sig_;
bool receiver_is_first_param_;
std::unique_ptr<OptimizedCompilationJob> job_;
};
inline bool CanUseGenericJsToWasmWrapper(ModuleOrigin origin,
const CanonicalSig* sig) {
#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_PPC64 || \
V8_TARGET_ARCH_LOONG64)
return origin == kWasmOrigin && v8_flags.wasm_generic_wrapper &&
IsJSCompatibleSignature(sig);
#else
return false;
#endif
}
}
#endif