diff options
| author | 2016-02-16 23:12:02 +0000 | |
|---|---|---|
| committer | 2016-02-16 23:12:02 +0000 | |
| commit | b93c21e83c8fbf0191093c01a8951adb5be9010b (patch) | |
| tree | d7dc0fb40c2fedbb9aad37fd8f9aba48fc4a6a26 | |
| parent | 88f38e9b4e9ba0aca3d6fd4823be3a7226c87f33 (diff) | |
| parent | 361e04aaa5d3eca9f978a802ee44b1213f31da58 (diff) | |
Merge "Add custom arena deleter for RegisterLine"
| -rw-r--r-- | runtime/base/scoped_arena_containers.h | 18 | ||||
| -rw-r--r-- | runtime/verifier/method_verifier.cc | 6 | ||||
| -rw-r--r-- | runtime/verifier/method_verifier.h | 8 | ||||
| -rw-r--r-- | runtime/verifier/register_line-inl.h | 13 | ||||
| -rw-r--r-- | runtime/verifier/register_line.h | 10 |
5 files changed, 41 insertions, 14 deletions
diff --git a/runtime/base/scoped_arena_containers.h b/runtime/base/scoped_arena_containers.h index 1236585afd..9b56856f11 100644 --- a/runtime/base/scoped_arena_containers.h +++ b/runtime/base/scoped_arena_containers.h @@ -201,22 +201,28 @@ inline ScopedArenaAllocatorAdapter<void> ScopedArenaAllocator::Adapter(ArenaAllo template <typename T> class ArenaDelete { static constexpr uint8_t kMagicFill = 0xCE; - public: - void operator()(T* ptr) const { - ptr->~T(); + protected: + // Used for variable sized objects such as RegisterLine. + ALWAYS_INLINE void ProtectMemory(T* ptr, size_t size) const { if (RUNNING_ON_MEMORY_TOOL > 0) { // Writing to the memory will fail if it we already destroyed the pointer with // DestroyOnlyDelete since we make it no access. - memset(ptr, kMagicFill, sizeof(T)); - MEMORY_TOOL_MAKE_NOACCESS(ptr, sizeof(T)); + memset(ptr, kMagicFill, size); + MEMORY_TOOL_MAKE_NOACCESS(ptr, size); } else if (kIsDebugBuild) { CHECK(ArenaStack::ArenaTagForAllocation(reinterpret_cast<void*>(ptr)) == ArenaFreeTag::kUsed) << "Freeing invalid object " << ptr; ArenaStack::ArenaTagForAllocation(reinterpret_cast<void*>(ptr)) = ArenaFreeTag::kFree; // Write a magic value to try and catch use after free error. - memset(ptr, kMagicFill, sizeof(T)); + memset(ptr, kMagicFill, size); } } + + public: + void operator()(T* ptr) const { + ptr->~T(); + ProtectMemory(ptr, sizeof(T)); + } }; // In general we lack support for arrays. We would need to call the destructor on each element, diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 1d31408cf0..a6cf9eaf86 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -1960,8 +1960,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { // We need to ensure the work line is consistent while performing validation. When we spot a // peephole pattern we compute a new line for either the fallthrough instruction or the // branch target. - ArenaUniquePtr<RegisterLine> branch_line; - ArenaUniquePtr<RegisterLine> fallthrough_line; + RegisterLineArenaUniquePtr branch_line; + RegisterLineArenaUniquePtr fallthrough_line; switch (inst->Opcode()) { case Instruction::NOP: @@ -4824,7 +4824,7 @@ bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_lin AdjustReturnLine(this, ret_inst, target_line); } } else { - ArenaUniquePtr<RegisterLine> copy; + RegisterLineArenaUniquePtr copy; if (kDebugVerify) { copy.reset(RegisterLine::Create(target_line->NumRegs(), this)); copy->CopyFromLine(target_line); diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index c7d1e6bc90..b53a45cf41 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -30,6 +30,7 @@ #include "handle.h" #include "instruction_flags.h" #include "method_reference.h" +#include "register_line.h" #include "reg_type_cache.h" namespace art { @@ -45,6 +46,7 @@ namespace verifier { class DexPcToReferenceMap; class MethodVerifier; class RegisterLine; +using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>; class RegType; /* @@ -127,7 +129,7 @@ class PcToRegisterLineTable { } private: - ScopedArenaVector<ArenaUniquePtr<RegisterLine>> register_lines_; + ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_; DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable); }; @@ -771,14 +773,14 @@ class MethodVerifier { PcToRegisterLineTable reg_table_; // Storage for the register status we're currently working on. - ArenaUniquePtr<RegisterLine> work_line_; + RegisterLineArenaUniquePtr work_line_; // The address of the instruction we're currently working on, note that this is in 2 byte // quantities uint32_t work_insn_idx_; // Storage for the register status we're saving for later. - ArenaUniquePtr<RegisterLine> saved_line_; + RegisterLineArenaUniquePtr saved_line_; const uint32_t dex_method_idx_; // The method we're working on. // Its object representation if known. diff --git a/runtime/verifier/register_line-inl.h b/runtime/verifier/register_line-inl.h index 330c06ab46..bfbb78f58a 100644 --- a/runtime/verifier/register_line-inl.h +++ b/runtime/verifier/register_line-inl.h @@ -185,9 +185,12 @@ inline void RegisterLine::VerifyMonitorStackEmpty(MethodVerifier* verifier) cons } } +inline size_t RegisterLine::ComputeSize(size_t num_regs) { + return OFFSETOF_MEMBER(RegisterLine, line_) + num_regs * sizeof(uint16_t); +} + inline RegisterLine* RegisterLine::Create(size_t num_regs, MethodVerifier* verifier) { - void* memory = verifier->GetArena().Alloc(OFFSETOF_MEMBER(RegisterLine, line_) + - (num_regs * sizeof(uint16_t))); + void* memory = verifier->GetArena().Alloc(ComputeSize(num_regs)); return new (memory) RegisterLine(num_regs, verifier); } @@ -200,6 +203,12 @@ inline RegisterLine::RegisterLine(size_t num_regs, MethodVerifier* verifier) SetResultTypeToUnknown(verifier); } +inline void RegisterLineArenaDelete::operator()(RegisterLine* ptr) const { + const size_t size = ptr != nullptr ? RegisterLine::ComputeSize(ptr->NumRegs()) : 0u; + ptr->~RegisterLine(); + ProtectMemory(ptr, size); +} + } // namespace verifier } // namespace art diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h index b2f5555d8b..d50845421f 100644 --- a/runtime/verifier/register_line.h +++ b/runtime/verifier/register_line.h @@ -197,6 +197,9 @@ class RegisterLine { return num_regs_; } + // Return how many bytes of memory a register line uses. + ALWAYS_INLINE static size_t ComputeSize(size_t num_regs); + /* * Get the "this" pointer from a non-static method invocation. This returns the RegType so the * caller can decide whether it needs the reference to be initialized or not. (Can also return @@ -401,6 +404,13 @@ class RegisterLine { DISALLOW_COPY_AND_ASSIGN(RegisterLine); }; +class RegisterLineArenaDelete : public ArenaDelete<RegisterLine> { + public: + void operator()(RegisterLine* ptr) const; +}; + + + } // namespace verifier } // namespace art |