// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/wasm/baseline/liftoff-compiler.h" #include "src/base/enum-set.h" #include "src/base/optional.h" #include "src/base/platform/wrappers.h" #include "src/codegen/assembler-inl.h" // TODO(clemensb): Remove dependences on compiler stuff. #include "src/codegen/external-reference.h" #include "src/codegen/interface-descriptors-inl.h" #include "src/codegen/machine-type.h" #include "src/codegen/macro-assembler-inl.h" #include "src/compiler/linkage.h" #include "src/compiler/wasm-compiler.h" #include "src/logging/counters.h" #include "src/logging/log.h" #include "src/objects/smi.h" #include "src/tracing/trace-event.h" #include "src/utils/ostreams.h" #include "src/utils/utils.h" #include "src/wasm/baseline/liftoff-assembler.h" #include "src/wasm/baseline/liftoff-register.h" #include "src/wasm/function-body-decoder-impl.h" #include "src/wasm/function-compiler.h" #include "src/wasm/memory-tracing.h" #include "src/wasm/object-access.h" #include "src/wasm/simd-shuffle.h" #include "src/wasm/wasm-debug.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-linkage.h" #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-opcodes-inl.h" namespace v8 { namespace internal { namespace wasm { constexpr auto kRegister = LiftoffAssembler::VarState::kRegister; constexpr auto kIntConst = LiftoffAssembler::VarState::kIntConst; constexpr auto kStack = LiftoffAssembler::VarState::kStack; namespace { #define __ asm_. #define TRACE(...) \ do { \ if (FLAG_trace_liftoff) PrintF("[liftoff] " __VA_ARGS__); \ } while (false) #define WASM_INSTANCE_OBJECT_FIELD_OFFSET(name) \ ObjectAccess::ToTagged(WasmInstanceObject::k##name##Offset) template struct assert_field_size { static_assert(expected_size == actual_size, "field in WasmInstance does not have the expected size"); static constexpr int size = actual_size; }; #define WASM_INSTANCE_OBJECT_FIELD_SIZE(name) \ FIELD_SIZE(WasmInstanceObject::k##name##Offset) #define LOAD_INSTANCE_FIELD(dst, name, load_size, pinned) \ __ LoadFromInstance(dst, LoadInstanceIntoRegister(pinned, dst), \ WASM_INSTANCE_OBJECT_FIELD_OFFSET(name), \ assert_field_size::size); #define LOAD_TAGGED_PTR_INSTANCE_FIELD(dst, name, pinned) \ static_assert(WASM_INSTANCE_OBJECT_FIELD_SIZE(name) == kTaggedSize, \ "field in WasmInstance does not have the expected size"); \ __ LoadTaggedPointerFromInstance(dst, LoadInstanceIntoRegister(pinned, dst), \ WASM_INSTANCE_OBJECT_FIELD_OFFSET(name)); #ifdef V8_CODE_COMMENTS #define CODE_COMMENT(str) \ do { \ __ RecordComment(str); \ } while (false) #else #define CODE_COMMENT(str) ((void)0) #endif constexpr LoadType::LoadTypeValue kPointerLoadType = kSystemPointerSize == 8 ? LoadType::kI64Load : LoadType::kI32Load; constexpr ValueKind kPointerKind = LiftoffAssembler::kPointerKind; constexpr ValueKind kSmiKind = LiftoffAssembler::kSmiKind; constexpr ValueKind kTaggedKind = LiftoffAssembler::kTaggedKind; // Used to construct fixed-size signatures: MakeSig::Returns(...).Params(...); using MakeSig = FixedSizeSignature; #if V8_TARGET_ARCH_ARM64 // On ARM64, the Assembler keeps track of pointers to Labels to resolve // branches to distant targets. Moving labels would confuse the Assembler, // thus store the label on the heap and keep a unique_ptr. class MovableLabel { public: MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(MovableLabel); MovableLabel() : label_(new Label()) {} Label* get() { return label_.get(); } private: std::unique_ptr