diff options
author | 2022-06-24 11:16:35 +0100 | |
---|---|---|
committer | 2022-10-07 14:48:14 +0000 | |
commit | ab1d559aee05873f70494514922ad4b767c6a709 (patch) | |
tree | 0a0831e8b9fe543b050a56fc03b2e395721cca46 /compiler/optimizing | |
parent | 8c5e881904c30de5dbc03536ea67bbe2d48088fd (diff) |
Runtime implementation of try catch inlining
The main differences in the runtime are:
1) We now use a list of dex_pcs to find the correct catch handler
instead of a single dex pc
2) We now need to restore vregs of the whole frame, which may be
an inline frame.
Bug: 227283224
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I95d2f32088e1d420c83962a1693be18f3b63f8b4
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 25 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_stream.cc | 21 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_stream.h | 15 |
3 files changed, 43 insertions, 18 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index bd8db30d44..1c5912d87e 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -15,6 +15,7 @@ */ #include "code_generator.h" +#include "base/globals.h" #ifdef ART_ENABLE_CODEGEN_arm #include "code_generator_arm_vixl.h" @@ -1339,8 +1340,11 @@ void CodeGenerator::RecordCatchBlockInfo() { continue; } - // Get the outer dex_pc - uint32_t outer_dex_pc = block->GetDexPc(); + // Get the outer dex_pc. We save the full environment list for DCHECK purposes in kIsDebugBuild. + std::vector<uint32_t> dex_pc_list_for_verification; + if (kIsDebugBuild) { + dex_pc_list_for_verification.push_back(block->GetDexPc()); + } DCHECK(block->GetFirstInstruction()->IsNop()); DCHECK(block->GetFirstInstruction()->AsNop()->NeedsEnvironment()); HEnvironment* const environment = block->GetFirstInstruction()->GetEnvironment(); @@ -1348,15 +1352,26 @@ void CodeGenerator::RecordCatchBlockInfo() { HEnvironment* outer_environment = environment; while (outer_environment->GetParent() != nullptr) { outer_environment = outer_environment->GetParent(); + if (kIsDebugBuild) { + dex_pc_list_for_verification.push_back(outer_environment->GetDexPc()); + } + } + + if (kIsDebugBuild) { + // dex_pc_list_for_verification is set from innnermost to outermost. Let's reverse it + // since we are expected to pass from outermost to innermost. + std::reverse(dex_pc_list_for_verification.begin(), dex_pc_list_for_verification.end()); + DCHECK_EQ(dex_pc_list_for_verification.front(), outer_environment->GetDexPc()); } - outer_dex_pc = outer_environment->GetDexPc(); uint32_t native_pc = GetAddressOf(block); - stack_map_stream->BeginStackMapEntry(outer_dex_pc, + stack_map_stream->BeginStackMapEntry(outer_environment->GetDexPc(), native_pc, /* register_mask= */ 0, /* sp_mask= */ nullptr, - StackMap::Kind::Catch); + StackMap::Kind::Catch, + /* needs_vreg_info= */ true, + dex_pc_list_for_verification); EmitEnvironment(environment, /* slow_path= */ nullptr, diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index c13a35567b..31428d5c2a 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -20,6 +20,7 @@ #include <vector> #include "art_method-inl.h" +#include "base/globals.h" #include "base/stl_util.h" #include "class_linker.h" #include "dex/dex_file.h" @@ -101,16 +102,21 @@ void StackMapStream::EndMethod(size_t code_size) { } } -void StackMapStream::BeginStackMapEntry(uint32_t dex_pc, - uint32_t native_pc_offset, - uint32_t register_mask, - BitVector* stack_mask, - StackMap::Kind kind, - bool needs_vreg_info) { +void StackMapStream::BeginStackMapEntry( + uint32_t dex_pc, + uint32_t native_pc_offset, + uint32_t register_mask, + BitVector* stack_mask, + StackMap::Kind kind, + bool needs_vreg_info, + const std::vector<uint32_t>& dex_pc_list_for_catch_verification) { DCHECK(in_method_) << "Call BeginMethod first"; DCHECK(!in_stack_map_) << "Mismatched Begin/End calls"; in_stack_map_ = true; + DCHECK_IMPLIES(!dex_pc_list_for_catch_verification.empty(), kind == StackMap::Kind::Catch); + DCHECK_IMPLIES(!dex_pc_list_for_catch_verification.empty(), kIsDebugBuild); + current_stack_map_ = BitTableBuilder<StackMap>::Entry(); current_stack_map_[StackMap::kKind] = static_cast<uint32_t>(kind); current_stack_map_[StackMap::kPackedNativePc] = @@ -151,7 +157,8 @@ void StackMapStream::BeginStackMapEntry(uint32_t dex_pc, instruction_set_); CHECK_EQ(stack_map.Row(), stack_map_index); } else if (kind == StackMap::Kind::Catch) { - StackMap stack_map = code_info.GetCatchStackMapForDexPc(dex_pc); + StackMap stack_map = code_info.GetCatchStackMapForDexPc( + ArrayRef<const uint32_t>(dex_pc_list_for_catch_verification)); CHECK_EQ(stack_map.Row(), stack_map_index); } StackMap stack_map = code_info.GetStackMapAt(stack_map_index); diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h index 1aaa6aee9e..2ba60279ff 100644 --- a/compiler/optimizing/stack_map_stream.h +++ b/compiler/optimizing/stack_map_stream.h @@ -68,12 +68,15 @@ class StackMapStream : public DeletableArenaObject<kArenaAllocStackMapStream> { bool debuggable); void EndMethod(size_t code_size); - void BeginStackMapEntry(uint32_t dex_pc, - uint32_t native_pc_offset, - uint32_t register_mask = 0, - BitVector* sp_mask = nullptr, - StackMap::Kind kind = StackMap::Kind::Default, - bool needs_vreg_info = true); + void BeginStackMapEntry( + uint32_t dex_pc, + uint32_t native_pc_offset, + uint32_t register_mask = 0, + BitVector* sp_mask = nullptr, + StackMap::Kind kind = StackMap::Kind::Default, + bool needs_vreg_info = true, + const std::vector<uint32_t>& dex_pc_list_for_catch_verification = std::vector<uint32_t>()); + void EndStackMapEntry(); void AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t value) { |