ART: Clean up verifier
Clean up verifier post-Quick.
Change-Id: I0b05e10dd06edd228fe2068c8afffc4b7d7fdffa
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index 7c9ce1e..1491a18 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -64,7 +64,6 @@
DCHECK_EQ(it->second->GetDevirtMap().size(), verified_method->GetDevirtMap().size());
DCHECK_EQ(it->second->GetSafeCastSet().size(), verified_method->GetSafeCastSet().size());
}
- DCHECK_EQ(it->second->GetDexGcMap().size(), verified_method->GetDexGcMap().size());
// Delete the new verified method since there was already an existing one registered. It
// is unsafe to replace the existing one since the JIT may be using it to generate a
// native GC map.
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
index 9ae2164..5c0253c 100644
--- a/compiler/dex/verified_method.cc
+++ b/compiler/dex/verified_method.cc
@@ -30,7 +30,6 @@
#include "mirror/dex_cache-inl.h"
#include "mirror/object-inl.h"
#include "utils.h"
-#include "verifier/dex_gc_map.h"
#include "verifier/method_verifier-inl.h"
#include "verifier/reg_type-inl.h"
#include "verifier/register_line-inl.h"
@@ -49,14 +48,6 @@
method_verifier->HasInstructionThatWillThrow()));
if (compile) {
- /* Generate a register map. */
- if (!verified_method->GenerateGcMap(method_verifier)) {
- return nullptr; // Not a real failure, but a failure to encode.
- }
- if (kIsDebugBuild) {
- VerifyGcMap(method_verifier, verified_method->dex_gc_map_);
- }
-
// TODO: move this out when DEX-to-DEX supports devirtualization.
if (method_verifier->HasVirtualOrInterfaceInvokes()) {
verified_method->GenerateDevirtMap(method_verifier);
@@ -90,120 +81,6 @@
return std::binary_search(safe_cast_set_.begin(), safe_cast_set_.end(), pc);
}
-bool VerifiedMethod::GenerateGcMap(verifier::MethodVerifier* method_verifier) {
- DCHECK(dex_gc_map_.empty());
- size_t num_entries, ref_bitmap_bits, pc_bits;
- ComputeGcMapSizes(method_verifier, &num_entries, &ref_bitmap_bits, &pc_bits);
- const size_t ref_bitmap_bytes = RoundUp(ref_bitmap_bits, kBitsPerByte) / kBitsPerByte;
- static constexpr size_t kFormatBits = 3;
- // We have 16 - kFormatBits available for the ref_bitmap_bytes.
- if ((ref_bitmap_bytes >> (16u - kFormatBits)) != 0) {
- LOG(WARNING) << "Cannot encode GC map for method with " << ref_bitmap_bits << " registers: "
- << PrettyMethod(method_verifier->GetMethodReference().dex_method_index,
- *method_verifier->GetMethodReference().dex_file);
- return false;
- }
- // There are 2 bytes to encode the number of entries.
- if (num_entries > std::numeric_limits<uint16_t>::max()) {
- LOG(WARNING) << "Cannot encode GC map for method with " << num_entries << " entries: "
- << PrettyMethod(method_verifier->GetMethodReference().dex_method_index,
- *method_verifier->GetMethodReference().dex_file);
- return false;
- }
- size_t pc_bytes;
- verifier::RegisterMapFormat format;
- if (pc_bits <= kBitsPerByte) {
- format = verifier::kRegMapFormatCompact8;
- pc_bytes = 1;
- } else if (pc_bits <= kBitsPerByte * 2) {
- format = verifier::kRegMapFormatCompact16;
- pc_bytes = 2;
- } else {
- LOG(WARNING) << "Cannot encode GC map for method with "
- << (1 << pc_bits) << " instructions (number is rounded up to nearest power of 2): "
- << PrettyMethod(method_verifier->GetMethodReference().dex_method_index,
- *method_verifier->GetMethodReference().dex_file);
- return false;
- }
- size_t table_size = ((pc_bytes + ref_bitmap_bytes) * num_entries) + 4;
- dex_gc_map_.reserve(table_size);
- // Write table header.
- dex_gc_map_.push_back(format | ((ref_bitmap_bytes & ~0xFF) >> (kBitsPerByte - kFormatBits)));
- dex_gc_map_.push_back(ref_bitmap_bytes & 0xFF);
- dex_gc_map_.push_back(num_entries & 0xFF);
- dex_gc_map_.push_back((num_entries >> 8) & 0xFF);
- // Write table data.
- const DexFile::CodeItem* code_item = method_verifier->CodeItem();
- for (size_t i = 0; i < code_item->insns_size_in_code_units_; i++) {
- if (method_verifier->GetInstructionFlags(i).IsCompileTimeInfoPoint()) {
- dex_gc_map_.push_back(i & 0xFF);
- if (pc_bytes == 2) {
- dex_gc_map_.push_back((i >> 8) & 0xFF);
- }
- verifier::RegisterLine* line = method_verifier->GetRegLine(i);
- line->WriteReferenceBitMap(method_verifier, &dex_gc_map_, ref_bitmap_bytes);
- }
- }
- DCHECK_EQ(dex_gc_map_.size(), table_size);
- return true;
-}
-
-void VerifiedMethod::VerifyGcMap(verifier::MethodVerifier* method_verifier,
- const std::vector<uint8_t>& data) {
- // Check that for every GC point there is a map entry, there aren't entries for non-GC points,
- // that the table data is well formed and all references are marked (or not) in the bitmap.
- verifier::DexPcToReferenceMap map(&data[0]);
- CHECK_EQ(data.size(), map.RawSize()) << map.NumEntries() << " " << map.RegWidth();
- size_t map_index = 0;
- const DexFile::CodeItem* code_item = method_verifier->CodeItem();
- for (size_t i = 0; i < code_item->insns_size_in_code_units_; i++) {
- const uint8_t* reg_bitmap = map.FindBitMap(i, false);
- if (method_verifier->GetInstructionFlags(i).IsCompileTimeInfoPoint()) {
- DCHECK_LT(map_index, map.NumEntries());
- DCHECK_EQ(map.GetDexPc(map_index), i);
- DCHECK_EQ(map.GetBitMap(map_index), reg_bitmap);
- map_index++;
- verifier::RegisterLine* line = method_verifier->GetRegLine(i);
- for (size_t j = 0; j < code_item->registers_size_; j++) {
- if (line->GetRegisterType(method_verifier, j).IsNonZeroReferenceTypes()) {
- DCHECK_LT(j / kBitsPerByte, map.RegWidth());
- DCHECK_EQ((reg_bitmap[j / kBitsPerByte] >> (j % kBitsPerByte)) & 1, 1);
- } else if ((j / kBitsPerByte) < map.RegWidth()) {
- DCHECK_EQ((reg_bitmap[j / kBitsPerByte] >> (j % kBitsPerByte)) & 1, 0);
- } else {
- // If a register doesn't contain a reference then the bitmap may be shorter than the line.
- }
- }
- } else {
- DCHECK(i >= 65536 || reg_bitmap == nullptr);
- }
- }
-}
-
-void VerifiedMethod::ComputeGcMapSizes(verifier::MethodVerifier* method_verifier,
- size_t* gc_points, size_t* ref_bitmap_bits,
- size_t* log2_max_gc_pc) {
- size_t local_gc_points = 0;
- size_t max_insn = 0;
- size_t max_ref_reg = -1;
- const DexFile::CodeItem* code_item = method_verifier->CodeItem();
- for (size_t i = 0; i < code_item->insns_size_in_code_units_; i++) {
- if (method_verifier->GetInstructionFlags(i).IsCompileTimeInfoPoint()) {
- local_gc_points++;
- max_insn = i;
- verifier::RegisterLine* line = method_verifier->GetRegLine(i);
- max_ref_reg = line->GetMaxNonZeroReferenceReg(method_verifier, max_ref_reg);
- }
- }
- *gc_points = local_gc_points;
- *ref_bitmap_bits = max_ref_reg + 1; // If max register is 0 we need 1 bit to encode (ie +1).
- size_t i = 0;
- while ((1U << i) <= max_insn) {
- i++;
- }
- *log2_max_gc_pc = i;
-}
-
bool VerifiedMethod::GenerateDequickenMap(verifier::MethodVerifier* method_verifier) {
if (method_verifier->HasFailures()) {
return false;
diff --git a/compiler/dex/verified_method.h b/compiler/dex/verified_method.h
index 12d0219..495acf0 100644
--- a/compiler/dex/verified_method.h
+++ b/compiler/dex/verified_method.h
@@ -47,10 +47,6 @@
SHARED_REQUIRES(Locks::mutator_lock_);
~VerifiedMethod() = default;
- const std::vector<uint8_t>& GetDexGcMap() const {
- return dex_gc_map_;
- }
-
const DevirtualizationMap& GetDevirtMap() const {
return devirt_map_;
}
@@ -114,7 +110,6 @@
void GenerateSafeCastSet(verifier::MethodVerifier* method_verifier)
SHARED_REQUIRES(Locks::mutator_lock_);
- std::vector<uint8_t> dex_gc_map_;
DevirtualizationMap devirt_map_;
// Dequicken map is required for compiling quickened byte codes. The quicken maps from
// dex PC to dex method index or dex field index based on the instruction.
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 32869ec..f113921 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -54,7 +54,6 @@
#include "parallel_move_resolver.h"
#include "ssa_liveness_analysis.h"
#include "utils/assembler.h"
-#include "verifier/dex_gc_map.h"
#include "vmap_table.h"
namespace art {
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 48a9d91..335b6e1 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -61,7 +61,6 @@
#include "stack_map.h"
#include "ScopedLocalRef.h"
#include "thread_list.h"
-#include "verifier/dex_gc_map.h"
#include "verifier/method_verifier.h"
#include "vmap_table.h"
#include "well_known_classes.h"
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 0c6541e..542a2c4 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -187,7 +187,6 @@
type_lookup_table.cc \
utf.cc \
utils.cc \
- verifier/dex_gc_map.cc \
verifier/instruction_flags.cc \
verifier/method_verifier.cc \
verifier/reg_type.cc \
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 6317f5e..6d1403c 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -342,11 +342,7 @@
updated_vregs = GetThread()->GetUpdatedVRegFlags(frame_id);
DCHECK(updated_vregs != nullptr);
}
- if (GetCurrentOatQuickMethodHeader()->IsOptimized()) {
- HandleOptimizingDeoptimization(method, new_frame, updated_vregs);
- } else {
- HandleQuickDeoptimization(method, new_frame, updated_vregs);
- }
+ HandleOptimizingDeoptimization(method, new_frame, updated_vregs);
if (updated_vregs != nullptr) {
// Calling Thread::RemoveDebuggerShadowFrameMapping will also delete the updated_vregs
// array so this must come after we processed the frame.
@@ -475,132 +471,6 @@
return static_cast<VRegKind>(kinds.at(reg * 2));
}
- void HandleQuickDeoptimization(ArtMethod* m,
- ShadowFrame* new_frame,
- const bool* updated_vregs)
- SHARED_REQUIRES(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = m->GetCodeItem();
- CHECK(code_item != nullptr) << "No code item for " << PrettyMethod(m);
- uint16_t num_regs = code_item->registers_size_;
- uint32_t dex_pc = GetDexPc();
- StackHandleScope<2> hs(GetThread()); // Dex cache and class loader.
- mirror::Class* declaring_class = m->GetDeclaringClass();
- Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
- Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
- verifier::MethodVerifier verifier(GetThread(), h_dex_cache->GetDexFile(), h_dex_cache,
- h_class_loader, &m->GetClassDef(), code_item,
- m->GetDexMethodIndex(), m, m->GetAccessFlags(), true, true,
- true, true);
- bool verifier_success = verifier.Verify();
- CHECK(verifier_success) << PrettyMethod(m);
- {
- ScopedStackedShadowFramePusher pusher(GetThread(), new_frame,
- StackedShadowFrameType::kShadowFrameUnderConstruction);
- const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
-
- // Markers for dead values, used when the verifier knows a Dex register is undefined,
- // or when the compiler knows the register has not been initialized, or is not used
- // anymore in the method.
- static constexpr uint32_t kDeadValue = 0xEBADDE09;
- static constexpr uint64_t kLongDeadValue = 0xEBADDE09EBADDE09;
- for (uint16_t reg = 0; reg < num_regs; ++reg) {
- if (updated_vregs != nullptr && updated_vregs[reg]) {
- // Keep the value set by debugger.
- continue;
- }
- VRegKind kind = GetVRegKind(reg, kinds);
- switch (kind) {
- case kUndefined:
- new_frame->SetVReg(reg, kDeadValue);
- break;
- case kConstant:
- new_frame->SetVReg(reg, kinds.at((reg * 2) + 1));
- break;
- case kReferenceVReg: {
- uint32_t value = 0;
- // Check IsReferenceVReg in case the compiled GC map doesn't agree with the verifier.
- // We don't want to copy a stale reference into the shadow frame as a reference.
- // b/20736048
- if (GetVReg(m, reg, kind, &value) && IsReferenceVReg(m, reg)) {
- new_frame->SetVRegReference(reg, reinterpret_cast<mirror::Object*>(value));
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- break;
- }
- case kLongLoVReg:
- if (GetVRegKind(reg + 1, kinds) == kLongHiVReg) {
- // Treat it as a "long" register pair.
- uint64_t value = 0;
- if (GetVRegPair(m, reg, kLongLoVReg, kLongHiVReg, &value)) {
- new_frame->SetVRegLong(reg, value);
- } else {
- new_frame->SetVRegLong(reg, kLongDeadValue);
- }
- } else {
- uint32_t value = 0;
- if (GetVReg(m, reg, kind, &value)) {
- new_frame->SetVReg(reg, value);
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- }
- break;
- case kLongHiVReg:
- if (GetVRegKind(reg - 1, kinds) == kLongLoVReg) {
- // Nothing to do: we treated it as a "long" register pair.
- } else {
- uint32_t value = 0;
- if (GetVReg(m, reg, kind, &value)) {
- new_frame->SetVReg(reg, value);
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- }
- break;
- case kDoubleLoVReg:
- if (GetVRegKind(reg + 1, kinds) == kDoubleHiVReg) {
- uint64_t value = 0;
- if (GetVRegPair(m, reg, kDoubleLoVReg, kDoubleHiVReg, &value)) {
- // Treat it as a "double" register pair.
- new_frame->SetVRegLong(reg, value);
- } else {
- new_frame->SetVRegLong(reg, kLongDeadValue);
- }
- } else {
- uint32_t value = 0;
- if (GetVReg(m, reg, kind, &value)) {
- new_frame->SetVReg(reg, value);
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- }
- break;
- case kDoubleHiVReg:
- if (GetVRegKind(reg - 1, kinds) == kDoubleLoVReg) {
- // Nothing to do: we treated it as a "double" register pair.
- } else {
- uint32_t value = 0;
- if (GetVReg(m, reg, kind, &value)) {
- new_frame->SetVReg(reg, value);
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- }
- break;
- default:
- uint32_t value = 0;
- if (GetVReg(m, reg, kind, &value)) {
- new_frame->SetVReg(reg, value);
- } else {
- new_frame->SetVReg(reg, kDeadValue);
- }
- break;
- }
- }
- }
- }
-
QuickExceptionHandler* const exception_handler_;
ShadowFrame* prev_shadow_frame_;
bool stacked_shadow_frame_pushed_;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 42b5a4a..e3adf9f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -70,7 +70,6 @@
#include "thread_list.h"
#include "thread-inl.h"
#include "utils.h"
-#include "verifier/dex_gc_map.h"
#include "verifier/method_verifier.h"
#include "verify_object-inl.h"
#include "vmap_table.h"
diff --git a/runtime/verifier/dex_gc_map.cc b/runtime/verifier/dex_gc_map.cc
deleted file mode 100644
index c435f9f..0000000
--- a/runtime/verifier/dex_gc_map.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "verifier/dex_gc_map.h"
-
-#include "base/logging.h"
-
-namespace art {
-namespace verifier {
-
-const uint8_t* DexPcToReferenceMap::FindBitMap(uint16_t dex_pc, bool error_if_not_present) const {
- size_t num_entries = NumEntries();
- // Do linear or binary search?
- static const size_t kSearchThreshold = 8;
- if (num_entries < kSearchThreshold) {
- for (size_t i = 0; i < num_entries; i++) {
- if (GetDexPc(i) == dex_pc) {
- return GetBitMap(i);
- }
- }
- } else {
- int lo = 0;
- int hi = num_entries -1;
- while (hi >= lo) {
- int mid = (hi + lo) / 2;
- int mid_pc = GetDexPc(mid);
- if (dex_pc > mid_pc) {
- lo = mid + 1;
- } else if (dex_pc < mid_pc) {
- hi = mid - 1;
- } else {
- return GetBitMap(mid);
- }
- }
- }
- if (error_if_not_present) {
- LOG(ERROR) << "Didn't find reference bit map for dex_pc " << dex_pc;
- }
- return nullptr;
-}
-
-} // namespace verifier
-} // namespace art
diff --git a/runtime/verifier/dex_gc_map.h b/runtime/verifier/dex_gc_map.h
deleted file mode 100644
index 03a7821..0000000
--- a/runtime/verifier/dex_gc_map.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
-#define ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
-
-#include <stdint.h>
-
-#include "base/logging.h"
-#include "base/macros.h"
-
-namespace art {
-namespace verifier {
-
-/*
- * Format enumeration for RegisterMap data area.
- */
-enum RegisterMapFormat {
- kRegMapFormatUnknown = 0,
- kRegMapFormatNone = 1, // Indicates no map data follows.
- kRegMapFormatCompact8 = 2, // Compact layout, 8-bit addresses.
- kRegMapFormatCompact16 = 3, // Compact layout, 16-bit addresses.
-};
-
-// Lightweight wrapper for Dex PC to reference bit maps.
-class DexPcToReferenceMap {
- public:
- explicit DexPcToReferenceMap(const uint8_t* data) : data_(data) {
- CHECK(data_ != nullptr);
- }
-
- // The total size of the reference bit map including header.
- size_t RawSize() const {
- return EntryWidth() * NumEntries() + 4u /* header */;
- }
-
- // The number of entries in the table
- size_t NumEntries() const {
- return GetData()[2] | (GetData()[3] << 8);
- }
-
- // Get the Dex PC at the given index
- uint16_t GetDexPc(size_t index) const {
- size_t entry_offset = index * EntryWidth();
- if (DexPcWidth() == 1) {
- return Table()[entry_offset];
- } else {
- return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
- }
- }
-
- // Return address of bitmap encoding what are live references
- const uint8_t* GetBitMap(size_t index) const {
- size_t entry_offset = index * EntryWidth();
- return &Table()[entry_offset + DexPcWidth()];
- }
-
- // Find the bitmap associated with the given dex pc
- const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const;
-
- // The number of bytes used to encode registers
- size_t RegWidth() const {
- return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift);
- }
-
- private:
- // Table of num_entries * (dex pc, bitmap)
- const uint8_t* Table() const {
- return GetData() + 4;
- }
-
- // The format of the table of the PCs for the table
- RegisterMapFormat Format() const {
- return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
- }
-
- // Number of bytes used to encode a dex pc
- size_t DexPcWidth() const {
- RegisterMapFormat format = Format();
- switch (format) {
- case kRegMapFormatCompact8:
- return 1;
- case kRegMapFormatCompact16:
- return 2;
- default:
- LOG(FATAL) << "Invalid format " << static_cast<int>(format);
- return -1;
- }
- }
-
- // The width of an entry in the table
- size_t EntryWidth() const {
- return DexPcWidth() + RegWidth();
- }
-
- const uint8_t* GetData() const {
- return data_;
- }
-
- static const int kRegMapFormatShift = 5;
- static const uint8_t kRegMapFormatMask = 0x7;
-
- const uint8_t* const data_; // The header and table data
-};
-
-} // namespace verifier
-} // namespace art
-
-#endif // ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 55d1720..5109443 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -47,7 +47,6 @@
#include "scoped_thread_state_change.h"
#include "utils.h"
#include "handle_scope-inl.h"
-#include "verifier/dex_gc_map.h"
namespace art {
namespace verifier {
@@ -367,9 +366,20 @@
MethodVerifier::FailureData result;
uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
- MethodVerifier verifier(self, dex_file, dex_cache, class_loader, class_def, code_item,
- method_idx, method, method_access_flags, true, allow_soft_failures,
- need_precise_constants, true);
+ MethodVerifier verifier(self,
+ dex_file,
+ dex_cache,
+ class_loader,
+ class_def,
+ code_item,
+ method_idx,
+ method,
+ method_access_flags,
+ true /* can_load_classes */,
+ allow_soft_failures,
+ need_precise_constants,
+ false /* verify to dump */,
+ true /* allow_thread_suspension */);
if (verifier.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
// to hard fail.
@@ -441,9 +451,20 @@
const DexFile::CodeItem* code_item,
ArtMethod* method,
uint32_t method_access_flags) {
- MethodVerifier* verifier = new MethodVerifier(self, dex_file, dex_cache, class_loader,
- class_def, code_item, dex_method_idx, method,
- method_access_flags, true, true, true, true);
+ MethodVerifier* verifier = new MethodVerifier(self,
+ dex_file,
+ dex_cache,
+ class_loader,
+ class_def,
+ code_item,
+ dex_method_idx,
+ method,
+ method_access_flags,
+ true /* can_load_classes */,
+ true /* allow_soft_failures */,
+ true /* need_precise_constants */,
+ true /* verify_to_dump */,
+ true /* allow_thread_suspension */);
verifier->Verify();
verifier->DumpFailures(vios->Stream());
vios->Stream() << verifier->info_messages_.str();
@@ -520,9 +541,20 @@
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
- MethodVerifier verifier(hs.Self(), m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(),
- false, true, false, false);
+ MethodVerifier verifier(hs.Self(),
+ m->GetDexFile(),
+ dex_cache,
+ class_loader,
+ &m->GetClassDef(),
+ m->GetCodeItem(),
+ m->GetDexMethodIndex(),
+ m,
+ m->GetAccessFlags(),
+ false /* can_load_classes */,
+ true /* allow_soft_failures */,
+ false /* need_precise_constants */,
+ false /* verify_to_dump */,
+ false /* allow_thread_suspension */);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
verifier.FindLocksAtDexPc();
@@ -564,9 +596,20 @@
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
- MethodVerifier verifier(hs.Self(), m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false, true);
+ MethodVerifier verifier(hs.Self(),
+ m->GetDexFile(),
+ dex_cache,
+ class_loader,
+ &m->GetClassDef(),
+ m->GetCodeItem(),
+ m->GetDexMethodIndex(),
+ m,
+ m->GetAccessFlags(),
+ true /* can_load_classes */,
+ true /* allow_soft_failures */,
+ false /* need_precise_constants */,
+ false /* verify_to_dump */,
+ true /* allow_thread_suspension */);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -593,9 +636,20 @@
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
- MethodVerifier verifier(hs.Self(), m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false, true);
+ MethodVerifier verifier(hs.Self(),
+ m->GetDexFile(),
+ dex_cache,
+ class_loader,
+ &m->GetClassDef(),
+ m->GetCodeItem(),
+ m->GetDexMethodIndex(),
+ m,
+ m->GetAccessFlags(),
+ true /* can_load_classes */,
+ true /* allow_soft_failures */,
+ false /* need_precise_constants */,
+ false /* verify_to_dump */,
+ true /* allow_thread_suspension */);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 6d8e1ab..ba9bca0 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -43,7 +43,6 @@
namespace verifier {
-class DexPcToReferenceMap;
class MethodVerifier;
class RegisterLine;
using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>;
@@ -220,35 +219,6 @@
return can_load_classes_;
}
- MethodVerifier(Thread* self,
- const DexFile* dex_file,
- Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader,
- const DexFile::ClassDef* class_def,
- const DexFile::CodeItem* code_item,
- uint32_t method_idx,
- ArtMethod* method,
- uint32_t access_flags,
- bool can_load_classes,
- bool allow_soft_failures,
- bool need_precise_constants,
- bool allow_thread_suspension)
- SHARED_REQUIRES(Locks::mutator_lock_)
- : MethodVerifier(self,
- dex_file,
- dex_cache,
- class_loader,
- class_def,
- code_item,
- method_idx,
- method,
- access_flags,
- can_load_classes,
- allow_soft_failures,
- need_precise_constants,
- false,
- allow_thread_suspension) {}
-
~MethodVerifier();
// Run verification on the method. Returns true if verification completes and false if the input
@@ -304,20 +274,6 @@
}
private:
- void UninstantiableError(const char* descriptor);
- static bool IsInstantiableOrPrimitive(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_);
-
- // Is the method being verified a constructor? See the comment on the field.
- bool IsConstructor() const {
- return is_constructor_;
- }
-
- // Is the method verified static?
- bool IsStatic() const {
- return (method_access_flags_ & kAccStatic) != 0;
- }
-
- // Private constructor for dumping.
MethodVerifier(Thread* self,
const DexFile* dex_file,
Handle<mirror::DexCache> dex_cache,
@@ -334,6 +290,19 @@
bool allow_thread_suspension)
SHARED_REQUIRES(Locks::mutator_lock_);
+ void UninstantiableError(const char* descriptor);
+ static bool IsInstantiableOrPrimitive(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_);
+
+ // Is the method being verified a constructor? See the comment on the field.
+ bool IsConstructor() const {
+ return is_constructor_;
+ }
+
+ // Is the method verified static?
+ bool IsStatic() const {
+ return (method_access_flags_ & kAccStatic) != 0;
+ }
+
// Adds the given string to the beginning of the last failure message.
void PrependToLastFailMessage(std::string);
diff --git a/runtime/verifier/register_line-inl.h b/runtime/verifier/register_line-inl.h
index 29d87c4..d2f3485 100644
--- a/runtime/verifier/register_line-inl.h
+++ b/runtime/verifier/register_line-inl.h
@@ -127,17 +127,6 @@
}
}
-inline size_t RegisterLine::GetMaxNonZeroReferenceReg(MethodVerifier* verifier,
- size_t max_ref_reg) const {
- size_t i = static_cast<int>(max_ref_reg) < 0 ? 0 : max_ref_reg;
- for (; i < num_regs_; i++) {
- if (GetRegisterType(verifier, i).IsNonZeroReferenceTypes()) {
- max_ref_reg = i;
- }
- }
- return max_ref_reg;
-}
-
inline bool RegisterLine::VerifyRegisterType(MethodVerifier* verifier, uint32_t vsrc,
const RegType& check_type) {
// Verify the src register type against the check type refining the type of the register
diff --git a/runtime/verifier/register_line.cc b/runtime/verifier/register_line.cc
index 82c371d..71aa94e 100644
--- a/runtime/verifier/register_line.cc
+++ b/runtime/verifier/register_line.cc
@@ -543,24 +543,5 @@
return changed;
}
-void RegisterLine::WriteReferenceBitMap(MethodVerifier* verifier,
- std::vector<uint8_t>* data, size_t max_bytes) {
- for (size_t i = 0; i < num_regs_; i += 8) {
- uint8_t val = 0;
- for (size_t j = 0; j < 8 && (i + j) < num_regs_; j++) {
- // Note: we write 1 for a Reference but not for Null
- if (GetRegisterType(verifier, i + j).IsNonZeroReferenceTypes()) {
- val |= 1 << j;
- }
- }
- if ((i / 8) >= max_bytes) {
- DCHECK_EQ(0, val);
- continue;
- }
- DCHECK_LT(i / 8, max_bytes) << "val=" << static_cast<uint32_t>(val);
- data->push_back(val);
- }
-}
-
} // namespace verifier
} // namespace art
diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h
index 15ae202..56846c1 100644
--- a/runtime/verifier/register_line.h
+++ b/runtime/verifier/register_line.h
@@ -346,11 +346,6 @@
bool MergeRegisters(MethodVerifier* verifier, const RegisterLine* incoming_line)
SHARED_REQUIRES(Locks::mutator_lock_);
- size_t GetMaxNonZeroReferenceReg(MethodVerifier* verifier, size_t max_ref_reg) const;
-
- // 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() const {
return monitors_.size();
}