summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-02-16 23:12:02 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-02-16 23:12:02 +0000
commitb93c21e83c8fbf0191093c01a8951adb5be9010b (patch)
treed7dc0fb40c2fedbb9aad37fd8f9aba48fc4a6a26
parent88f38e9b4e9ba0aca3d6fd4823be3a7226c87f33 (diff)
parent361e04aaa5d3eca9f978a802ee44b1213f31da58 (diff)
Merge "Add custom arena deleter for RegisterLine"
-rw-r--r--runtime/base/scoped_arena_containers.h18
-rw-r--r--runtime/verifier/method_verifier.cc6
-rw-r--r--runtime/verifier/method_verifier.h8
-rw-r--r--runtime/verifier/register_line-inl.h13
-rw-r--r--runtime/verifier/register_line.h10
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