1
0
Fork 0
forked from suyu/suyu

Merge pull request #4658 from lioncash/copy3

nca_patch: Reduce stack usage size within SearchBucketEntry()
This commit is contained in:
Rodrigo Locatti 2020-09-16 00:25:11 +00:00 committed by GitHub
commit 004bfefeb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 44 deletions

View file

@ -12,6 +12,49 @@
#include "core/file_sys/nca_patch.h" #include "core/file_sys/nca_patch.h"
namespace FileSys { namespace FileSys {
namespace {
template <bool Subsection, typename BlockType, typename BucketType>
std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, const BlockType& block,
const BucketType& buckets) {
if constexpr (Subsection) {
const auto& last_bucket = buckets[block.number_buckets - 1];
if (offset >= last_bucket.entries[last_bucket.number_entries].address_patch) {
return {block.number_buckets - 1, last_bucket.number_entries};
}
} else {
ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block.");
}
std::size_t bucket_id = std::count_if(
block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets,
[&offset](u64 base_offset) { return base_offset <= offset; });
const auto& bucket = buckets[bucket_id];
if (bucket.number_entries == 1) {
return {bucket_id, 0};
}
std::size_t low = 0;
std::size_t mid = 0;
std::size_t high = bucket.number_entries - 1;
while (low <= high) {
mid = (low + high) / 2;
if (bucket.entries[mid].address_patch > offset) {
high = mid - 1;
} else {
if (mid == bucket.number_entries - 1 ||
bucket.entries[mid + 1].address_patch > offset) {
return {bucket_id, mid};
}
low = mid + 1;
}
}
UNREACHABLE_MSG("Offset could not be found in BKTR block.");
}
} // Anonymous namespace
BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock relocation_, BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock relocation_,
std::vector<RelocationBucket> relocation_buckets_, SubsectionBlock subsection_, std::vector<RelocationBucket> relocation_buckets_, SubsectionBlock subsection_,
@ -110,46 +153,6 @@ std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const {
return raw_read; return raw_read;
} }
template <bool Subsection, typename BlockType, typename BucketType>
std::pair<std::size_t, std::size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block,
BucketType buckets) const {
if constexpr (Subsection) {
const auto last_bucket = buckets[block.number_buckets - 1];
if (offset >= last_bucket.entries[last_bucket.number_entries].address_patch)
return {block.number_buckets - 1, last_bucket.number_entries};
} else {
ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block.");
}
std::size_t bucket_id = std::count_if(
block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets,
[&offset](u64 base_offset) { return base_offset <= offset; });
const auto bucket = buckets[bucket_id];
if (bucket.number_entries == 1)
return {bucket_id, 0};
std::size_t low = 0;
std::size_t mid = 0;
std::size_t high = bucket.number_entries - 1;
while (low <= high) {
mid = (low + high) / 2;
if (bucket.entries[mid].address_patch > offset) {
high = mid - 1;
} else {
if (mid == bucket.number_entries - 1 ||
bucket.entries[mid + 1].address_patch > offset) {
return {bucket_id, mid};
}
low = mid + 1;
}
}
UNREACHABLE_MSG("Offset could not be found in BKTR block.");
}
RelocationEntry BKTR::GetRelocationEntry(u64 offset) const { RelocationEntry BKTR::GetRelocationEntry(u64 offset) const {
const auto res = SearchBucketEntry<false>(offset, relocation, relocation_buckets); const auto res = SearchBucketEntry<false>(offset, relocation, relocation_buckets);
return relocation_buckets[res.first].entries[res.second]; return relocation_buckets[res.first].entries[res.second];

View file

@ -117,10 +117,6 @@ public:
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
private: private:
template <bool Subsection, typename BlockType, typename BucketType>
std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, BlockType block,
BucketType buckets) const;
RelocationEntry GetRelocationEntry(u64 offset) const; RelocationEntry GetRelocationEntry(u64 offset) const;
RelocationEntry GetNextRelocationEntry(u64 offset) const; RelocationEntry GetNextRelocationEntry(u64 offset) const;