Merge pull request #4658 from lioncash/copy3
nca_patch: Reduce stack usage size within SearchBucketEntry()
This commit is contained in:
		| @@ -12,6 +12,49 @@ | ||||
| #include "core/file_sys/nca_patch.h" | ||||
|  | ||||
| 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_, | ||||
|            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; | ||||
| } | ||||
|  | ||||
| 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 { | ||||
|     const auto res = SearchBucketEntry<false>(offset, relocation, relocation_buckets); | ||||
|     return relocation_buckets[res.first].entries[res.second]; | ||||
|   | ||||
| @@ -117,10 +117,6 @@ public: | ||||
|     bool Rename(std::string_view name) override; | ||||
|  | ||||
| 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 GetNextRelocationEntry(u64 offset) const; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rodrigo Locatti
					Rodrigo Locatti