diff options
| -rw-r--r-- | compiler/common_compiler_test.cc | 11 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.cc | 4 | ||||
| -rw-r--r-- | runtime/utils.h | 18 |
3 files changed, 21 insertions, 12 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index afc8463878..e4bfac9ee7 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -122,16 +122,7 @@ void CommonCompilerTest::MakeExecutable(const void* code_start, size_t code_leng int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC); CHECK_EQ(result, 0); - // Flush instruction cache - // Only uses __builtin___clear_cache if GCC >= 4.3.3 -#if GCC_VERSION >= 40303 - __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len)); -#else - // Only warn if not Intel as Intel doesn't have cache flush instructions. -#if !defined(__i386__) && !defined(__x86_64__) - UNIMPLEMENTED(WARNING) << "cache flush"; -#endif -#endif + FlushInstructionCache(reinterpret_cast<char*>(base), reinterpret_cast<char*>(base + len)); } void CommonCompilerTest::MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name) { diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index b0e5fdeeb1..f325949c6f 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -321,8 +321,8 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self, code_size); } - __builtin___clear_cache(reinterpret_cast<char*>(code_ptr), - reinterpret_cast<char*>(code_ptr + code_size)); + FlushInstructionCache(reinterpret_cast<char*>(code_ptr), + reinterpret_cast<char*>(code_ptr + code_size)); number_of_compilations_++; } // We need to update the entry point in the runnable state for the instrumentation. diff --git a/runtime/utils.h b/runtime/utils.h index 153749eff4..c00db11c16 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -388,6 +388,24 @@ int64_t GetFileSizeBytes(const std::string& filename); // Sleep forever and never come back. NO_RETURN void SleepForever(); +inline void FlushInstructionCache(char* begin, char* end) { + // Only use __builtin___clear_cache with Clang or with GCC >= 4.3.0 + // (__builtin___clear_cache was introduced in GCC 4.3.0). +#if defined(__clang__) || GCC_VERSION >= 40300 + __builtin___clear_cache(begin, end); +#else + // Only warn on non-Intel platforms, as x86 and x86-64 do not need + // cache flush instructions, as long as the "code uses the same + // linear address for modifying and fetching the instruction". See + // "Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3A: System Programming Guide, Part 1", section 11.6 + // "Self-Modifying Code". +#if !defined(__i386__) && !defined(__x86_64__) + UNIMPLEMENTED(WARNING) << "cache flush"; +#endif +#endif +} + } // namespace art #endif // ART_RUNTIME_UTILS_H_ |