diff options
| -rw-r--r-- | runtime/arch/context.h | 1 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.cc | 4 | ||||
| -rw-r--r-- | runtime/runtime.cc | 22 | ||||
| -rw-r--r-- | runtime/runtime.h | 3 |
4 files changed, 28 insertions, 2 deletions
diff --git a/runtime/arch/context.h b/runtime/arch/context.h index a50064851b..d067f667cb 100644 --- a/runtime/arch/context.h +++ b/runtime/arch/context.h @@ -92,7 +92,6 @@ class Context { // Switches execution of the executing context to this context NO_RETURN virtual void DoLongJump() = 0; - protected: enum { kBadGprBase = 0xebad6070, kBadFprBase = 0xebad8070, diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 56efd25a63..52322529c8 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -18,6 +18,7 @@ #include <sstream> +#include "arch/context.h" #include "art_method-inl.h" #include "base/enums.h" #include "base/stl_util.h" @@ -325,7 +326,8 @@ static uint8_t* GetRootTable(const void* code_ptr, uint32_t* number_of_roots = n // Use a sentinel for marking entries in the JIT table that have been cleared. // This helps diagnosing in case the compiled code tries to wrongly access such // entries. -static mirror::Class* const weak_sentinel = reinterpret_cast<mirror::Class*>(0x1); +static mirror::Class* const weak_sentinel = + reinterpret_cast<mirror::Class*>(Context::kBadGprBase + 0xff); // Helper for the GC to process a weak class in a JIT root table. static inline void ProcessWeakClass(GcRoot<mirror::Class>* root_ptr, diff --git a/runtime/runtime.cc b/runtime/runtime.cc index b169373612..3697f2176c 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -390,6 +390,7 @@ Runtime::~Runtime() { low_4gb_arena_pool_.reset(); arena_pool_.reset(); jit_arena_pool_.reset(); + protected_fault_page_.reset(); MemMap::Shutdown(); // TODO: acquire a static mutex on Runtime to avoid racing. @@ -1400,6 +1401,27 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { callbacks_->NextRuntimePhase(RuntimePhaseCallback::RuntimePhase::kInitialAgents); } + // Try to reserve a dedicated fault page. This is allocated for clobbered registers and sentinels. + // If we cannot reserve it, log a warning. + // Note: This is allocated last so that the heap and other things have priority, if necessary. + { + constexpr uintptr_t kSentinelAddr = + RoundDown(static_cast<uintptr_t>(Context::kBadGprBase), kPageSize); + protected_fault_page_.reset(MemMap::MapAnonymous("Sentinel fault page", + reinterpret_cast<uint8_t*>(kSentinelAddr), + kPageSize, + PROT_NONE, + true, + false, + &error_msg)); + if (protected_fault_page_ == nullptr) { + LOG(WARNING) << "Could not reserve sentinel fault page: " << error_msg; + } else if (reinterpret_cast<uintptr_t>(protected_fault_page_->Begin()) != kSentinelAddr) { + LOG(WARNING) << "Could not reserve sentinel fault page at the right address."; + protected_fault_page_.reset(); + } + } + VLOG(startup) << "Runtime::Init exiting"; return true; diff --git a/runtime/runtime.h b/runtime/runtime.h index 4931382e55..2e3b8d7bae 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -81,6 +81,7 @@ class DexFile; class InternTable; class JavaVMExt; class LinearAlloc; +class MemMap; class MonitorList; class MonitorPool; class NullPointerHandler; @@ -942,6 +943,8 @@ class Runtime { std::atomic<uint32_t> deoptimization_counts_[ static_cast<uint32_t>(DeoptimizationKind::kLast) + 1]; + std::unique_ptr<MemMap> protected_fault_page_; + DISALLOW_COPY_AND_ASSIGN(Runtime); }; std::ostream& operator<<(std::ostream& os, const Runtime::CalleeSaveType& rhs); |