diff options
| -rw-r--r-- | compiler/compiled_method.cc | 16 | ||||
| -rw-r--r-- | compiler/dex/frontend.cc | 3 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 3 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.h | 1 | ||||
| -rw-r--r-- | compiler/jni/quick/jni_compiler.cc | 21 | ||||
| -rw-r--r-- | compiler/llvm/llvm_compilation_unit.cc | 19 | ||||
| -rw-r--r-- | compiler/oat_writer.cc | 42 | ||||
| -rw-r--r-- | runtime/instruction_set.cc | 70 | ||||
| -rw-r--r-- | runtime/instruction_set.h | 4 | ||||
| -rw-r--r-- | runtime/utils.h | 8 |
10 files changed, 103 insertions, 84 deletions
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc index 8e013c1ece..59ed8277d0 100644 --- a/compiler/compiled_method.cc +++ b/compiler/compiled_method.cc @@ -82,21 +82,7 @@ uint32_t CompiledCode::AlignCode(uint32_t offset) const { } uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) { - switch (instruction_set) { - case kArm: - case kThumb2: - return RoundUp(offset, kArmAlignment); - case kArm64: - return RoundUp(offset, kArm64Alignment); - case kMips: - return RoundUp(offset, kMipsAlignment); - case kX86: // Fall-through. - case kX86_64: - return RoundUp(offset, kX86Alignment); - default: - LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; - return 0; - } + return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); } size_t CompiledCode::CodeDelta() const { diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc index 201dc47bf7..1bf5fce989 100644 --- a/compiler/dex/frontend.cc +++ b/compiler/dex/frontend.cc @@ -158,7 +158,7 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver, if (cu.instruction_set == kArm) { cu.instruction_set = kThumb2; } - cu.target64 = (cu.instruction_set == kX86_64) || (cu.instruction_set == kArm64); + cu.target64 = Is64BitInstructionSet(cu.instruction_set); cu.compiler = compiler; // TODO: x86_64 & arm64 are not yet implemented. CHECK((cu.instruction_set == kThumb2) || @@ -166,7 +166,6 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver, (cu.instruction_set == kX86_64) || (cu.instruction_set == kMips)); - /* Adjust this value accordingly once inlining is performed */ cu.num_dalvik_registers = code_item->registers_size_; // TODO: set this from command line diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 2b20c6fc75..0ad30be3fe 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -339,7 +339,6 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options, compiler_(Compiler::Create(compiler_kind)), instruction_set_(instruction_set), instruction_set_features_(instruction_set_features), - instruction_set_is_64_bit_(instruction_set == kX86_64 || instruction_set == kArm64), freezing_constructor_lock_("freezing constructor lock"), compiled_classes_lock_("compiled classes lock"), compiled_methods_lock_("compiled method lock"), @@ -448,7 +447,7 @@ CompilerTls* CompilerDriver::GetTls() { } #define CREATE_TRAMPOLINE(type, abi, offset) \ - if (instruction_set_is_64_bit_) { \ + if (Is64BitInstructionSet(instruction_set_)) { \ return CreateTrampoline64(instruction_set_, abi, \ type ## _ENTRYPOINT_OFFSET(8, offset)); \ } else { \ diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index d49523a172..d7d40d554a 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -692,7 +692,6 @@ class CompilerDriver { const InstructionSet instruction_set_; const InstructionSetFeatures instruction_set_features_; - const bool instruction_set_is_64_bit_; // All class references that require mutable ReaderWriterMutex freezing_constructor_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc index 64508d10fc..e03aefb134 100644 --- a/compiler/jni/quick/jni_compiler.cc +++ b/compiler/jni/quick/jni_compiler.cc @@ -64,6 +64,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, if (instruction_set == kThumb2) { instruction_set = kArm; } + const bool is_64_bit_target = Is64BitInstructionSet(instruction_set); // Calling conventions used to iterate over parameters to method UniquePtr<JniCallingConvention> main_jni_conv( JniCallingConvention::Create(is_static, is_synchronized, shorty, instruction_set)); @@ -109,7 +110,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, main_jni_conv->ReferenceCount(), mr_conv->InterproceduralScratchRegister()); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ CopyRawPtrFromThread64(main_jni_conv->SirtLinkOffset(), Thread::TopSirtOffset<8>(), mr_conv->InterproceduralScratchRegister()); @@ -171,7 +172,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, } // 4. Write out the end of the quick frames. - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ StoreStackPointerToThread64(Thread::TopOfManagedStackOffset<8>()); __ StoreImmediateToThread64(Thread::TopOfManagedStackPcOffset<8>(), 0, mr_conv->InterproceduralScratchRegister()); @@ -216,7 +217,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, } if (main_jni_conv->IsCurrentParamInRegister()) { __ GetCurrentThread(main_jni_conv->CurrentParamRegister()); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ Call(main_jni_conv->CurrentParamRegister(), Offset(jni_start64), main_jni_conv->InterproceduralScratchRegister()); } else { @@ -226,7 +227,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, } else { __ GetCurrentThread(main_jni_conv->CurrentParamStackOffset(), main_jni_conv->InterproceduralScratchRegister()); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ CallFromThread64(jni_start64, main_jni_conv->InterproceduralScratchRegister()); } else { __ CallFromThread32(jni_start32, main_jni_conv->InterproceduralScratchRegister()); @@ -292,14 +293,14 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, if (main_jni_conv->IsCurrentParamInRegister()) { ManagedRegister jni_env = main_jni_conv->CurrentParamRegister(); DCHECK(!jni_env.Equals(main_jni_conv->InterproceduralScratchRegister())); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ LoadRawPtrFromThread64(jni_env, Thread::JniEnvOffset<8>()); } else { __ LoadRawPtrFromThread32(jni_env, Thread::JniEnvOffset<4>()); } } else { FrameOffset jni_env = main_jni_conv->CurrentParamStackOffset(); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ CopyRawPtrFromThread64(jni_env, Thread::JniEnvOffset<8>(), main_jni_conv->InterproceduralScratchRegister()); } else { @@ -313,7 +314,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, mr_conv->InterproceduralScratchRegister()); // 10. Fix differences in result widths. - if (instruction_set == kX86 || instruction_set == kX86_64) { + if (is_64_bit_target) { if (main_jni_conv->GetReturnType() == Primitive::kPrimByte || main_jni_conv->GetReturnType() == Primitive::kPrimShort) { __ SignExtend(main_jni_conv->ReturnRegister(), @@ -331,7 +332,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, if (instruction_set == kMips && main_jni_conv->GetReturnType() == Primitive::kPrimDouble && return_save_location.Uint32Value() % 8 != 0) { // Ensure doubles are 8-byte aligned for MIPS - return_save_location = FrameOffset(return_save_location.Uint32Value() + kPointerSize); + return_save_location = FrameOffset(return_save_location.Uint32Value() + kMipsPointerSize); } CHECK_LT(return_save_location.Uint32Value(), frame_size+main_out_arg_size); __ Store(return_save_location, main_jni_conv->ReturnRegister(), main_jni_conv->SizeOfReturnValue()); @@ -380,7 +381,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, } if (end_jni_conv->IsCurrentParamInRegister()) { __ GetCurrentThread(end_jni_conv->CurrentParamRegister()); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ Call(end_jni_conv->CurrentParamRegister(), Offset(jni_end64), end_jni_conv->InterproceduralScratchRegister()); } else { @@ -390,7 +391,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler, } else { __ GetCurrentThread(end_jni_conv->CurrentParamStackOffset(), end_jni_conv->InterproceduralScratchRegister()); - if (instruction_set == kArm64 || instruction_set == kX86_64) { + if (is_64_bit_target) { __ CallFromThread64(ThreadOffset<8>(jni_end64), end_jni_conv->InterproceduralScratchRegister()); } else { __ CallFromThread32(ThreadOffset<4>(jni_end32), end_jni_conv->InterproceduralScratchRegister()); diff --git a/compiler/llvm/llvm_compilation_unit.cc b/compiler/llvm/llvm_compilation_unit.cc index 1d027f9d3b..fe609593dc 100644 --- a/compiler/llvm/llvm_compilation_unit.cc +++ b/compiler/llvm/llvm_compilation_unit.cc @@ -314,23 +314,8 @@ bool LlvmCompilationUnit::MaterializeToRawOStream(::llvm::raw_ostream& out_strea // section if the section alignment is greater than kArchAlignment. void LlvmCompilationUnit::CheckCodeAlign(uint32_t align) const { InstructionSet insn_set = GetInstructionSet(); - switch (insn_set) { - case kThumb2: - case kArm: - CHECK_LE(align, static_cast<uint32_t>(kArmAlignment)); - break; - - case kX86: - CHECK_LE(align, static_cast<uint32_t>(kX86Alignment)); - break; - - case kMips: - CHECK_LE(align, static_cast<uint32_t>(kMipsAlignment)); - break; - - default: - LOG(FATAL) << "Unknown instruction set: " << insn_set; - } + size_t insn_set_align = GetInstructionSetAlignment(insn_set); + CHECK_LE(align, static_cast<uint32_t>(insn_set_align)); } diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index eff2425bb7..dc66e9c108 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -345,36 +345,6 @@ size_t OatWriter::InitOatCodeClassDef(size_t offset, return offset; } -static void DCheckCodeAlignment(size_t offset, InstructionSet isa) { - switch (isa) { - case kArm: - // Fall-through. - case kThumb2: - DCHECK_ALIGNED(offset, kArmAlignment); - break; - - case kArm64: - DCHECK_ALIGNED(offset, kArm64Alignment); - break; - - case kMips: - DCHECK_ALIGNED(offset, kMipsAlignment); - break; - - case kX86_64: - // Fall-through. - case kX86: - DCHECK_ALIGNED(offset, kX86Alignment); - break; - - case kNone: - // Use a DCHECK instead of FATAL so that in the non-debug case the whole switch can - // be optimized away. - DCHECK(false); - break; - } -} - size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, size_t __attribute__((unused)) class_def_index, size_t class_def_method_index, @@ -406,7 +376,8 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, } else { CHECK(quick_code != nullptr); offset = compiled_method->AlignCode(offset); - DCheckCodeAlignment(offset, compiled_method->GetInstructionSet()); + DCHECK_ALIGNED_PARAM(offset, + GetInstructionSetAlignment(compiled_method->GetInstructionSet())); uint32_t code_size = quick_code->size() * sizeof(uint8_t); CHECK_NE(code_size, 0U); @@ -539,11 +510,7 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, refs++; } } - InstructionSet trg_isa = compiler_driver_->GetInstructionSet(); - size_t pointer_size = 4; - if (trg_isa == kArm64 || trg_isa == kX86_64) { - pointer_size = 8; - } + size_t pointer_size = GetInstructionSetPointerSize(compiler_driver_->GetInstructionSet()); size_t sirt_size = StackIndirectReferenceTable::GetAlignedSirtSizeTarget(pointer_size, refs); // Get the generic spill masks and base frame size. @@ -857,7 +824,8 @@ size_t OatWriter::WriteCodeMethod(OutputStream* out, const size_t file_offset, relative_offset += aligned_code_delta; DCHECK_OFFSET(); } - DCheckCodeAlignment(relative_offset, compiled_method->GetInstructionSet()); + DCHECK_ALIGNED_PARAM(relative_offset, + GetInstructionSetAlignment(compiled_method->GetInstructionSet())); uint32_t code_size = quick_code->size() * sizeof(uint8_t); CHECK_NE(code_size, 0U); diff --git a/runtime/instruction_set.cc b/runtime/instruction_set.cc index c96462915b..73d427985f 100644 --- a/runtime/instruction_set.cc +++ b/runtime/instruction_set.cc @@ -16,8 +16,78 @@ #include "instruction_set.h" +#include "globals.h" +#include "base/logging.h" // Logging is required for FATAL in the helper functions. + namespace art { +size_t GetInstructionSetPointerSize(InstructionSet isa) { + switch (isa) { + case kArm: + // Fall-through. + case kThumb2: + return kArmPointerSize; + case kArm64: + return kArm64PointerSize; + case kX86: + return kX86PointerSize; + case kX86_64: + return kX86_64PointerSize; + case kMips: + return kMipsPointerSize; + case kNone: + LOG(FATAL) << "ISA kNone does not have pointer size."; + return 0; + default: + LOG(FATAL) << "Unknown ISA " << isa; + return 0; + } +} + +size_t GetInstructionSetAlignment(InstructionSet isa) { + switch (isa) { + case kArm: + // Fall-through. + case kThumb2: + return kArmAlignment; + case kArm64: + return kArm64Alignment; + case kX86: + // Fall-through. + case kX86_64: + return kX86Alignment; + case kMips: + return kMipsAlignment; + case kNone: + LOG(FATAL) << "ISA kNone does not have alignment."; + return 0; + default: + LOG(FATAL) << "Unknown ISA " << isa; + return 0; + } +} + +bool Is64BitInstructionSet(InstructionSet isa) { + switch (isa) { + case kArm: + case kThumb2: + case kX86: + case kMips: + return false; + + case kArm64: + case kX86_64: + return true; + + case kNone: + LOG(FATAL) << "ISA kNone does not have bit width."; + return 0; + default: + LOG(FATAL) << "Unknown ISA " << isa; + return 0; + } +} + std::string InstructionSetFeatures::GetFeatureString() const { std::string result; if ((mask_ & kHwDiv) != 0) { diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h index a08becfb76..c746e06307 100644 --- a/runtime/instruction_set.h +++ b/runtime/instruction_set.h @@ -35,6 +35,10 @@ enum InstructionSet { }; std::ostream& operator<<(std::ostream& os, const InstructionSet& rhs); +size_t GetInstructionSetPointerSize(InstructionSet isa); +size_t GetInstructionSetAlignment(InstructionSet isa); +bool Is64BitInstructionSet(InstructionSet isa); + #if defined(__arm__) static constexpr InstructionSet kRuntimeISA = kArm; #elif defined(__aarch64__) diff --git a/runtime/utils.h b/runtime/utils.h index dbc3ab7634..5def66b56c 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -62,12 +62,20 @@ static inline bool IsAligned(T* x) { return IsAligned<n>(reinterpret_cast<const uintptr_t>(x)); } +template<typename T> +static inline bool IsAlignedParam(T x, int n) { + return (x & (n - 1)) == 0; +} + #define CHECK_ALIGNED(value, alignment) \ CHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value) #define DCHECK_ALIGNED(value, alignment) \ DCHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value) +#define DCHECK_ALIGNED_PARAM(value, alignment) \ + DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value) + // Check whether an N-bit two's-complement representation can hold value. static inline bool IsInt(int N, word value) { CHECK_LT(0, N); |