summaryrefslogtreecommitdiffstats
path: root/runtime/verifier/register_line.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/verifier/register_line.h')
-rw-r--r--runtime/verifier/register_line.h92
1 files changed, 48 insertions, 44 deletions
diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h
index a9d0dbb073..c7fd369472 100644
--- a/runtime/verifier/register_line.h
+++ b/runtime/verifier/register_line.h
@@ -57,50 +57,54 @@ class RegisterLine {
}
// Implement category-1 "move" instructions. Copy a 32-bit value from "vsrc" to "vdst".
- void CopyRegister1(uint32_t vdst, uint32_t vsrc, TypeCategory cat)
+ void CopyRegister1(MethodVerifier* verifier, uint32_t vdst, uint32_t vsrc, TypeCategory cat)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implement category-2 "move" instructions. Copy a 64-bit value from "vsrc" to "vdst". This
// copies both halves of the register.
- void CopyRegister2(uint32_t vdst, uint32_t vsrc)
+ void CopyRegister2(MethodVerifier* verifier, uint32_t vdst, uint32_t vsrc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implement "move-result". Copy the category-1 value from the result register to another
// register, and reset the result register.
- void CopyResultRegister1(uint32_t vdst, bool is_reference)
+ void CopyResultRegister1(MethodVerifier* verifier, uint32_t vdst, bool is_reference)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implement "move-result-wide". Copy the category-2 value from the result register to another
// register, and reset the result register.
- void CopyResultRegister2(uint32_t vdst)
+ void CopyResultRegister2(MethodVerifier* verifier, uint32_t vdst)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Set the invisible result register to unknown
- void SetResultTypeToUnknown() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetResultTypeToUnknown(MethodVerifier* verifier) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Set the type of register N, verifying that the register is valid. If "newType" is the "Lo"
// part of a 64-bit value, register N+1 will be set to "newType+1".
// The register index was validated during the static pass, so we don't need to check it here.
- bool SetRegisterType(uint32_t vdst, const RegType& new_type)
+ ALWAYS_INLINE bool SetRegisterType(MethodVerifier* verifier, uint32_t vdst,
+ const RegType& new_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool SetRegisterTypeWide(uint32_t vdst, const RegType& new_type1, const RegType& new_type2)
+ bool SetRegisterTypeWide(MethodVerifier* verifier, uint32_t vdst, const RegType& new_type1,
+ const RegType& new_type2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/* Set the type of the "result" register. */
- void SetResultRegisterType(const RegType& new_type)
+ void SetResultRegisterType(MethodVerifier* verifier, const RegType& new_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetResultRegisterTypeWide(const RegType& new_type1, const RegType& new_type2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get the type of register vsrc.
- const RegType& GetRegisterType(uint32_t vsrc) const;
+ const RegType& GetRegisterType(MethodVerifier* verifier, uint32_t vsrc) const;
- bool VerifyRegisterType(uint32_t vsrc, const RegType& check_type)
+ ALWAYS_INLINE bool VerifyRegisterType(MethodVerifier* verifier, uint32_t vsrc,
+ const RegType& check_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool VerifyRegisterTypeWide(uint32_t vsrc, const RegType& check_type1, const RegType& check_type2)
+ bool VerifyRegisterTypeWide(MethodVerifier* verifier, uint32_t vsrc, const RegType& check_type1,
+ const RegType& check_type2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CopyFromLine(const RegisterLine* src) {
@@ -110,7 +114,7 @@ class RegisterLine {
reg_to_lock_depths_ = src->reg_to_lock_depths_;
}
- std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ std::string Dump(MethodVerifier* verifier) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FillWithGarbage() {
memset(&line_, 0xf1, num_regs_ * sizeof(uint16_t));
@@ -126,7 +130,7 @@ class RegisterLine {
* to prevent them from being used (otherwise, MarkRefsAsInitialized would mark the old ones and
* the new ones at the same time).
*/
- void MarkUninitRefsAsInvalid(const RegType& uninit_type)
+ void MarkUninitRefsAsInvalid(MethodVerifier* verifier, const RegType& uninit_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
@@ -134,15 +138,15 @@ class RegisterLine {
* reference type. This is called when an appropriate constructor is invoked -- all copies of
* the reference must be marked as initialized.
*/
- void MarkRefsAsInitialized(const RegType& uninit_type)
+ void MarkRefsAsInitialized(MethodVerifier* verifier, const RegType& uninit_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
* Update all registers to be Conflict except vsrc.
*/
- void MarkAllRegistersAsConflicts();
- void MarkAllRegistersAsConflictsExcept(uint32_t vsrc);
- void MarkAllRegistersAsConflictsExceptWide(uint32_t vsrc);
+ void MarkAllRegistersAsConflicts(MethodVerifier* verifier);
+ void MarkAllRegistersAsConflictsExcept(MethodVerifier* verifier, uint32_t vsrc);
+ void MarkAllRegistersAsConflictsExceptWide(MethodVerifier* verifier, uint32_t vsrc);
/*
* Check constraints on constructor return. Specifically, make sure that the "this" argument got
@@ -151,7 +155,7 @@ class RegisterLine {
* of the list in slot 0. If we see a register with an uninitialized slot 0 reference, we know it
* somehow didn't get initialized.
*/
- bool CheckConstructorReturn() const;
+ bool CheckConstructorReturn(MethodVerifier* verifier) const;
// Compare two register lines. Returns 0 if they match.
// Using this for a sort is unwise, since the value can change based on machine endianness.
@@ -173,28 +177,29 @@ class RegisterLine {
* The argument count is in vA, and the first argument is in vC, for both "simple" and "range"
* versions. We just need to make sure vA is >= 1 and then return vC.
*/
- const RegType& GetInvocationThis(const Instruction* inst, bool is_range)
+ const RegType& GetInvocationThis(MethodVerifier* verifier, const Instruction* inst,
+ bool is_range)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
* Verify types for a simple two-register instruction (e.g. "neg-int").
* "dst_type" is stored into vA, and "src_type" is verified against vB.
*/
- void CheckUnaryOp(const Instruction* inst, const RegType& dst_type,
+ void CheckUnaryOp(MethodVerifier* verifier, const Instruction* inst, const RegType& dst_type,
const RegType& src_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckUnaryOpWide(const Instruction* inst,
+ void CheckUnaryOpWide(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type1, const RegType& dst_type2,
const RegType& src_type1, const RegType& src_type2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckUnaryOpToWide(const Instruction* inst,
+ void CheckUnaryOpToWide(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type1, const RegType& dst_type2,
const RegType& src_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckUnaryOpFromWide(const Instruction* inst,
+ void CheckUnaryOpFromWide(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type,
const RegType& src_type1, const RegType& src_type2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -204,18 +209,18 @@ class RegisterLine {
* "dst_type" is stored into vA, and "src_type1"/"src_type2" are verified
* against vB/vC.
*/
- void CheckBinaryOp(const Instruction* inst,
+ void CheckBinaryOp(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type, const RegType& src_type1, const RegType& src_type2,
bool check_boolean_op)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckBinaryOpWide(const Instruction* inst,
+ void CheckBinaryOpWide(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type1, const RegType& dst_type2,
const RegType& src_type1_1, const RegType& src_type1_2,
const RegType& src_type2_1, const RegType& src_type2_2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckBinaryOpWideShift(const Instruction* inst,
+ void CheckBinaryOpWideShift(MethodVerifier* verifier, const Instruction* inst,
const RegType& long_lo_type, const RegType& long_hi_type,
const RegType& int_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -224,19 +229,19 @@ class RegisterLine {
* Verify types for a binary "2addr" operation. "src_type1"/"src_type2"
* are verified against vA/vB, then "dst_type" is stored into vA.
*/
- void CheckBinaryOp2addr(const Instruction* inst,
+ void CheckBinaryOp2addr(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type,
const RegType& src_type1, const RegType& src_type2,
bool check_boolean_op)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckBinaryOp2addrWide(const Instruction* inst,
+ void CheckBinaryOp2addrWide(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type1, const RegType& dst_type2,
const RegType& src_type1_1, const RegType& src_type1_2,
const RegType& src_type2_1, const RegType& src_type2_2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CheckBinaryOp2addrWideShift(const Instruction* inst,
+ void CheckBinaryOp2addrWideShift(MethodVerifier* verifier, const Instruction* inst,
const RegType& long_lo_type, const RegType& long_hi_type,
const RegType& int_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -247,16 +252,18 @@ class RegisterLine {
*
* If "check_boolean_op" is set, we use the constant value in vC.
*/
- void CheckLiteralOp(const Instruction* inst,
+ void CheckLiteralOp(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type, const RegType& src_type,
bool check_boolean_op, bool is_lit16)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Verify/push monitor onto the monitor stack, locking the value in reg_idx at location insn_idx.
- void PushMonitor(uint32_t reg_idx, int32_t insn_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void PushMonitor(MethodVerifier* verifier, uint32_t reg_idx, int32_t insn_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Verify/pop monitor from monitor stack ensuring that we believe the monitor is locked
- void PopMonitor(uint32_t reg_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void PopMonitor(MethodVerifier* verifier, uint32_t reg_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Stack of currently held monitors and where they were locked
size_t MonitorStackDepth() const {
@@ -265,23 +272,23 @@ class RegisterLine {
// We expect no monitors to be held at certain points, such a method returns. Verify the stack
// is empty, failing and returning false if not.
- bool VerifyMonitorStackEmpty() const;
+ bool VerifyMonitorStackEmpty(MethodVerifier* verifier) const;
- bool MergeRegisters(const RegisterLine* incoming_line)
+ bool MergeRegisters(MethodVerifier* verifier, const RegisterLine* incoming_line)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- size_t GetMaxNonZeroReferenceReg(size_t max_ref_reg) {
+ size_t GetMaxNonZeroReferenceReg(MethodVerifier* verifier, size_t max_ref_reg) {
size_t i = static_cast<int>(max_ref_reg) < 0 ? 0 : max_ref_reg;
for (; i < num_regs_; i++) {
- if (GetRegisterType(i).IsNonZeroReferenceTypes()) {
+ if (GetRegisterType(verifier, i).IsNonZeroReferenceTypes()) {
max_ref_reg = i;
}
}
return max_ref_reg;
}
- // Write a bit at each register location that holds a reference
- void WriteReferenceBitMap(std::vector<uint8_t>& data, size_t max_bytes);
+ // Write a bit at each register location that holds a reference.
+ void WriteReferenceBitMap(MethodVerifier* verifier, std::vector<uint8_t>* data, size_t max_bytes);
size_t GetMonitorEnterCount() {
return monitors_.size();
@@ -337,19 +344,17 @@ class RegisterLine {
}
RegisterLine(size_t num_regs, MethodVerifier* verifier)
- : verifier_(verifier), num_regs_(num_regs) {
+ : num_regs_(num_regs) {
memset(&line_, 0, num_regs_ * sizeof(uint16_t));
- SetResultTypeToUnknown();
+ SetResultTypeToUnknown(verifier);
}
// Storage for the result register's type, valid after an invocation
uint16_t result_[2];
- // Back link to the verifier
- MethodVerifier* verifier_;
-
// Length of reg_types_
const uint32_t num_regs_;
+
// A stack of monitor enter locations
std::vector<uint32_t, TrackingAllocator<uint32_t, kAllocatorTagVerifier>> monitors_;
// A map from register to a bit vector of indices into the monitors_ stack. As we pop the monitor
@@ -360,7 +365,6 @@ class RegisterLine {
// An array of RegType Ids associated with each dex register.
uint16_t line_[0];
};
-std::ostream& operator<<(std::ostream& os, const RegisterLine& rhs);
} // namespace verifier
} // namespace art