// Helper class for tests checking that the compiler keeps track of dex registers // holding references. class CheckReferenceMapVisitor : public StackVisitor { public: explicit CheckReferenceMapVisitor(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {}
bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod(); if (m->IsCalleeSaveMethod() || m->IsNative()) {
CHECK_EQ(GetDexPc(), dex::kDexNoIndex);
}
// If the method is not compiled, continue the stack walk. if (m == nullptr ||
m->IsNative() ||
m->IsRuntimeMethod() ||
IsShadowFrame() ||
!GetCurrentOatQuickMethodHeader()->IsOptimized()) { returntrue;
}
LOG(INFO) << "At " << m->PrettyMethod(false);
if (m->IsCalleeSaveMethod()) {
LOG(WARNING) << "no PC for " << m->PrettyMethod(); returntrue;
}
if (!Runtime::Current()->IsAsyncDeoptimizeable(GetOuterMethod(), GetCurrentQuickFramePc())) { // We can only guarantee dex register info presence for debuggable methods. return;
}
DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
DCHECK_EQ(dex_register_map.size(), number_of_dex_registers);
uint32_t register_mask = code_info.GetRegisterMaskOf(stack_map);
BitMemoryRegion stack_mask = code_info.GetStackMaskOf(stack_map); for (int i = 0; i < number_of_references; ++i) { int reg = registers[i];
CHECK_LT(reg, accessor.RegistersSize());
DexRegisterLocation location = dex_register_map[reg]; switch (location.GetKind()) { case DexRegisterLocation::Kind::kNone: // Not set, should not be a reference.
CHECK(false); break; case DexRegisterLocation::Kind::kInStack:
CHECK(stack_mask.IsValid());
DCHECK_EQ(location.GetValue() % kFrameSlotSize, 0);
CHECK(stack_mask.LoadBit(location.GetValue() / kFrameSlotSize)); break; case DexRegisterLocation::Kind::kInRegister: case DexRegisterLocation::Kind::kInRegisterHigh:
CHECK_NE(register_mask & (1 << location.GetValue()), 0u); break; case DexRegisterLocation::Kind::kInFpuRegister: case DexRegisterLocation::Kind::kInFpuRegisterHigh: // In Fpu register, should not be a reference.
CHECK(false); break; case DexRegisterLocation::Kind::kConstant:
CHECK_EQ(location.GetValue(), 0); break; default:
LOG(FATAL) << "Unexpected location kind " << location.GetKind();
}
}
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.