diff options
author | Ian Rogers <irogers@google.com> | 2014-10-17 02:29:32 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-10-17 02:29:32 +0000 |
commit | b3f18cf7466f85e15c6b7f005f544867a4d6847a (patch) | |
tree | 62035f08dc38038b74c9796118ae0bab0e7608fb /compiler | |
parent | cb142101f29a4f1e097f03a220db3da6d4bd679f (diff) | |
parent | 6f3dbbadf4ce66982eb3d400e0a74cb73eb034f3 (diff) | |
download | art-b3f18cf7466f85e15c6b7f005f544867a4d6847a.zip art-b3f18cf7466f85e15c6b7f005f544867a4d6847a.tar.gz art-b3f18cf7466f85e15c6b7f005f544867a4d6847a.tar.bz2 |
Merge "Make ART compile with GCC -O0 again."
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/Android.mk | 1 | ||||
-rw-r--r-- | compiler/common_compiler_test.cc | 170 | ||||
-rw-r--r-- | compiler/common_compiler_test.h | 2 | ||||
-rw-r--r-- | compiler/dex/compiler_ir.h | 2 | ||||
-rw-r--r-- | compiler/dex/quick/arm/utility_arm.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 6 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 2 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 6 | ||||
-rw-r--r-- | compiler/jni/jni_compiler_test.cc | 6 | ||||
-rw-r--r-- | compiler/oat_test.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/gvn.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.h | 4 | ||||
-rw-r--r-- | compiler/utils/arena_allocator.cc | 1 |
13 files changed, 43 insertions, 191 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk index edc5bd0..f413576 100644 --- a/compiler/Android.mk +++ b/compiler/Android.mk @@ -223,6 +223,7 @@ $$(ENUM_OPERATOR_OUT_GEN): $$(GENERATED_SRC_DIR)/%_operator_out.cc : $(LOCAL_PAT else # host LOCAL_CLANG := $(ART_HOST_CLANG) LOCAL_CFLAGS += $(ART_HOST_CFLAGS) + LOCAL_LDLIBS := $(ART_HOST_LDLIBS) ifeq ($$(art_ndebug_or_debug),debug) LOCAL_CFLAGS += $(ART_HOST_DEBUG_CFLAGS) else diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index d1d47fb..9a5f74d 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -16,18 +16,12 @@ #include "common_compiler_test.h" -#if defined(__arm__) -#include <sys/ucontext.h> -#endif -#include <fstream> - #include "class_linker.h" #include "compiled_method.h" #include "dex/quick_compiler_callbacks.h" #include "dex/verification_results.h" #include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" -#include "entrypoints/entrypoint_utils.h" #include "interpreter/interpreter.h" #include "mirror/art_method.h" #include "mirror/dex_cache.h" @@ -38,128 +32,9 @@ namespace art { -// Normally the ClassLinker supplies this. -extern "C" void art_quick_generic_jni_trampoline(mirror::ArtMethod*); - -#if defined(__arm__) -// A signal handler called when have an illegal instruction. We record the fact in -// a global boolean and then increment the PC in the signal context to return to -// the next instruction. We know the instruction is an sdiv (4 bytes long). -static void baddivideinst(int signo, siginfo *si, void *data) { - UNUSED(signo); - UNUSED(si); - struct ucontext *uc = (struct ucontext *)data; - struct sigcontext *sc = &uc->uc_mcontext; - sc->arm_r0 = 0; // set R0 to #0 to signal error - sc->arm_pc += 4; // skip offending instruction -} - -// This is in arch/arm/arm_sdiv.S. It does the following: -// mov r1,#1 -// sdiv r0,r1,r1 -// bx lr -// -// the result will be the value 1 if sdiv is supported. If it is not supported -// a SIGILL signal will be raised and the signal handler (baddivideinst) called. -// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction. -// Thus if the instruction is not supported, the result of this function will be #0 - -extern "C" bool CheckForARMSDIVInstruction(); - -static InstructionSetFeatures GuessInstructionFeatures() { - InstructionSetFeatures f; - - // Uncomment this for processing of /proc/cpuinfo. - if (false) { - // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that - // the kernel puts the appropriate feature flags in here. Sometimes it doesn't. - std::ifstream in("/proc/cpuinfo"); - if (in) { - while (!in.eof()) { - std::string line; - std::getline(in, line); - if (!in.eof()) { - if (line.find("Features") != std::string::npos) { - if (line.find("idivt") != std::string::npos) { - f.SetHasDivideInstruction(true); - } - } - } - in.close(); - } - } else { - LOG(INFO) << "Failed to open /proc/cpuinfo"; - } - } - - // See if have a sdiv instruction. Register a signal handler and try to execute - // an sdiv instruction. If we get a SIGILL then it's not supported. We can't use - // the /proc/cpuinfo method for this because Krait devices don't always put the idivt - // feature in the list. - struct sigaction sa, osa; - sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; - sa.sa_sigaction = baddivideinst; - sigaction(SIGILL, &sa, &osa); - - if (CheckForARMSDIVInstruction()) { - f.SetHasDivideInstruction(true); - } - - // Restore the signal handler. - sigaction(SIGILL, &osa, nullptr); - - // Other feature guesses in here. - return f; -} -#endif - -// Given a set of instruction features from the build, parse it. The -// input 'str' is a comma separated list of feature names. Parse it and -// return the InstructionSetFeatures object. -static InstructionSetFeatures ParseFeatureList(std::string str) { - InstructionSetFeatures result; - typedef std::vector<std::string> FeatureList; - FeatureList features; - Split(str, ',', features); - for (FeatureList::iterator i = features.begin(); i != features.end(); i++) { - std::string feature = Trim(*i); - if (feature == "default") { - // Nothing to do. - } else if (feature == "div") { - // Supports divide instruction. - result.SetHasDivideInstruction(true); - } else if (feature == "nodiv") { - // Turn off support for divide instruction. - result.SetHasDivideInstruction(false); - } else { - LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'"; - } - } - // Others... - return result; -} - CommonCompilerTest::CommonCompilerTest() {} CommonCompilerTest::~CommonCompilerTest() {} -OatFile::OatMethod CommonCompilerTest::CreateOatMethod(const void* code, const uint8_t* gc_map) { - CHECK(code != nullptr); - const uint8_t* base; - uint32_t code_offset, gc_map_offset; - if (gc_map == nullptr) { - base = reinterpret_cast<const uint8_t*>(code); // Base of data points at code. - base -= sizeof(void*); // Move backward so that code_offset != 0. - code_offset = sizeof(void*); - gc_map_offset = 0; - } else { - // TODO: 64bit support. - base = nullptr; // Base of data in oat file, ie 0. - code_offset = PointerToLowMemUInt32(code); - gc_map_offset = PointerToLowMemUInt32(gc_map); - } - return OatFile::OatMethod(base, code_offset, gc_map_offset); -} - void CommonCompilerTest::MakeExecutable(mirror::ArtMethod* method) { CHECK(method != nullptr); @@ -174,7 +49,8 @@ void CommonCompilerTest::MakeExecutable(mirror::ArtMethod* method) { if (compiled_method != nullptr) { const std::vector<uint8_t>* code = compiled_method->GetQuickCode(); const void* code_ptr; - if (code != nullptr) { + bool is_portable = (code == nullptr); + if (!is_portable) { uint32_t code_size = code->size(); CHECK_NE(0u, code_size); const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable(); @@ -210,33 +86,11 @@ void CommonCompilerTest::MakeExecutable(mirror::ArtMethod* method) { const void* method_code = CompiledMethod::CodePointer(code_ptr, compiled_method->GetInstructionSet()); LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; - OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); - oat_method.LinkMethod(method); - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); + class_linker_->SetEntryPointsToCompiledCode(method, method_code, is_portable); } else { // No code? You must mean to go into the interpreter. // Or the generic JNI... - if (!method->IsNative()) { - const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge() - : GetQuickToInterpreterBridge(); - OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); - oat_method.LinkMethod(method); - method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge); - } else { - const void* method_code = reinterpret_cast<void*>(art_quick_generic_jni_trampoline); - - OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); - oat_method.LinkMethod(method); - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); - } - } - // Create bridges to transition between different kinds of compiled bridge. - if (method->GetEntryPointFromPortableCompiledCode() == nullptr) { - method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge()); - } else { - CHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr); - method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge()); - method->SetIsPortableCompiled(); + class_linker_->SetEntryPointsToInterpreter(method); } } @@ -282,19 +136,9 @@ void CommonCompilerTest::SetUp() { { ScopedObjectAccess soa(Thread::Current()); - InstructionSet instruction_set = kRuntimeISA; - + const InstructionSet instruction_set = kRuntimeISA; // Take the default set of instruction features from the build. - InstructionSetFeatures instruction_set_features = - ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures()); - -#if defined(__arm__) - InstructionSetFeatures runtime_features = GuessInstructionFeatures(); - - // for ARM, do a runtime check to make sure that the features we are passed from - // the build match the features we actually determine at runtime. - ASSERT_LE(instruction_set_features, runtime_features); -#endif + instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines()); runtime_->SetInstructionSet(instruction_set); for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { @@ -313,7 +157,7 @@ void CommonCompilerTest::SetUp() { verification_results_.get(), method_inliner_map_.get(), compiler_kind, instruction_set, - instruction_set_features, + instruction_set_features_.get(), true, new std::set<std::string>, 2, true, true, timer_.get())); } diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index df06b71..20b750c 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -81,6 +81,8 @@ class CommonCompilerTest : public CommonRuntimeTest { std::unique_ptr<CompilerCallbacks> callbacks_; std::unique_ptr<CompilerDriver> compiler_driver_; std::unique_ptr<CumulativeLogger> timer_; + std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; + private: std::unique_ptr<MemMap> image_reservation_; diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h index 37e3a7a..34585c1 100644 --- a/compiler/dex/compiler_ir.h +++ b/compiler/dex/compiler_ir.h @@ -68,7 +68,7 @@ struct CompilationUnit { InstructionSet instruction_set; bool target64; - InstructionSetFeatures GetInstructionSetFeatures() { + const InstructionSetFeatures* GetInstructionSetFeatures() { return compiler_driver->GetInstructionSetFeatures(); } diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc index e833c9a..09acf4c 100644 --- a/compiler/dex/quick/arm/utility_arm.cc +++ b/compiler/dex/quick/arm/utility_arm.cc @@ -969,9 +969,9 @@ LIR* ArmMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_ size = k32; } LIR* load; - if (UNLIKELY(is_volatile == kVolatile && - (size == k64 || size == kDouble) && - !cu_->compiler_driver->GetInstructionSetFeatures().HasLpae())) { + if (is_volatile == kVolatile && (size == k64 || size == kDouble) && + !cu_->compiler_driver->GetInstructionSetFeatures()-> + AsArmInstructionSetFeatures()->HasLpae()) { // Only 64-bit load needs special handling. // If the cpu supports LPAE, aligned LDRD is atomic - fall through to LoadBaseDisp(). DCHECK(!r_dest.IsFloat()); // See RegClassForFieldLoadSave(). @@ -1093,9 +1093,9 @@ LIR* ArmMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r } LIR* store; - if (UNLIKELY(is_volatile == kVolatile && - (size == k64 || size == kDouble) && - !cu_->compiler_driver->GetInstructionSetFeatures().HasLpae())) { + if (is_volatile == kVolatile && (size == k64 || size == kDouble) && + !cu_->compiler_driver->GetInstructionSetFeatures()-> + AsArmInstructionSetFeatures()->HasLpae()) { // Only 64-bit store needs special handling. // If the cpu supports LPAE, aligned STRD is atomic - fall through to StoreBaseDisp(). // Use STREXD for the atomic store. (Expect displacement > 0, don't optimize for == 0.) diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 12ca065..a33d15f 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -1606,7 +1606,8 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv); done = true; } else if (cu_->instruction_set == kThumb2) { - if (cu_->GetInstructionSetFeatures().HasDivideInstruction()) { + if (cu_->GetInstructionSetFeatures()->AsArmInstructionSetFeatures()-> + HasDivideInstruction()) { // Use ARM SDIV instruction for division. For remainder we also need to // calculate using a MUL and subtract. rl_src1 = LoadValue(rl_src1, kCoreReg); @@ -1875,7 +1876,8 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re rl_result = GenDivRemLit(rl_dest, rl_src, lit, is_div); done = true; } else if (cu_->instruction_set == kThumb2) { - if (cu_->GetInstructionSetFeatures().HasDivideInstruction()) { + if (cu_->GetInstructionSetFeatures()->AsArmInstructionSetFeatures()-> + HasDivideInstruction()) { // Use ARM SDIV instruction for division. For remainder we also need to // calculate using a MUL and subtract. rl_src = LoadValue(rl_src, kCoreReg); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index fb648fc..aac33d2 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -329,7 +329,7 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options, DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, - InstructionSetFeatures instruction_set_features, + const InstructionSetFeatures* instruction_set_features, bool image, std::set<std::string>* image_classes, size_t thread_count, bool dump_stats, bool dump_passes, CumulativeLogger* timer, std::string profile_file) diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index c445683..0425d27 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -88,7 +88,7 @@ class CompilerDriver { DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, - InstructionSetFeatures instruction_set_features, + const InstructionSetFeatures* instruction_set_features, bool image, std::set<std::string>* image_classes, size_t thread_count, bool dump_stats, bool dump_passes, CumulativeLogger* timer, std::string profile_file = ""); @@ -115,7 +115,7 @@ class CompilerDriver { return instruction_set_; } - InstructionSetFeatures GetInstructionSetFeatures() const { + const InstructionSetFeatures* GetInstructionSetFeatures() const { return instruction_set_features_; } @@ -475,7 +475,7 @@ class CompilerDriver { std::unique_ptr<Compiler> compiler_; const InstructionSet instruction_set_; - const InstructionSetFeatures instruction_set_features_; + const InstructionSetFeatures* const instruction_set_features_; // All class references that require mutable ReaderWriterMutex freezing_constructor_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc index fd7d350..0fea2a7 100644 --- a/compiler/jni/jni_compiler_test.cc +++ b/compiler/jni/jni_compiler_test.cc @@ -73,10 +73,10 @@ class JniCompilerTest : public CommonCompilerTest { } ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig; if (check_generic_jni_) { - method->SetEntryPointFromQuickCompiledCode(class_linker_->GetQuickGenericJniTrampoline()); + method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub()); } else { - if (method->GetEntryPointFromQuickCompiledCode() == nullptr || - method->GetEntryPointFromQuickCompiledCode() == class_linker_->GetQuickGenericJniTrampoline()) { + const void* code = method->GetEntryPointFromQuickCompiledCode(); + if (code == nullptr || class_linker_->IsQuickGenericJniStub(code)) { CompileMethod(method); ASSERT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr) << method_name << " " << method_sig; diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 3fcc369..a9d30b6 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -95,7 +95,10 @@ TEST_F(OatTest, WriteRead) { : Compiler::kQuick; InstructionSet insn_set = kIsTargetBuild ? kThumb2 : kX86; - InstructionSetFeatures insn_features; + std::string error_msg; + std::unique_ptr<const InstructionSetFeatures> insn_features( + InstructionSetFeatures::FromFeatureString(insn_set, "default", &error_msg)); + ASSERT_TRUE(insn_features.get() != nullptr) << error_msg; compiler_options_.reset(new CompilerOptions); verification_results_.reset(new VerificationResults(compiler_options_.get())); method_inliner_map_.reset(new DexFileToMethodInlinerMap); @@ -106,7 +109,7 @@ TEST_F(OatTest, WriteRead) { verification_results_.get(), method_inliner_map_.get(), compiler_kind, insn_set, - insn_features, false, NULL, 2, true, true, + insn_features.get(), false, NULL, 2, true, true, timer_.get())); jobject class_loader = NULL; if (kCompile) { @@ -135,7 +138,6 @@ TEST_F(OatTest, WriteRead) { if (kCompile) { // OatWriter strips the code, regenerate to compare compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings); } - std::string error_msg; std::unique_ptr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(), tmp.GetFilename(), NULL, false, &error_msg)); ASSERT_TRUE(oat_file.get() != nullptr) << error_msg; @@ -193,13 +195,16 @@ TEST_F(OatTest, OatHeaderSizeCheck) { } TEST_F(OatTest, OatHeaderIsValid) { - InstructionSet instruction_set = kX86; - InstructionSetFeatures instruction_set_features; + InstructionSet insn_set = kX86; + std::string error_msg; + std::unique_ptr<const InstructionSetFeatures> insn_features( + InstructionSetFeatures::FromFeatureString(insn_set, "default", &error_msg)); + ASSERT_TRUE(insn_features.get() != nullptr) << error_msg; std::vector<const DexFile*> dex_files; uint32_t image_file_location_oat_checksum = 0; uint32_t image_file_location_oat_begin = 0; - std::unique_ptr<OatHeader> oat_header(OatHeader::Create(instruction_set, - instruction_set_features, + std::unique_ptr<OatHeader> oat_header(OatHeader::Create(insn_set, + insn_features.get(), &dex_files, image_file_location_oat_checksum, image_file_location_oat_begin, diff --git a/compiler/optimizing/gvn.h b/compiler/optimizing/gvn.h index 41b3ceb..a98d714 100644 --- a/compiler/optimizing/gvn.h +++ b/compiler/optimizing/gvn.h @@ -17,7 +17,6 @@ #ifndef ART_COMPILER_OPTIMIZING_GVN_H_ #define ART_COMPILER_OPTIMIZING_GVN_H_ -#include <gtest/gtest.h> #include "nodes.h" namespace art { @@ -221,7 +220,7 @@ class GlobalValueNumberer : public ValueObject { // Mark visisted blocks. Only used for debugging. GrowableArray<bool> visited_; - FRIEND_TEST(GVNTest, LoopSideEffects); + ART_FRIEND_TEST(GVNTest, LoopSideEffects); DISALLOW_COPY_AND_ASSIGN(GlobalValueNumberer); }; diff --git a/compiler/optimizing/register_allocator.h b/compiler/optimizing/register_allocator.h index d4c233a..0c3a9b3 100644 --- a/compiler/optimizing/register_allocator.h +++ b/compiler/optimizing/register_allocator.h @@ -21,8 +21,6 @@ #include "primitive.h" #include "utils/growable_array.h" -#include "gtest/gtest.h" - namespace art { class CodeGenerator; @@ -189,7 +187,7 @@ class RegisterAllocator { // The maximum live registers at safepoints. size_t maximum_number_of_live_registers_; - FRIEND_TEST(RegisterAllocatorTest, FreeUntil); + ART_FRIEND_TEST(RegisterAllocatorTest, FreeUntil); DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); }; diff --git a/compiler/utils/arena_allocator.cc b/compiler/utils/arena_allocator.cc index 516ac2b..0c93f0a 100644 --- a/compiler/utils/arena_allocator.cc +++ b/compiler/utils/arena_allocator.cc @@ -15,6 +15,7 @@ */ #include <algorithm> +#include <iomanip> #include <numeric> #include "arena_allocator.h" |