summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2011-11-02 17:12:02 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-11-02 17:12:02 -0700
commit0b3a52a3ec75f1a248e040b267776c68d016e940 (patch)
tree4f639e995a2dc081a9a5f6e2e489d722b122eb69 /src
parentff9146509a092d23f6837525a24831a0e3fb5155 (diff)
parent55d249fc84c313aa071a717f53f9164fa49e2a59 (diff)
downloadart-0b3a52a3ec75f1a248e040b267776c68d016e940.zip
art-0b3a52a3ec75f1a248e040b267776c68d016e940.tar.gz
art-0b3a52a3ec75f1a248e040b267776c68d016e940.tar.bz2
Merge "Fix monitor stack depth bug, allow unresolved field in put." into dalvik-dev
Diffstat (limited to 'src')
-rw-r--r--src/dex_verifier.cc37
-rw-r--r--src/dex_verifier.h10
2 files changed, 32 insertions, 15 deletions
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 5ab21bb..3ad9996 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -766,7 +766,7 @@ void RegisterLine::PushMonitor(uint32_t reg_idx, int32_t insn_idx) {
verifier_->Fail(VERIFY_ERROR_GENERIC) << "monitor-enter on non-object (" << reg_type << ")";
} else {
SetRegToLockDepth(reg_idx, monitors_.size());
- monitors_.push(insn_idx);
+ monitors_.push_back(insn_idx);
}
}
@@ -777,7 +777,7 @@ void RegisterLine::PopMonitor(uint32_t reg_idx) {
} else if (monitors_.empty()) {
verifier_->Fail(VERIFY_ERROR_GENERIC) << "monitor-exit stack underflow";
} else {
- monitors_.pop();
+ monitors_.pop_back();
if(!IsSetLockDepth(reg_idx, monitors_.size())) {
// Bug 3215458: Locks and unlocks are on objects, if that object is a literal then before
// format "036" the constant collector may create unlocks on the same object but referenced
@@ -812,7 +812,7 @@ bool RegisterLine::MergeRegisters(const RegisterLine* incoming_line) {
line_[idx] = new_type.GetId();
}
}
- if(monitors_ != incoming_line->monitors_) {
+ if(monitors_.size() != incoming_line->monitors_.size()) {
verifier_->Fail(VERIFY_ERROR_GENERIC) << "mismatched stack depths (depth="
<< MonitorStackDepth() << ", incoming depth=" << incoming_line->MonitorStackDepth() << ")";
} else if (reg_to_lock_depths_ != incoming_line->reg_to_lock_depths_) {
@@ -3407,22 +3407,35 @@ void DexVerifier::VerifyISGet(const Instruction::DecodedInstruction& dec_insn,
void DexVerifier::VerifyISPut(const Instruction::DecodedInstruction& dec_insn,
const RegType& insn_type, bool is_primitive, bool is_static) {
+ uint32_t field_idx = is_static ? dec_insn.vB_ : dec_insn.vC_;
Field* field;
if (is_static) {
- field = GetStaticField(dec_insn.vB_);
+ field = GetStaticField(field_idx);
} else {
const RegType& object_type = work_line_->GetRegisterType(dec_insn.vB_);
- field = GetInstanceField(object_type, dec_insn.vC_);
+ field = GetInstanceField(object_type, field_idx);
}
- if (field != NULL) {
- if (field->IsFinal() && field->GetDeclaringClass() != method_->GetDeclaringClass()) {
- Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
+ if (failure_ != VERIFY_ERROR_NONE) {
+ work_line_->SetRegisterType(dec_insn.vA_, reg_types_.Unknown());
+ } else {
+ const char* descriptor;
+ const ClassLoader* loader;
+ if (field != NULL) {
+ descriptor = field->GetTypeDescriptor();
+ loader = field->GetDeclaringClass()->GetClassLoader();
+ } else {
+ const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
+ descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
+ loader = method_->GetDeclaringClass()->GetClassLoader();
+ }
+ const RegType& field_type = reg_types_.FromDescriptor(loader, descriptor);
+ if (field != NULL) {
+ if (field->IsFinal() && field->GetDeclaringClass() != method_->GetDeclaringClass()) {
+ Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
<< " from other class " << PrettyClass(method_->GetDeclaringClass());
- return;
+ return;
+ }
}
- const RegType& field_type =
- reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
- field->GetTypeDescriptor());
if (is_primitive) {
// Primitive field assignability rules are weaker than regular assignability rules
bool instruction_compatible;
diff --git a/src/dex_verifier.h b/src/dex_verifier.h
index dbe92f6..a703cbc 100644
--- a/src/dex_verifier.h
+++ b/src/dex_verifier.h
@@ -11,9 +11,9 @@
#include "stl_util.h"
#include "UniquePtr.h"
+#include <deque>
#include <limits>
#include <map>
-#include <stack>
#include <vector>
namespace art {
@@ -572,13 +572,17 @@ class RegisterLine {
result += GetRegisterType(i).Dump();
result += "],";
}
+ typedef std::deque<uint32_t>::const_iterator It; // TODO: C++0x auto
+ for (It it = monitors_.begin(), end = monitors_.end(); it != end ; ++it) {
+ result += StringPrintf("{%d},", *it);
+ }
return result;
}
void FillWithGarbage() {
memset(line_.get(), 0xf1, num_regs_ * sizeof(uint16_t));
while (!monitors_.empty()) {
- monitors_.pop();
+ monitors_.pop_back();
}
reg_to_lock_depths_.clear();
}
@@ -758,7 +762,7 @@ class RegisterLine {
// Length of reg_types_
const size_t num_regs_;
// A stack of monitor enter locations
- std::stack<uint32_t> monitors_;
+ std::deque<uint32_t> monitors_;
// A map from register to a bit vector of indices into the monitors_ stack. As we pop the monitor
// stack we verify that monitor-enter/exit are correctly nested. That is, if there was a
// monitor-enter on v5 and then on v6, we expect the monitor-exit to be on v6 then on v5