1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef LIBPANDAFILE_FILE_ITEM_CONTAINER_H 17b1994897Sopenharmony_ci#define LIBPANDAFILE_FILE_ITEM_CONTAINER_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include "file_items.h" 20b1994897Sopenharmony_ci#include "file_writer.h" 21b1994897Sopenharmony_ci#include "pgo.h" 22b1994897Sopenharmony_ci 23b1994897Sopenharmony_ci#include <list> 24b1994897Sopenharmony_ci#include <map> 25b1994897Sopenharmony_ci#include <memory> 26b1994897Sopenharmony_ci#include <set> 27b1994897Sopenharmony_ci#include <string> 28b1994897Sopenharmony_ci#include <unordered_map> 29b1994897Sopenharmony_ci#include <unordered_set> 30b1994897Sopenharmony_ci 31b1994897Sopenharmony_cinamespace panda::panda_file { 32b1994897Sopenharmony_ci 33b1994897Sopenharmony_ciclass ItemDeduper; 34b1994897Sopenharmony_ci 35b1994897Sopenharmony_ciclass ItemContainer { 36b1994897Sopenharmony_cipublic: 37b1994897Sopenharmony_ci explicit ItemContainer(); 38b1994897Sopenharmony_ci ~ItemContainer() = default; 39b1994897Sopenharmony_ci NO_COPY_SEMANTIC(ItemContainer); 40b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(ItemContainer); 41b1994897Sopenharmony_ci 42b1994897Sopenharmony_ci StringItem *GetOrCreateStringItem(const std::string &str); 43b1994897Sopenharmony_ci 44b1994897Sopenharmony_ci LiteralArrayItem *GetOrCreateLiteralArrayItem(const std::string &id); 45b1994897Sopenharmony_ci 46b1994897Sopenharmony_ci ClassItem *GetOrCreateClassItem(const std::string &str); 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_ci ForeignClassItem *GetOrCreateForeignClassItem(const std::string &str); 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ci ScalarValueItem *GetOrCreateIntegerValueItem(uint32_t v); 51b1994897Sopenharmony_ci 52b1994897Sopenharmony_ci ScalarValueItem *GetOrCreateLongValueItem(uint64_t v); 53b1994897Sopenharmony_ci 54b1994897Sopenharmony_ci ScalarValueItem *GetOrCreateFloatValueItem(float v); 55b1994897Sopenharmony_ci 56b1994897Sopenharmony_ci ScalarValueItem *GetOrCreateDoubleValueItem(double v); 57b1994897Sopenharmony_ci 58b1994897Sopenharmony_ci ScalarValueItem *GetOrCreateIdValueItem(BaseItem *v); 59b1994897Sopenharmony_ci 60b1994897Sopenharmony_ci ClassItem *GetOrCreateGlobalClassItem() 61b1994897Sopenharmony_ci { 62b1994897Sopenharmony_ci return GetOrCreateClassItem("L_GLOBAL;"); 63b1994897Sopenharmony_ci } 64b1994897Sopenharmony_ci 65b1994897Sopenharmony_ci ProtoItem *GetOrCreateProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> ¶ms); 66b1994897Sopenharmony_ci 67b1994897Sopenharmony_ci PrimitiveTypeItem *GetOrCreatePrimitiveTypeItem(Type type); 68b1994897Sopenharmony_ci 69b1994897Sopenharmony_ci PrimitiveTypeItem *GetOrCreatePrimitiveTypeItem(Type::TypeId type); 70b1994897Sopenharmony_ci 71b1994897Sopenharmony_ci LineNumberProgramItem *CreateLineNumberProgramItem(); 72b1994897Sopenharmony_ci 73b1994897Sopenharmony_ci template <class T, class... Args> 74b1994897Sopenharmony_ci T *CreateItem(Args &&... args) 75b1994897Sopenharmony_ci { 76b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, StringItem>, "Use GetOrCreateStringItem to create StringItem"); 77b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, ClassItem>, "Use GetOrCreateClassItem to create ClassItem"); 78b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, ForeignClassItem>, 79b1994897Sopenharmony_ci "Use GetOrCreateForeignClassItem to create ForeignClassItem"); 80b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, ValueItem>, "Use GetOrCreateValueItem functions to create ValueItem"); 81b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, ProtoItem>, "Use GetOrCreateProtoItem to create ValueItem"); 82b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, LineNumberProgramItem>, 83b1994897Sopenharmony_ci "Use CreateLineNumberProgramItem to create LineNumberProgramItem"); 84b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, PrimitiveTypeItem>, 85b1994897Sopenharmony_ci "Use GetOrCreatePrimitiveTypeItem to create PrimitiveTypeItem"); 86b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, MethodItem>, "Use ClassItem instance to create MethodItem"); 87b1994897Sopenharmony_ci static_assert(!std::is_same_v<T, FieldItem>, "Use ClassItem instance to create FieldItem"); 88b1994897Sopenharmony_ci 89b1994897Sopenharmony_ci std::unique_ptr<T> ptr = nullptr; 90b1994897Sopenharmony_ci if constexpr (std::is_same_v<T, ForeignFieldItem> || std::is_same_v<T, ForeignMethodItem> || 91b1994897Sopenharmony_ci std::is_same_v<T, ScalarValueItem> || std::is_same_v<T, ArrayValueItem> || 92b1994897Sopenharmony_ci std::is_same_v<T, LiteralArrayItem>) { 93b1994897Sopenharmony_ci ptr = std::make_unique<T>(std::forward<Args>(args)..., this); 94b1994897Sopenharmony_ci } else { 95b1994897Sopenharmony_ci ptr = std::make_unique<T>(std::forward<Args>(args)...); 96b1994897Sopenharmony_ci } 97b1994897Sopenharmony_ci 98b1994897Sopenharmony_ci auto ret = ptr.get(); 99b1994897Sopenharmony_ci if (ptr->IsForeign()) { 100b1994897Sopenharmony_ci foreign_items_.emplace_back(std::move(ptr)); 101b1994897Sopenharmony_ci } else { 102b1994897Sopenharmony_ci items_.insert(GetInsertPosition<T>(), std::move(ptr)); 103b1994897Sopenharmony_ci } 104b1994897Sopenharmony_ci return ret; 105b1994897Sopenharmony_ci } 106b1994897Sopenharmony_ci 107b1994897Sopenharmony_ci void ReLayout(); 108b1994897Sopenharmony_ci uint32_t ComputeLayout(); 109b1994897Sopenharmony_ci bool Write(Writer *writer, bool deduplicateItems = true); 110b1994897Sopenharmony_ci 111b1994897Sopenharmony_ci std::map<std::string, size_t> GetStat(); 112b1994897Sopenharmony_ci 113b1994897Sopenharmony_ci void DumpItemsStat(std::ostream &os) const; 114b1994897Sopenharmony_ci 115b1994897Sopenharmony_ci uint32_t CalculateRoundUpSize(uint32_t before, uint32_t after) 116b1994897Sopenharmony_ci { 117b1994897Sopenharmony_ci return after - before; 118b1994897Sopenharmony_ci } 119b1994897Sopenharmony_ci 120b1994897Sopenharmony_ci std::unordered_map<std::string, StringItem *> *GetStringMap() 121b1994897Sopenharmony_ci { 122b1994897Sopenharmony_ci return &string_map_; 123b1994897Sopenharmony_ci } 124b1994897Sopenharmony_ci 125b1994897Sopenharmony_ci LiteralArrayItem *GetLiteralArrayItem(const std::string &key) 126b1994897Sopenharmony_ci { 127b1994897Sopenharmony_ci return literalarray_map_.at(key); 128b1994897Sopenharmony_ci } 129b1994897Sopenharmony_ci 130b1994897Sopenharmony_ci std::map<std::string, BaseClassItem *> *GetClassMap() 131b1994897Sopenharmony_ci { 132b1994897Sopenharmony_ci return &class_map_; 133b1994897Sopenharmony_ci } 134b1994897Sopenharmony_ci 135b1994897Sopenharmony_ci std::unordered_map<uint32_t, ValueItem *> *GetIntValueMap() 136b1994897Sopenharmony_ci { 137b1994897Sopenharmony_ci return &int_value_map_; 138b1994897Sopenharmony_ci } 139b1994897Sopenharmony_ci 140b1994897Sopenharmony_ci std::unordered_map<uint64_t, ValueItem *> *GetLongValueMap() 141b1994897Sopenharmony_ci { 142b1994897Sopenharmony_ci return &long_value_map_; 143b1994897Sopenharmony_ci } 144b1994897Sopenharmony_ci 145b1994897Sopenharmony_ci std::unordered_map<uint32_t, ValueItem *> *GetFloatValueMap() 146b1994897Sopenharmony_ci { 147b1994897Sopenharmony_ci return &float_value_map_; 148b1994897Sopenharmony_ci } 149b1994897Sopenharmony_ci 150b1994897Sopenharmony_ci std::unordered_map<uint64_t, ValueItem *> *GetDoubleValueMap() 151b1994897Sopenharmony_ci { 152b1994897Sopenharmony_ci return &double_value_map_; 153b1994897Sopenharmony_ci } 154b1994897Sopenharmony_ci 155b1994897Sopenharmony_ci std::unordered_map<BaseItem *, ValueItem *> *GetScalarValueMap() 156b1994897Sopenharmony_ci { 157b1994897Sopenharmony_ci return &id_value_map_; 158b1994897Sopenharmony_ci } 159b1994897Sopenharmony_ci 160b1994897Sopenharmony_ci ProtoItem *GetProtoItem(TypeItem *retType, const std::vector<MethodParamItem> ¶ms) 161b1994897Sopenharmony_ci { 162b1994897Sopenharmony_ci return proto_map_.at(ProtoKey {retType, params}); 163b1994897Sopenharmony_ci } 164b1994897Sopenharmony_ci 165b1994897Sopenharmony_ci std::unordered_map<Type::TypeId, PrimitiveTypeItem *> *GetPrimitiveTypeMap() 166b1994897Sopenharmony_ci { 167b1994897Sopenharmony_ci return &primitive_type_map_; 168b1994897Sopenharmony_ci } 169b1994897Sopenharmony_ci 170b1994897Sopenharmony_ci std::list<std::unique_ptr<BaseItem>> &GetItems() 171b1994897Sopenharmony_ci { 172b1994897Sopenharmony_ci return items_; 173b1994897Sopenharmony_ci } 174b1994897Sopenharmony_ci 175b1994897Sopenharmony_ci const std::list<std::unique_ptr<BaseItem>> &GetItems() const 176b1994897Sopenharmony_ci { 177b1994897Sopenharmony_ci return items_; 178b1994897Sopenharmony_ci } 179b1994897Sopenharmony_ci 180b1994897Sopenharmony_ci const std::vector<std::unique_ptr<BaseItem>> &GetForeigtems() 181b1994897Sopenharmony_ci { 182b1994897Sopenharmony_ci return foreign_items_; 183b1994897Sopenharmony_ci } 184b1994897Sopenharmony_ci 185b1994897Sopenharmony_ci BaseItem *GetEndItem() 186b1994897Sopenharmony_ci { 187b1994897Sopenharmony_ci return end_; 188b1994897Sopenharmony_ci } 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci void ReorderItems(panda::panda_file::pgo::ProfileOptimizer *profile_opt); 191b1994897Sopenharmony_ci 192b1994897Sopenharmony_ci void DeduplicateItems(bool computeLayout = true); 193b1994897Sopenharmony_ci 194b1994897Sopenharmony_ci void DeduplicateCodeAndDebugInfo(); 195b1994897Sopenharmony_ci 196b1994897Sopenharmony_ci void DeduplicateAnnotations(); 197b1994897Sopenharmony_ci 198b1994897Sopenharmony_ci void DeduplicateLineNumberProgram(DebugInfoItem *item, ItemDeduper *deduper); 199b1994897Sopenharmony_ci 200b1994897Sopenharmony_ci void DeduplicateDebugInfo(MethodItem *method, ItemDeduper *debug_info_deduper, 201b1994897Sopenharmony_ci ItemDeduper *line_number_program_deduper); 202b1994897Sopenharmony_ci 203b1994897Sopenharmony_ci size_t GetIndexedItemCount() const 204b1994897Sopenharmony_ci { 205b1994897Sopenharmony_ci return indexed_item_count_; 206b1994897Sopenharmony_ci } 207b1994897Sopenharmony_ci 208b1994897Sopenharmony_ci void IncIndexedItemCount() 209b1994897Sopenharmony_ci { 210b1994897Sopenharmony_ci indexed_item_count_++; 211b1994897Sopenharmony_ci } 212b1994897Sopenharmony_ci 213b1994897Sopenharmony_ci static void SetApi(uint8_t api) 214b1994897Sopenharmony_ci { 215b1994897Sopenharmony_ci ItemContainer::apiVersion = api; 216b1994897Sopenharmony_ci } 217b1994897Sopenharmony_ci 218b1994897Sopenharmony_ci static void SetSubApi(std::string subApi) 219b1994897Sopenharmony_ci { 220b1994897Sopenharmony_ci ItemContainer::subApiVersion = subApi; 221b1994897Sopenharmony_ci } 222b1994897Sopenharmony_ci 223b1994897Sopenharmony_ci static std::string GetSubApi() 224b1994897Sopenharmony_ci { 225b1994897Sopenharmony_ci return ItemContainer::subApiVersion; 226b1994897Sopenharmony_ci } 227b1994897Sopenharmony_ci 228b1994897Sopenharmony_ci static uint8_t GetApi() 229b1994897Sopenharmony_ci { 230b1994897Sopenharmony_ci return ItemContainer::apiVersion; 231b1994897Sopenharmony_ci } 232b1994897Sopenharmony_ci 233b1994897Sopenharmony_ci static uint8_t apiVersion; 234b1994897Sopenharmony_ci static std::string subApiVersion; 235b1994897Sopenharmony_ci 236b1994897Sopenharmony_ciprivate: 237b1994897Sopenharmony_ci template <class T> 238b1994897Sopenharmony_ci auto GetInsertPosition() 239b1994897Sopenharmony_ci { 240b1994897Sopenharmony_ci if (std::is_same_v<T, CodeItem>) { 241b1994897Sopenharmony_ci return code_items_end_; 242b1994897Sopenharmony_ci } 243b1994897Sopenharmony_ci 244b1994897Sopenharmony_ci if (std::is_same_v<T, DebugInfoItem>) { 245b1994897Sopenharmony_ci return debug_items_end_; 246b1994897Sopenharmony_ci } 247b1994897Sopenharmony_ci 248b1994897Sopenharmony_ci return items_end_; 249b1994897Sopenharmony_ci } 250b1994897Sopenharmony_ci 251b1994897Sopenharmony_ci class IndexItem : public BaseItem { 252b1994897Sopenharmony_ci public: 253b1994897Sopenharmony_ci IndexItem(IndexType type, size_t max_index) : type_(type), max_index_(max_index) 254b1994897Sopenharmony_ci { 255b1994897Sopenharmony_ci ASSERT(type_ != IndexType::NONE); 256b1994897Sopenharmony_ci 257b1994897Sopenharmony_ci const auto bc_version = GetVersionByApi(ItemContainer::GetApi(), ItemContainer::GetSubApi()); 258b1994897Sopenharmony_ci if (bc_version.value().front() >= API_12 && (type == IndexType::FIELD || type == IndexType::PROTO)) { 259b1994897Sopenharmony_ci SetNeedsEmit(false); 260b1994897Sopenharmony_ci } 261b1994897Sopenharmony_ci } 262b1994897Sopenharmony_ci 263b1994897Sopenharmony_ci ~IndexItem() override = default; 264b1994897Sopenharmony_ci 265b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(IndexItem); 266b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(IndexItem); 267b1994897Sopenharmony_ci 268b1994897Sopenharmony_ci size_t Alignment() override 269b1994897Sopenharmony_ci { 270b1994897Sopenharmony_ci return sizeof(uint32_t); 271b1994897Sopenharmony_ci } 272b1994897Sopenharmony_ci 273b1994897Sopenharmony_ci bool Write(Writer *writer) override; 274b1994897Sopenharmony_ci 275b1994897Sopenharmony_ci ItemTypes GetItemType() const override; 276b1994897Sopenharmony_ci 277b1994897Sopenharmony_ci bool Add(IndexedItem *item); 278b1994897Sopenharmony_ci 279b1994897Sopenharmony_ci bool Has(IndexedItem *item) const 280b1994897Sopenharmony_ci { 281b1994897Sopenharmony_ci auto res = index_.find(item); 282b1994897Sopenharmony_ci return res != index_.cend(); 283b1994897Sopenharmony_ci } 284b1994897Sopenharmony_ci 285b1994897Sopenharmony_ci void Remove(IndexedItem *item) 286b1994897Sopenharmony_ci { 287b1994897Sopenharmony_ci index_.erase(item); 288b1994897Sopenharmony_ci } 289b1994897Sopenharmony_ci 290b1994897Sopenharmony_ci size_t GetNumItems() const 291b1994897Sopenharmony_ci { 292b1994897Sopenharmony_ci return index_.size(); 293b1994897Sopenharmony_ci } 294b1994897Sopenharmony_ci 295b1994897Sopenharmony_ci void UpdateItems(BaseItem *start, BaseItem *end) 296b1994897Sopenharmony_ci { 297b1994897Sopenharmony_ci size_t i = 0; 298b1994897Sopenharmony_ci for (auto *item : index_) { 299b1994897Sopenharmony_ci item->SetIndex(start, end, i++); 300b1994897Sopenharmony_ci } 301b1994897Sopenharmony_ci } 302b1994897Sopenharmony_ci 303b1994897Sopenharmony_ci void Reset() 304b1994897Sopenharmony_ci { 305b1994897Sopenharmony_ci for (auto *item : index_) { 306b1994897Sopenharmony_ci item->ClearIndexes(); 307b1994897Sopenharmony_ci } 308b1994897Sopenharmony_ci } 309b1994897Sopenharmony_ci 310b1994897Sopenharmony_ci protected: 311b1994897Sopenharmony_ci size_t CalculateSize() const override 312b1994897Sopenharmony_ci { 313b1994897Sopenharmony_ci if (NeedsEmit()) { 314b1994897Sopenharmony_ci return index_.size() * ID_SIZE; 315b1994897Sopenharmony_ci } 316b1994897Sopenharmony_ci return 0; 317b1994897Sopenharmony_ci } 318b1994897Sopenharmony_ci 319b1994897Sopenharmony_ci private: 320b1994897Sopenharmony_ci struct Comparator { 321b1994897Sopenharmony_ci bool operator()(IndexedItem *item1, IndexedItem *item2) const noexcept 322b1994897Sopenharmony_ci { 323b1994897Sopenharmony_ci auto index_type = item1->GetIndexType(); 324b1994897Sopenharmony_ci if (index_type == IndexType::CLASS) { 325b1994897Sopenharmony_ci auto type_item1 = static_cast<TypeItem *>(item1); 326b1994897Sopenharmony_ci auto type_item2 = static_cast<TypeItem *>(item2); 327b1994897Sopenharmony_ci auto type_id1 = static_cast<size_t>(type_item1->GetType().GetId()); 328b1994897Sopenharmony_ci auto type_id2 = static_cast<size_t>(type_item2->GetType().GetId()); 329b1994897Sopenharmony_ci if (type_id1 != type_id2) { 330b1994897Sopenharmony_ci return type_id1 < type_id2; 331b1994897Sopenharmony_ci } 332b1994897Sopenharmony_ci } 333b1994897Sopenharmony_ci 334b1994897Sopenharmony_ci if (index_type == IndexType::LINE_NUMBER_PROG) { 335b1994897Sopenharmony_ci auto ref_count1 = item1->GetRefCount(); 336b1994897Sopenharmony_ci auto ref_count2 = item2->GetRefCount(); 337b1994897Sopenharmony_ci if (ref_count1 != ref_count2) { 338b1994897Sopenharmony_ci return ref_count1 > ref_count2; 339b1994897Sopenharmony_ci } 340b1994897Sopenharmony_ci } 341b1994897Sopenharmony_ci 342b1994897Sopenharmony_ci return item1->GetIndexedItemCount() < item2->GetIndexedItemCount(); 343b1994897Sopenharmony_ci } 344b1994897Sopenharmony_ci }; 345b1994897Sopenharmony_ci 346b1994897Sopenharmony_ci IndexType type_; 347b1994897Sopenharmony_ci size_t max_index_; 348b1994897Sopenharmony_ci std::set<IndexedItem *, Comparator> index_; 349b1994897Sopenharmony_ci }; 350b1994897Sopenharmony_ci 351b1994897Sopenharmony_ci class LineNumberProgramIndexItem : public IndexItem { 352b1994897Sopenharmony_ci public: 353b1994897Sopenharmony_ci LineNumberProgramIndexItem() : IndexItem(IndexType::LINE_NUMBER_PROG, MAX_INDEX_32) {} 354b1994897Sopenharmony_ci ~LineNumberProgramIndexItem() override = default; 355b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(LineNumberProgramIndexItem); 356b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(LineNumberProgramIndexItem); 357b1994897Sopenharmony_ci 358b1994897Sopenharmony_ci void IncRefCount(LineNumberProgramItem *item) 359b1994897Sopenharmony_ci { 360b1994897Sopenharmony_ci ASSERT(Has(item)); 361b1994897Sopenharmony_ci Remove(item); 362b1994897Sopenharmony_ci item->IncRefCount(); 363b1994897Sopenharmony_ci Add(item); 364b1994897Sopenharmony_ci } 365b1994897Sopenharmony_ci 366b1994897Sopenharmony_ci void DecRefCount(LineNumberProgramItem *item) 367b1994897Sopenharmony_ci { 368b1994897Sopenharmony_ci ASSERT(Has(item)); 369b1994897Sopenharmony_ci Remove(item); 370b1994897Sopenharmony_ci item->DecRefCount(); 371b1994897Sopenharmony_ci Add(item); 372b1994897Sopenharmony_ci } 373b1994897Sopenharmony_ci }; 374b1994897Sopenharmony_ci 375b1994897Sopenharmony_ci class IndexHeaderItem : public BaseItem { 376b1994897Sopenharmony_ci public: 377b1994897Sopenharmony_ci explicit IndexHeaderItem(std::vector<IndexItem *> indexes) : indexes_(std::move(indexes)) 378b1994897Sopenharmony_ci { 379b1994897Sopenharmony_ci ASSERT(indexes_.size() == INDEX_COUNT_16); 380b1994897Sopenharmony_ci } 381b1994897Sopenharmony_ci 382b1994897Sopenharmony_ci ~IndexHeaderItem() override = default; 383b1994897Sopenharmony_ci 384b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(IndexHeaderItem); 385b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(IndexHeaderItem); 386b1994897Sopenharmony_ci 387b1994897Sopenharmony_ci size_t Alignment() override 388b1994897Sopenharmony_ci { 389b1994897Sopenharmony_ci return ID_SIZE; 390b1994897Sopenharmony_ci } 391b1994897Sopenharmony_ci 392b1994897Sopenharmony_ci bool Write(Writer *writer) override; 393b1994897Sopenharmony_ci 394b1994897Sopenharmony_ci ItemTypes GetItemType() const override 395b1994897Sopenharmony_ci { 396b1994897Sopenharmony_ci return ItemTypes::INDEX_HEADER; 397b1994897Sopenharmony_ci } 398b1994897Sopenharmony_ci 399b1994897Sopenharmony_ci bool Add(const std::list<IndexedItem *> &items); 400b1994897Sopenharmony_ci 401b1994897Sopenharmony_ci void Remove(const std::list<IndexedItem *> &items); 402b1994897Sopenharmony_ci 403b1994897Sopenharmony_ci void SetStart(BaseItem *item) 404b1994897Sopenharmony_ci { 405b1994897Sopenharmony_ci start_ = item; 406b1994897Sopenharmony_ci } 407b1994897Sopenharmony_ci 408b1994897Sopenharmony_ci void SetEnd(BaseItem *item) 409b1994897Sopenharmony_ci { 410b1994897Sopenharmony_ci end_ = item; 411b1994897Sopenharmony_ci } 412b1994897Sopenharmony_ci 413b1994897Sopenharmony_ci void UpdateItems() 414b1994897Sopenharmony_ci { 415b1994897Sopenharmony_ci for (auto *index : indexes_) { 416b1994897Sopenharmony_ci index->UpdateItems(start_, end_); 417b1994897Sopenharmony_ci } 418b1994897Sopenharmony_ci } 419b1994897Sopenharmony_ci 420b1994897Sopenharmony_ci protected: 421b1994897Sopenharmony_ci size_t CalculateSize() const override 422b1994897Sopenharmony_ci { 423b1994897Sopenharmony_ci return sizeof(File::IndexHeader); 424b1994897Sopenharmony_ci } 425b1994897Sopenharmony_ci 426b1994897Sopenharmony_ci private: 427b1994897Sopenharmony_ci IndexItem *IndexGetIndexByType(IndexType type) const 428b1994897Sopenharmony_ci { 429b1994897Sopenharmony_ci auto i = static_cast<size_t>(type); 430b1994897Sopenharmony_ci return indexes_[i]; 431b1994897Sopenharmony_ci } 432b1994897Sopenharmony_ci 433b1994897Sopenharmony_ci BaseItem *start_ {nullptr}; 434b1994897Sopenharmony_ci BaseItem *end_ {nullptr}; 435b1994897Sopenharmony_ci std::vector<IndexItem *> indexes_; 436b1994897Sopenharmony_ci }; 437b1994897Sopenharmony_ci 438b1994897Sopenharmony_ci class IndexSectionItem : public BaseItem { 439b1994897Sopenharmony_ci public: 440b1994897Sopenharmony_ci size_t Alignment() override 441b1994897Sopenharmony_ci { 442b1994897Sopenharmony_ci return ID_SIZE; 443b1994897Sopenharmony_ci } 444b1994897Sopenharmony_ci 445b1994897Sopenharmony_ci bool Write(Writer *writer) override; 446b1994897Sopenharmony_ci 447b1994897Sopenharmony_ci ItemTypes GetItemType() const override 448b1994897Sopenharmony_ci { 449b1994897Sopenharmony_ci return ItemTypes::INDEX_SECTION; 450b1994897Sopenharmony_ci } 451b1994897Sopenharmony_ci 452b1994897Sopenharmony_ci void Reset() 453b1994897Sopenharmony_ci { 454b1994897Sopenharmony_ci headers_.clear(); 455b1994897Sopenharmony_ci 456b1994897Sopenharmony_ci for (auto &index : indexes_) { 457b1994897Sopenharmony_ci index.Reset(); 458b1994897Sopenharmony_ci } 459b1994897Sopenharmony_ci 460b1994897Sopenharmony_ci indexes_.clear(); 461b1994897Sopenharmony_ci } 462b1994897Sopenharmony_ci 463b1994897Sopenharmony_ci void AddHeader(); 464b1994897Sopenharmony_ci 465b1994897Sopenharmony_ci IndexHeaderItem *GetCurrentHeader() 466b1994897Sopenharmony_ci { 467b1994897Sopenharmony_ci return &headers_.back(); 468b1994897Sopenharmony_ci } 469b1994897Sopenharmony_ci 470b1994897Sopenharmony_ci bool IsEmpty() const 471b1994897Sopenharmony_ci { 472b1994897Sopenharmony_ci return headers_.empty(); 473b1994897Sopenharmony_ci } 474b1994897Sopenharmony_ci 475b1994897Sopenharmony_ci size_t GetNumHeaders() const 476b1994897Sopenharmony_ci { 477b1994897Sopenharmony_ci return headers_.size(); 478b1994897Sopenharmony_ci } 479b1994897Sopenharmony_ci 480b1994897Sopenharmony_ci void ComputeLayout() override; 481b1994897Sopenharmony_ci 482b1994897Sopenharmony_ci void UpdateItems() 483b1994897Sopenharmony_ci { 484b1994897Sopenharmony_ci for (auto &header : headers_) { 485b1994897Sopenharmony_ci header.UpdateItems(); 486b1994897Sopenharmony_ci } 487b1994897Sopenharmony_ci } 488b1994897Sopenharmony_ci 489b1994897Sopenharmony_ci protected: 490b1994897Sopenharmony_ci size_t CalculateSize() const override; 491b1994897Sopenharmony_ci 492b1994897Sopenharmony_ci private: 493b1994897Sopenharmony_ci std::list<IndexHeaderItem> headers_; 494b1994897Sopenharmony_ci std::list<IndexItem> indexes_; 495b1994897Sopenharmony_ci }; 496b1994897Sopenharmony_ci 497b1994897Sopenharmony_ci class ProtoKey { 498b1994897Sopenharmony_ci public: 499b1994897Sopenharmony_ci ProtoKey(TypeItem *ret_type, const std::vector<MethodParamItem> ¶ms); 500b1994897Sopenharmony_ci 501b1994897Sopenharmony_ci ~ProtoKey() = default; 502b1994897Sopenharmony_ci 503b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(ProtoKey); 504b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(ProtoKey); 505b1994897Sopenharmony_ci 506b1994897Sopenharmony_ci size_t GetHash() const 507b1994897Sopenharmony_ci { 508b1994897Sopenharmony_ci return hash_; 509b1994897Sopenharmony_ci } 510b1994897Sopenharmony_ci 511b1994897Sopenharmony_ci bool operator==(const ProtoKey &key) const 512b1994897Sopenharmony_ci { 513b1994897Sopenharmony_ci return shorty_ == key.shorty_ && ref_types_ == key.ref_types_; 514b1994897Sopenharmony_ci } 515b1994897Sopenharmony_ci 516b1994897Sopenharmony_ci private: 517b1994897Sopenharmony_ci void Add(TypeItem *item); 518b1994897Sopenharmony_ci 519b1994897Sopenharmony_ci size_t hash_; 520b1994897Sopenharmony_ci std::string shorty_; 521b1994897Sopenharmony_ci std::vector<TypeItem *> ref_types_; 522b1994897Sopenharmony_ci }; 523b1994897Sopenharmony_ci 524b1994897Sopenharmony_ci struct ProtoKeyHash { 525b1994897Sopenharmony_ci size_t operator()(const ProtoKey &key) const noexcept 526b1994897Sopenharmony_ci { 527b1994897Sopenharmony_ci return key.GetHash(); 528b1994897Sopenharmony_ci }; 529b1994897Sopenharmony_ci }; 530b1994897Sopenharmony_ci 531b1994897Sopenharmony_ci class EndItem : public BaseItem { 532b1994897Sopenharmony_ci public: 533b1994897Sopenharmony_ci EndItem() 534b1994897Sopenharmony_ci { 535b1994897Sopenharmony_ci SetNeedsEmit(false); 536b1994897Sopenharmony_ci } 537b1994897Sopenharmony_ci 538b1994897Sopenharmony_ci ~EndItem() override = default; 539b1994897Sopenharmony_ci 540b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(EndItem); 541b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(EndItem); 542b1994897Sopenharmony_ci 543b1994897Sopenharmony_ci size_t CalculateSize() const override 544b1994897Sopenharmony_ci { 545b1994897Sopenharmony_ci return 0; 546b1994897Sopenharmony_ci } 547b1994897Sopenharmony_ci 548b1994897Sopenharmony_ci bool Write([[maybe_unused]] Writer *writer) override 549b1994897Sopenharmony_ci { 550b1994897Sopenharmony_ci return true; 551b1994897Sopenharmony_ci } 552b1994897Sopenharmony_ci 553b1994897Sopenharmony_ci ItemTypes GetItemType() const override 554b1994897Sopenharmony_ci { 555b1994897Sopenharmony_ci return ItemTypes::END_ITEM; 556b1994897Sopenharmony_ci } 557b1994897Sopenharmony_ci }; 558b1994897Sopenharmony_ci 559b1994897Sopenharmony_ci bool WriteHeader(Writer *writer, ssize_t *checksum_offset); 560b1994897Sopenharmony_ci 561b1994897Sopenharmony_ci bool WriteItems(Writer *writer); 562b1994897Sopenharmony_ci 563b1994897Sopenharmony_ci bool WriteHeaderIndexInfo(Writer *writer); 564b1994897Sopenharmony_ci 565b1994897Sopenharmony_ci void RebuildIndexSection(); 566b1994897Sopenharmony_ci 567b1994897Sopenharmony_ci void RebuildLineNumberProgramIndex(); 568b1994897Sopenharmony_ci 569b1994897Sopenharmony_ci void UpdateOrderIndexes(); 570b1994897Sopenharmony_ci 571b1994897Sopenharmony_ci void AddIndexDependecies(BaseItem *item); 572b1994897Sopenharmony_ci 573b1994897Sopenharmony_ci void ProcessIndexDependecies(BaseItem *item); 574b1994897Sopenharmony_ci 575b1994897Sopenharmony_ci size_t GetForeignOffset() const; 576b1994897Sopenharmony_ci 577b1994897Sopenharmony_ci size_t GetForeignSize() const; 578b1994897Sopenharmony_ci 579b1994897Sopenharmony_ci std::unordered_map<std::string, StringItem *> string_map_; 580b1994897Sopenharmony_ci std::unordered_map<std::string, LiteralArrayItem *> literalarray_map_; 581b1994897Sopenharmony_ci 582b1994897Sopenharmony_ci std::map<std::string, BaseClassItem *> class_map_; 583b1994897Sopenharmony_ci 584b1994897Sopenharmony_ci std::unordered_map<uint32_t, ValueItem *> int_value_map_; 585b1994897Sopenharmony_ci std::unordered_map<uint64_t, ValueItem *> long_value_map_; 586b1994897Sopenharmony_ci // NB! For f32 and f64 value maps we use integral keys 587b1994897Sopenharmony_ci // (in fact, bit patterns of corresponding values) to 588b1994897Sopenharmony_ci // workaround 0.0 == -0.0 semantics. 589b1994897Sopenharmony_ci std::unordered_map<uint32_t, ValueItem *> float_value_map_; 590b1994897Sopenharmony_ci std::unordered_map<uint64_t, ValueItem *> double_value_map_; 591b1994897Sopenharmony_ci std::unordered_map<BaseItem *, ValueItem *> id_value_map_; 592b1994897Sopenharmony_ci std::unordered_map<ProtoKey, ProtoItem *, ProtoKeyHash> proto_map_; 593b1994897Sopenharmony_ci std::unordered_map<Type::TypeId, PrimitiveTypeItem *> primitive_type_map_; 594b1994897Sopenharmony_ci 595b1994897Sopenharmony_ci std::list<std::unique_ptr<BaseItem>> items_; 596b1994897Sopenharmony_ci 597b1994897Sopenharmony_ci std::vector<std::unique_ptr<BaseItem>> foreign_items_; 598b1994897Sopenharmony_ci 599b1994897Sopenharmony_ci IndexSectionItem index_section_item_; 600b1994897Sopenharmony_ci 601b1994897Sopenharmony_ci LineNumberProgramIndexItem line_number_program_index_item_; 602b1994897Sopenharmony_ci 603b1994897Sopenharmony_ci std::list<std::unique_ptr<BaseItem>>::iterator items_end_; 604b1994897Sopenharmony_ci std::list<std::unique_ptr<BaseItem>>::iterator code_items_end_; 605b1994897Sopenharmony_ci std::list<std::unique_ptr<BaseItem>>::iterator debug_items_end_; 606b1994897Sopenharmony_ci 607b1994897Sopenharmony_ci // Get Roundup Alignment Size 608b1994897Sopenharmony_ci std::unordered_map<std::string, size_t> items_round_up_size_; 609b1994897Sopenharmony_ci uint32_t foreign_item_roundup_size_ {0}; 610b1994897Sopenharmony_ci uint32_t line_number_item_roundup_size_ {0}; 611b1994897Sopenharmony_ci 612b1994897Sopenharmony_ci BaseItem *end_; 613b1994897Sopenharmony_ci size_t indexed_item_count_ {0}; 614b1994897Sopenharmony_ci}; 615b1994897Sopenharmony_ci 616b1994897Sopenharmony_ci} // namespace panda::panda_file 617b1994897Sopenharmony_ci 618b1994897Sopenharmony_ci#endif // LIBPANDAFILE_FILE_ITEM_CONTAINER_H 619