Ensure method GC maps are setup during runtime verification
Change-Id: Icd5013710a269cc6df439e36c534a8d40c1e3324
diff --git a/src/compiled_method.cc b/src/compiled_method.cc
index 40230b4..ca7858a 100644
--- a/src/compiled_method.cc
+++ b/src/compiled_method.cc
@@ -50,22 +50,7 @@
CHECK_NE(mapping_table_.size(), 0U);
CHECK_NE(vmap_table_.size(), 0U);
- std::vector<uint8_t> length_prefixed_gc_map;
- length_prefixed_gc_map.push_back((gc_map.size() & 0xff000000) >> 24);
- length_prefixed_gc_map.push_back((gc_map.size() & 0x00ff0000) >> 16);
- length_prefixed_gc_map.push_back((gc_map.size() & 0x0000ff00) >> 8);
- length_prefixed_gc_map.push_back((gc_map.size() & 0x000000ff) >> 0);
- length_prefixed_gc_map.insert(length_prefixed_gc_map.end(),
- gc_map.begin(),
- gc_map.end());
- DCHECK_EQ(gc_map.size() + 4, length_prefixed_gc_map.size());
- DCHECK_EQ(gc_map.size(),
- static_cast<size_t>((length_prefixed_gc_map[0] << 24) |
- (length_prefixed_gc_map[1] << 16) |
- (length_prefixed_gc_map[2] << 8) |
- (length_prefixed_gc_map[3] << 0)));
-
- gc_map_ = length_prefixed_gc_map;
+ gc_map_ = gc_map;
}
CompiledMethod::CompiledMethod(InstructionSet instruction_set,
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index c219042..deffdc2 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -24,7 +24,22 @@
static const bool gDebugVerify = false;
std::ostream& operator<<(std::ostream& os, const VerifyError& rhs) {
- return os << (int)rhs;
+ switch (rhs) {
+ case VERIFY_ERROR_NONE: os << "VERIFY_ERROR_NONE"; break;
+ case VERIFY_ERROR_GENERIC: os << "VERIFY_ERROR_GENERIC"; break;
+ case VERIFY_ERROR_NO_CLASS: os << "VERIFY_ERROR_NO_CLASS"; break;
+ case VERIFY_ERROR_NO_FIELD: os << "VERIFY_ERROR_NO_FIELD"; break;
+ case VERIFY_ERROR_NO_METHOD: os << "VERIFY_ERROR_NO_METHOD"; break;
+ case VERIFY_ERROR_ACCESS_CLASS: os << "VERIFY_ERROR_ACCESS_CLASS"; break;
+ case VERIFY_ERROR_ACCESS_FIELD: os << "VERIFY_ERROR_ACCESS_FIELD"; break;
+ case VERIFY_ERROR_ACCESS_METHOD: os << "VERIFY_ERROR_ACCESS_METHOD"; break;
+ case VERIFY_ERROR_CLASS_CHANGE: os << "VERIFY_ERROR_CLASS_CHANGE"; break;
+ case VERIFY_ERROR_INSTANTIATION: os << "VERIFY_ERROR_INSTANTIATION"; break;
+ default:
+ os << "VerifyError[" << static_cast<int>(rhs) << "]";
+ break;
+ }
+ return os;
}
static const char* type_strings[] = {
@@ -941,6 +956,8 @@
bool DexVerifier::VerifyMethod(Method* method) {
DexVerifier verifier(method);
bool success = verifier.Verify();
+ CHECK_EQ(success, verifier.failure_ == VERIFY_ERROR_NONE);
+
// We expect either success and no verification error, or failure and a generic failure to
// reject the class.
if (success) {
@@ -1496,6 +1513,24 @@
return true;
}
+const std::vector<uint8_t>* CreateLengthPrefixedGcMap(const std::vector<uint8_t>& gc_map) {
+ std::vector<uint8_t>* length_prefixed_gc_map = new std::vector<uint8_t>;
+ length_prefixed_gc_map->push_back((gc_map.size() & 0xff000000) >> 24);
+ length_prefixed_gc_map->push_back((gc_map.size() & 0x00ff0000) >> 16);
+ length_prefixed_gc_map->push_back((gc_map.size() & 0x0000ff00) >> 8);
+ length_prefixed_gc_map->push_back((gc_map.size() & 0x000000ff) >> 0);
+ length_prefixed_gc_map->insert(length_prefixed_gc_map->end(),
+ gc_map.begin(),
+ gc_map.end());
+ DCHECK_EQ(gc_map.size() + 4, length_prefixed_gc_map->size());
+ DCHECK_EQ(gc_map.size(),
+ static_cast<size_t>((length_prefixed_gc_map->at(0) << 24) |
+ (length_prefixed_gc_map->at(1) << 16) |
+ (length_prefixed_gc_map->at(2) << 8) |
+ (length_prefixed_gc_map->at(3) << 0)));
+ return length_prefixed_gc_map;
+}
+
bool DexVerifier::VerifyCodeFlow() {
uint16_t registers_size = code_item_->registers_size_;
uint32_t insns_size = code_item_->insns_size_in_code_units_;
@@ -1519,19 +1554,23 @@
}
/* Perform code flow verification. */
if (!CodeFlowVerifyMethod()) {
+ DCHECK_NE(failure_, VERIFY_ERROR_NONE);
return false;
}
/* Generate a register map and add it to the method. */
- const std::vector<uint8_t>* map = GenerateGcMap();
- if (map == NULL) {
+ UniquePtr<const std::vector<uint8_t> > map(GenerateGcMap());
+ if (map.get() == NULL) {
+ DCHECK_NE(failure_, VERIFY_ERROR_NONE);
return false; // Not a real failure, but a failure to encode
}
- Compiler::MethodReference ref(dex_file_, method_->GetDexMethodIndex());
- verifier::DexVerifier::SetGcMap(ref, *map);
#ifndef NDEBUG
VerifyGcMap(*map);
#endif
+ const std::vector<uint8_t>* gc_map = CreateLengthPrefixedGcMap(*(map.get()));
+ Compiler::MethodReference ref(dex_file_, method_->GetDexMethodIndex());
+ verifier::DexVerifier::SetGcMap(ref, *gc_map);
+ method_->SetGcMap(&gc_map->at(0));
return true;
}