if (declaring_class.IsJavaLangObject()) {
// "this" is implicitly initialized.
reg_line->SetThisInitialized();
- reg_line->SetRegisterType(this, arg_start + cur_arg, declaring_class);
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
} else {
- reg_line->SetRegisterType(this, arg_start + cur_arg,
- reg_types_.UninitializedThisArgument(declaring_class));
+ reg_line->SetRegisterType<LockOp::kClear>(
+ this,
+ arg_start + cur_arg,
+ reg_types_.UninitializedThisArgument(declaring_class));
}
} else {
- reg_line->SetRegisterType(this, arg_start + cur_arg, declaring_class);
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
}
cur_arg++;
}
DCHECK(HasFailures());
return false;
}
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_type);
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_type);
}
break;
case 'Z':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Boolean());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Boolean());
break;
case 'C':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Char());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Char());
break;
case 'B':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Byte());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Byte());
break;
case 'I':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Integer());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Integer());
break;
case 'S':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Short());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Short());
break;
case 'F':
- reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Float());
+ reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Float());
break;
case 'J':
case 'D': {
* that as part of extracting the exception type from the catch block list.
*/
const RegType& res_type = GetCaughtExceptionType();
- work_line_->SetRegisterType(this, inst->VRegA_11x(), res_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_11x(), res_type);
break;
}
case Instruction::RETURN_VOID:
/* could be boolean, int, float, or a null reference */
case Instruction::CONST_4: {
int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
- work_line_->SetRegisterType(this, inst->VRegA_11n(),
- DetermineCat1Constant(val, need_precise_constants_));
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_11n(), DetermineCat1Constant(val, need_precise_constants_));
break;
}
case Instruction::CONST_16: {
int16_t val = static_cast<int16_t>(inst->VRegB_21s());
- work_line_->SetRegisterType(this, inst->VRegA_21s(),
- DetermineCat1Constant(val, need_precise_constants_));
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_21s(), DetermineCat1Constant(val, need_precise_constants_));
break;
}
case Instruction::CONST: {
int32_t val = inst->VRegB_31i();
- work_line_->SetRegisterType(this, inst->VRegA_31i(),
- DetermineCat1Constant(val, need_precise_constants_));
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_31i(), DetermineCat1Constant(val, need_precise_constants_));
break;
}
case Instruction::CONST_HIGH16: {
int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
- work_line_->SetRegisterType(this, inst->VRegA_21h(),
- DetermineCat1Constant(val, need_precise_constants_));
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_21h(), DetermineCat1Constant(val, need_precise_constants_));
break;
}
/* could be long or double; resolved upon use */
break;
}
case Instruction::CONST_STRING:
- work_line_->SetRegisterType(this, inst->VRegA_21c(), reg_types_.JavaLangString());
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_21c(), reg_types_.JavaLangString());
break;
case Instruction::CONST_STRING_JUMBO:
- work_line_->SetRegisterType(this, inst->VRegA_31c(), reg_types_.JavaLangString());
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_31c(), reg_types_.JavaLangString());
break;
case Instruction::CONST_CLASS: {
// Get type from instruction if unresolved then we need an access check
// TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
// Register holds class, ie its type is class, on error it will hold Conflict.
- work_line_->SetRegisterType(this, inst->VRegA_21c(),
- res_type.IsConflict() ? res_type
- : reg_types_.JavaLangClass());
+ work_line_->SetRegisterType<LockOp::kClear>(
+ this, inst->VRegA_21c(), res_type.IsConflict() ? res_type
+ : reg_types_.JavaLangClass());
break;
}
case Instruction::MONITOR_ENTER:
DCHECK_NE(failures_.size(), 0U);
if (!is_checkcast) {
- work_line_->SetRegisterType(this, inst->VRegA_22c(), reg_types_.Boolean());
+ work_line_->SetRegisterType<LockOp::kClear>(this,
+ inst->VRegA_22c(),
+ reg_types_.Boolean());
}
break; // bad class
}
}
} else {
if (is_checkcast) {
- work_line_->SetRegisterType(this, inst->VRegA_21c(), res_type);
+ work_line_->SetRegisterType<LockOp::kKeep>(this, inst->VRegA_21c(), res_type);
} else {
- work_line_->SetRegisterType(this, inst->VRegA_22c(), reg_types_.Boolean());
+ work_line_->SetRegisterType<LockOp::kClear>(this,
+ inst->VRegA_22c(),
+ reg_types_.Boolean());
}
}
break;
if (!res_type.IsArrayTypes() && !res_type.IsZero()) { // ie not an array or null
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
} else {
- work_line_->SetRegisterType(this, inst->VRegA_12x(), reg_types_.Integer());
+ work_line_->SetRegisterType<LockOp::kClear>(this,
+ inst->VRegA_12x(),
+ reg_types_.Integer());
}
} else {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
// initialized must be marked invalid.
work_line_->MarkUninitRefsAsInvalid(this, uninit_type);
// add the new uninitialized reference to the register state
- work_line_->SetRegisterType(this, inst->VRegA_21c(), uninit_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_21c(), uninit_type);
break;
}
case Instruction::NEW_ARRAY:
if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) {
break;
}
- work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
break;
case Instruction::CMPL_DOUBLE:
case Instruction::CMPG_DOUBLE:
reg_types_.DoubleHi())) {
break;
}
- work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
break;
case Instruction::CMP_LONG:
if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(),
reg_types_.LongHi())) {
break;
}
- work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
break;
case Instruction::THROW: {
const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x());
branch_line.reset(update_line);
}
update_line->CopyFromLine(work_line_.get());
- update_line->SetRegisterType(this, instance_of_inst->VRegB_22c(), cast_type);
+ update_line->SetRegisterType<LockOp::kKeep>(this,
+ instance_of_inst->VRegB_22c(),
+ cast_type);
if (!insn_flags_[instance_of_idx].IsBranchTarget() && 0 != instance_of_idx) {
// See if instance-of was preceded by a move-object operation, common due to the small
// register encoding space of instance-of, and propagate type information to the source
switch (move_inst->Opcode()) {
case Instruction::MOVE_OBJECT:
if (move_inst->VRegA_12x() == instance_of_inst->VRegB_22c()) {
- update_line->SetRegisterType(this, move_inst->VRegB_12x(), cast_type);
+ update_line->SetRegisterType<LockOp::kKeep>(this,
+ move_inst->VRegB_12x(),
+ cast_type);
}
break;
case Instruction::MOVE_OBJECT_FROM16:
if (move_inst->VRegA_22x() == instance_of_inst->VRegB_22c()) {
- update_line->SetRegisterType(this, move_inst->VRegB_22x(), cast_type);
+ update_line->SetRegisterType<LockOp::kKeep>(this,
+ move_inst->VRegB_22x(),
+ cast_type);
}
break;
case Instruction::MOVE_OBJECT_16:
if (move_inst->VRegA_32x() == instance_of_inst->VRegB_22c()) {
- update_line->SetRegisterType(this, move_inst->VRegB_32x(), cast_type);
+ update_line->SetRegisterType<LockOp::kKeep>(this,
+ move_inst->VRegB_32x(),
+ cast_type);
}
break;
default:
// is good enough for some other verification to occur without hard-failing.
const uint32_t vreg_target_object = inst->VRegA_22x(); // box-lambda vA, vB
const RegType& reg_type = reg_types_.JavaLangObject(need_precise_constants_);
- work_line_->SetRegisterType(this, vreg_target_object, reg_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, vreg_target_object, reg_type);
break;
}
work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer());
/* set register type to array class */
const RegType& precise_type = reg_types_.FromUninitialized(res_type);
- work_line_->SetRegisterType(this, inst->VRegA_22c(), precise_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_22c(), precise_type);
} else {
// Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
// the list and fail. It's legal, if silly, for arg_count to be zero.
// instruction type. TODO: have a proper notion of bottom here.
if (!is_primitive || insn_type.IsCategory1Types()) {
// Reference or category 1
- work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Zero());
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Zero());
} else {
// Category 2
work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(),
// instruction, which can't differentiate object types and ints from floats, longs from
// doubles.
if (!component_type.IsLowHalf()) {
- work_line_->SetRegisterType(this, inst->VRegA_23x(), component_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), component_type);
} else {
work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type,
component_type.HighHalf(®_types_));
<< "' but found type '" << *field_type
<< "' in get-object";
if (error != VERIFY_ERROR_BAD_CLASS_HARD) {
- work_line_->SetRegisterType(this, vregA, reg_types_.Conflict());
+ work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict());
}
return;
}
}
if (!field_type->IsLowHalf()) {
- work_line_->SetRegisterType(this, vregA, *field_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type);
} else {
work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(®_types_));
}
<< " to be compatible with type '" << insn_type
<< "' but found type '" << *field_type
<< "' in get-object";
- work_line_->SetRegisterType(this, vregA, reg_types_.Conflict());
+ work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict());
return;
}
}
if (!field_type->IsLowHalf()) {
- work_line_->SetRegisterType(this, vregA, *field_type);
+ work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type);
} else {
work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(®_types_));
}
for (const auto& monitor : monitors_) {
result += StringPrintf("{%d},", monitor);
}
+ for (auto& pairs : reg_to_lock_depths_) {
+ result += StringPrintf("<%d -> %x>", pairs.first, pairs.second);
+ }
return result;
}
<< "copyRes1 v" << vdst << "<- result0" << " type=" << type;
} else {
DCHECK(verifier->GetRegTypeCache()->GetFromId(result_[1]).IsUndefined());
- SetRegisterType(verifier, vdst, type);
+ SetRegisterType<LockOp::kClear>(verifier, vdst, type);
result_[0] = verifier->GetRegTypeCache()->Undefined().GetId();
}
}
void RegisterLine::CheckUnaryOp(MethodVerifier* verifier, const Instruction* inst,
const RegType& dst_type, const RegType& src_type) {
if (VerifyRegisterType(verifier, inst->VRegB_12x(), src_type)) {
- SetRegisterType(verifier, inst->VRegA_12x(), dst_type);
+ SetRegisterType<LockOp::kClear>(verifier, inst->VRegA_12x(), dst_type);
}
}
const RegType& dst_type,
const RegType& src_type1, const RegType& src_type2) {
if (VerifyRegisterTypeWide(verifier, inst->VRegB_12x(), src_type1, src_type2)) {
- SetRegisterType(verifier, inst->VRegA_12x(), dst_type);
+ SetRegisterType<LockOp::kClear>(verifier, inst->VRegA_12x(), dst_type);
}
}
DCHECK(dst_type.IsInteger());
if (GetRegisterType(verifier, vregB).IsBooleanTypes() &&
GetRegisterType(verifier, vregC).IsBooleanTypes()) {
- SetRegisterType(verifier, inst->VRegA_23x(), verifier->GetRegTypeCache()->Boolean());
+ SetRegisterType<LockOp::kClear>(verifier,
+ inst->VRegA_23x(),
+ verifier->GetRegTypeCache()->Boolean());
return;
}
}
- SetRegisterType(verifier, inst->VRegA_23x(), dst_type);
+ SetRegisterType<LockOp::kClear>(verifier, inst->VRegA_23x(), dst_type);
}
}
DCHECK(dst_type.IsInteger());
if (GetRegisterType(verifier, vregA).IsBooleanTypes() &&
GetRegisterType(verifier, vregB).IsBooleanTypes()) {
- SetRegisterType(verifier, vregA, verifier->GetRegTypeCache()->Boolean());
+ SetRegisterType<LockOp::kClear>(verifier,
+ vregA,
+ verifier->GetRegTypeCache()->Boolean());
return;
}
}
- SetRegisterType(verifier, vregA, dst_type);
+ SetRegisterType<LockOp::kClear>(verifier, vregA, dst_type);
}
}
/* check vB with the call, then check the constant manually */
const uint32_t val = is_lit16 ? inst->VRegC_22s() : inst->VRegC_22b();
if (GetRegisterType(verifier, vregB).IsBooleanTypes() && (val == 0 || val == 1)) {
- SetRegisterType(verifier, vregA, verifier->GetRegTypeCache()->Boolean());
+ SetRegisterType<LockOp::kClear>(verifier,
+ vregA,
+ verifier->GetRegTypeCache()->Boolean());
return;
}
}
- SetRegisterType(verifier, vregA, dst_type);
+ SetRegisterType<LockOp::kClear>(verifier, vregA, dst_type);
}
}