NativePcOffsetToReferenceMap
Rather than translate a native PC to a Dex PC and then to the reference
bitmap, just go straight from the native PC to the reference bitmap.
Encode the native PC offsets using a hash rather than linearly
searching.
Change-Id: Iee1073d93c941c0a31f639e5f23cea9e9f747bee
diff --git a/src/verifier/gc_map.cc b/src/verifier/dex_gc_map.cc
similarity index 97%
rename from src/verifier/gc_map.cc
rename to src/verifier/dex_gc_map.cc
index 66cb6c7..c1c9a29 100644
--- a/src/verifier/gc_map.cc
+++ b/src/verifier/dex_gc_map.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "gc_map.h"
+#include "verifier/dex_gc_map.h"
#include "logging.h"
diff --git a/src/verifier/gc_map.h b/src/verifier/dex_gc_map.h
similarity index 88%
rename from src/verifier/gc_map.h
rename to src/verifier/dex_gc_map.h
index d6a1c46..d588cfd 100644
--- a/src/verifier/gc_map.h
+++ b/src/verifier/dex_gc_map.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_SRC_VERIFIER_GC_MAP_H_
-#define ART_SRC_VERIFIER_GC_MAP_H_
+#ifndef ART_SRC_VERIFIER_DEX_GC_MAP_H_
+#define ART_SRC_VERIFIER_DEX_GC_MAP_H_
#include "logging.h"
#include "macros.h"
@@ -37,8 +37,7 @@
// Lightweight wrapper for Dex PC to reference bit maps.
class DexPcToReferenceMap {
public:
- DexPcToReferenceMap(const uint8_t* data, size_t data_length) {
- data_ = data;
+ DexPcToReferenceMap(const uint8_t* data, size_t data_length) : data_(data) {
CHECK(data_ != NULL);
// Check the size of the table agrees with the number of entries
size_t data_size = data_length - 4;
@@ -53,7 +52,7 @@
// Get the Dex PC at the given index
uint16_t GetDexPc(size_t index) const {
size_t entry_offset = index * EntryWidth();
- if (PcWidth() == 1) {
+ if (DexPcWidth() == 1) {
return Table()[entry_offset];
} else {
return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
@@ -63,7 +62,7 @@
// 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 + PcWidth()];
+ return &Table()[entry_offset + DexPcWidth()];
}
// Find the bitmap associated with the given dex pc
@@ -86,7 +85,7 @@
}
// Number of bytes used to encode a dex pc
- size_t PcWidth() const {
+ size_t DexPcWidth() const {
RegisterMapFormat format = Format();
switch (format) {
case kRegMapFormatCompact8:
@@ -101,7 +100,7 @@
// The width of an entry in the table
size_t EntryWidth() const {
- return PcWidth() + RegWidth();
+ return DexPcWidth() + RegWidth();
}
const uint8_t* GetData() const {
@@ -113,10 +112,10 @@
static const int kRegMapFormatShift = 5;
static const uint8_t kRegMapFormatMask = 0x7;
- const uint8_t* data_; // The header and table data
+ const uint8_t* const data_; // The header and table data
};
} // namespace verifier
} // namespace art
-#endif // ART_SRC_VERIFIER_GC_MAP_H_
+#endif // ART_SRC_VERIFIER_DEX_GC_MAP_H_
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index a01aa8d..73aee9c 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -24,7 +24,7 @@
#include "dex_file.h"
#include "dex_instruction.h"
#include "dex_instruction_visitor.h"
-#include "gc_map.h"
+#include "verifier/dex_gc_map.h"
#include "intern_table.h"
#include "leb128.h"
#include "logging.h"
@@ -549,8 +549,9 @@
bool MethodVerifier::VerifyInstructions() {
const Instruction* inst = Instruction::At(code_item_->insns_);
- /* Flag the start of the method as a branch target. */
+ /* 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].SetGcPoint();
uint32_t insns_size = code_item_->insns_size_in_code_units_;
for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
@@ -945,7 +946,7 @@
return true;
}
-const std::vector<uint8_t>* CreateLengthPrefixedGcMap(const std::vector<uint8_t>& gc_map) {
+static const std::vector<uint8_t>* CreateLengthPrefixedDexGcMap(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);
@@ -1004,12 +1005,8 @@
#ifndef NDEBUG
VerifyGcMap(*map);
#endif
- const std::vector<uint8_t>* gc_map = CreateLengthPrefixedGcMap(*(map.get()));
- verifier::MethodVerifier::SetGcMap(ref, *gc_map);
-
- if (foo_method_ != NULL) {
- foo_method_->SetGcMap(&gc_map->at(0));
- }
+ const std::vector<uint8_t>* dex_gc_map = CreateLengthPrefixedDexGcMap(*(map.get()));
+ verifier::MethodVerifier::SetDexGcMap(ref, *dex_gc_map);
#else // defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
/* Generate Inferred Register Category for LLVM-based Code Generator */
@@ -3212,31 +3209,31 @@
}
}
-void MethodVerifier::SetGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map) {
+void MethodVerifier::SetDexGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map) {
{
- MutexLock mu(*gc_maps_lock_);
- GcMapTable::iterator it = gc_maps_->find(ref);
- if (it != gc_maps_->end()) {
+ MutexLock mu(*dex_gc_maps_lock_);
+ DexGcMapTable::iterator it = dex_gc_maps_->find(ref);
+ if (it != dex_gc_maps_->end()) {
delete it->second;
- gc_maps_->erase(it);
+ dex_gc_maps_->erase(it);
}
- gc_maps_->Put(ref, &gc_map);
+ dex_gc_maps_->Put(ref, &gc_map);
}
- CHECK(GetGcMap(ref) != NULL);
+ CHECK(GetDexGcMap(ref) != NULL);
}
-const std::vector<uint8_t>* MethodVerifier::GetGcMap(Compiler::MethodReference ref) {
- MutexLock mu(*gc_maps_lock_);
- GcMapTable::const_iterator it = gc_maps_->find(ref);
- if (it == gc_maps_->end()) {
+const std::vector<uint8_t>* MethodVerifier::GetDexGcMap(Compiler::MethodReference ref) {
+ MutexLock mu(*dex_gc_maps_lock_);
+ DexGcMapTable::const_iterator it = dex_gc_maps_->find(ref);
+ if (it == dex_gc_maps_->end()) {
return NULL;
}
CHECK(it->second != NULL);
return it->second;
}
-Mutex* MethodVerifier::gc_maps_lock_ = NULL;
-MethodVerifier::GcMapTable* MethodVerifier::gc_maps_ = NULL;
+Mutex* MethodVerifier::dex_gc_maps_lock_ = NULL;
+MethodVerifier::DexGcMapTable* MethodVerifier::dex_gc_maps_ = NULL;
Mutex* MethodVerifier::rejected_classes_lock_ = NULL;
MethodVerifier::RejectedClassesTable* MethodVerifier::rejected_classes_ = NULL;
@@ -3247,10 +3244,10 @@
#endif
void MethodVerifier::Init() {
- gc_maps_lock_ = new Mutex("verifier GC maps lock");
+ dex_gc_maps_lock_ = new Mutex("verifier GC maps lock");
{
- MutexLock mu(*gc_maps_lock_);
- gc_maps_ = new MethodVerifier::GcMapTable;
+ MutexLock mu(*dex_gc_maps_lock_);
+ dex_gc_maps_ = new MethodVerifier::DexGcMapTable;
}
rejected_classes_lock_ = new Mutex("verifier rejected classes lock");
@@ -3270,13 +3267,13 @@
void MethodVerifier::Shutdown() {
{
- MutexLock mu(*gc_maps_lock_);
- STLDeleteValues(gc_maps_);
- delete gc_maps_;
- gc_maps_ = NULL;
+ MutexLock mu(*dex_gc_maps_lock_);
+ STLDeleteValues(dex_gc_maps_);
+ delete dex_gc_maps_;
+ dex_gc_maps_ = NULL;
}
- delete gc_maps_lock_;
- gc_maps_lock_ = NULL;
+ delete dex_gc_maps_lock_;
+ dex_gc_maps_lock_ = NULL;
{
MutexLock mu(*rejected_classes_lock_);
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index 92621ef..c1c2562 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -188,8 +188,8 @@
// information
void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref)
- LOCKS_EXCLUDED(gc_maps_lock_);
+ static const std::vector<uint8_t>* GetDexGcMap(Compiler::MethodReference ref)
+ LOCKS_EXCLUDED(dex_gc_maps_lock_);
// Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
// to the locks held at 'dex_pc' in 'm'.
@@ -578,11 +578,11 @@
InsnFlags* CurrentInsnFlags();
// All the GC maps that the verifier has created
- typedef SafeMap<const Compiler::MethodReference, const std::vector<uint8_t>*> GcMapTable;
- static Mutex* gc_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- static GcMapTable* gc_maps_ GUARDED_BY(gc_maps_lock_);
- static void SetGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map)
- LOCKS_EXCLUDED(gc_maps_lock_);
+ typedef SafeMap<const Compiler::MethodReference, const std::vector<uint8_t>*> DexGcMapTable;
+ static Mutex* dex_gc_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ static DexGcMapTable* dex_gc_maps_ GUARDED_BY(dex_gc_maps_lock_);
+ static void SetDexGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& dex_gc_map)
+ LOCKS_EXCLUDED(dex_gc_maps_lock_);
typedef std::set<Compiler::ClassReference> RejectedClassesTable;
static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;