image_index.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
  5. #define COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <map>
  9. #include <vector>
  10. #include "base/check_op.h"
  11. #include "components/zucchini/buffer_view.h"
  12. #include "components/zucchini/image_utils.h"
  13. #include "components/zucchini/reference_set.h"
  14. #include "components/zucchini/target_pool.h"
  15. namespace zucchini {
  16. class Disassembler;
  17. // A class that holds annotations of an image, allowing quick access to its raw
  18. // and reference content. The memory overhead of storing all references is
  19. // relatively high, so this is only used during patch generation.
  20. class ImageIndex {
  21. public:
  22. explicit ImageIndex(ConstBufferView image);
  23. ImageIndex(const ImageIndex&) = delete;
  24. ImageIndex(ImageIndex&&);
  25. ~ImageIndex();
  26. // Inserts all references read from |disasm|. This should be called exactly
  27. // once. If overlap between any two references of any type is encountered,
  28. // returns false and leaves the object in an invalid state. Otherwise,
  29. // returns true.
  30. // TODO(huangs): Refactor ReaderFactory and WriterFactory so
  31. // |const Disassembler&| can be used here.
  32. bool Initialize(Disassembler* disasm);
  33. // Returns the array size needed to accommodate all reference type values.
  34. size_t TypeCount() const {
  35. if (reference_sets_.empty())
  36. return 0U;
  37. return reference_sets_.rbegin()->first.value() + 1; // Max key + 1.
  38. }
  39. // Returns the array size needed to accommodate all pool values.
  40. size_t PoolCount() const {
  41. if (target_pools_.empty())
  42. return 0U;
  43. return target_pools_.rbegin()->first.value() + 1; // Max key + 1.
  44. }
  45. // Returns true if |image_[location]| is either:
  46. // - A raw value.
  47. // - The first byte of a reference.
  48. bool IsToken(offset_t location) const;
  49. // Returns true if |image_[location]| is part of a reference.
  50. bool IsReference(offset_t location) const {
  51. return LookupType(location) != kNoTypeTag;
  52. }
  53. // Returns the type tag of the reference covering |location|, or kNoTypeTag if
  54. // |location| is not part of a reference.
  55. TypeTag LookupType(offset_t location) const {
  56. DCHECK_LT(location, size());
  57. return type_tags_[location];
  58. }
  59. // Returns the raw value at |location|.
  60. uint8_t GetRawValue(offset_t location) const {
  61. DCHECK_LT(location, size());
  62. return image_[location];
  63. }
  64. const std::map<PoolTag, TargetPool>& target_pools() const {
  65. return target_pools_;
  66. }
  67. const std::map<TypeTag, ReferenceSet>& reference_sets() const {
  68. return reference_sets_;
  69. }
  70. const TargetPool& pool(PoolTag pool_tag) const {
  71. return target_pools_.at(pool_tag);
  72. }
  73. const ReferenceSet& refs(TypeTag type_tag) const {
  74. return reference_sets_.at(type_tag);
  75. }
  76. // Returns the size of the image.
  77. size_t size() const { return image_.size(); }
  78. private:
  79. // Inserts to |*this| index, all references described by |traits| read from
  80. // |ref_reader|, which gets consumed. This should be called exactly once for
  81. // each reference type. If overlap between any two references of any type is
  82. // encountered, returns false and leaves the object in an invalid state.
  83. // Otherwise, returns true.
  84. bool InsertReferences(const ReferenceTypeTraits& traits,
  85. ReferenceReader&& ref_reader);
  86. const ConstBufferView image_;
  87. // Used for random access lookup of reference type, for each byte in |image_|.
  88. std::vector<TypeTag> type_tags_;
  89. std::map<PoolTag, TargetPool> target_pools_;
  90. std::map<TypeTag, ReferenceSet> reference_sets_;
  91. };
  92. } // namespace zucchini
  93. #endif // COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_