summaryrefslogtreecommitdiff
path: root/compiler/optimizing/stack_map_stream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/stack_map_stream.cc')
-rw-r--r--compiler/optimizing/stack_map_stream.cc94
1 files changed, 55 insertions, 39 deletions
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index 3f41e3594e..c571312faa 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -137,34 +137,41 @@ uint32_t StackMapStream::ComputeMaxNativePcOffset() const {
size_t StackMapStream::PrepareForFillIn() {
int stack_mask_number_of_bits = stack_mask_max_ + 1; // Need room for max element too.
- stack_mask_size_ = RoundUp(stack_mask_number_of_bits, kBitsPerByte) / kBitsPerByte;
inline_info_size_ = ComputeInlineInfoSize();
dex_register_maps_size_ = ComputeDexRegisterMapsSize();
uint32_t max_native_pc_offset = ComputeMaxNativePcOffset();
- stack_map_encoding_ = StackMapEncoding::CreateFromSizes(stack_mask_size_,
- inline_info_size_,
- dex_register_maps_size_,
- dex_pc_max_,
- max_native_pc_offset,
- register_mask_max_);
- stack_maps_size_ = stack_maps_.size() * stack_map_encoding_.ComputeStackMapSize();
+ size_t stack_map_size = stack_map_encoding_.SetFromSizes(max_native_pc_offset,
+ dex_pc_max_,
+ dex_register_maps_size_,
+ inline_info_size_,
+ register_mask_max_,
+ stack_mask_number_of_bits);
+ stack_maps_size_ = stack_maps_.size() * stack_map_size;
dex_register_location_catalog_size_ = ComputeDexRegisterLocationCatalogSize();
- // Note: use RoundUp to word-size here if you want CodeInfo objects to be word aligned.
- needed_size_ = CodeInfo::kFixedSize
- + stack_maps_size_
- + dex_register_location_catalog_size_
- + dex_register_maps_size_
- + inline_info_size_;
+ size_t non_header_size =
+ stack_maps_size_ +
+ dex_register_location_catalog_size_ +
+ dex_register_maps_size_ +
+ inline_info_size_;
+
+ // Prepare the CodeInfo variable-sized encoding.
+ CodeInfoEncoding code_info_encoding;
+ code_info_encoding.non_header_size = non_header_size;
+ code_info_encoding.stack_map_encoding = stack_map_encoding_;
+ code_info_encoding.number_of_stack_maps = stack_maps_.size();
+ code_info_encoding.stack_map_size_in_bytes = stack_map_size;
+ code_info_encoding.number_of_location_catalog_entries = location_catalog_entries_.size();
+ code_info_encoding.Compress(&code_info_encoding_);
- stack_maps_start_ = CodeInfo::kFixedSize;
// TODO: Move the catalog at the end. It is currently too expensive at runtime
// to compute its size (note that we do not encode that size in the CodeInfo).
- dex_register_location_catalog_start_ = stack_maps_start_ + stack_maps_size_;
+ dex_register_location_catalog_start_ = code_info_encoding_.size() + stack_maps_size_;
dex_register_maps_start_ =
dex_register_location_catalog_start_ + dex_register_location_catalog_size_;
inline_infos_start_ = dex_register_maps_start_ + dex_register_maps_size_;
+ needed_size_ = code_info_encoding_.size() + non_header_size;
return needed_size_;
}
@@ -227,9 +234,13 @@ void StackMapStream::FillIn(MemoryRegion region) {
DCHECK_EQ(0u, current_entry_.dex_pc) << "EndStackMapEntry not called after BeginStackMapEntry";
DCHECK_NE(0u, needed_size_) << "PrepareForFillIn not called before FillIn";
- CodeInfo code_info(region);
DCHECK_EQ(region.size(), needed_size_);
- code_info.SetOverallSize(region.size());
+
+ // Note that the memory region does not have to be zeroed when we JIT code
+ // because we do not use the arena allocator there.
+
+ // Write the CodeInfo header.
+ region.CopyFrom(0, MemoryRegion(code_info_encoding_.data(), code_info_encoding_.size()));
MemoryRegion dex_register_locations_region = region.Subregion(
dex_register_maps_start_, dex_register_maps_size_);
@@ -237,12 +248,11 @@ void StackMapStream::FillIn(MemoryRegion region) {
MemoryRegion inline_infos_region = region.Subregion(
inline_infos_start_, inline_info_size_);
- code_info.SetEncoding(stack_map_encoding_);
- code_info.SetNumberOfStackMaps(stack_maps_.size());
- DCHECK_EQ(code_info.GetStackMapsSize(code_info.ExtractEncoding()), stack_maps_size_);
+ CodeInfo code_info(region);
+ CodeInfoEncoding encoding = code_info.ExtractEncoding();
+ DCHECK_EQ(code_info.GetStackMapsSize(encoding), stack_maps_size_);
// Set the Dex register location catalog.
- code_info.SetNumberOfLocationCatalogEntries(location_catalog_entries_.size());
MemoryRegion dex_register_location_catalog_region = region.Subregion(
dex_register_location_catalog_start_, dex_register_location_catalog_size_);
DexRegisterLocationCatalog dex_register_location_catalog(dex_register_location_catalog_region);
@@ -260,17 +270,22 @@ void StackMapStream::FillIn(MemoryRegion region) {
uintptr_t next_dex_register_map_offset = 0;
uintptr_t next_inline_info_offset = 0;
for (size_t i = 0, e = stack_maps_.size(); i < e; ++i) {
- StackMap stack_map = code_info.GetStackMapAt(i, stack_map_encoding_);
+ StackMap stack_map = code_info.GetStackMapAt(i, encoding);
StackMapEntry entry = stack_maps_[i];
stack_map.SetDexPc(stack_map_encoding_, entry.dex_pc);
stack_map.SetNativePcOffset(stack_map_encoding_, entry.native_pc_offset);
stack_map.SetRegisterMask(stack_map_encoding_, entry.register_mask);
+ size_t number_of_stack_mask_bits = stack_map.GetNumberOfStackMaskBits(stack_map_encoding_);
if (entry.sp_mask != nullptr) {
- stack_map.SetStackMask(stack_map_encoding_, *entry.sp_mask);
+ for (size_t bit = 0; bit < number_of_stack_mask_bits; bit++) {
+ stack_map.SetStackMaskBit(stack_map_encoding_, bit, entry.sp_mask->IsBitSet(bit));
+ }
} else {
// The MemoryRegion does not have to be zeroed, so make sure we clear the bits.
- stack_map.SetStackMask(stack_map_encoding_, empty_bitmask);
+ for (size_t bit = 0; bit < number_of_stack_mask_bits; bit++) {
+ stack_map.SetStackMaskBit(stack_map_encoding_, bit, false);
+ }
}
if (entry.num_dex_registers == 0 || (entry.live_dex_registers_mask->NumSetBits() == 0)) {
@@ -282,7 +297,7 @@ void StackMapStream::FillIn(MemoryRegion region) {
// If we have a hit reuse the offset.
stack_map.SetDexRegisterMapOffset(
stack_map_encoding_,
- code_info.GetStackMapAt(entry.same_dex_register_map_as_, stack_map_encoding_)
+ code_info.GetStackMapAt(entry.same_dex_register_map_as_, encoding)
.GetDexRegisterMapOffset(stack_map_encoding_));
} else {
// New dex registers maps should be added to the stack map.
@@ -437,7 +452,7 @@ void StackMapStream::CheckDexRegisterMap(const CodeInfo& code_info,
size_t num_dex_registers,
BitVector* live_dex_registers_mask,
size_t dex_register_locations_index) const {
- StackMapEncoding encoding = code_info.ExtractEncoding();
+ CodeInfoEncoding encoding = code_info.ExtractEncoding();
for (size_t reg = 0; reg < num_dex_registers; reg++) {
// Find the location we tried to encode.
DexRegisterLocation expected = DexRegisterLocation::None();
@@ -464,25 +479,26 @@ void StackMapStream::CheckDexRegisterMap(const CodeInfo& code_info,
// Check that all StackMapStream inputs are correctly encoded by trying to read them back.
void StackMapStream::CheckCodeInfo(MemoryRegion region) const {
CodeInfo code_info(region);
- StackMapEncoding encoding = code_info.ExtractEncoding();
- DCHECK_EQ(code_info.GetNumberOfStackMaps(), stack_maps_.size());
+ CodeInfoEncoding encoding = code_info.ExtractEncoding();
+ DCHECK_EQ(code_info.GetNumberOfStackMaps(encoding), stack_maps_.size());
for (size_t s = 0; s < stack_maps_.size(); ++s) {
const StackMap stack_map = code_info.GetStackMapAt(s, encoding);
+ const StackMapEncoding& stack_map_encoding = encoding.stack_map_encoding;
StackMapEntry entry = stack_maps_[s];
// Check main stack map fields.
- DCHECK_EQ(stack_map.GetNativePcOffset(encoding), entry.native_pc_offset);
- DCHECK_EQ(stack_map.GetDexPc(encoding), entry.dex_pc);
- DCHECK_EQ(stack_map.GetRegisterMask(encoding), entry.register_mask);
- MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
+ DCHECK_EQ(stack_map.GetNativePcOffset(stack_map_encoding), entry.native_pc_offset);
+ DCHECK_EQ(stack_map.GetDexPc(stack_map_encoding), entry.dex_pc);
+ DCHECK_EQ(stack_map.GetRegisterMask(stack_map_encoding), entry.register_mask);
+ size_t num_stack_mask_bits = stack_map.GetNumberOfStackMaskBits(stack_map_encoding);
if (entry.sp_mask != nullptr) {
- DCHECK_GE(stack_mask.size_in_bits(), entry.sp_mask->GetNumberOfBits());
- for (size_t b = 0; b < stack_mask.size_in_bits(); b++) {
- DCHECK_EQ(stack_mask.LoadBit(b), entry.sp_mask->IsBitSet(b));
+ DCHECK_GE(num_stack_mask_bits, entry.sp_mask->GetNumberOfBits());
+ for (size_t b = 0; b < num_stack_mask_bits; b++) {
+ DCHECK_EQ(stack_map.GetStackMaskBit(stack_map_encoding, b), entry.sp_mask->IsBitSet(b));
}
} else {
- for (size_t b = 0; b < stack_mask.size_in_bits(); b++) {
- DCHECK_EQ(stack_mask.LoadBit(b), 0u);
+ for (size_t b = 0; b < num_stack_mask_bits; b++) {
+ DCHECK_EQ(stack_map.GetStackMaskBit(stack_map_encoding, b), 0u);
}
}
@@ -494,7 +510,7 @@ void StackMapStream::CheckCodeInfo(MemoryRegion region) const {
entry.dex_register_locations_start_index);
// Check inline info.
- DCHECK_EQ(stack_map.HasInlineInfo(encoding), (entry.inlining_depth != 0));
+ DCHECK_EQ(stack_map.HasInlineInfo(stack_map_encoding), (entry.inlining_depth != 0));
if (entry.inlining_depth != 0) {
InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
DCHECK_EQ(inline_info.GetDepth(), entry.inlining_depth);