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