| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "jni_macro_assembler.h" |
| |
| #include <algorithm> |
| #include <vector> |
| |
| #ifdef ART_ENABLE_CODEGEN_arm |
| #include "arm/jni_macro_assembler_arm_vixl.h" |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_arm64 |
| #include "arm64/jni_macro_assembler_arm64.h" |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_riscv64 |
| #include "riscv64/jni_macro_assembler_riscv64.h" |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_x86 |
| #include "x86/jni_macro_assembler_x86.h" |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_x86_64 |
| #include "x86_64/jni_macro_assembler_x86_64.h" |
| #endif |
| #include "base/casts.h" |
| #include "base/globals.h" |
| #include "base/memory_region.h" |
| #include "gc_root.h" |
| #include "jni/jni_env_ext.h" |
| #include "jni/local_reference_table.h" |
| #include "stack_reference.h" |
| |
| namespace art HIDDEN { |
| |
| using MacroAsm32UniquePtr = std::unique_ptr<JNIMacroAssembler<PointerSize::k32>>; |
| |
| template <> |
| MacroAsm32UniquePtr JNIMacroAssembler<PointerSize::k32>::Create( |
| ArenaAllocator* allocator, |
| InstructionSet instruction_set, |
| const InstructionSetFeatures* instruction_set_features) { |
| // TODO: Remove the parameter from API (not needed after Mips target was removed). |
| UNUSED(instruction_set_features); |
| |
| switch (instruction_set) { |
| #ifdef ART_ENABLE_CODEGEN_arm |
| case InstructionSet::kArm: |
| case InstructionSet::kThumb2: |
| return MacroAsm32UniquePtr(new (allocator) arm::ArmVIXLJNIMacroAssembler(allocator)); |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_x86 |
| case InstructionSet::kX86: |
| return MacroAsm32UniquePtr(new (allocator) x86::X86JNIMacroAssembler(allocator)); |
| #endif |
| default: |
| UNUSED(allocator); |
| LOG(FATAL) << "Unknown/unsupported 4B InstructionSet: " << instruction_set; |
| UNREACHABLE(); |
| } |
| } |
| |
| using MacroAsm64UniquePtr = std::unique_ptr<JNIMacroAssembler<PointerSize::k64>>; |
| |
| template <> |
| MacroAsm64UniquePtr JNIMacroAssembler<PointerSize::k64>::Create( |
| ArenaAllocator* allocator, |
| InstructionSet instruction_set, |
| const InstructionSetFeatures* instruction_set_features) { |
| // TODO: Remove the parameter from API (not needed after Mips64 target was removed). |
| UNUSED(instruction_set_features); |
| |
| switch (instruction_set) { |
| #ifdef ART_ENABLE_CODEGEN_arm64 |
| case InstructionSet::kArm64: |
| return MacroAsm64UniquePtr(new (allocator) arm64::Arm64JNIMacroAssembler(allocator)); |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_riscv64 |
| case InstructionSet::kRiscv64: |
| return MacroAsm64UniquePtr(new (allocator) riscv64::Riscv64JNIMacroAssembler(allocator)); |
| #endif |
| #ifdef ART_ENABLE_CODEGEN_x86_64 |
| case InstructionSet::kX86_64: |
| return MacroAsm64UniquePtr(new (allocator) x86_64::X86_64JNIMacroAssembler(allocator)); |
| #endif |
| default: |
| UNUSED(allocator); |
| LOG(FATAL) << "Unknown/unsupported 8B InstructionSet: " << instruction_set; |
| UNREACHABLE(); |
| } |
| } |
| |
| template <PointerSize kPointerSize> |
| void JNIMacroAssembler<kPointerSize>::LoadGcRootWithoutReadBarrier(ManagedRegister dest, |
| ManagedRegister base, |
| MemberOffset offs) { |
| static_assert(sizeof(uint32_t) == sizeof(GcRoot<mirror::Object>)); |
| Load(dest, base, offs, sizeof(uint32_t)); |
| } |
| |
| template |
| void JNIMacroAssembler<PointerSize::k32>::LoadGcRootWithoutReadBarrier(ManagedRegister dest, |
| ManagedRegister base, |
| MemberOffset offs); |
| template |
| void JNIMacroAssembler<PointerSize::k64>::LoadGcRootWithoutReadBarrier(ManagedRegister dest, |
| ManagedRegister base, |
| MemberOffset offs); |
| |
| template <PointerSize kPointerSize> |
| void JNIMacroAssembler<kPointerSize>::LoadStackReference(ManagedRegister dest, FrameOffset offs) { |
| static_assert(sizeof(uint32_t) == sizeof(StackReference<mirror::Object>)); |
| Load(dest, offs, sizeof(uint32_t)); |
| } |
| |
| template |
| void JNIMacroAssembler<PointerSize::k32>::LoadStackReference(ManagedRegister dest, |
| FrameOffset offs); |
| template |
| void JNIMacroAssembler<PointerSize::k64>::LoadStackReference(ManagedRegister dest, |
| FrameOffset offs); |
| |
| template <PointerSize kPointerSize> |
| void JNIMacroAssembler<kPointerSize>::LoadLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg) { |
| constexpr size_t kLRTSegmentStateSize = sizeof(jni::LRTSegmentState); |
| const MemberOffset previous_state_offset = JNIEnvExt::LrtPreviousStateOffset(kPointerSize); |
| const MemberOffset current_state_offset = JNIEnvExt::LrtSegmentStateOffset(kPointerSize); |
| |
| Load(previous_state_reg, jni_env_reg, previous_state_offset, kLRTSegmentStateSize); |
| Load(current_state_reg, jni_env_reg, current_state_offset, kLRTSegmentStateSize); |
| } |
| |
| template |
| void JNIMacroAssembler<PointerSize::k32>::LoadLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg); |
| template |
| void JNIMacroAssembler<PointerSize::k64>::LoadLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg); |
| |
| template <PointerSize kPointerSize> |
| void JNIMacroAssembler<kPointerSize>::StoreLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg) { |
| constexpr size_t kLRTSegmentStateSize = sizeof(jni::LRTSegmentState); |
| const MemberOffset previous_state_offset = JNIEnvExt::LrtPreviousStateOffset(kPointerSize); |
| const MemberOffset segment_state_offset = JNIEnvExt::LrtSegmentStateOffset(kPointerSize); |
| |
| Store(jni_env_reg, previous_state_offset, previous_state_reg, kLRTSegmentStateSize); |
| Store(jni_env_reg, segment_state_offset, current_state_reg, kLRTSegmentStateSize); |
| } |
| |
| template |
| void JNIMacroAssembler<PointerSize::k32>::StoreLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg); |
| template |
| void JNIMacroAssembler<PointerSize::k64>::StoreLocalReferenceTableStates( |
| ManagedRegister jni_env_reg, |
| ManagedRegister previous_state_reg, |
| ManagedRegister current_state_reg); |
| |
| } // namespace art |