diff options
| -rw-r--r-- | compiler/optimizing/builder.cc | 467 | ||||
| -rw-r--r-- | compiler/optimizing/builder.h | 22 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.cc | 92 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 571 |
4 files changed, 600 insertions, 552 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 1650fd1ced..7a3aa58149 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -46,7 +46,7 @@ class Temporaries : public ValueObject { explicit Temporaries(HGraph* graph) : graph_(graph), index_(0) {} void Add(HInstruction* instruction) { - HInstruction* temp = new (graph_->GetArena()) HTemporary(index_); + HInstruction* temp = new (graph_->GetArena()) HTemporary(index_, instruction->GetDexPc()); instruction->GetBlock()->AddInstruction(temp); DCHECK(temp->GetPrevious() == instruction); @@ -161,23 +161,25 @@ void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) { if (!dex_compilation_unit_->IsStatic()) { // Add the implicit 'this' argument, not expressed in the signature. - HParameterValue* parameter = - new (arena_) HParameterValue(parameter_index++, Primitive::kPrimNot, true); + HParameterValue* parameter = new (arena_) HParameterValue(parameter_index++, + Primitive::kPrimNot, + true); entry_block_->AddInstruction(parameter); HLocal* local = GetLocalAt(locals_index++); - entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); + entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter, local->GetDexPc())); number_of_parameters--; } uint32_t pos = 1; for (int i = 0; i < number_of_parameters; i++) { - HParameterValue* parameter = - new (arena_) HParameterValue(parameter_index++, Primitive::GetType(shorty[pos++])); + HParameterValue* parameter = new (arena_) HParameterValue(parameter_index++, + Primitive::GetType(shorty[pos++]), + false); entry_block_->AddInstruction(parameter); HLocal* local = GetLocalAt(locals_index++); // Store the parameter value in the local that the dex code will use // to reference that parameter. - entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); + entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter, local->GetDexPc())); bool is_wide = (parameter->GetType() == Primitive::kPrimLong) || (parameter->GetType() == Primitive::kPrimDouble); if (is_wide) { @@ -196,11 +198,11 @@ void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) { DCHECK(branch_target != nullptr); DCHECK(fallthrough_target != nullptr); PotentiallyAddSuspendCheck(branch_target, dex_pc); - HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); - HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); - T* comparison = new (arena_) T(first, second); + HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt, dex_pc); + T* comparison = new (arena_) T(first, second, dex_pc); current_block_->AddInstruction(comparison); - HInstruction* ifinst = new (arena_) HIf(comparison); + HInstruction* ifinst = new (arena_) HIf(comparison, dex_pc); current_block_->AddInstruction(ifinst); current_block_->AddSuccessor(branch_target); current_block_->AddSuccessor(fallthrough_target); @@ -215,10 +217,10 @@ void HGraphBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) { DCHECK(branch_target != nullptr); DCHECK(fallthrough_target != nullptr); PotentiallyAddSuspendCheck(branch_target, dex_pc); - HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); - T* comparison = new (arena_) T(value, graph_->GetIntConstant(0)); + HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt, dex_pc); + T* comparison = new (arena_) T(value, graph_->GetIntConstant(0, dex_pc), dex_pc); current_block_->AddInstruction(comparison); - HInstruction* ifinst = new (arena_) HIf(comparison); + HInstruction* ifinst = new (arena_) HIf(comparison, dex_pc); current_block_->AddInstruction(ifinst); current_block_->AddSuccessor(branch_target); current_block_->AddSuccessor(fallthrough_target); @@ -320,7 +322,7 @@ void HGraphBuilder::SplitTryBoundaryEdge(HBasicBlock* predecessor, const DexFile::CodeItem& code_item, const DexFile::TryItem& try_item) { // Split the edge with a single TryBoundary instruction. - HTryBoundary* try_boundary = new (arena_) HTryBoundary(kind); + HTryBoundary* try_boundary = new (arena_) HTryBoundary(kind, successor->GetDexPc()); HBasicBlock* try_entry_block = graph_->SplitEdge(predecessor, successor); try_entry_block->AddInstruction(try_boundary); @@ -538,7 +540,7 @@ void HGraphBuilder::MaybeUpdateCurrentBlock(size_t dex_pc) { // Branching instructions clear current_block, so we know // the last instruction of the current block is not a branching // instruction. We add an unconditional goto to the found block. - current_block_->AddInstruction(new (arena_) HGoto()); + current_block_->AddInstruction(new (arena_) HGoto(dex_pc)); current_block_->AddSuccessor(block); } graph_->AddBlock(block); @@ -634,104 +636,92 @@ HBasicBlock* HGraphBuilder::FindOrCreateBlockStartingAt(int32_t dex_pc) { } template<typename T> -void HGraphBuilder::Unop_12x(const Instruction& instruction, Primitive::Type type) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - current_block_->AddInstruction(new (arena_) T(type, first)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); +void HGraphBuilder::Unop_12x(const Instruction& instruction, + Primitive::Type type, + uint32_t dex_pc) { + HInstruction* first = LoadLocal(instruction.VRegB(), type, dex_pc); + current_block_->AddInstruction(new (arena_) T(type, first, dex_pc)); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } void HGraphBuilder::Conversion_12x(const Instruction& instruction, Primitive::Type input_type, Primitive::Type result_type, uint32_t dex_pc) { - HInstruction* first = LoadLocal(instruction.VRegB(), input_type); + HInstruction* first = LoadLocal(instruction.VRegB(), input_type, dex_pc); current_block_->AddInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); -} - -template<typename T> -void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - HInstruction* second = LoadLocal(instruction.VRegC(), type); - current_block_->AddInstruction(new (arena_) T(type, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - HInstruction* second = LoadLocal(instruction.VRegC(), type); + HInstruction* first = LoadLocal(instruction.VRegB(), type, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegC(), type, dex_pc); current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> void HGraphBuilder::Binop_23x_shift(const Instruction& instruction, - Primitive::Type type) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt); - current_block_->AddInstruction(new (arena_) T(type, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + Primitive::Type type, + uint32_t dex_pc) { + HInstruction* first = LoadLocal(instruction.VRegB(), type, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt, dex_pc); + current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction, Primitive::Type type, ComparisonBias bias, uint32_t dex_pc) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - HInstruction* second = LoadLocal(instruction.VRegC(), type); + HInstruction* first = LoadLocal(instruction.VRegB(), type, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegC(), type, dex_pc); current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> -void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) { - HInstruction* first = LoadLocal(instruction.VRegA(), type); - HInstruction* second = LoadLocal(instruction.VRegB(), type); - current_block_->AddInstruction(new (arena_) T(type, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); -} - -template<typename T> -void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type) { - HInstruction* first = LoadLocal(instruction.VRegA(), type); - HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); - current_block_->AddInstruction(new (arena_) T(type, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); +void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type, + uint32_t dex_pc) { + HInstruction* first = LoadLocal(instruction.VRegA(), type, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt, dex_pc); + current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc) { - HInstruction* first = LoadLocal(instruction.VRegA(), type); - HInstruction* second = LoadLocal(instruction.VRegB(), type); + HInstruction* first = LoadLocal(instruction.VRegA(), type, dex_pc); + HInstruction* second = LoadLocal(instruction.VRegB(), type, dex_pc); current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> -void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse) { - HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); - HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s()); +void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc) { + HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt, dex_pc); + HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s(), dex_pc); if (reverse) { std::swap(first, second); } - current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc)); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } template<typename T> -void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse) { - HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); - HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b()); +void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc) { + HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt, dex_pc); + HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b(), dex_pc); if (reverse) { std::swap(first, second); } - current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc)); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, const CompilerDriver& driver) { @@ -740,7 +730,9 @@ static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, const Compi && driver.RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex()); } -void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) { +void HGraphBuilder::BuildReturn(const Instruction& instruction, + Primitive::Type type, + uint32_t dex_pc) { if (type == Primitive::kPrimVoid) { if (graph_->ShouldGenerateConstructorBarrier()) { // The compilation unit is null during testing. @@ -748,12 +740,12 @@ void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type DCHECK(RequiresConstructorBarrier(dex_compilation_unit_, *compiler_driver_)) << "Inconsistent use of ShouldGenerateConstructorBarrier. Should not generate a barrier."; } - current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore)); + current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore, dex_pc)); } - current_block_->AddInstruction(new (arena_) HReturnVoid()); + current_block_->AddInstruction(new (arena_) HReturnVoid(dex_pc)); } else { - HInstruction* value = LoadLocal(instruction.VRegA(), type); - current_block_->AddInstruction(new (arena_) HReturn(value)); + HInstruction* value = LoadLocal(instruction.VRegA(), type, dex_pc); + current_block_->AddInstruction(new (arena_) HReturn(value, dex_pc)); } current_block_->AddSuccessor(exit_block_); current_block_ = nullptr; @@ -1050,6 +1042,7 @@ bool HGraphBuilder::SetupArgumentsAndAddInvoke(HInvoke* invoke, size_t start_index = 0; size_t argument_index = 0; uint32_t descriptor_index = 1; // Skip the return type. + uint32_t dex_pc = invoke->GetDexPc(); bool is_instance_call = invoke->GetOriginalInvokeType() != InvokeType::kStatic; bool is_string_init = invoke->IsInvokeStaticOrDirect() @@ -1060,7 +1053,7 @@ bool HGraphBuilder::SetupArgumentsAndAddInvoke(HInvoke* invoke, argument_index = 0; } else if (is_instance_call) { Temporaries temps(graph_); - HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot); + HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot, dex_pc); HNullCheck* null_check = new (arena_) HNullCheck(arg, invoke->GetDexPc()); current_block_->AddInstruction(null_check); temps.Add(null_check); @@ -1089,7 +1082,7 @@ bool HGraphBuilder::SetupArgumentsAndAddInvoke(HInvoke* invoke, MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); return false; } - HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); + HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type, dex_pc); invoke->SetArgumentAt(argument_index, arg); if (is_wide) { i++; @@ -1122,7 +1115,7 @@ bool HGraphBuilder::SetupArgumentsAndAddInvoke(HInvoke* invoke, // Add move-result for StringFactory method. if (is_string_init) { uint32_t orig_this_reg = is_range ? register_index : args[0]; - HInstruction* fake_string = LoadLocal(orig_this_reg, Primitive::kPrimNot); + HInstruction* fake_string = LoadLocal(orig_this_reg, Primitive::kPrimNot, dex_pc); invoke->SetArgumentAt(argument_index, fake_string); current_block_->AddInstruction(invoke); PotentiallySimplifyFakeString(orig_this_reg, invoke->GetDexPc(), invoke); @@ -1148,15 +1141,15 @@ void HGraphBuilder::PotentiallySimplifyFakeString(uint16_t original_dex_register const VerifiedMethod* verified_method = compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex()); if (verified_method != nullptr) { - UpdateLocal(original_dex_register, actual_string); + UpdateLocal(original_dex_register, actual_string, dex_pc); const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map = verified_method->GetStringInitPcRegMap(); auto map_it = string_init_map.find(dex_pc); if (map_it != string_init_map.end()) { std::set<uint32_t> reg_set = map_it->second; for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) { - HInstruction* load_local = LoadLocal(original_dex_register, Primitive::kPrimNot); - UpdateLocal(*set_it, load_local); + HInstruction* load_local = LoadLocal(original_dex_register, Primitive::kPrimNot, dex_pc); + UpdateLocal(*set_it, load_local, dex_pc); } } } else { @@ -1190,14 +1183,14 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); - HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot); + HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot, dex_pc); current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc)); if (is_put) { Temporaries temps(graph_); HInstruction* null_check = current_block_->GetLastInstruction(); // We need one temporary for the null check. temps.Add(null_check); - HInstruction* value = LoadLocal(source_or_dest_reg, field_type); + HInstruction* value = LoadLocal(source_or_dest_reg, field_type, dex_pc); current_block_->AddInstruction(new (arena_) HInstanceFieldSet( null_check, value, @@ -1206,7 +1199,8 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, resolved_field->IsVolatile(), field_index, *dex_file_, - dex_compilation_unit_->GetDexCache())); + dex_compilation_unit_->GetDexCache(), + dex_pc)); } else { current_block_->AddInstruction(new (arena_) HInstanceFieldGet( current_block_->GetLastInstruction(), @@ -1215,9 +1209,10 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, resolved_field->IsVolatile(), field_index, *dex_file_, - dex_compilation_unit_->GetDexCache())); + dex_compilation_unit_->GetDexCache(), + dex_pc)); - UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); + UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction(), dex_pc); } return true; } @@ -1328,7 +1323,7 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, // We need to keep the class alive before loading the value. Temporaries temps(graph_); temps.Add(cls); - HInstruction* value = LoadLocal(source_or_dest_reg, field_type); + HInstruction* value = LoadLocal(source_or_dest_reg, field_type, dex_pc); DCHECK_EQ(value->GetType(), field_type); current_block_->AddInstruction(new (arena_) HStaticFieldSet(cls, value, @@ -1337,7 +1332,8 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, resolved_field->IsVolatile(), field_index, *dex_file_, - dex_cache_)); + dex_cache_, + dex_pc)); } else { current_block_->AddInstruction(new (arena_) HStaticFieldGet(cls, field_type, @@ -1345,8 +1341,9 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, resolved_field->IsVolatile(), field_index, *dex_file_, - dex_cache_)); - UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); + dex_cache_, + dex_pc)); + UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction(), dex_pc); } return true; } @@ -1360,16 +1357,16 @@ void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg, bool isDiv) { DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong); - HInstruction* first = LoadLocal(first_vreg, type); + HInstruction* first = LoadLocal(first_vreg, type, dex_pc); HInstruction* second = nullptr; if (second_is_constant) { if (type == Primitive::kPrimInt) { - second = graph_->GetIntConstant(second_vreg_or_constant); + second = graph_->GetIntConstant(second_vreg_or_constant, dex_pc); } else { - second = graph_->GetLongConstant(second_vreg_or_constant); + second = graph_->GetLongConstant(second_vreg_or_constant, dex_pc); } } else { - second = LoadLocal(second_vreg_or_constant, type); + second = LoadLocal(second_vreg_or_constant, type, dex_pc); } if (!second_is_constant @@ -1386,7 +1383,7 @@ void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg, } else { current_block_->AddInstruction(new (arena_) HRem(type, first, second, dex_pc)); } - UpdateLocal(out_vreg, current_block_->GetLastInstruction()); + UpdateLocal(out_vreg, current_block_->GetLastInstruction(), dex_pc); } void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, @@ -1400,26 +1397,26 @@ void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, // We need one temporary for the null check, one for the index, and one for the length. Temporaries temps(graph_); - HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot); + HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot, dex_pc); object = new (arena_) HNullCheck(object, dex_pc); current_block_->AddInstruction(object); temps.Add(object); - HInstruction* length = new (arena_) HArrayLength(object); + HInstruction* length = new (arena_) HArrayLength(object, dex_pc); current_block_->AddInstruction(length); temps.Add(length); - HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt); + HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt, dex_pc); index = new (arena_) HBoundsCheck(index, length, dex_pc); current_block_->AddInstruction(index); temps.Add(index); if (is_put) { - HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type); + HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type, dex_pc); // TODO: Insert a type check node if the type is Object. current_block_->AddInstruction(new (arena_) HArraySet( object, index, value, anticipated_type, dex_pc)); } else { - current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type)); - UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); + current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type, dex_pc)); + UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction(), dex_pc); } graph_->SetHasBoundsChecks(true); } @@ -1430,7 +1427,7 @@ void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc, bool is_range, uint32_t* args, uint32_t register_index) { - HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments); + HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments, dex_pc); QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) ? kQuickAllocArrayWithAccessCheck : kQuickAllocArray; @@ -1454,8 +1451,8 @@ void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc, Temporaries temps(graph_); temps.Add(object); for (size_t i = 0; i < number_of_vreg_arguments; ++i) { - HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type); - HInstruction* index = graph_->GetIntConstant(i); + HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type, dex_pc); + HInstruction* index = graph_->GetIntConstant(i, dex_pc); current_block_->AddInstruction( new (arena_) HArraySet(object, index, value, type, dex_pc)); } @@ -1469,8 +1466,8 @@ void HGraphBuilder::BuildFillArrayData(HInstruction* object, Primitive::Type anticipated_type, uint32_t dex_pc) { for (uint32_t i = 0; i < element_count; ++i) { - HInstruction* index = graph_->GetIntConstant(i); - HInstruction* value = graph_->GetIntConstant(data[i]); + HInstruction* index = graph_->GetIntConstant(i, dex_pc); + HInstruction* value = graph_->GetIntConstant(data[i], dex_pc); current_block_->AddInstruction(new (arena_) HArraySet( object, index, value, anticipated_type, dex_pc)); } @@ -1478,12 +1475,12 @@ void HGraphBuilder::BuildFillArrayData(HInstruction* object, void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) { Temporaries temps(graph_); - HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot); + HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot, dex_pc); HNullCheck* null_check = new (arena_) HNullCheck(array, dex_pc); current_block_->AddInstruction(null_check); temps.Add(null_check); - HInstruction* length = new (arena_) HArrayLength(null_check); + HInstruction* length = new (arena_) HArrayLength(null_check, dex_pc); current_block_->AddInstruction(length); int32_t payload_offset = instruction.VRegB_31t() + dex_pc; @@ -1494,7 +1491,7 @@ void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t // Implementation of this DEX instruction seems to be that the bounds check is // done before doing any stores. - HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1); + HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1, dex_pc); current_block_->AddInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc)); switch (payload->element_width) { @@ -1536,8 +1533,8 @@ void HGraphBuilder::BuildFillWideArrayData(HInstruction* object, uint32_t element_count, uint32_t dex_pc) { for (uint32_t i = 0; i < element_count; ++i) { - HInstruction* index = graph_->GetIntConstant(i); - HInstruction* value = graph_->GetLongConstant(data[i]); + HInstruction* index = graph_->GetIntConstant(i, dex_pc); + HInstruction* value = graph_->GetLongConstant(data[i], dex_pc); current_block_->AddInstruction(new (arena_) HArraySet( object, index, value, Primitive::kPrimLong, dex_pc)); } @@ -1562,7 +1559,7 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction, MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); return false; } - HInstruction* object = LoadLocal(reference, Primitive::kPrimNot); + HInstruction* object = LoadLocal(reference, Primitive::kPrimNot, dex_pc); HLoadClass* cls = new (arena_) HLoadClass( graph_->GetCurrentMethod(), type_index, @@ -1576,7 +1573,7 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction, if (instruction.Opcode() == Instruction::INSTANCE_OF) { current_block_->AddInstruction( new (arena_) HInstanceOf(object, cls, type_known_final, dex_pc)); - UpdateLocal(destination, current_block_->GetLastInstruction()); + UpdateLocal(destination, current_block_->GetLastInstruction(), dex_pc); } else { DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST); current_block_->AddInstruction( @@ -1598,7 +1595,7 @@ void HGraphBuilder::BuildPackedSwitch(const Instruction& instruction, uint32_t d SwitchTable table(instruction, dex_pc, false); // Value to test against. - HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); + HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt, dex_pc); // Retrieve number of entries. uint16_t num_entries = table.GetNumEntries(); @@ -1623,7 +1620,7 @@ void HGraphBuilder::BuildSparseSwitch(const Instruction& instruction, uint32_t d SwitchTable table(instruction, dex_pc, true); // Value to test against. - HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); + HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt, dex_pc); uint16_t num_entries = table.GetNumEntries(); @@ -1642,12 +1639,12 @@ void HGraphBuilder::BuildSwitchCaseHelper(const Instruction& instruction, size_t PotentiallyAddSuspendCheck(case_target, dex_pc); // The current case's value. - HInstruction* this_case_value = graph_->GetIntConstant(case_value_int); + HInstruction* this_case_value = graph_->GetIntConstant(case_value_int, dex_pc); // Compare value and this_case_value. - HEqual* comparison = new (arena_) HEqual(value, this_case_value); + HEqual* comparison = new (arena_) HEqual(value, this_case_value, dex_pc); current_block_->AddInstruction(comparison); - HInstruction* ifinst = new (arena_) HIf(comparison); + HInstruction* ifinst = new (arena_) HIf(comparison, dex_pc); current_block_->AddInstruction(ifinst); // Case hit: use the target offset to determine where to go. @@ -1711,29 +1708,29 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 switch (instruction.Opcode()) { case Instruction::CONST_4: { int32_t register_index = instruction.VRegA(); - HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n()); - UpdateLocal(register_index, constant); + HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n(), dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } case Instruction::CONST_16: { int32_t register_index = instruction.VRegA(); - HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s()); - UpdateLocal(register_index, constant); + HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s(), dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } case Instruction::CONST: { int32_t register_index = instruction.VRegA(); - HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i()); - UpdateLocal(register_index, constant); + HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i(), dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } case Instruction::CONST_HIGH16: { int32_t register_index = instruction.VRegA(); - HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16); - UpdateLocal(register_index, constant); + HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16, dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } @@ -1743,8 +1740,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 int64_t value = instruction.VRegB_21s(); value <<= 48; value >>= 48; - HLongConstant* constant = graph_->GetLongConstant(value); - UpdateLocal(register_index, constant); + HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } @@ -1754,23 +1751,23 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 int64_t value = instruction.VRegB_31i(); value <<= 32; value >>= 32; - HLongConstant* constant = graph_->GetLongConstant(value); - UpdateLocal(register_index, constant); + HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } case Instruction::CONST_WIDE: { int32_t register_index = instruction.VRegA(); - HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l()); - UpdateLocal(register_index, constant); + HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l(), dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } case Instruction::CONST_WIDE_HIGH16: { int32_t register_index = instruction.VRegA(); int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48; - HLongConstant* constant = graph_->GetLongConstant(value); - UpdateLocal(register_index, constant); + HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); + UpdateLocal(register_index, constant, dex_pc); break; } @@ -1778,8 +1775,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::MOVE: case Instruction::MOVE_FROM16: case Instruction::MOVE_16: { - HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); - UpdateLocal(instruction.VRegA(), value); + HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt, dex_pc); + UpdateLocal(instruction.VRegA(), value, dex_pc); break; } @@ -1787,22 +1784,22 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::MOVE_WIDE: case Instruction::MOVE_WIDE_FROM16: case Instruction::MOVE_WIDE_16: { - HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong); - UpdateLocal(instruction.VRegA(), value); + HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong, dex_pc); + UpdateLocal(instruction.VRegA(), value, dex_pc); break; } case Instruction::MOVE_OBJECT: case Instruction::MOVE_OBJECT_16: case Instruction::MOVE_OBJECT_FROM16: { - HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot); - UpdateLocal(instruction.VRegA(), value); + HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot, dex_pc); + UpdateLocal(instruction.VRegA(), value, dex_pc); break; } case Instruction::RETURN_VOID_NO_BARRIER: case Instruction::RETURN_VOID: { - BuildReturn(instruction, Primitive::kPrimVoid); + BuildReturn(instruction, Primitive::kPrimVoid, dex_pc); break; } @@ -1824,24 +1821,24 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 HBasicBlock* target = FindBlockStartingAt(offset + dex_pc); DCHECK(target != nullptr); PotentiallyAddSuspendCheck(target, dex_pc); - current_block_->AddInstruction(new (arena_) HGoto()); + current_block_->AddInstruction(new (arena_) HGoto(dex_pc)); current_block_->AddSuccessor(target); current_block_ = nullptr; break; } case Instruction::RETURN: { - BuildReturn(instruction, return_type_); + BuildReturn(instruction, return_type_, dex_pc); break; } case Instruction::RETURN_OBJECT: { - BuildReturn(instruction, return_type_); + BuildReturn(instruction, return_type_, dex_pc); break; } case Instruction::RETURN_WIDE: { - BuildReturn(instruction, return_type_); + BuildReturn(instruction, return_type_, dex_pc); break; } @@ -1895,32 +1892,32 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::NEG_INT: { - Unop_12x<HNeg>(instruction, Primitive::kPrimInt); + Unop_12x<HNeg>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::NEG_LONG: { - Unop_12x<HNeg>(instruction, Primitive::kPrimLong); + Unop_12x<HNeg>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::NEG_FLOAT: { - Unop_12x<HNeg>(instruction, Primitive::kPrimFloat); + Unop_12x<HNeg>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::NEG_DOUBLE: { - Unop_12x<HNeg>(instruction, Primitive::kPrimDouble); + Unop_12x<HNeg>(instruction, Primitive::kPrimDouble, dex_pc); break; } case Instruction::NOT_INT: { - Unop_12x<HNot>(instruction, Primitive::kPrimInt); + Unop_12x<HNot>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::NOT_LONG: { - Unop_12x<HNot>(instruction, Primitive::kPrimLong); + Unop_12x<HNot>(instruction, Primitive::kPrimLong, dex_pc); break; } @@ -2000,67 +1997,67 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::ADD_INT: { - Binop_23x<HAdd>(instruction, Primitive::kPrimInt); + Binop_23x<HAdd>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::ADD_LONG: { - Binop_23x<HAdd>(instruction, Primitive::kPrimLong); + Binop_23x<HAdd>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::ADD_DOUBLE: { - Binop_23x<HAdd>(instruction, Primitive::kPrimDouble); + Binop_23x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc); break; } case Instruction::ADD_FLOAT: { - Binop_23x<HAdd>(instruction, Primitive::kPrimFloat); + Binop_23x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::SUB_INT: { - Binop_23x<HSub>(instruction, Primitive::kPrimInt); + Binop_23x<HSub>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SUB_LONG: { - Binop_23x<HSub>(instruction, Primitive::kPrimLong); + Binop_23x<HSub>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::SUB_FLOAT: { - Binop_23x<HSub>(instruction, Primitive::kPrimFloat); + Binop_23x<HSub>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::SUB_DOUBLE: { - Binop_23x<HSub>(instruction, Primitive::kPrimDouble); + Binop_23x<HSub>(instruction, Primitive::kPrimDouble, dex_pc); break; } case Instruction::ADD_INT_2ADDR: { - Binop_12x<HAdd>(instruction, Primitive::kPrimInt); + Binop_12x<HAdd>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::MUL_INT: { - Binop_23x<HMul>(instruction, Primitive::kPrimInt); + Binop_23x<HMul>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::MUL_LONG: { - Binop_23x<HMul>(instruction, Primitive::kPrimLong); + Binop_23x<HMul>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::MUL_FLOAT: { - Binop_23x<HMul>(instruction, Primitive::kPrimFloat); + Binop_23x<HMul>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::MUL_DOUBLE: { - Binop_23x<HMul>(instruction, Primitive::kPrimDouble); + Binop_23x<HMul>(instruction, Primitive::kPrimDouble, dex_pc); break; } @@ -2109,117 +2106,117 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::AND_INT: { - Binop_23x<HAnd>(instruction, Primitive::kPrimInt); + Binop_23x<HAnd>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::AND_LONG: { - Binop_23x<HAnd>(instruction, Primitive::kPrimLong); + Binop_23x<HAnd>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::SHL_INT: { - Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt); + Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SHL_LONG: { - Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong); + Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::SHR_INT: { - Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt); + Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SHR_LONG: { - Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong); + Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::USHR_INT: { - Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt); + Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::USHR_LONG: { - Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong); + Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::OR_INT: { - Binop_23x<HOr>(instruction, Primitive::kPrimInt); + Binop_23x<HOr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::OR_LONG: { - Binop_23x<HOr>(instruction, Primitive::kPrimLong); + Binop_23x<HOr>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::XOR_INT: { - Binop_23x<HXor>(instruction, Primitive::kPrimInt); + Binop_23x<HXor>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::XOR_LONG: { - Binop_23x<HXor>(instruction, Primitive::kPrimLong); + Binop_23x<HXor>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::ADD_LONG_2ADDR: { - Binop_12x<HAdd>(instruction, Primitive::kPrimLong); + Binop_12x<HAdd>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::ADD_DOUBLE_2ADDR: { - Binop_12x<HAdd>(instruction, Primitive::kPrimDouble); + Binop_12x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc); break; } case Instruction::ADD_FLOAT_2ADDR: { - Binop_12x<HAdd>(instruction, Primitive::kPrimFloat); + Binop_12x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::SUB_INT_2ADDR: { - Binop_12x<HSub>(instruction, Primitive::kPrimInt); + Binop_12x<HSub>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SUB_LONG_2ADDR: { - Binop_12x<HSub>(instruction, Primitive::kPrimLong); + Binop_12x<HSub>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::SUB_FLOAT_2ADDR: { - Binop_12x<HSub>(instruction, Primitive::kPrimFloat); + Binop_12x<HSub>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::SUB_DOUBLE_2ADDR: { - Binop_12x<HSub>(instruction, Primitive::kPrimDouble); + Binop_12x<HSub>(instruction, Primitive::kPrimDouble, dex_pc); break; } case Instruction::MUL_INT_2ADDR: { - Binop_12x<HMul>(instruction, Primitive::kPrimInt); + Binop_12x<HMul>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::MUL_LONG_2ADDR: { - Binop_12x<HMul>(instruction, Primitive::kPrimLong); + Binop_12x<HMul>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::MUL_FLOAT_2ADDR: { - Binop_12x<HMul>(instruction, Primitive::kPrimFloat); + Binop_12x<HMul>(instruction, Primitive::kPrimFloat, dex_pc); break; } case Instruction::MUL_DOUBLE_2ADDR: { - Binop_12x<HMul>(instruction, Primitive::kPrimDouble); + Binop_12x<HMul>(instruction, Primitive::kPrimDouble, dex_pc); break; } @@ -2258,32 +2255,32 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::SHL_INT_2ADDR: { - Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt); + Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SHL_LONG_2ADDR: { - Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong); + Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::SHR_INT_2ADDR: { - Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt); + Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::SHR_LONG_2ADDR: { - Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong); + Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::USHR_INT_2ADDR: { - Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt); + Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::USHR_LONG_2ADDR: { - Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong); + Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc); break; } @@ -2298,92 +2295,92 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::AND_INT_2ADDR: { - Binop_12x<HAnd>(instruction, Primitive::kPrimInt); + Binop_12x<HAnd>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::AND_LONG_2ADDR: { - Binop_12x<HAnd>(instruction, Primitive::kPrimLong); + Binop_12x<HAnd>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::OR_INT_2ADDR: { - Binop_12x<HOr>(instruction, Primitive::kPrimInt); + Binop_12x<HOr>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::OR_LONG_2ADDR: { - Binop_12x<HOr>(instruction, Primitive::kPrimLong); + Binop_12x<HOr>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::XOR_INT_2ADDR: { - Binop_12x<HXor>(instruction, Primitive::kPrimInt); + Binop_12x<HXor>(instruction, Primitive::kPrimInt, dex_pc); break; } case Instruction::XOR_LONG_2ADDR: { - Binop_12x<HXor>(instruction, Primitive::kPrimLong); + Binop_12x<HXor>(instruction, Primitive::kPrimLong, dex_pc); break; } case Instruction::ADD_INT_LIT16: { - Binop_22s<HAdd>(instruction, false); + Binop_22s<HAdd>(instruction, false, dex_pc); break; } case Instruction::AND_INT_LIT16: { - Binop_22s<HAnd>(instruction, false); + Binop_22s<HAnd>(instruction, false, dex_pc); break; } case Instruction::OR_INT_LIT16: { - Binop_22s<HOr>(instruction, false); + Binop_22s<HOr>(instruction, false, dex_pc); break; } case Instruction::XOR_INT_LIT16: { - Binop_22s<HXor>(instruction, false); + Binop_22s<HXor>(instruction, false, dex_pc); break; } case Instruction::RSUB_INT: { - Binop_22s<HSub>(instruction, true); + Binop_22s<HSub>(instruction, true, dex_pc); break; } case Instruction::MUL_INT_LIT16: { - Binop_22s<HMul>(instruction, false); + Binop_22s<HMul>(instruction, false, dex_pc); break; } case Instruction::ADD_INT_LIT8: { - Binop_22b<HAdd>(instruction, false); + Binop_22b<HAdd>(instruction, false, dex_pc); break; } case Instruction::AND_INT_LIT8: { - Binop_22b<HAnd>(instruction, false); + Binop_22b<HAnd>(instruction, false, dex_pc); break; } case Instruction::OR_INT_LIT8: { - Binop_22b<HOr>(instruction, false); + Binop_22b<HOr>(instruction, false, dex_pc); break; } case Instruction::XOR_INT_LIT8: { - Binop_22b<HXor>(instruction, false); + Binop_22b<HXor>(instruction, false, dex_pc); break; } case Instruction::RSUB_INT_LIT8: { - Binop_22b<HSub>(instruction, true); + Binop_22b<HSub>(instruction, true, dex_pc); break; } case Instruction::MUL_INT_LIT8: { - Binop_22b<HMul>(instruction, false); + Binop_22b<HMul>(instruction, false, dex_pc); break; } @@ -2402,17 +2399,17 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 } case Instruction::SHL_INT_LIT8: { - Binop_22b<HShl>(instruction, false); + Binop_22b<HShl>(instruction, false, dex_pc); break; } case Instruction::SHR_INT_LIT8: { - Binop_22b<HShr>(instruction, false); + Binop_22b<HShr>(instruction, false, dex_pc); break; } case Instruction::USHR_INT_LIT8: { - Binop_22b<HUShr>(instruction, false); + Binop_22b<HUShr>(instruction, false, dex_pc); break; } @@ -2420,9 +2417,9 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 uint16_t type_index = instruction.VRegB_21c(); if (compiler_driver_->IsStringTypeIndex(type_index, dex_file_)) { int32_t register_index = instruction.VRegA(); - HFakeString* fake_string = new (arena_) HFakeString(); + HFakeString* fake_string = new (arena_) HFakeString(dex_pc); current_block_->AddInstruction(fake_string); - UpdateLocal(register_index, fake_string); + UpdateLocal(register_index, fake_string, dex_pc); } else { QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) ? kQuickAllocObjectWithAccessCheck @@ -2434,14 +2431,14 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 type_index, *dex_compilation_unit_->GetDexFile(), entrypoint)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction(), dex_pc); } break; } case Instruction::NEW_ARRAY: { uint16_t type_index = instruction.VRegC_22c(); - HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); + HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt, dex_pc); QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) ? kQuickAllocArrayWithAccessCheck : kQuickAllocArray; @@ -2451,7 +2448,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 type_index, *dex_compilation_unit_->GetDexFile(), entrypoint)); - UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction(), dex_pc); break; } @@ -2491,7 +2488,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 // FilledNewArray, the local needs to be updated after the array was // filled, otherwise we might overwrite an input vreg. HStoreLocal* update_local = - new (arena_) HStoreLocal(GetLocalAt(instruction.VRegA()), latest_result_); + new (arena_) HStoreLocal(GetLocalAt(instruction.VRegA()), latest_result_, dex_pc); HBasicBlock* block = latest_result_->GetBlock(); if (block == current_block_) { // MoveResult and the previous instruction are in the same block. @@ -2621,27 +2618,27 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 ARRAY_XX(_SHORT, Primitive::kPrimShort); case Instruction::ARRAY_LENGTH: { - HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot); + HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot, dex_pc); // No need for a temporary for the null check, it is the only input of the following // instruction. object = new (arena_) HNullCheck(object, dex_pc); current_block_->AddInstruction(object); - current_block_->AddInstruction(new (arena_) HArrayLength(object)); - UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction()); + current_block_->AddInstruction(new (arena_) HArrayLength(object, dex_pc)); + UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction(), dex_pc); break; } case Instruction::CONST_STRING: { current_block_->AddInstruction( new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_21c(), dex_pc)); - UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction(), dex_pc); break; } case Instruction::CONST_STRING_JUMBO: { current_block_->AddInstruction( new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_31c(), dex_pc)); - UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction(), dex_pc); break; } @@ -2667,19 +2664,19 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 *dex_compilation_unit_->GetDexFile(), IsOutermostCompilingClass(type_index), dex_pc)); - UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); + UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction(), dex_pc); break; } case Instruction::MOVE_EXCEPTION: { - current_block_->AddInstruction(new (arena_) HLoadException()); - UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction()); - current_block_->AddInstruction(new (arena_) HClearException()); + current_block_->AddInstruction(new (arena_) HLoadException(dex_pc)); + UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction(), dex_pc); + current_block_->AddInstruction(new (arena_) HClearException(dex_pc)); break; } case Instruction::THROW: { - HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot); + HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot, dex_pc); current_block_->AddInstruction(new (arena_) HThrow(exception, dex_pc)); // A throw instruction must branch to the exit block. current_block_->AddSuccessor(exit_block_); @@ -2710,7 +2707,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::MONITOR_ENTER: { current_block_->AddInstruction(new (arena_) HMonitorOperation( - LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), + LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot, dex_pc), HMonitorOperation::kEnter, dex_pc)); break; @@ -2718,7 +2715,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::MONITOR_EXIT: { current_block_->AddInstruction(new (arena_) HMonitorOperation( - LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), + LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot, dex_pc), HMonitorOperation::kExit, dex_pc)); break; @@ -2749,14 +2746,18 @@ HLocal* HGraphBuilder::GetLocalAt(int register_index) const { return locals_.Get(register_index); } -void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const { +void HGraphBuilder::UpdateLocal(int register_index, + HInstruction* instruction, + uint32_t dex_pc) const { HLocal* local = GetLocalAt(register_index); - current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction)); + current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction, dex_pc)); } -HInstruction* HGraphBuilder::LoadLocal(int register_index, Primitive::Type type) const { +HInstruction* HGraphBuilder::LoadLocal(int register_index, + Primitive::Type type, + uint32_t dex_pc) const { HLocal* local = GetLocalAt(register_index); - current_block_->AddInstruction(new (arena_) HLoadLocal(local, type)); + current_block_->AddInstruction(new (arena_) HLoadLocal(local, type, dex_pc)); return current_block_->GetLastInstruction(); } diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 560ed86e50..b0238dc5f8 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -131,23 +131,20 @@ class HGraphBuilder : public ValueObject { void InitializeLocals(uint16_t count); HLocal* GetLocalAt(int register_index) const; - void UpdateLocal(int register_index, HInstruction* instruction) const; - HInstruction* LoadLocal(int register_index, Primitive::Type type) const; + void UpdateLocal(int register_index, HInstruction* instruction, uint32_t dex_pc) const; + HInstruction* LoadLocal(int register_index, Primitive::Type type, uint32_t dex_pc) const; void PotentiallyAddSuspendCheck(HBasicBlock* target, uint32_t dex_pc); void InitializeParameters(uint16_t number_of_parameters); bool NeedsAccessCheck(uint32_t type_index) const; template<typename T> - void Unop_12x(const Instruction& instruction, Primitive::Type type); - - template<typename T> - void Binop_23x(const Instruction& instruction, Primitive::Type type); + void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); template<typename T> void Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); template<typename T> - void Binop_23x_shift(const Instruction& instruction, Primitive::Type type); + void Binop_23x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); void Binop_23x_cmp(const Instruction& instruction, Primitive::Type type, @@ -155,19 +152,16 @@ class HGraphBuilder : public ValueObject { uint32_t dex_pc); template<typename T> - void Binop_12x(const Instruction& instruction, Primitive::Type type); - - template<typename T> void Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); template<typename T> - void Binop_12x_shift(const Instruction& instruction, Primitive::Type type); + void Binop_12x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); template<typename T> - void Binop_22b(const Instruction& instruction, bool reverse); + void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc); template<typename T> - void Binop_22s(const Instruction& instruction, bool reverse); + void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc); template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc); template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc); @@ -185,7 +179,7 @@ class HGraphBuilder : public ValueObject { bool second_is_lit, bool is_div); - void BuildReturn(const Instruction& instruction, Primitive::Type type); + void BuildReturn(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); // Builds an instance field access node and returns whether the instruction is supported. bool BuildInstanceFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 4332d7ed02..650c8e5fed 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -207,7 +207,7 @@ void HGraph::SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor) { // Insert a new node between `block` and `successor` to split the // critical edge. HBasicBlock* new_block = SplitEdge(block, successor); - new_block->AddInstruction(new (arena_) HGoto()); + new_block->AddInstruction(new (arena_) HGoto(successor->GetDexPc())); if (successor->IsLoopHeader()) { // If we split at a back edge boundary, make the new block the back edge. HLoopInformation* info = successor->GetLoopInformation(); @@ -228,7 +228,7 @@ void HGraph::SimplifyLoop(HBasicBlock* header) { if (number_of_incomings != 1) { HBasicBlock* pre_header = new (arena_) HBasicBlock(this, header->GetDexPc()); AddBlock(pre_header); - pre_header->AddInstruction(new (arena_) HGoto()); + pre_header->AddInstruction(new (arena_) HGoto(header->GetDexPc())); for (size_t pred = 0; pred < header->GetPredecessors().Size(); ++pred) { HBasicBlock* predecessor = header->GetPredecessors().Get(pred); @@ -409,12 +409,12 @@ void HGraph::InsertConstant(HConstant* constant) { } } -HNullConstant* HGraph::GetNullConstant() { +HNullConstant* HGraph::GetNullConstant(uint32_t dex_pc) { // For simplicity, don't bother reviving the cached null constant if it is // not null and not in a block. Otherwise, we need to clear the instruction // id and/or any invariants the graph is assuming when adding new instructions. if ((cached_null_constant_ == nullptr) || (cached_null_constant_->GetBlock() == nullptr)) { - cached_null_constant_ = new (arena_) HNullConstant(); + cached_null_constant_ = new (arena_) HNullConstant(dex_pc); InsertConstant(cached_null_constant_); } return cached_null_constant_; @@ -426,7 +426,8 @@ HCurrentMethod* HGraph::GetCurrentMethod() { // id and/or any invariants the graph is assuming when adding new instructions. if ((cached_current_method_ == nullptr) || (cached_current_method_->GetBlock() == nullptr)) { cached_current_method_ = new (arena_) HCurrentMethod( - Is64BitInstructionSet(instruction_set_) ? Primitive::kPrimLong : Primitive::kPrimInt); + Is64BitInstructionSet(instruction_set_) ? Primitive::kPrimLong : Primitive::kPrimInt, + entry_block_->GetDexPc()); if (entry_block_->GetFirstInstruction() == nullptr) { entry_block_->AddInstruction(cached_current_method_); } else { @@ -437,7 +438,7 @@ HCurrentMethod* HGraph::GetCurrentMethod() { return cached_current_method_; } -HConstant* HGraph::GetConstant(Primitive::Type type, int64_t value) { +HConstant* HGraph::GetConstant(Primitive::Type type, int64_t value, uint32_t dex_pc) { switch (type) { case Primitive::Type::kPrimBoolean: DCHECK(IsUint<1>(value)); @@ -447,10 +448,10 @@ HConstant* HGraph::GetConstant(Primitive::Type type, int64_t value) { case Primitive::Type::kPrimShort: case Primitive::Type::kPrimInt: DCHECK(IsInt(Primitive::ComponentSize(type) * kBitsPerByte, value)); - return GetIntConstant(static_cast<int32_t>(value)); + return GetIntConstant(static_cast<int32_t>(value), dex_pc); case Primitive::Type::kPrimLong: - return GetLongConstant(value); + return GetLongConstant(value, dex_pc); default: LOG(FATAL) << "Unsupported constant type"; @@ -944,11 +945,11 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { int32_t value = GetInput()->AsIntConstant()->GetValue(); switch (GetResultType()) { case Primitive::kPrimLong: - return graph->GetLongConstant(static_cast<int64_t>(value)); + return graph->GetLongConstant(static_cast<int64_t>(value), GetDexPc()); case Primitive::kPrimFloat: - return graph->GetFloatConstant(static_cast<float>(value)); + return graph->GetFloatConstant(static_cast<float>(value), GetDexPc()); case Primitive::kPrimDouble: - return graph->GetDoubleConstant(static_cast<double>(value)); + return graph->GetDoubleConstant(static_cast<double>(value), GetDexPc()); default: return nullptr; } @@ -956,11 +957,11 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { int64_t value = GetInput()->AsLongConstant()->GetValue(); switch (GetResultType()) { case Primitive::kPrimInt: - return graph->GetIntConstant(static_cast<int32_t>(value)); + return graph->GetIntConstant(static_cast<int32_t>(value), GetDexPc()); case Primitive::kPrimFloat: - return graph->GetFloatConstant(static_cast<float>(value)); + return graph->GetFloatConstant(static_cast<float>(value), GetDexPc()); case Primitive::kPrimDouble: - return graph->GetDoubleConstant(static_cast<double>(value)); + return graph->GetDoubleConstant(static_cast<double>(value), GetDexPc()); default: return nullptr; } @@ -969,22 +970,22 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { switch (GetResultType()) { case Primitive::kPrimInt: if (std::isnan(value)) - return graph->GetIntConstant(0); + return graph->GetIntConstant(0, GetDexPc()); if (value >= kPrimIntMax) - return graph->GetIntConstant(kPrimIntMax); + return graph->GetIntConstant(kPrimIntMax, GetDexPc()); if (value <= kPrimIntMin) - return graph->GetIntConstant(kPrimIntMin); - return graph->GetIntConstant(static_cast<int32_t>(value)); + return graph->GetIntConstant(kPrimIntMin, GetDexPc()); + return graph->GetIntConstant(static_cast<int32_t>(value), GetDexPc()); case Primitive::kPrimLong: if (std::isnan(value)) - return graph->GetLongConstant(0); + return graph->GetLongConstant(0, GetDexPc()); if (value >= kPrimLongMax) - return graph->GetLongConstant(kPrimLongMax); + return graph->GetLongConstant(kPrimLongMax, GetDexPc()); if (value <= kPrimLongMin) - return graph->GetLongConstant(kPrimLongMin); - return graph->GetLongConstant(static_cast<int64_t>(value)); + return graph->GetLongConstant(kPrimLongMin, GetDexPc()); + return graph->GetLongConstant(static_cast<int64_t>(value), GetDexPc()); case Primitive::kPrimDouble: - return graph->GetDoubleConstant(static_cast<double>(value)); + return graph->GetDoubleConstant(static_cast<double>(value), GetDexPc()); default: return nullptr; } @@ -993,22 +994,22 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { switch (GetResultType()) { case Primitive::kPrimInt: if (std::isnan(value)) - return graph->GetIntConstant(0); + return graph->GetIntConstant(0, GetDexPc()); if (value >= kPrimIntMax) - return graph->GetIntConstant(kPrimIntMax); + return graph->GetIntConstant(kPrimIntMax, GetDexPc()); if (value <= kPrimLongMin) - return graph->GetIntConstant(kPrimIntMin); - return graph->GetIntConstant(static_cast<int32_t>(value)); + return graph->GetIntConstant(kPrimIntMin, GetDexPc()); + return graph->GetIntConstant(static_cast<int32_t>(value), GetDexPc()); case Primitive::kPrimLong: if (std::isnan(value)) - return graph->GetLongConstant(0); + return graph->GetLongConstant(0, GetDexPc()); if (value >= kPrimLongMax) - return graph->GetLongConstant(kPrimLongMax); + return graph->GetLongConstant(kPrimLongMax, GetDexPc()); if (value <= kPrimLongMin) - return graph->GetLongConstant(kPrimLongMin); - return graph->GetLongConstant(static_cast<int64_t>(value)); + return graph->GetLongConstant(kPrimLongMin, GetDexPc()); + return graph->GetLongConstant(static_cast<int64_t>(value), GetDexPc()); case Primitive::kPrimFloat: - return graph->GetFloatConstant(static_cast<float>(value)); + return graph->GetFloatConstant(static_cast<float>(value), GetDexPc()); default: return nullptr; } @@ -1122,7 +1123,8 @@ HBasicBlock* HBasicBlock::SplitBefore(HInstruction* cursor) { DCHECK(!graph_->IsInSsaForm()) << "Support for SSA form not implemented"; DCHECK_EQ(cursor->GetBlock(), this); - HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), GetDexPc()); + HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), + cursor->GetDexPc()); new_block->instructions_.first_instruction_ = cursor; new_block->instructions_.last_instruction_ = instructions_.last_instruction_; instructions_.last_instruction_ = cursor->previous_; @@ -1134,7 +1136,7 @@ HBasicBlock* HBasicBlock::SplitBefore(HInstruction* cursor) { } new_block->instructions_.SetBlockOfInstructions(new_block); - AddInstruction(new (GetGraph()->GetArena()) HGoto()); + AddInstruction(new (GetGraph()->GetArena()) HGoto(new_block->GetDexPc())); for (size_t i = 0, e = GetSuccessors().Size(); i < e; ++i) { HBasicBlock* successor = GetSuccessors().Get(i); @@ -1309,7 +1311,7 @@ void HBasicBlock::DisconnectAndDelete() { predecessor->RemoveSuccessor(this); if (predecessor->GetSuccessors().Size() == 1u) { DCHECK(last_instruction->IsIf()); - predecessor->AddInstruction(new (graph_->GetArena()) HGoto()); + predecessor->AddInstruction(new (graph_->GetArena()) HGoto(last_instruction->GetDexPc())); } else { // The predecessor has no remaining successors and therefore must be dead. // We deliberately leave it without a control-flow instruction so that the @@ -1562,13 +1564,13 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { if (!returns_void) { return_value = last->InputAt(0); } - predecessor->AddInstruction(new (allocator) HGoto()); + predecessor->AddInstruction(new (allocator) HGoto(last->GetDexPc())); predecessor->RemoveInstruction(last); } else { if (!returns_void) { // There will be multiple returns. return_value = new (allocator) HPhi( - allocator, kNoRegNumber, 0, HPhi::ToPhiType(invoke->GetType())); + allocator, kNoRegNumber, 0, HPhi::ToPhiType(invoke->GetType()), to->GetDexPc()); to->AddPhi(return_value->AsPhi()); } for (size_t i = 0, e = to->GetPredecessors().Size(); i < e; ++i) { @@ -1577,7 +1579,7 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { if (!returns_void) { return_value->AsPhi()->AddInput(last->InputAt(0)); } - predecessor->AddInstruction(new (allocator) HGoto()); + predecessor->AddInstruction(new (allocator) HGoto(last->GetDexPc())); predecessor->RemoveInstruction(last); } } @@ -1659,15 +1661,19 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { for (HInstructionIterator it(entry_block_->GetInstructions()); !it.Done(); it.Advance()) { HInstruction* current = it.Current(); if (current->IsNullConstant()) { - current->ReplaceWith(outer_graph->GetNullConstant()); + current->ReplaceWith(outer_graph->GetNullConstant(current->GetDexPc())); } else if (current->IsIntConstant()) { - current->ReplaceWith(outer_graph->GetIntConstant(current->AsIntConstant()->GetValue())); + current->ReplaceWith(outer_graph->GetIntConstant( + current->AsIntConstant()->GetValue(), current->GetDexPc())); } else if (current->IsLongConstant()) { - current->ReplaceWith(outer_graph->GetLongConstant(current->AsLongConstant()->GetValue())); + current->ReplaceWith(outer_graph->GetLongConstant( + current->AsLongConstant()->GetValue(), current->GetDexPc())); } else if (current->IsFloatConstant()) { - current->ReplaceWith(outer_graph->GetFloatConstant(current->AsFloatConstant()->GetValue())); + current->ReplaceWith(outer_graph->GetFloatConstant( + current->AsFloatConstant()->GetValue(), current->GetDexPc())); } else if (current->IsDoubleConstant()) { - current->ReplaceWith(outer_graph->GetDoubleConstant(current->AsDoubleConstant()->GetValue())); + current->ReplaceWith(outer_graph->GetDoubleConstant( + current->AsDoubleConstant()->GetValue(), current->GetDexPc())); } else if (current->IsParameterValue()) { if (kIsDebugBuild && invoke->IsInvokeStaticOrDirect() diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index dc0a5df8ae..23d605b7b5 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -77,6 +77,8 @@ static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1); static constexpr InvokeType kInvalidInvokeType = static_cast<InvokeType>(-1); +static constexpr uint32_t kNoDexPc = -1; + enum IfCondition { kCondEQ, kCondNE, @@ -316,24 +318,24 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { // Returns a constant of the given type and value. If it does not exist // already, it is created and inserted into the graph. This method is only for // integral types. - HConstant* GetConstant(Primitive::Type type, int64_t value); + HConstant* GetConstant(Primitive::Type type, int64_t value, uint32_t dex_pc = kNoDexPc); // TODO: This is problematic for the consistency of reference type propagation // because it can be created anytime after the pass and thus it will be left // with an invalid type. - HNullConstant* GetNullConstant(); + HNullConstant* GetNullConstant(uint32_t dex_pc = kNoDexPc); - HIntConstant* GetIntConstant(int32_t value) { - return CreateConstant(value, &cached_int_constants_); + HIntConstant* GetIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) { + return CreateConstant(value, &cached_int_constants_, dex_pc); } - HLongConstant* GetLongConstant(int64_t value) { - return CreateConstant(value, &cached_long_constants_); + HLongConstant* GetLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) { + return CreateConstant(value, &cached_long_constants_, dex_pc); } - HFloatConstant* GetFloatConstant(float value) { - return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_); + HFloatConstant* GetFloatConstant(float value, uint32_t dex_pc = kNoDexPc) { + return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_, dex_pc); } - HDoubleConstant* GetDoubleConstant(double value) { - return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_); + HDoubleConstant* GetDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) { + return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_, dex_pc); } HCurrentMethod* GetCurrentMethod(); @@ -372,7 +374,8 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { template <class InstructionType, typename ValueType> InstructionType* CreateConstant(ValueType value, - ArenaSafeMap<ValueType, InstructionType*>* cache) { + ArenaSafeMap<ValueType, InstructionType*>* cache, + uint32_t dex_pc = kNoDexPc) { // Try to find an existing constant of the given value. InstructionType* constant = nullptr; auto cached_constant = cache->find(value); @@ -383,7 +386,7 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { // If not found or previously deleted, create and cache a new instruction. // Don't bother reviving a previously deleted instruction, for simplicity. if (constant == nullptr || constant->GetBlock() == nullptr) { - constant = new (arena_) InstructionType(value); + constant = new (arena_) InstructionType(value, dex_pc); cache->Overwrite(value, constant); InsertConstant(constant); } @@ -618,7 +621,6 @@ class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { }; static constexpr size_t kNoLifetime = -1; -static constexpr uint32_t kNoDexPc = -1; // A block in a method. Contains the list of instructions represented // as a double linked list. Each block knows its predecessors and @@ -626,7 +628,7 @@ static constexpr uint32_t kNoDexPc = -1; class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { public: - explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc) + HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc) : graph_(graph), predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors), successors_(graph->GetArena(), kDefaultNumberOfSuccessors), @@ -683,6 +685,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { int GetBlockId() const { return block_id_; } void SetBlockId(int id) { block_id_ = id; } + uint32_t GetDexPc() const { return dex_pc_; } HBasicBlock* GetDominator() const { return dominator_; } void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; } @@ -943,7 +946,6 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { void SetLifetimeStart(size_t start) { lifetime_start_ = start; } void SetLifetimeEnd(size_t end) { lifetime_end_ = end; } - uint32_t GetDexPc() const { return dex_pc_; } bool EndsWithControlFlowInstruction() const; bool EndsWithIf() const; @@ -1691,10 +1693,11 @@ std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs); class HInstruction : public ArenaObject<kArenaAllocInstruction> { public: - explicit HInstruction(SideEffects side_effects) + HInstruction(SideEffects side_effects, uint32_t dex_pc = kNoDexPc) : previous_(nullptr), next_(nullptr), block_(nullptr), + dex_pc_(dex_pc), id_(-1), ssa_index_(-1), environment_(nullptr), @@ -1737,9 +1740,9 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { } virtual bool NeedsEnvironment() const { return false; } - virtual uint32_t GetDexPc() const { - return kNoDexPc; - } + + uint32_t GetDexPc() const { return dex_pc_; } + virtual bool IsControlFlow() const { return false; } virtual bool CanThrow() const { return false; } @@ -1942,6 +1945,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { HInstruction* previous_; HInstruction* next_; HBasicBlock* block_; + const uint32_t dex_pc_; // An instruction gets an id when it is added to the graph. // It reflects creation order. A negative id means the instruction @@ -2046,8 +2050,8 @@ class HBackwardInstructionIterator : public ValueObject { template<size_t N> class HTemplateInstruction: public HInstruction { public: - HTemplateInstruction<N>(SideEffects side_effects) - : HInstruction(side_effects), inputs_() {} + HTemplateInstruction<N>(SideEffects side_effects, uint32_t dex_pc = kNoDexPc) + : HInstruction(side_effects, dex_pc), inputs_() {} virtual ~HTemplateInstruction() {} size_t InputCount() const OVERRIDE { return N; } @@ -2073,7 +2077,9 @@ class HTemplateInstruction: public HInstruction { template<> class HTemplateInstruction<0>: public HInstruction { public: - explicit HTemplateInstruction(SideEffects side_effects) : HInstruction(side_effects) {} + explicit HTemplateInstruction<0>(SideEffects side_effects, uint32_t dex_pc = kNoDexPc) + : HInstruction(side_effects, dex_pc) {} + virtual ~HTemplateInstruction() {} size_t InputCount() const OVERRIDE { return 0; } @@ -2097,8 +2103,8 @@ class HTemplateInstruction<0>: public HInstruction { template<intptr_t N> class HExpression : public HTemplateInstruction<N> { public: - HExpression<N>(Primitive::Type type, SideEffects side_effects) - : HTemplateInstruction<N>(side_effects), type_(type) {} + HExpression<N>(Primitive::Type type, SideEffects side_effects, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction<N>(side_effects, dex_pc), type_(type) {} virtual ~HExpression() {} Primitive::Type GetType() const OVERRIDE { return type_; } @@ -2111,7 +2117,8 @@ class HExpression : public HTemplateInstruction<N> { // instruction that branches to the exit block. class HReturnVoid : public HTemplateInstruction<0> { public: - HReturnVoid() : HTemplateInstruction(SideEffects::None()) {} + explicit HReturnVoid(uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc) {} bool IsControlFlow() const OVERRIDE { return true; } @@ -2125,7 +2132,8 @@ class HReturnVoid : public HTemplateInstruction<0> { // instruction that branches to the exit block. class HReturn : public HTemplateInstruction<1> { public: - explicit HReturn(HInstruction* value) : HTemplateInstruction(SideEffects::None()) { + explicit HReturn(HInstruction* value, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc) { SetRawInputAt(0, value); } @@ -2142,7 +2150,7 @@ class HReturn : public HTemplateInstruction<1> { // exit block. class HExit : public HTemplateInstruction<0> { public: - HExit() : HTemplateInstruction(SideEffects::None()) {} + explicit HExit(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {} bool IsControlFlow() const OVERRIDE { return true; } @@ -2155,7 +2163,7 @@ class HExit : public HTemplateInstruction<0> { // Jumps from one block to another. class HGoto : public HTemplateInstruction<0> { public: - HGoto() : HTemplateInstruction(SideEffects::None()) {} + explicit HGoto(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {} bool IsControlFlow() const OVERRIDE { return true; } @@ -2171,7 +2179,8 @@ class HGoto : public HTemplateInstruction<0> { class HConstant : public HExpression<0> { public: - explicit HConstant(Primitive::Type type) : HExpression(type, SideEffects::None()) {} + explicit HConstant(Primitive::Type type, uint32_t dex_pc = kNoDexPc) + : HExpression(type, SideEffects::None(), dex_pc) {} bool CanBeMoved() const OVERRIDE { return true; } @@ -2196,7 +2205,7 @@ class HNullConstant : public HConstant { DECLARE_INSTRUCTION(NullConstant); private: - HNullConstant() : HConstant(Primitive::kPrimNot) {} + explicit HNullConstant(uint32_t dex_pc = kNoDexPc) : HConstant(Primitive::kPrimNot, dex_pc) {} friend class HGraph; DISALLOW_COPY_AND_ASSIGN(HNullConstant); @@ -2222,8 +2231,10 @@ class HIntConstant : public HConstant { DECLARE_INSTRUCTION(IntConstant); private: - explicit HIntConstant(int32_t value) : HConstant(Primitive::kPrimInt), value_(value) {} - explicit HIntConstant(bool value) : HConstant(Primitive::kPrimInt), value_(value ? 1 : 0) {} + explicit HIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimInt, dex_pc), value_(value) {} + explicit HIntConstant(bool value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimInt, dex_pc), value_(value ? 1 : 0) {} const int32_t value_; @@ -2251,7 +2262,8 @@ class HLongConstant : public HConstant { DECLARE_INSTRUCTION(LongConstant); private: - explicit HLongConstant(int64_t value) : HConstant(Primitive::kPrimLong), value_(value) {} + explicit HLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimLong, dex_pc), value_(value) {} const int64_t value_; @@ -2263,7 +2275,8 @@ class HLongConstant : public HConstant { // two successors. class HIf : public HTemplateInstruction<1> { public: - explicit HIf(HInstruction* input) : HTemplateInstruction(SideEffects::None()) { + explicit HIf(HInstruction* input, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc) { SetRawInputAt(0, input); } @@ -2296,8 +2309,8 @@ class HTryBoundary : public HTemplateInstruction<0> { kExit, }; - explicit HTryBoundary(BoundaryKind kind) - : HTemplateInstruction(SideEffects::None()), kind_(kind) {} + explicit HTryBoundary(BoundaryKind kind, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc), kind_(kind) {} bool IsControlFlow() const OVERRIDE { return true; } @@ -2354,21 +2367,17 @@ class HExceptionHandlerIterator : public ValueObject { // Deoptimize to interpreter, upon checking a condition. class HDeoptimize : public HTemplateInstruction<1> { public: - HDeoptimize(HInstruction* cond, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::None()), - dex_pc_(dex_pc) { + explicit HDeoptimize(HInstruction* cond, uint32_t dex_pc) + : HTemplateInstruction(SideEffects::None(), dex_pc) { SetRawInputAt(0, cond); } bool NeedsEnvironment() const OVERRIDE { return true; } bool CanThrow() const OVERRIDE { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } DECLARE_INSTRUCTION(Deoptimize); private: - uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HDeoptimize); }; @@ -2377,7 +2386,8 @@ class HDeoptimize : public HTemplateInstruction<1> { // instructions that work with the dex cache. class HCurrentMethod : public HExpression<0> { public: - explicit HCurrentMethod(Primitive::Type type) : HExpression(type, SideEffects::None()) {} + explicit HCurrentMethod(Primitive::Type type, uint32_t dex_pc = kNoDexPc) + : HExpression(type, SideEffects::None(), dex_pc) {} DECLARE_INSTRUCTION(CurrentMethod); @@ -2387,8 +2397,8 @@ class HCurrentMethod : public HExpression<0> { class HUnaryOperation : public HExpression<1> { public: - HUnaryOperation(Primitive::Type result_type, HInstruction* input) - : HExpression(result_type, SideEffects::None()) { + HUnaryOperation(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) + : HExpression(result_type, SideEffects::None(), dex_pc) { SetRawInputAt(0, input); } @@ -2421,8 +2431,9 @@ class HBinaryOperation : public HExpression<2> { HBinaryOperation(Primitive::Type result_type, HInstruction* left, HInstruction* right, - SideEffects side_effects = SideEffects::None()) - : HExpression(result_type, side_effects) { + SideEffects side_effects = SideEffects::None(), + uint32_t dex_pc = kNoDexPc) + : HExpression(result_type, side_effects, dex_pc) { SetRawInputAt(0, left); SetRawInputAt(1, right); } @@ -2514,8 +2525,8 @@ enum class ComparisonBias { class HCondition : public HBinaryOperation { public: - HCondition(HInstruction* first, HInstruction* second) - : HBinaryOperation(Primitive::kPrimBoolean, first, second), + HCondition(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(Primitive::kPrimBoolean, first, second, SideEffects::None(), dex_pc), needs_materialization_(true), bias_(ComparisonBias::kNoBias) {} @@ -2566,18 +2577,20 @@ class HCondition : public HBinaryOperation { // Instruction to check if two inputs are equal to each other. class HEqual : public HCondition { public: - HEqual(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } template <typename T> bool Compute(T x, T y) const { return x == y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Equal); @@ -2596,18 +2609,20 @@ class HEqual : public HCondition { class HNotEqual : public HCondition { public: - HNotEqual(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HNotEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } template <typename T> bool Compute(T x, T y) const { return x != y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(NotEqual); @@ -2626,16 +2641,18 @@ class HNotEqual : public HCondition { class HLessThan : public HCondition { public: - HLessThan(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HLessThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} template <typename T> bool Compute(T x, T y) const { return x < y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(LessThan); @@ -2654,16 +2671,18 @@ class HLessThan : public HCondition { class HLessThanOrEqual : public HCondition { public: - HLessThanOrEqual(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HLessThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} template <typename T> bool Compute(T x, T y) const { return x <= y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(LessThanOrEqual); @@ -2682,16 +2701,18 @@ class HLessThanOrEqual : public HCondition { class HGreaterThan : public HCondition { public: - HGreaterThan(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HGreaterThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} template <typename T> bool Compute(T x, T y) const { return x > y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(GreaterThan); @@ -2710,16 +2731,18 @@ class HGreaterThan : public HCondition { class HGreaterThanOrEqual : public HCondition { public: - HGreaterThanOrEqual(HInstruction* first, HInstruction* second) - : HCondition(first, second) {} + HGreaterThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) + : HCondition(first, second, dex_pc) {} template <typename T> bool Compute(T x, T y) const { return x >= y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(GreaterThanOrEqual); @@ -2746,9 +2769,12 @@ class HCompare : public HBinaryOperation { HInstruction* second, ComparisonBias bias, uint32_t dex_pc) - : HBinaryOperation(Primitive::kPrimInt, first, second, SideEffectsForArchRuntimeCalls(type)), - bias_(bias), - dex_pc_(dex_pc) { + : HBinaryOperation(Primitive::kPrimInt, + first, + second, + SideEffectsForArchRuntimeCalls(type), + dex_pc), + bias_(bias) { DCHECK_EQ(type, first->GetType()); DCHECK_EQ(type, second->GetType()); } @@ -2757,10 +2783,12 @@ class HCompare : public HBinaryOperation { int32_t Compute(T x, T y) const { return x == y ? 0 : x > y ? 1 : -1; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } bool InstructionDataEquals(HInstruction* other) const OVERRIDE { @@ -2771,7 +2799,6 @@ class HCompare : public HBinaryOperation { bool IsGtBias() { return bias_ == ComparisonBias::kGtBias; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type type) { // MIPS64 uses a runtime call for FP comparisons. @@ -2782,7 +2809,6 @@ class HCompare : public HBinaryOperation { private: const ComparisonBias bias_; - const uint32_t dex_pc_; DISALLOW_COPY_AND_ASSIGN(HCompare); }; @@ -2791,7 +2817,7 @@ class HCompare : public HBinaryOperation { class HLocal : public HTemplateInstruction<0> { public: explicit HLocal(uint16_t reg_number) - : HTemplateInstruction(SideEffects::None()), reg_number_(reg_number) {} + : HTemplateInstruction(SideEffects::None(), kNoDexPc), reg_number_(reg_number) {} DECLARE_INSTRUCTION(Local); @@ -2807,8 +2833,8 @@ class HLocal : public HTemplateInstruction<0> { // Load a given local. The local is an input of this instruction. class HLoadLocal : public HExpression<1> { public: - HLoadLocal(HLocal* local, Primitive::Type type) - : HExpression(type, SideEffects::None()) { + HLoadLocal(HLocal* local, Primitive::Type type, uint32_t dex_pc = kNoDexPc) + : HExpression(type, SideEffects::None(), dex_pc) { SetRawInputAt(0, local); } @@ -2824,7 +2850,8 @@ class HLoadLocal : public HExpression<1> { // and the local. class HStoreLocal : public HTemplateInstruction<2> { public: - HStoreLocal(HLocal* local, HInstruction* value) : HTemplateInstruction(SideEffects::None()) { + HStoreLocal(HLocal* local, HInstruction* value, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc) { SetRawInputAt(0, local); SetRawInputAt(1, value); } @@ -2865,9 +2892,10 @@ class HFloatConstant : public HConstant { DECLARE_INSTRUCTION(FloatConstant); private: - explicit HFloatConstant(float value) : HConstant(Primitive::kPrimFloat), value_(value) {} - explicit HFloatConstant(int32_t value) - : HConstant(Primitive::kPrimFloat), value_(bit_cast<float, int32_t>(value)) {} + explicit HFloatConstant(float value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimFloat, dex_pc), value_(value) {} + explicit HFloatConstant(int32_t value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimFloat, dex_pc), value_(bit_cast<float, int32_t>(value)) {} const float value_; @@ -2905,9 +2933,10 @@ class HDoubleConstant : public HConstant { DECLARE_INSTRUCTION(DoubleConstant); private: - explicit HDoubleConstant(double value) : HConstant(Primitive::kPrimDouble), value_(value) {} - explicit HDoubleConstant(int64_t value) - : HConstant(Primitive::kPrimDouble), value_(bit_cast<double, int64_t>(value)) {} + explicit HDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimDouble, dex_pc), value_(value) {} + explicit HDoubleConstant(int64_t value, uint32_t dex_pc = kNoDexPc) + : HConstant(Primitive::kPrimDouble, dex_pc), value_(bit_cast<double, int64_t>(value)) {} const double value_; @@ -2954,7 +2983,6 @@ class HInvoke : public HInstruction { Primitive::Type GetType() const OVERRIDE { return return_type_; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint32_t GetDexMethodIndex() const { return dex_method_index_; } const DexFile& GetDexFile() const { return GetEnvironment()->GetDexFile(); } @@ -2987,11 +3015,10 @@ class HInvoke : public HInstruction { uint32_t dex_method_index, InvokeType original_invoke_type) : HInstruction( - SideEffects::AllExceptGCDependency()), // Assume write/read on all fields/arrays. + SideEffects::AllExceptGCDependency(), dex_pc), // Assume write/read on all fields/arrays. number_of_arguments_(number_of_arguments), inputs_(arena, number_of_arguments), return_type_(return_type), - dex_pc_(dex_pc), dex_method_index_(dex_method_index), original_invoke_type_(original_invoke_type), intrinsic_(Intrinsics::kNone), @@ -3008,7 +3035,6 @@ class HInvoke : public HInstruction { uint32_t number_of_arguments_; GrowableArray<HUserRecord<HInstruction*> > inputs_; const Primitive::Type return_type_; - const uint32_t dex_pc_; const uint32_t dex_method_index_; const InvokeType original_invoke_type_; Intrinsics intrinsic_; @@ -3309,15 +3335,13 @@ class HNewInstance : public HExpression<1> { uint16_t type_index, const DexFile& dex_file, QuickEntrypointEnum entrypoint) - : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC()), - dex_pc_(dex_pc), + : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), type_index_(type_index), dex_file_(dex_file), entrypoint_(entrypoint) { SetRawInputAt(0, current_method); } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint16_t GetTypeIndex() const { return type_index_; } const DexFile& GetDexFile() const { return dex_file_; } @@ -3336,7 +3360,6 @@ class HNewInstance : public HExpression<1> { DECLARE_INSTRUCTION(NewInstance); private: - const uint32_t dex_pc_; const uint16_t type_index_; const DexFile& dex_file_; const QuickEntrypointEnum entrypoint_; @@ -3346,16 +3369,16 @@ class HNewInstance : public HExpression<1> { class HNeg : public HUnaryOperation { public: - HNeg(Primitive::Type result_type, HInstruction* input) - : HUnaryOperation(result_type, input) {} + HNeg(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) + : HUnaryOperation(result_type, input, dex_pc) {} template <typename T> T Compute(T x) const { return -x; } HConstant* Evaluate(HIntConstant* x) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Neg); @@ -3372,8 +3395,7 @@ class HNewArray : public HExpression<2> { uint16_t type_index, const DexFile& dex_file, QuickEntrypointEnum entrypoint) - : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC()), - dex_pc_(dex_pc), + : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), type_index_(type_index), dex_file_(dex_file), entrypoint_(entrypoint) { @@ -3381,7 +3403,6 @@ class HNewArray : public HExpression<2> { SetRawInputAt(1, current_method); } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint16_t GetTypeIndex() const { return type_index_; } const DexFile& GetDexFile() const { return dex_file_; } @@ -3398,7 +3419,6 @@ class HNewArray : public HExpression<2> { DECLARE_INSTRUCTION(NewArray); private: - const uint32_t dex_pc_; const uint16_t type_index_; const DexFile& dex_file_; const QuickEntrypointEnum entrypoint_; @@ -3408,18 +3428,23 @@ class HNewArray : public HExpression<2> { class HAdd : public HBinaryOperation { public: - HAdd(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HAdd(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } template <typename T> T Compute(T x, T y) const { return x + y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Add); @@ -3430,16 +3455,21 @@ class HAdd : public HBinaryOperation { class HSub : public HBinaryOperation { public: - HSub(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HSub(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} template <typename T> T Compute(T x, T y) const { return x - y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Sub); @@ -3450,18 +3480,23 @@ class HSub : public HBinaryOperation { class HMul : public HBinaryOperation { public: - HMul(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HMul(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } template <typename T> T Compute(T x, T y) const { return x * y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Mul); @@ -3472,9 +3507,11 @@ class HMul : public HBinaryOperation { class HDiv : public HBinaryOperation { public: - HDiv(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc) - : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls()), - dex_pc_(dex_pc) {} + HDiv(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc) + : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {} template <typename T> T Compute(T x, T y) const { @@ -3486,14 +3523,14 @@ class HDiv : public HBinaryOperation { } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } - static SideEffects SideEffectsForArchRuntimeCalls() { // The generated code can use a runtime call. return SideEffects::CanTriggerGC(); @@ -3502,16 +3539,16 @@ class HDiv : public HBinaryOperation { DECLARE_INSTRUCTION(Div); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HDiv); }; class HRem : public HBinaryOperation { public: - HRem(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc) - : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls()), - dex_pc_(dex_pc) {} + HRem(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc) + : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {} template <typename T> T Compute(T x, T y) const { @@ -3523,13 +3560,14 @@ class HRem : public HBinaryOperation { } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } static SideEffects SideEffectsForArchRuntimeCalls() { return SideEffects::CanTriggerGC(); @@ -3538,15 +3576,13 @@ class HRem : public HBinaryOperation { DECLARE_INSTRUCTION(Rem); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HRem); }; class HDivZeroCheck : public HExpression<1> { public: HDivZeroCheck(HInstruction* value, uint32_t dex_pc) - : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) { + : HExpression(value->GetType(), SideEffects::None(), dex_pc) { SetRawInputAt(0, value); } @@ -3562,20 +3598,19 @@ class HDivZeroCheck : public HExpression<1> { bool NeedsEnvironment() const OVERRIDE { return true; } bool CanThrow() const OVERRIDE { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } - DECLARE_INSTRUCTION(DivZeroCheck); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HDivZeroCheck); }; class HShl : public HBinaryOperation { public: - HShl(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HShl(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} template <typename T, typename U, typename V> T Compute(T x, U y, V max_shift_value) const { @@ -3586,17 +3621,17 @@ class HShl : public HBinaryOperation { HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); } // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this // case is handled as `x << static_cast<int>(y)`. HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } DECLARE_INSTRUCTION(Shl); @@ -3607,8 +3642,11 @@ class HShl : public HBinaryOperation { class HShr : public HBinaryOperation { public: - HShr(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HShr(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} template <typename T, typename U, typename V> T Compute(T x, U y, V max_shift_value) const { @@ -3619,17 +3657,17 @@ class HShr : public HBinaryOperation { HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); } // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this // case is handled as `x >> static_cast<int>(y)`. HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } DECLARE_INSTRUCTION(Shr); @@ -3640,8 +3678,11 @@ class HShr : public HBinaryOperation { class HUShr : public HBinaryOperation { public: - HUShr(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HUShr(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} template <typename T, typename U, typename V> T Compute(T x, U y, V max_shift_value) const { @@ -3653,17 +3694,17 @@ class HUShr : public HBinaryOperation { HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); } // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this // case is handled as `x >>> static_cast<int>(y)`. HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue)); + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); } DECLARE_INSTRUCTION(UShr); @@ -3674,8 +3715,11 @@ class HUShr : public HBinaryOperation { class HAnd : public HBinaryOperation { public: - HAnd(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HAnd(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } @@ -3683,16 +3727,20 @@ class HAnd : public HBinaryOperation { auto Compute(T x, U y) const -> decltype(x & y) { return x & y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(And); @@ -3703,8 +3751,11 @@ class HAnd : public HBinaryOperation { class HOr : public HBinaryOperation { public: - HOr(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HOr(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } @@ -3712,16 +3763,20 @@ class HOr : public HBinaryOperation { auto Compute(T x, U y) const -> decltype(x | y) { return x | y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Or); @@ -3732,8 +3787,11 @@ class HOr : public HBinaryOperation { class HXor : public HBinaryOperation { public: - HXor(Primitive::Type result_type, HInstruction* left, HInstruction* right) - : HBinaryOperation(result_type, left, right) {} + HXor(Primitive::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) + : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} bool IsCommutative() const OVERRIDE { return true; } @@ -3741,16 +3799,20 @@ class HXor : public HBinaryOperation { auto Compute(T x, U y) const -> decltype(x ^ y) { return x ^ y; } HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Xor); @@ -3763,8 +3825,10 @@ class HXor : public HBinaryOperation { // the calling convention. class HParameterValue : public HExpression<0> { public: - HParameterValue(uint8_t index, Primitive::Type parameter_type, bool is_this = false) - : HExpression(parameter_type, SideEffects::None()), + HParameterValue(uint8_t index, + Primitive::Type parameter_type, + bool is_this = false) + : HExpression(parameter_type, SideEffects::None(), kNoDexPc), index_(index), is_this_(is_this), can_be_null_(!is_this) {} @@ -3793,8 +3857,8 @@ class HParameterValue : public HExpression<0> { class HNot : public HUnaryOperation { public: - HNot(Primitive::Type result_type, HInstruction* input) - : HUnaryOperation(result_type, input) {} + HNot(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) + : HUnaryOperation(result_type, input, dex_pc) {} bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(HInstruction* other) const OVERRIDE { @@ -3805,10 +3869,10 @@ class HNot : public HUnaryOperation { template <typename T> T Compute(T x) const { return ~x; } HConstant* Evaluate(HIntConstant* x) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue())); + return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); } DECLARE_INSTRUCTION(Not); @@ -3819,8 +3883,8 @@ class HNot : public HUnaryOperation { class HBooleanNot : public HUnaryOperation { public: - explicit HBooleanNot(HInstruction* input) - : HUnaryOperation(Primitive::Type::kPrimBoolean, input) {} + explicit HBooleanNot(HInstruction* input, uint32_t dex_pc = kNoDexPc) + : HUnaryOperation(Primitive::Type::kPrimBoolean, input, dex_pc) {} bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(HInstruction* other) const OVERRIDE { @@ -3834,7 +3898,7 @@ class HBooleanNot : public HUnaryOperation { } HConstant* Evaluate(HIntConstant* x) const OVERRIDE { - return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue())); + return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for long values"; @@ -3851,8 +3915,9 @@ class HTypeConversion : public HExpression<1> { public: // Instantiate a type conversion of `input` to `result_type`. HTypeConversion(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc) - : HExpression(result_type, SideEffectsForArchRuntimeCalls(input->GetType(), result_type)), - dex_pc_(dex_pc) { + : HExpression(result_type, + SideEffectsForArchRuntimeCalls(input->GetType(), result_type), + dex_pc) { SetRawInputAt(0, input); DCHECK_NE(input->GetType(), result_type); } @@ -3863,7 +3928,6 @@ class HTypeConversion : public HExpression<1> { // Required by the x86 and ARM code generators when producing calls // to the runtime. - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } @@ -3887,8 +3951,6 @@ class HTypeConversion : public HExpression<1> { DECLARE_INSTRUCTION(TypeConversion); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HTypeConversion); }; @@ -3896,8 +3958,12 @@ static constexpr uint32_t kNoRegNumber = -1; class HPhi : public HInstruction { public: - HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type) - : HInstruction(SideEffects::None()), + HPhi(ArenaAllocator* arena, + uint32_t reg_number, + size_t number_of_inputs, + Primitive::Type type, + uint32_t dex_pc = kNoDexPc) + : HInstruction(SideEffects::None(), dex_pc), inputs_(arena, number_of_inputs), reg_number_(reg_number), type_(type), @@ -3975,7 +4041,7 @@ class HPhi : public HInstruction { class HNullCheck : public HExpression<1> { public: HNullCheck(HInstruction* value, uint32_t dex_pc) - : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) { + : HExpression(value->GetType(), SideEffects::None(), dex_pc) { SetRawInputAt(0, value); } @@ -3991,13 +4057,10 @@ class HNullCheck : public HExpression<1> { bool CanBeNull() const OVERRIDE { return false; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } DECLARE_INSTRUCTION(NullCheck); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HNullCheck); }; @@ -4040,10 +4103,11 @@ class HInstanceFieldGet : public HExpression<1> { bool is_volatile, uint32_t field_idx, const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) + Handle<mirror::DexCache> dex_cache, + uint32_t dex_pc = kNoDexPc) : HExpression( field_type, - SideEffects::FieldReadOfType(field_type, is_volatile)), + SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) { SetRawInputAt(0, value); } @@ -4085,9 +4149,10 @@ class HInstanceFieldSet : public HTemplateInstruction<2> { bool is_volatile, uint32_t field_idx, const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) + Handle<mirror::DexCache> dex_cache, + uint32_t dex_pc = kNoDexPc) : HTemplateInstruction( - SideEffects::FieldWriteOfType(field_type, is_volatile)), + SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache), value_can_be_null_(true) { SetRawInputAt(0, object); @@ -4117,8 +4182,11 @@ class HInstanceFieldSet : public HTemplateInstruction<2> { class HArrayGet : public HExpression<2> { public: - HArrayGet(HInstruction* array, HInstruction* index, Primitive::Type type) - : HExpression(type, SideEffects::ArrayReadOfType(type)) { + HArrayGet(HInstruction* array, + HInstruction* index, + Primitive::Type type, + uint32_t dex_pc = kNoDexPc) + : HExpression(type, SideEffects::ArrayReadOfType(type), dex_pc) { SetRawInputAt(0, array); SetRawInputAt(1, index); } @@ -4158,8 +4226,7 @@ class HArraySet : public HTemplateInstruction<3> { uint32_t dex_pc) : HTemplateInstruction( SideEffects::ArrayWriteOfType(expected_component_type).Union( - SideEffectsForArchRuntimeCalls(value->GetType()))), - dex_pc_(dex_pc), + SideEffectsForArchRuntimeCalls(value->GetType())), dex_pc), expected_component_type_(expected_component_type), needs_type_check_(value->GetType() == Primitive::kPrimNot), value_can_be_null_(true) { @@ -4194,8 +4261,6 @@ class HArraySet : public HTemplateInstruction<3> { bool GetValueCanBeNull() const { return value_can_be_null_; } bool NeedsTypeCheck() const { return needs_type_check_; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } - HInstruction* GetArray() const { return InputAt(0); } HInstruction* GetIndex() const { return InputAt(1); } HInstruction* GetValue() const { return InputAt(2); } @@ -4218,7 +4283,6 @@ class HArraySet : public HTemplateInstruction<3> { DECLARE_INSTRUCTION(ArraySet); private: - const uint32_t dex_pc_; const Primitive::Type expected_component_type_; bool needs_type_check_; bool value_can_be_null_; @@ -4228,8 +4292,8 @@ class HArraySet : public HTemplateInstruction<3> { class HArrayLength : public HExpression<1> { public: - explicit HArrayLength(HInstruction* array) - : HExpression(Primitive::kPrimInt, SideEffects::None()) { + explicit HArrayLength(HInstruction* array, uint32_t dex_pc = kNoDexPc) + : HExpression(Primitive::kPrimInt, SideEffects::None(), dex_pc) { // Note that arrays do not change length, so the instruction does not // depend on any write. SetRawInputAt(0, array); @@ -4253,7 +4317,7 @@ class HArrayLength : public HExpression<1> { class HBoundsCheck : public HExpression<2> { public: HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc) - : HExpression(index->GetType(), SideEffects::None()), dex_pc_(dex_pc) { + : HExpression(index->GetType(), SideEffects::None(), dex_pc) { DCHECK(index->GetType() == Primitive::kPrimInt); SetRawInputAt(0, index); SetRawInputAt(1, length); @@ -4269,13 +4333,10 @@ class HBoundsCheck : public HExpression<2> { bool CanThrow() const OVERRIDE { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } DECLARE_INSTRUCTION(BoundsCheck); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HBoundsCheck); }; @@ -4288,7 +4349,8 @@ class HBoundsCheck : public HExpression<2> { */ class HTemporary : public HTemplateInstruction<0> { public: - explicit HTemporary(size_t index) : HTemplateInstruction(SideEffects::None()), index_(index) {} + explicit HTemporary(size_t index, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc), index_(index) {} size_t GetIndex() const { return index_; } @@ -4302,28 +4364,24 @@ class HTemporary : public HTemplateInstruction<0> { private: const size_t index_; - DISALLOW_COPY_AND_ASSIGN(HTemporary); }; class HSuspendCheck : public HTemplateInstruction<0> { public: explicit HSuspendCheck(uint32_t dex_pc) - : HTemplateInstruction(SideEffects::CanTriggerGC()), dex_pc_(dex_pc), slow_path_(nullptr) {} + : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc), slow_path_(nullptr) {} bool NeedsEnvironment() const OVERRIDE { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; } SlowPathCode* GetSlowPath() const { return slow_path_; } DECLARE_INSTRUCTION(SuspendCheck); private: - const uint32_t dex_pc_; - // Only used for code generation, in order to share the same slow path between back edges // of a same loop. SlowPathCode* slow_path_; @@ -4341,11 +4399,10 @@ class HLoadClass : public HExpression<1> { const DexFile& dex_file, bool is_referrers_class, uint32_t dex_pc) - : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls()), + : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc), type_index_(type_index), dex_file_(dex_file), is_referrers_class_(is_referrers_class), - dex_pc_(dex_pc), generate_clinit_check_(false), loaded_class_rti_(ReferenceTypeInfo::CreateInvalid()) { SetRawInputAt(0, current_method); @@ -4359,7 +4416,6 @@ class HLoadClass : public HExpression<1> { size_t ComputeHashCode() const OVERRIDE { return type_index_; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint16_t GetTypeIndex() const { return type_index_; } bool IsReferrersClass() const { return is_referrers_class_; } bool CanBeNull() const OVERRIDE { return false; } @@ -4412,7 +4468,6 @@ class HLoadClass : public HExpression<1> { const uint16_t type_index_; const DexFile& dex_file_; const bool is_referrers_class_; - const uint32_t dex_pc_; // Whether this instruction must generate the initialization check. // Used for code generation. bool generate_clinit_check_; @@ -4425,9 +4480,8 @@ class HLoadClass : public HExpression<1> { class HLoadString : public HExpression<1> { public: HLoadString(HCurrentMethod* current_method, uint32_t string_index, uint32_t dex_pc) - : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls()), - string_index_(string_index), - dex_pc_(dex_pc) { + : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc), + string_index_(string_index) { SetRawInputAt(0, current_method); } @@ -4439,7 +4493,6 @@ class HLoadString : public HExpression<1> { size_t ComputeHashCode() const OVERRIDE { return string_index_; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint32_t GetStringIndex() const { return string_index_; } // TODO: Can we deopt or debug when we resolve a string? @@ -4455,7 +4508,6 @@ class HLoadString : public HExpression<1> { private: const uint32_t string_index_; - const uint32_t dex_pc_; DISALLOW_COPY_AND_ASSIGN(HLoadString); }; @@ -4468,8 +4520,8 @@ class HClinitCheck : public HExpression<1> { HClinitCheck(HLoadClass* constant, uint32_t dex_pc) : HExpression( Primitive::kPrimNot, - SideEffects::AllChanges()), // Assume write/read on all fields/arrays. - dex_pc_(dex_pc) { + SideEffects::AllChanges(), // Assume write/read on all fields/arrays. + dex_pc) { SetRawInputAt(0, constant); } @@ -4484,15 +4536,12 @@ class HClinitCheck : public HExpression<1> { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); } DECLARE_INSTRUCTION(ClinitCheck); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HClinitCheck); }; @@ -4504,10 +4553,11 @@ class HStaticFieldGet : public HExpression<1> { bool is_volatile, uint32_t field_idx, const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) + Handle<mirror::DexCache> dex_cache, + uint32_t dex_pc = kNoDexPc) : HExpression( field_type, - SideEffects::FieldReadOfType(field_type, is_volatile)), + SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) { SetRawInputAt(0, cls); } @@ -4546,9 +4596,10 @@ class HStaticFieldSet : public HTemplateInstruction<2> { bool is_volatile, uint32_t field_idx, const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) + Handle<mirror::DexCache> dex_cache, + uint32_t dex_pc = kNoDexPc) : HTemplateInstruction( - SideEffects::FieldWriteOfType(field_type, is_volatile)), + SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache), value_can_be_null_(true) { SetRawInputAt(0, cls); @@ -4576,7 +4627,8 @@ class HStaticFieldSet : public HTemplateInstruction<2> { // Implement the move-exception DEX instruction. class HLoadException : public HExpression<0> { public: - HLoadException() : HExpression(Primitive::kPrimNot, SideEffects::None()) {} + explicit HLoadException(uint32_t dex_pc = kNoDexPc) + : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc) {} bool CanBeNull() const OVERRIDE { return false; } @@ -4590,7 +4642,8 @@ class HLoadException : public HExpression<0> { // Must not be removed because the runtime expects the TLS to get cleared. class HClearException : public HTemplateInstruction<0> { public: - HClearException() : HTemplateInstruction(SideEffects::AllWrites()) {} + explicit HClearException(uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::AllWrites(), dex_pc) {} DECLARE_INSTRUCTION(ClearException); @@ -4601,7 +4654,7 @@ class HClearException : public HTemplateInstruction<0> { class HThrow : public HTemplateInstruction<1> { public: HThrow(HInstruction* exception, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::CanTriggerGC()), dex_pc_(dex_pc) { + : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) { SetRawInputAt(0, exception); } @@ -4611,13 +4664,10 @@ class HThrow : public HTemplateInstruction<1> { bool CanThrow() const OVERRIDE { return true; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } DECLARE_INSTRUCTION(Throw); private: - const uint32_t dex_pc_; - DISALLOW_COPY_AND_ASSIGN(HThrow); }; @@ -4627,10 +4677,11 @@ class HInstanceOf : public HExpression<2> { HLoadClass* constant, bool class_is_final, uint32_t dex_pc) - : HExpression(Primitive::kPrimBoolean, SideEffectsForArchRuntimeCalls(class_is_final)), + : HExpression(Primitive::kPrimBoolean, + SideEffectsForArchRuntimeCalls(class_is_final), + dex_pc), class_is_final_(class_is_final), - must_do_null_check_(true), - dex_pc_(dex_pc) { + must_do_null_check_(true) { SetRawInputAt(0, object); SetRawInputAt(1, constant); } @@ -4645,8 +4696,6 @@ class HInstanceOf : public HExpression<2> { return false; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } - bool IsClassFinal() const { return class_is_final_; } // Used only in code generation. @@ -4662,7 +4711,6 @@ class HInstanceOf : public HExpression<2> { private: const bool class_is_final_; bool must_do_null_check_; - const uint32_t dex_pc_; DISALLOW_COPY_AND_ASSIGN(HInstanceOf); }; @@ -4671,8 +4719,11 @@ class HBoundType : public HExpression<1> { public: // Constructs an HBoundType with the given upper_bound. // Ensures that the upper_bound is valid. - HBoundType(HInstruction* input, ReferenceTypeInfo upper_bound, bool upper_can_be_null) - : HExpression(Primitive::kPrimNot, SideEffects::None()), + HBoundType(HInstruction* input, + ReferenceTypeInfo upper_bound, + bool upper_can_be_null, + uint32_t dex_pc = kNoDexPc) + : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc), upper_bound_(upper_bound), upper_can_be_null_(upper_can_be_null), can_be_null_(upper_can_be_null) { @@ -4716,10 +4767,9 @@ class HCheckCast : public HTemplateInstruction<2> { HLoadClass* constant, bool class_is_final, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::CanTriggerGC()), + : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc), class_is_final_(class_is_final), - must_do_null_check_(true), - dex_pc_(dex_pc) { + must_do_null_check_(true) { SetRawInputAt(0, object); SetRawInputAt(1, constant); } @@ -4740,7 +4790,6 @@ class HCheckCast : public HTemplateInstruction<2> { bool MustDoNullCheck() const { return must_do_null_check_; } void ClearMustDoNullCheck() { must_do_null_check_ = false; } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } bool IsClassFinal() const { return class_is_final_; } @@ -4749,16 +4798,15 @@ class HCheckCast : public HTemplateInstruction<2> { private: const bool class_is_final_; bool must_do_null_check_; - const uint32_t dex_pc_; DISALLOW_COPY_AND_ASSIGN(HCheckCast); }; class HMemoryBarrier : public HTemplateInstruction<0> { public: - explicit HMemoryBarrier(MemBarrierKind barrier_kind) + explicit HMemoryBarrier(MemBarrierKind barrier_kind, uint32_t dex_pc = kNoDexPc) : HTemplateInstruction( - SideEffects::AllWritesAndReads()), // Assume write/read on all fields/arrays. + SideEffects::AllWritesAndReads(), dex_pc), // Assume write/read on all fields/arrays. barrier_kind_(barrier_kind) {} MemBarrierKind GetBarrierKind() { return barrier_kind_; } @@ -4780,8 +4828,8 @@ class HMonitorOperation : public HTemplateInstruction<1> { HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc) : HTemplateInstruction( - SideEffects::AllExceptGCDependency()), // Assume write/read on all fields/arrays. - kind_(kind), dex_pc_(dex_pc) { + SideEffects::AllExceptGCDependency(), dex_pc), // Assume write/read on all fields/arrays. + kind_(kind) { SetRawInputAt(0, object); } @@ -4795,7 +4843,6 @@ class HMonitorOperation : public HTemplateInstruction<1> { return IsEnter(); } - uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } bool IsEnter() const { return kind_ == kEnter; } @@ -4803,7 +4850,6 @@ class HMonitorOperation : public HTemplateInstruction<1> { private: const OperationKind kind_; - const uint32_t dex_pc_; private: DISALLOW_COPY_AND_ASSIGN(HMonitorOperation); @@ -4818,7 +4864,8 @@ class HMonitorOperation : public HTemplateInstruction<1> { */ class HFakeString : public HTemplateInstruction<0> { public: - HFakeString() : HTemplateInstruction(SideEffects::None()) {} + explicit HFakeString(uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc) {} Primitive::Type GetType() const OVERRIDE { return Primitive::kPrimNot; } @@ -4906,8 +4953,8 @@ static constexpr size_t kDefaultNumberOfMoves = 4; class HParallelMove : public HTemplateInstruction<0> { public: - explicit HParallelMove(ArenaAllocator* arena) - : HTemplateInstruction(SideEffects::None()), moves_(arena, kDefaultNumberOfMoves) {} + explicit HParallelMove(ArenaAllocator* arena, uint32_t dex_pc = kNoDexPc) + : HTemplateInstruction(SideEffects::None(), dex_pc), moves_(arena, kDefaultNumberOfMoves) {} void AddMove(Location source, Location destination, |