[optimizing] Don't record None locations in the stack maps.
- moved environment recording from code generator to stack map stream
- added creation/loading factory methods for the DexRegisterMap (hides
internal details)
- added new tests
Change-Id: Ic8b6d044f0d8255c6759c19a41df332ef37876fe
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index a6ab208..9ebf887 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -577,142 +577,42 @@
pc_info.native_pc = GetAssembler()->CodeSize();
pc_infos_.Add(pc_info);
- // Populate stack map information.
-
+ uint32_t inlining_depth = 0;
if (instruction == nullptr) {
// For stack overflow checks.
- stack_map_stream_.AddStackMapEntry(dex_pc, pc_info.native_pc, 0, 0, 0, 0);
- return;
- }
+ stack_map_stream_.RecordEnvironment(
+ /* environment */ nullptr,
+ /* environment_size */ 0,
+ /* locations */ nullptr,
+ dex_pc,
+ pc_info.native_pc,
+ /* register_mask */ 0,
+ inlining_depth);
+ } else {
+ LocationSummary* locations = instruction->GetLocations();
+ HEnvironment* environment = instruction->GetEnvironment();
+ size_t environment_size = instruction->EnvironmentSize();
- LocationSummary* locations = instruction->GetLocations();
- HEnvironment* environment = instruction->GetEnvironment();
-
- size_t environment_size = instruction->EnvironmentSize();
-
- size_t inlining_depth = 0;
- uint32_t register_mask = locations->GetRegisterMask();
- if (locations->OnlyCallsOnSlowPath()) {
- // In case of slow path, we currently set the location of caller-save registers
- // to register (instead of their stack location when pushed before the slow-path
- // call). Therefore register_mask contains both callee-save and caller-save
- // registers that hold objects. We must remove the caller-save from the mask, since
- // they will be overwritten by the callee.
- register_mask &= core_callee_save_mask_;
- }
- // The register mask must be a subset of callee-save registers.
- DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask);
- stack_map_stream_.AddStackMapEntry(
- dex_pc, pc_info.native_pc, register_mask,
- locations->GetStackMask(), environment_size, inlining_depth);
-
- // Walk over the environment, and record the location of dex registers.
- for (size_t i = 0; i < environment_size; ++i) {
- HInstruction* current = environment->GetInstructionAt(i);
- if (current == nullptr) {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0);
- continue;
+ uint32_t register_mask = locations->GetRegisterMask();
+ if (locations->OnlyCallsOnSlowPath()) {
+ // In case of slow path, we currently set the location of caller-save registers
+ // to register (instead of their stack location when pushed before the slow-path
+ // call). Therefore register_mask contains both callee-save and caller-save
+ // registers that hold objects. We must remove the caller-save from the mask, since
+ // they will be overwritten by the callee.
+ register_mask &= core_callee_save_mask_;
}
+ // The register mask must be a subset of callee-save registers.
+ DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask);
- Location location = locations->GetEnvironmentAt(i);
- switch (location.GetKind()) {
- case Location::kConstant: {
- DCHECK_EQ(current, location.GetConstant());
- if (current->IsLongConstant()) {
- int64_t value = current->AsLongConstant()->GetValue();
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant,
- Low32Bits(value));
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant,
- High32Bits(value));
- ++i;
- DCHECK_LT(i, environment_size);
- } else if (current->IsDoubleConstant()) {
- int64_t value = bit_cast<double, int64_t>(current->AsDoubleConstant()->GetValue());
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant,
- Low32Bits(value));
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant,
- High32Bits(value));
- ++i;
- DCHECK_LT(i, environment_size);
- } else if (current->IsIntConstant()) {
- int32_t value = current->AsIntConstant()->GetValue();
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value);
- } else if (current->IsNullConstant()) {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, 0);
- } else {
- DCHECK(current->IsFloatConstant());
- int32_t value = bit_cast<float, int32_t>(current->AsFloatConstant()->GetValue());
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value);
- }
- break;
- }
-
- case Location::kStackSlot: {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack,
- location.GetStackIndex());
- break;
- }
-
- case Location::kDoubleStackSlot: {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack,
- location.GetStackIndex());
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack,
- location.GetHighStackIndex(kVRegSize));
- ++i;
- DCHECK_LT(i, environment_size);
- break;
- }
-
- case Location::kRegister : {
- int id = location.reg();
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, id);
- if (current->GetType() == Primitive::kPrimLong) {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, id);
- ++i;
- DCHECK_LT(i, environment_size);
- }
- break;
- }
-
- case Location::kFpuRegister : {
- int id = location.reg();
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, id);
- if (current->GetType() == Primitive::kPrimDouble) {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, id);
- ++i;
- DCHECK_LT(i, environment_size);
- }
- break;
- }
-
- case Location::kFpuRegisterPair : {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister,
- location.low());
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister,
- location.high());
- ++i;
- DCHECK_LT(i, environment_size);
- break;
- }
-
- case Location::kRegisterPair : {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister,
- location.low());
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister,
- location.high());
- ++i;
- DCHECK_LT(i, environment_size);
- break;
- }
-
- case Location::kInvalid: {
- stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0);
- break;
- }
-
- default:
- LOG(FATAL) << "Unexpected kind " << location.GetKind();
- }
+ // Populate stack map information.
+ stack_map_stream_.RecordEnvironment(environment,
+ environment_size,
+ locations,
+ dex_pc,
+ pc_info.native_pc,
+ register_mask,
+ inlining_depth);
}
}