当前仓库属于关闭状态,部分功能使用受限,详情请查阅 仓库状态说明
57 Star 30 Fork 160

OpenHarmony-SIG/arkcompiler_runtime_core
关闭

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
file_item_container.h 15.60 KB
一键复制 编辑 原始数据 按行查看 历史
K Prokopenko 提交于 2023-05-11 16:30 +08:00 . add bytecode static linker [squash]
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
/**
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBPANDAFILE_FILE_ITEM_CONTAINER_H_
#define LIBPANDAFILE_FILE_ITEM_CONTAINER_H_
#include "file_items.h"
#include "file_writer.h"
#include "pgo.h"
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
namespace panda::panda_file {
class ItemDeduper;
class ItemContainer {
public:
ItemContainer();
~ItemContainer() = default;
NO_COPY_SEMANTIC(ItemContainer);
NO_MOVE_SEMANTIC(ItemContainer);
constexpr static std::string_view GetGlobalClassName()
{
return "L_GLOBAL;";
}
StringItem *GetOrCreateStringItem(const std::string &str);
LiteralArrayItem *GetOrCreateLiteralArrayItem(const std::string &id);
ClassItem *GetOrCreateClassItem(const std::string &str);
ForeignClassItem *GetOrCreateForeignClassItem(const std::string &str);
ScalarValueItem *GetOrCreateIntegerValueItem(uint32_t v);
ScalarValueItem *GetOrCreateLongValueItem(uint64_t v);
ScalarValueItem *GetOrCreateFloatValueItem(float v);
ScalarValueItem *GetOrCreateDoubleValueItem(double v);
ScalarValueItem *GetOrCreateIdValueItem(BaseItem *v);
ClassItem *GetOrCreateGlobalClassItem()
{
return GetOrCreateClassItem(std::string(GetGlobalClassName()));
}
ProtoItem *GetOrCreateProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> &params);
PrimitiveTypeItem *GetOrCreatePrimitiveTypeItem(Type type);
PrimitiveTypeItem *GetOrCreatePrimitiveTypeItem(Type::TypeId type);
LineNumberProgramItem *CreateLineNumberProgramItem();
void IncRefLineNumberProgramItem(LineNumberProgramItem *it);
void SetQuickened()
{
is_quickened_ = true;
}
bool IsQuickened() const
{
return is_quickened_;
}
template <class T, class... Args>
T *CreateItem(Args &&...args)
{
static_assert(!std::is_same_v<T, StringItem>, "Use GetOrCreateStringItem to create StringItem");
static_assert(!std::is_same_v<T, ClassItem>, "Use GetOrCreateClassItem to create ClassItem");
static_assert(!std::is_same_v<T, ForeignClassItem>,
"Use GetOrCreateForeignClassItem to create ForeignClassItem");
static_assert(!std::is_same_v<T, ValueItem>, "Use GetOrCreateValueItem functions to create ValueItem");
static_assert(!std::is_same_v<T, ProtoItem>, "Use GetOrCreateProtoItem to create ValueItem");
static_assert(!std::is_same_v<T, LineNumberProgramItem>,
"Use CreateLineNumberProgramItem to create LineNumberProgramItem");
static_assert(!std::is_same_v<T, PrimitiveTypeItem>,
"Use GetOrCreatePrimitiveTypeItem to create PrimitiveTypeItem");
static_assert(!std::is_same_v<T, MethodItem>, "Use ClassItem instance to create MethodItem");
static_assert(!std::is_same_v<T, FieldItem>, "Use ClassItem instance to create FieldItem");
auto ptr = std::make_unique<T>(std::forward<Args>(args)...);
auto ret = ptr.get();
if (ptr->IsForeign()) {
foreign_items_.emplace_back(std::move(ptr));
} else {
items_.insert(GetInsertPosition<T>(), std::move(ptr));
}
return ret;
}
uint32_t ComputeLayout();
bool Write(Writer *writer, bool deduplicate_items = true, bool compute_layout = true);
std::map<std::string, size_t> GetStat();
void DumpItemsStat(std::ostream &os) const;
std::unordered_map<std::string, StringItem *> *GetStringMap()
{
return &string_map_;
}
LiteralArrayItem *GetLiteralArrayItem(const std::string &key)
{
return literalarray_map_.at(key);
}
std::map<std::string, BaseClassItem *> *GetClassMap()
{
return &class_map_;
}
std::unordered_map<uint32_t, ValueItem *> *GetIntValueMap()
{
return &int_value_map_;
}
std::unordered_map<uint64_t, ValueItem *> *GetLongValueMap()
{
return &long_value_map_;
}
std::unordered_map<uint32_t, ValueItem *> *GetFloatValueMap()
{
return &float_value_map_;
}
std::unordered_map<uint64_t, ValueItem *> *GetDoubleValueMap()
{
return &double_value_map_;
}
std::unordered_map<BaseItem *, ValueItem *> *GetScalarValueMap()
{
return &id_value_map_;
}
ProtoItem *GetProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> &params)
{
return proto_map_.at(ProtoKey {ret_type, params});
}
std::unordered_map<Type::TypeId, PrimitiveTypeItem *> *GetPrimitiveTypeMap()
{
return &primitive_type_map_;
}
const std::list<std::unique_ptr<BaseItem>> &GetItems() const
{
return items_;
}
const std::vector<std::unique_ptr<BaseItem>> &GetForeignItems()
{
return foreign_items_;
}
BaseItem *GetEndItem()
{
return end_;
}
void ReorderItems(panda::panda_file::pgo::ProfileOptimizer *profile_opt);
void DeduplicateItems(bool compute_layout = true);
void DeduplicateCodeAndDebugInfo();
void DeduplicateAnnotations();
void DeduplicateLineNumberProgram(DebugInfoItem *item, ItemDeduper *deduper);
void DeduplicateDebugInfo(MethodItem *method, ItemDeduper *debug_info_deduper,
ItemDeduper *line_number_program_deduper);
private:
template <class T>
auto GetInsertPosition()
{
if (std::is_same_v<T, CodeItem>) {
return code_items_end_;
}
if (std::is_same_v<T, DebugInfoItem>) {
return debug_items_end_;
}
if (std::is_same_v<T, AnnotationItem> || std::is_base_of_v<ValueItem, T>) {
return annotation_items_end_;
}
return items_end_;
}
class IndexItem : public BaseItem {
public:
IndexItem(IndexType type, size_t max_index) : type_(type), max_index_(max_index)
{
ASSERT(type_ != IndexType::NONE);
}
~IndexItem() override = default;
DEFAULT_COPY_SEMANTIC(IndexItem);
NO_MOVE_SEMANTIC(IndexItem);
size_t Alignment() override
{
return sizeof(uint32_t);
}
bool Write(Writer *writer) override;
ItemTypes GetItemType() const override;
bool Add(IndexedItem *item);
bool Has(IndexedItem *item) const
{
auto res = index_.find(item);
return res != index_.cend();
}
void Remove(IndexedItem *item)
{
index_.erase(item);
}
size_t GetNumItems() const
{
return index_.size();
}
void UpdateItems(BaseItem *start, BaseItem *end)
{
size_t i = 0;
for (auto *item : index_) {
item->SetIndex(start, end, i++);
}
}
void Reset()
{
for (auto *item : index_) {
item->ClearIndexes();
}
}
protected:
size_t CalculateSize() const override
{
return index_.size() * ID_SIZE;
}
private:
struct Comparator {
bool operator()(IndexedItem *item1, IndexedItem *item2) const noexcept
{
auto index_type = item1->GetIndexType();
if (index_type == IndexType::CLASS) {
auto type_item1 = static_cast<TypeItem *>(item1);
auto type_item2 = static_cast<TypeItem *>(item2);
auto type_id1 = static_cast<size_t>(type_item1->GetType().GetId());
auto type_id2 = static_cast<size_t>(type_item2->GetType().GetId());
if (type_id1 != type_id2) {
return type_id1 < type_id2;
}
}
if (index_type == IndexType::LINE_NUMBER_PROG) {
auto ref_count1 = item1->GetRefCount();
auto ref_count2 = item2->GetRefCount();
if (ref_count1 != ref_count2) {
return ref_count1 > ref_count2;
}
}
return item1->GetItemAllocId() < item2->GetItemAllocId();
}
};
IndexType type_;
size_t max_index_;
std::set<IndexedItem *, Comparator> index_;
};
class LineNumberProgramIndexItem : public IndexItem {
public:
LineNumberProgramIndexItem() : IndexItem(IndexType::LINE_NUMBER_PROG, MAX_INDEX_32) {}
~LineNumberProgramIndexItem() override = default;
DEFAULT_COPY_SEMANTIC(LineNumberProgramIndexItem);
NO_MOVE_SEMANTIC(LineNumberProgramIndexItem);
void IncRefCount(LineNumberProgramItem *item)
{
ASSERT(item->GetRefCount() > 0);
ASSERT(Has(item));
Remove(item);
item->IncRefCount();
Add(item);
}
void DecRefCount(LineNumberProgramItem *item)
{
ASSERT(Has(item));
Remove(item);
item->DecRefCount();
if (item->GetRefCount() == 0) {
item->SetNeedsEmit(false);
} else {
Add(item);
}
}
};
class RegionHeaderItem : public BaseItem {
public:
explicit RegionHeaderItem(std::vector<IndexItem *> indexes) : indexes_(std::move(indexes))
{
ASSERT(indexes_.size() == INDEX_COUNT_16);
}
~RegionHeaderItem() override = default;
DEFAULT_COPY_SEMANTIC(RegionHeaderItem);
NO_MOVE_SEMANTIC(RegionHeaderItem);
size_t Alignment() override
{
return ID_SIZE;
}
bool Write(Writer *writer) override;
ItemTypes GetItemType() const override
{
return ItemTypes::REGION_HEADER;
}
bool Add(const std::list<IndexedItem *> &items);
void Remove(const std::list<IndexedItem *> &items);
void SetStart(BaseItem *item)
{
start_ = item;
}
void SetEnd(BaseItem *item)
{
end_ = item;
}
void UpdateItems()
{
for (auto *index : indexes_) {
index->UpdateItems(start_, end_);
}
}
protected:
size_t CalculateSize() const override
{
return sizeof(File::RegionHeader);
}
private:
IndexItem *GetIndexByType(IndexType type) const
{
auto i = static_cast<size_t>(type);
return indexes_[i];
}
BaseItem *start_ {nullptr};
BaseItem *end_ {nullptr};
std::vector<IndexItem *> indexes_;
};
class RegionSectionItem : public BaseItem {
public:
size_t Alignment() override
{
return ID_SIZE;
}
bool Write(Writer *writer) override;
ItemTypes GetItemType() const override
{
return ItemTypes::REGION_SECTION;
}
void Reset()
{
headers_.clear();
for (auto &index : indexes_) {
index.Reset();
}
indexes_.clear();
}
void AddHeader();
RegionHeaderItem *GetCurrentHeader()
{
return &headers_.back();
}
bool IsEmpty() const
{
return headers_.empty();
}
size_t GetNumHeaders() const
{
return headers_.size();
}
void ComputeLayout() override;
void UpdateItems()
{
for (auto &header : headers_) {
header.UpdateItems();
}
}
protected:
size_t CalculateSize() const override;
private:
std::list<RegionHeaderItem> headers_;
std::list<IndexItem> indexes_;
};
class ProtoKey {
public:
ProtoKey(TypeItem *ret_type, const std::vector<MethodParamItem> &params);
~ProtoKey() = default;
DEFAULT_COPY_SEMANTIC(ProtoKey);
NO_MOVE_SEMANTIC(ProtoKey);
size_t GetHash() const
{
return hash_;
}
bool operator==(const ProtoKey &key) const
{
return shorty_ == key.shorty_ && ref_types_ == key.ref_types_;
}
private:
void Add(TypeItem *item);
size_t hash_;
std::string shorty_;
std::vector<TypeItem *> ref_types_;
};
struct ProtoKeyHash {
size_t operator()(const ProtoKey &key) const noexcept
{
return key.GetHash();
};
};
struct LiteralArrayCompare {
bool operator()(const std::string &lhs, const std::string &rhs) const
{
return lhs.length() < rhs.length() || (lhs.length() == rhs.length() && lhs < rhs);
}
};
class EndItem : public BaseItem {
public:
EndItem()
{
SetNeedsEmit(false);
}
~EndItem() override = default;
DEFAULT_COPY_SEMANTIC(EndItem);
NO_MOVE_SEMANTIC(EndItem);
size_t CalculateSize() const override
{
return 0;
}
bool Write([[maybe_unused]] Writer *writer) override
{
return true;
}
ItemTypes GetItemType() const override
{
return ItemTypes::END_ITEM;
}
};
bool WriteHeader(Writer *writer, ssize_t *checksum_offset);
bool WriteHeaderIndexInfo(Writer *writer);
void RebuildRegionSection();
void RebuildLineNumberProgramIndex();
void UpdateOrderIndexes();
void UpdateLiteralIndexes();
void ProcessIndexDependecies(BaseItem *item);
size_t GetForeignOffset() const;
size_t GetForeignSize() const;
std::unordered_map<std::string, StringItem *> string_map_;
std::map<std::string, LiteralArrayItem *, LiteralArrayCompare> literalarray_map_;
std::map<std::string, BaseClassItem *> class_map_;
std::unordered_map<uint32_t, ValueItem *> int_value_map_;
std::unordered_map<uint64_t, ValueItem *> long_value_map_;
// NB! For f32 and f64 value maps we use integral keys
// (in fact, bit patterns of corresponding values) to
// workaround 0.0 == -0.0 semantics.
std::unordered_map<uint32_t, ValueItem *> float_value_map_;
std::unordered_map<uint64_t, ValueItem *> double_value_map_;
std::unordered_map<BaseItem *, ValueItem *> id_value_map_;
std::unordered_map<ProtoKey, ProtoItem *, ProtoKeyHash> proto_map_;
std::unordered_map<Type::TypeId, PrimitiveTypeItem *> primitive_type_map_;
std::list<std::unique_ptr<BaseItem>> items_;
std::vector<std::unique_ptr<BaseItem>> foreign_items_;
RegionSectionItem region_section_item_;
LineNumberProgramIndexItem line_number_program_index_item_;
std::list<std::unique_ptr<BaseItem>>::iterator items_end_;
std::list<std::unique_ptr<BaseItem>>::iterator annotation_items_end_;
std::list<std::unique_ptr<BaseItem>>::iterator code_items_end_;
std::list<std::unique_ptr<BaseItem>>::iterator debug_items_end_;
BaseItem *end_;
bool is_quickened_ = false;
};
} // namespace panda::panda_file
#endif // LIBPANDAFILE_FILE_ITEM_CONTAINER_H_
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/openharmony-sig/arkcompiler_runtime_core.git
git@gitee.com:openharmony-sig/arkcompiler_runtime_core.git
openharmony-sig
arkcompiler_runtime_core
arkcompiler_runtime_core
master

搜索帮助