diff options
author | 2012-11-08 10:39:18 -0800 | |
---|---|---|
committer | 2012-11-16 14:01:34 -0800 | |
commit | 2bcb4a496b7aa00d996df3a070524f7568fb35a1 (patch) | |
tree | 8422ab8d65b7422008094b2eaadec0dad87b2df3 /src/stack.cc | |
parent | efc6369224b036a1fb77849f7ae65b3492c832c0 (diff) |
Add "kind" argument to Get/SetVReg.
In order to determine where a register is promoted its necessary to know
the kind of use of the register.
Extend notion of precise-ness to numeric verifier register types.
Dump verifier output in oatdump.
Dump vregs with their location or constant value.
Introduce indenting ostream utility.
Change-Id: Ia3d29497877976bc24465484743bca08236e1768
Diffstat (limited to 'src/stack.cc')
-rw-r--r-- | src/stack.cc | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/src/stack.cc b/src/stack.cc index 8a741c6150..f7126526be 100644 --- a/src/stack.cc +++ b/src/stack.cc @@ -64,49 +64,38 @@ size_t StackVisitor::GetNativePcOffset() const { return GetMethod()->NativePcOffset(cur_quick_frame_pc_); } - -uint32_t StackVisitor::GetVReg(AbstractMethod* m, int vreg) const { - DCHECK(m == GetMethod()); +uint32_t StackVisitor::GetVReg(AbstractMethod* m, uint16_t vreg, VRegKind kind) const { if (cur_quick_frame_ != NULL) { DCHECK(context_ != NULL); // You can't reliably read registers without a context. - uint32_t core_spills = m->GetCoreSpillMask(); + DCHECK(m == GetMethod()); const VmapTable vmap_table(m->GetVmapTableRaw()); uint32_t vmap_offset; // TODO: IsInContext stops before spotting floating point registers. - if (vmap_table.IsInContext(vreg, vmap_offset)) { - // Compute the register we need to load from the context. - uint32_t spill_mask = core_spills; - CHECK_LT(vmap_offset, static_cast<uint32_t>(__builtin_popcount(spill_mask))); - uint32_t matches = 0; - uint32_t spill_shifts = 0; - while (matches != (vmap_offset + 1)) { - DCHECK_NE(spill_mask, 0u); - matches += spill_mask & 1; // Add 1 if the low bit is set. - spill_mask >>= 1; - spill_shifts++; - } - spill_shifts--; // Wind back one as we want the last match. - return GetGPR(spill_shifts); + if (vmap_table.IsInContext(vreg, vmap_offset, kind)) { + bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); + uint32_t spill_mask = is_float ? m->GetFpSpillMask() + : m->GetCoreSpillMask(); + return GetGPR(vmap_table.ComputeRegister(spill_mask, vmap_offset, kind)); } else { const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem(); DCHECK(code_item != NULL) << PrettyMethod(m); // Can't be NULL or how would we compile its instructions? - uint32_t fp_spills = m->GetFpSpillMask(); size_t frame_size = m->GetFrameSizeInBytes(); - return GetVReg(cur_quick_frame_, code_item, core_spills, fp_spills, frame_size, vreg); + return GetVReg(cur_quick_frame_, code_item, m->GetCoreSpillMask(), m->GetFpSpillMask(), + frame_size, vreg); } } else { return cur_shadow_frame_->GetVReg(vreg); } } -void StackVisitor::SetVReg(AbstractMethod* m, int vreg, uint32_t new_value) { +void StackVisitor::SetVReg(AbstractMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind) { if (cur_quick_frame_ != NULL) { DCHECK(context_ != NULL); // You can't reliably write registers without a context. DCHECK(m == GetMethod()); const VmapTable vmap_table(m->GetVmapTableRaw()); uint32_t vmap_offset; // TODO: IsInContext stops before spotting floating point registers. - if (vmap_table.IsInContext(vreg, vmap_offset)) { + if (vmap_table.IsInContext(vreg, vmap_offset, kind)) { UNIMPLEMENTED(FATAL); } const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem(); @@ -118,7 +107,7 @@ void StackVisitor::SetVReg(AbstractMethod* m, int vreg, uint32_t new_value) { byte* vreg_addr = reinterpret_cast<byte*>(GetCurrentQuickFrame()) + offset; *reinterpret_cast<uint32_t*>(vreg_addr) = new_value; } else { - LOG(FATAL) << "Unimplemented - shadow frame SetVReg"; + return cur_shadow_frame_->SetVReg(vreg, new_value); } } @@ -129,7 +118,7 @@ uintptr_t StackVisitor::GetGPR(uint32_t reg) const { uintptr_t StackVisitor::GetReturnPc() const { AbstractMethod** sp = GetCurrentQuickFrame(); - CHECK(sp != NULL); + DCHECK(sp != NULL); byte* pc_addr = reinterpret_cast<byte*>(sp) + GetMethod()->GetReturnPcOffsetInBytes(); return *reinterpret_cast<uintptr_t*>(pc_addr); } |