summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator.cc
diff options
context:
space:
mode:
authorArtem Serov <artem.serov@linaro.org>2018-12-20 19:15:11 +0000
committerVladimir Marko <vmarko@google.com>2019-07-15 09:30:36 +0000
commit2808be84a8f86542450670acdb5e6b55498ff5f0 (patch)
treef41b63e3109a6a6a9bd534f32b8d92f20eb9ef35 /compiler/optimizing/code_generator.cc
parent460f05480379d5c75555d06c4938bc990ce6ff83 (diff)
ART: Introduce stackmap with no DexRegInfo.
Some of safepoints don't need to have DexRegisterMap info; this will decrease the stackmap size. .oat file size reduction: - boot.oat: -233 kb (-5.4%) - boot-framework.oat: -704 kb (-4.9%) Test: 461-get-reference-vreg, 466-get-live-vreg. Test: 543-env-long-ref, 616-cha*. Test: test-art-target, +gc-stress. Change-Id: Idbad355770e30a30dcf14127642e03ee666878b8
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r--compiler/optimizing/code_generator.cc69
1 files changed, 54 insertions, 15 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 3b5699bccd..6d3a5c6a73 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -1088,6 +1088,30 @@ ScopedArenaVector<uint8_t> CodeGenerator::BuildStackMaps(const dex::CodeItem* co
return stack_map;
}
+// Returns whether stackmap dex register info is needed for the instruction.
+//
+// The following cases mandate having a dex register map:
+// * Deoptimization
+// when we need to obtain the values to restore actual vregisters for interpreter.
+// * Debuggability
+// when we want to observe the values / asynchronously deoptimize.
+// * Monitor operations
+// to allow dumping in a stack trace locked dex registers for non-debuggable code.
+// * On-stack-replacement (OSR)
+// when entering compiled for OSR code from the interpreter we need to initialize the compiled
+// code values with the values from the vregisters.
+// * Method local catch blocks
+// a catch block must see the environment of the instruction from the same method that can
+// throw to this block.
+static bool NeedsVregInfo(HInstruction* instruction, bool osr) {
+ HGraph* graph = instruction->GetBlock()->GetGraph();
+ return instruction->IsDeoptimize() ||
+ graph->IsDebuggable() ||
+ graph->HasMonitorOperations() ||
+ osr ||
+ instruction->CanThrowIntoCatchBlock();
+}
+
void CodeGenerator::RecordPcInfo(HInstruction* instruction,
uint32_t dex_pc,
SlowPathCode* slow_path,
@@ -1166,12 +1190,15 @@ void CodeGenerator::RecordPcInfo(HInstruction* instruction,
StackMap::Kind kind = native_debug_info
? StackMap::Kind::Debug
: (osr ? StackMap::Kind::OSR : StackMap::Kind::Default);
+ bool needs_vreg_info = NeedsVregInfo(instruction, osr);
stack_map_stream->BeginStackMapEntry(outer_dex_pc,
native_pc,
register_mask,
locations->GetStackMask(),
- kind);
- EmitEnvironment(environment, slow_path);
+ kind,
+ needs_vreg_info);
+
+ EmitEnvironment(environment, slow_path, needs_vreg_info);
stack_map_stream->EndStackMapEntry();
if (osr) {
@@ -1284,19 +1311,8 @@ void CodeGenerator::AddSlowPath(SlowPathCode* slow_path) {
code_generation_data_->AddSlowPath(slow_path);
}
-void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slow_path) {
- if (environment == nullptr) return;
-
+void CodeGenerator::EmitVRegInfo(HEnvironment* environment, SlowPathCode* slow_path) {
StackMapStream* stack_map_stream = GetStackMapStream();
- if (environment->GetParent() != nullptr) {
- // We emit the parent environment first.
- EmitEnvironment(environment->GetParent(), slow_path);
- stack_map_stream->BeginInlineInfoEntry(environment->GetMethod(),
- environment->GetDexPc(),
- environment->Size(),
- &graph_->GetDexFile());
- }
-
// Walk over the environment, and record the location of dex registers.
for (size_t i = 0, environment_size = environment->Size(); i < environment_size; ++i) {
HInstruction* current = environment->GetInstructionAt(i);
@@ -1441,8 +1457,31 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo
LOG(FATAL) << "Unexpected kind " << location.GetKind();
}
}
+}
+
+void CodeGenerator::EmitEnvironment(HEnvironment* environment,
+ SlowPathCode* slow_path,
+ bool needs_vreg_info) {
+ if (environment == nullptr) return;
+
+ StackMapStream* stack_map_stream = GetStackMapStream();
+ bool emit_inline_info = environment->GetParent() != nullptr;
+
+ if (emit_inline_info) {
+ // We emit the parent environment first.
+ EmitEnvironment(environment->GetParent(), slow_path, needs_vreg_info);
+ stack_map_stream->BeginInlineInfoEntry(environment->GetMethod(),
+ environment->GetDexPc(),
+ needs_vreg_info ? environment->Size() : 0,
+ &graph_->GetDexFile());
+ }
+
+ if (needs_vreg_info) {
+ // If a dex register map is not required we just won't emit it.
+ EmitVRegInfo(environment, slow_path);
+ }
- if (environment->GetParent() != nullptr) {
+ if (emit_inline_info) {
stack_map_stream->EndInlineInfoEntry();
}
}