summaryrefslogtreecommitdiffstats
path: root/src/verifier/method_verifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/verifier/method_verifier.cc')
-rw-r--r--src/verifier/method_verifier.cc138
1 files changed, 8 insertions, 130 deletions
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index a3132df7a4..2b70e265d4 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -56,8 +56,8 @@ void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* fl
case kTrackRegsAll:
interesting = flags[i].IsOpcode();
break;
- case kTrackCompilerInterestPoints:
- interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget() ;
+ case kTrackRegsGcPoints:
+ interesting = flags[i].IsGcPoint() || flags[i].IsBranchTarget();
break;
case kTrackRegsBranches:
interesting = flags[i].IsBranchTarget();
@@ -496,7 +496,7 @@ bool MethodVerifier::VerifyInstructions() {
/* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */
insn_flags_[0].SetBranchTarget();
- insn_flags_[0].SetCompileTimeInfoPoint();
+ insn_flags_[0].SetGcPoint();
uint32_t insns_size = code_item_->insns_size_in_code_units_;
for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
@@ -505,10 +505,8 @@ bool MethodVerifier::VerifyInstructions() {
return false;
}
/* Flag instructions that are garbage collection points */
- // All invoke points are marked as "Throw" points already.
- // We are relying on this to also count all the invokes as interesting.
if (inst->IsBranch() || inst->IsSwitch() || inst->IsThrow() || inst->IsReturn()) {
- insn_flags_[dex_pc].SetCompileTimeInfoPoint();
+ insn_flags_[dex_pc].SetGcPoint();
}
dex_pc += inst->SizeInCodeUnits();
inst = inst->Next();
@@ -920,8 +918,7 @@ bool MethodVerifier::VerifyCodeFlow() {
<< " insns_size=" << insns_size << ")";
}
/* Create and initialize table holding register status */
- reg_table_.Init(kTrackCompilerInterestPoints, insn_flags_.get(), insns_size, registers_size, this);
-
+ reg_table_.Init(kTrackRegsGcPoints, insn_flags_.get(), insns_size, registers_size, this);
work_line_.reset(new RegisterLine(registers_size, this));
saved_line_.reset(new RegisterLine(registers_size, this));
@@ -955,10 +952,6 @@ bool MethodVerifier::VerifyCodeFlow() {
const std::vector<uint8_t>* dex_gc_map = CreateLengthPrefixedDexGcMap(*(map.get()));
verifier::MethodVerifier::SetDexGcMap(ref, *dex_gc_map);
- MethodVerifier::PcToConreteMethod* pc_to_conrete_method = GenerateDevirtMap();
- if(pc_to_conrete_method != NULL ) {
- SetDevirtMap(ref, pc_to_conrete_method);
- }
return true;
}
@@ -3144,7 +3137,7 @@ void MethodVerifier::ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bit
size_t max_insn = 0;
size_t max_ref_reg = -1;
for (size_t i = 0; i < code_item_->insns_size_in_code_units_; i++) {
- if (insn_flags_[i].IsCompileTimeInfoPoint()) {
+ if (insn_flags_[i].IsGcPoint()) {
local_gc_points++;
max_insn = i;
RegisterLine* line = reg_table_.GetLine(i);
@@ -3160,72 +3153,6 @@ void MethodVerifier::ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bit
*log2_max_gc_pc = i;
}
-MethodVerifier::PcToConreteMethod* MethodVerifier::GenerateDevirtMap() {
-
- PcToConreteMethod* pc_to_concrete_method = new PcToConreteMethod();
- uint32_t dex_pc = 0;
- const uint16_t* insns = code_item_->insns_ ;
- const Instruction* inst = Instruction::At(insns);
-
- for (; dex_pc < code_item_->insns_size_in_code_units_;
- dex_pc += insn_flags_[dex_pc].GetLengthInCodeUnits(), inst = inst->Next()) {
-
- bool is_virtual = (inst->Opcode() == Instruction::INVOKE_VIRTUAL) ||
- (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE);
- bool is_interface = (inst->Opcode() == Instruction::INVOKE_INTERFACE) ||
- (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
-
- if(!(is_interface || is_virtual))
- continue;
-
- // Check if vC ("this" pointer in the instruction) has a precise type.
- RegisterLine* line = reg_table_.GetLine(dex_pc);
- DecodedInstruction dec_insn(inst);
- const RegType& reg_type(line->GetRegisterType(dec_insn.vC));
-
- if (!reg_type.IsPreciseReference()) {
- continue;
- }
-
- CHECK(!(reg_type.GetClass()->IsInterface()));
- // If the class is an array class, it can be both Abstract and final and so
- // the reg_type will be created as precise.
- CHECK(!(reg_type.GetClass()->IsAbstract()) || reg_type.GetClass()->IsArrayClass());
- // Find the abstract method.
- // vB has the method index.
- mirror::AbstractMethod* abstract_method = NULL ;
- abstract_method = dex_cache_->GetResolvedMethod(dec_insn.vB);
- if(abstract_method == NULL) {
- // If the method is not found in the cache this means that it was never found
- // by ResolveMethodAndCheckAccess() called when verifying invoke_*.
- continue;
- }
- // Find the concrete method.
- mirror::AbstractMethod* concrete_method = NULL;
- if (is_interface) {
- concrete_method = reg_type.GetClass()->FindVirtualMethodForInterface(abstract_method);
- }
- if (is_virtual) {
- concrete_method = reg_type.GetClass()->FindVirtualMethodForVirtual(abstract_method);
- }
- CHECK(concrete_method != NULL);
- CHECK(!concrete_method->IsAbstract()) << PrettyMethod(concrete_method);
- // Build method reference.
- CompilerDriver::MethodReference concrete_ref(
- concrete_method->GetDeclaringClass()->GetDexCache()->GetDexFile(),
- concrete_method->GetDexMethodIndex());
- // Now Save the current PC and the concrete method reference to be used
- // in compiler driver.
- pc_to_concrete_method->Put(dex_pc, concrete_ref );
- }
-
- if (pc_to_concrete_method->size() == 0) {
- delete pc_to_concrete_method;
- return NULL ;
- }
- return pc_to_concrete_method;
-}
-
const std::vector<uint8_t>* MethodVerifier::GenerateGcMap() {
size_t num_entries, ref_bitmap_bits, pc_bits;
ComputeGcMapSizes(&num_entries, &ref_bitmap_bits, &pc_bits);
@@ -3272,7 +3199,7 @@ const std::vector<uint8_t>* MethodVerifier::GenerateGcMap() {
table->push_back((num_entries >> 8) & 0xFF);
// Write table data
for (size_t i = 0; i < code_item_->insns_size_in_code_units_; i++) {
- if (insn_flags_[i].IsCompileTimeInfoPoint()) {
+ if (insn_flags_[i].IsGcPoint()) {
table->push_back(i & 0xFF);
if (pc_bytes == 2) {
table->push_back((i >> 8) & 0xFF);
@@ -3292,7 +3219,7 @@ void MethodVerifier::VerifyGcMap(const std::vector<uint8_t>& data) {
size_t map_index = 0;
for (size_t i = 0; i < code_item_->insns_size_in_code_units_; i++) {
const uint8_t* reg_bitmap = map.FindBitMap(i, false);
- if (insn_flags_[i].IsCompileTimeInfoPoint()) {
+ if (insn_flags_[i].IsGcPoint()) {
CHECK_LT(map_index, map.NumEntries());
CHECK_EQ(map.GetDexPc(map_index), i);
CHECK_EQ(map.GetBitMap(map_index), reg_bitmap);
@@ -3327,21 +3254,6 @@ void MethodVerifier::SetDexGcMap(CompilerDriver::MethodReference ref, const std:
CHECK(GetDexGcMap(ref) != NULL);
}
-
-void MethodVerifier::SetDevirtMap(CompilerDriver::MethodReference ref, const PcToConreteMethod* devirt_map) {
-
- MutexLock mu(Thread::Current(), *devirt_maps_lock_);
- DevirtualizationMapTable::iterator it = devirt_maps_->find(ref);
- if (it != devirt_maps_->end()) {
- delete it->second;
- devirt_maps_->erase(it);
- }
-
- devirt_maps_->Put(ref, devirt_map);
- CHECK(devirt_maps_->find(ref) != devirt_maps_->end());
-}
-
-
const std::vector<uint8_t>* MethodVerifier::GetDexGcMap(CompilerDriver::MethodReference ref) {
MutexLock mu(Thread::Current(), *dex_gc_maps_lock_);
DexGcMapTable::const_iterator it = dex_gc_maps_->find(ref);
@@ -3353,22 +3265,6 @@ const std::vector<uint8_t>* MethodVerifier::GetDexGcMap(CompilerDriver::MethodRe
return it->second;
}
-const CompilerDriver::MethodReference* MethodVerifier::GetDevirtMap(CompilerDriver::MethodReference ref, uint32_t pc) {
- MutexLock mu(Thread::Current(), *devirt_maps_lock_);
- DevirtualizationMapTable::const_iterator it = devirt_maps_->find(ref);
- if (it == devirt_maps_->end()) {
- return NULL;
- }
-
- // Look up the PC in the map, get the concrete method to execute and return its reference.
- MethodVerifier::PcToConreteMethod::const_iterator pc_to_concrete_method = it->second->find(pc);
- if(pc_to_concrete_method != it->second->end()) {
- return &(pc_to_concrete_method->second);
- } else {
- return NULL;
- }
-}
-
std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
RegisterLine* line = reg_table_.GetLine(dex_pc);
std::vector<int32_t> result;
@@ -3416,9 +3312,6 @@ std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
Mutex* MethodVerifier::dex_gc_maps_lock_ = NULL;
MethodVerifier::DexGcMapTable* MethodVerifier::dex_gc_maps_ = NULL;
-Mutex* MethodVerifier::devirt_maps_lock_ = NULL;
-MethodVerifier::DevirtualizationMapTable* MethodVerifier::devirt_maps_ = NULL;
-
Mutex* MethodVerifier::rejected_classes_lock_ = NULL;
MethodVerifier::RejectedClassesTable* MethodVerifier::rejected_classes_ = NULL;
@@ -3430,12 +3323,6 @@ void MethodVerifier::Init() {
dex_gc_maps_ = new MethodVerifier::DexGcMapTable;
}
- devirt_maps_lock_ = new Mutex("verifier Devirtualization lock");
- {
- MutexLock mu(self, *devirt_maps_lock_);
- devirt_maps_ = new MethodVerifier::DevirtualizationMapTable();
- }
-
rejected_classes_lock_ = new Mutex("verifier rejected classes lock");
{
MutexLock mu(self, *rejected_classes_lock_);
@@ -3456,15 +3343,6 @@ void MethodVerifier::Shutdown() {
dex_gc_maps_lock_ = NULL;
{
- MutexLock mu(self, *devirt_maps_lock_);
- STLDeleteValues(devirt_maps_);
- delete devirt_maps_;
- devirt_maps_ = NULL;
- }
- delete devirt_maps_lock_;
- devirt_maps_lock_ = NULL;
-
- {
MutexLock mu(self, *rejected_classes_lock_);
delete rejected_classes_;
rejected_classes_ = NULL;