summaryrefslogtreecommitdiffstats
path: root/runtime/stack.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-05-08 14:19:26 -0700
committerMathieu Chartier <mathieuc@google.com>2015-05-08 15:09:17 -0700
commit50030ef998be09789da4a9a56738362852068f12 (patch)
tree02df1bd0954f9b970434d1363466b0cfe182bc12 /runtime/stack.cc
parent6727a48193db2a0cf01af971cccffe1a6518c247 (diff)
downloadart-50030ef998be09789da4a9a56738362852068f12.zip
art-50030ef998be09789da4a9a56738362852068f12.tar.gz
art-50030ef998be09789da4a9a56738362852068f12.tar.bz2
Check IsReferenceVReg during deopt
Required since the quick GC maps may not agree with the verifier ones. Without this check we may copy stale object references into the shadow frame. (cherry picked from commit f00baf56ef647684888a407dbb6adadd704a2039) Bug: 20736048 Change-Id: I7783c8a8ee45cf601b08b4c38f1dec7f7d11380c
Diffstat (limited to 'runtime/stack.cc')
-rw-r--r--runtime/stack.cc28
1 files changed, 28 insertions, 0 deletions
diff --git a/runtime/stack.cc b/runtime/stack.cc
index e49bc1d..a566886 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -19,6 +19,7 @@
#include "arch/context.h"
#include "base/hex_dump.h"
#include "entrypoints/runtime_asm_entrypoints.h"
+#include "gc_map.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object.h"
@@ -151,6 +152,33 @@ size_t StackVisitor::GetNativePcOffset() const {
return GetMethod()->NativeQuickPcOffset(cur_quick_frame_pc_);
}
+bool StackVisitor::IsReferenceVReg(mirror::ArtMethod* m, uint16_t vreg) {
+ // Process register map (which native and runtime methods don't have)
+ if (m->IsNative() || m->IsRuntimeMethod() || m->IsProxyMethod()) {
+ return false;
+ }
+ if (m->IsOptimized(sizeof(void*))) {
+ return true; // TODO: Implement.
+ }
+ const uint8_t* native_gc_map = m->GetNativeGcMap(sizeof(void*));
+ CHECK(native_gc_map != nullptr) << PrettyMethod(m);
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
+ // Can't be null or how would we compile its instructions?
+ DCHECK(code_item != nullptr) << PrettyMethod(m);
+ NativePcOffsetToReferenceMap map(native_gc_map);
+ size_t num_regs = std::min(map.RegWidth() * 8, static_cast<size_t>(code_item->registers_size_));
+ const uint8_t* reg_bitmap = nullptr;
+ if (num_regs > 0) {
+ Runtime* runtime = Runtime::Current();
+ const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*));
+ uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point);
+ reg_bitmap = map.FindBitMap(native_pc_offset);
+ DCHECK(reg_bitmap != nullptr);
+ }
+ // Does this register hold a reference?
+ return vreg < num_regs && TestBitmap(vreg, reg_bitmap);
+}
+
bool StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind,
uint32_t* val) const {
if (cur_quick_frame_ != nullptr) {