- art虚拟机为了提高性能,使用隐式的空指针检查,不需要在编译阶段额外加入检查的代码,提高oat的性能。
libartd.so!art::NullPointerHandler::Action(siginfo_t * sig, void * context) (\home\wangmin\code\aosp\android13\art\runtime\arch\x86\fault_handler_x86.cc:336)
libartd.so!art::FaultManager::HandleFault(art::FaultManager * this, int sig, siginfo_t * info, void * context) (\home\wangmin\code\aosp\android13\art\runtime\fault_handler.cc:228)
art::SignalChain::Handler(int signo, siginfo_t * siginfo, void * ucontext_raw) (\home\wangmin\code\aosp\android13\art\sigchainlib\sigchain.cc:364)
libc.so.6!<signal handler called> (Unknown Source:0)
classes.odex!oatexec (Unknown Source:0)
[Unknown/Just-In-Time compiled code] (Unknown Source:0)
libartd.so!art::ArtMethod::GetDeclaringClass<(art::ReadBarrierOption)1>(art::ArtMethod * this) (\home\wangmin\code\aosp\android13\art\runtime\art_method-inl.h:59)
在隐式检查的地方,添加一个StackMap,方便异常爬栈
void CodeGenerator::MaybeRecordImplicitNullCheck(HInstruction* instr) {
HNullCheck* null_check = instr->GetImplicitNullCheck();
if (null_check != nullptr) {
RecordPcInfo(null_check, null_check->GetDexPc(), GetAssembler()->CodePosition());
}
}
- 数组越界检查是在aput、aget等指令编译阶段插入额外BoundCheck实现
void HInstructionBuilder::BuildArrayAccess(const Instruction& instruction,
uint32_t dex_pc,
bool is_put,
DataType::Type anticipated_type) {
uint8_t source_or_dest_reg = instruction.VRegA_23x();
uint8_t array_reg = instruction.VRegB_23x();
uint8_t index_reg = instruction.VRegC_23x();
HInstruction* object = LoadNullCheckedLocal(array_reg, dex_pc);
HInstruction* length = new (allocator_) HArrayLength(object, dex_pc);
AppendInstruction(length);
HInstruction* index = LoadLocal(index_reg, DataType::Type::kInt32);
index = new (allocator_) HBoundsCheck(index, length, dex_pc);
AppendInstruction(index);
if (is_put) {
HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type);
// TODO: Insert a type check node if the type is Object.
HArraySet* aset = new (allocator_) HArraySet(object, index, value, anticipated_type, dex_pc);
ssa_builder_->MaybeAddAmbiguousArraySet(aset);
AppendInstruction(aset);
} else {
HArrayGet* aget = new (allocator_) HArrayGet(object, index, anticipated_type, dex_pc);
ssa_builder_->MaybeAddAmbiguousArrayGet(aget);
AppendInstruction(aget);
UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
}
graph_->SetHasBoundsChecks(true);
}