summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/compiled_method.cc16
-rw-r--r--compiler/dex/frontend.cc3
-rw-r--r--compiler/driver/compiler_driver.cc3
-rw-r--r--compiler/driver/compiler_driver.h1
-rw-r--r--compiler/jni/quick/jni_compiler.cc21
-rw-r--r--compiler/llvm/llvm_compilation_unit.cc19
-rw-r--r--compiler/oat_writer.cc42
-rw-r--r--runtime/instruction_set.cc70
-rw-r--r--runtime/instruction_set.h4
-rw-r--r--runtime/utils.h8
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);