summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator.cc25
-rw-r--r--compiler/optimizing/stack_map_stream.cc21
-rw-r--r--compiler/optimizing/stack_map_stream.h15
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) {