From df3eb0a366c7846910907d6640225a2e3316b7ba Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Fri, 12 Aug 2022 15:20:44 +0300 Subject: [PATCH] [Runtime] Optimize usage of the internal allocator inside class linker Change-Id: I149f6a6cc0c09c499fdfa50dbbe9a3e461ca8c21 Signed-off-by: Aleksandr Emelenko --- runtime/class_linker.cpp | 52 ++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/runtime/class_linker.cpp b/runtime/class_linker.cpp index 0194f2e77..b02150766 100644 --- a/runtime/class_linker.cpp +++ b/runtime/class_linker.cpp @@ -494,10 +494,19 @@ bool ClassLinker::LoadFields(Class *klass, panda_file::ClassDataAccessor *data_a } template -static void LayoutFieldsWithoutAlignment(size_t size, size_t *offset, size_t *space, PandaList *fields) +static void LayoutFieldsWithoutAlignment(size_t size, size_t *offset, size_t *space, PandaVector *fields) { - while ((space == nullptr || *space >= size) && !fields->empty()) { - Field *field = fields->front(); + auto last_proceeded_element = fields->end(); + // Iterating from beginning to end and erasing elements from the beginning of a vector + // is required for correct field layout between language class representation in C++ code + // and generated by methods in class linker. + // (e.g. class String should have length field before hash field, not vice versa) + for (auto i = fields->begin(); i != fields->end(); i++) { + if (!(space == nullptr || *space >= size)) { + last_proceeded_element = i; + break; + } + Field *field = *i; // NOLINTNEXTLINE(readability-braces-around-statements) if constexpr (reverse_layout) { *offset -= size; @@ -510,11 +519,11 @@ static void LayoutFieldsWithoutAlignment(size_t size, size_t *offset, size_t *sp if (space != nullptr) { *space -= size; } - fields->pop_front(); } + fields->erase(fields->begin(), last_proceeded_element); } -static uint32_t LayoutReferenceFields(size_t size, size_t *offset, const PandaList &fields) +static uint32_t LayoutReferenceFields(size_t size, size_t *offset, const PandaVector &fields) { uint32_t volatile_fields_num = 0; // layout volatile fields firstly @@ -534,10 +543,10 @@ static uint32_t LayoutReferenceFields(size_t size, size_t *offset, const PandaLi return volatile_fields_num; } -static size_t LayoutFieldsInBaseClassPadding(Class *klass, PandaList *tagged_fields, - PandaList *fields64, PandaList *fields32, - PandaList *fields16, PandaList *fields8, - PandaList *ref_fields, bool is_static) +static size_t LayoutFieldsInBaseClassPadding(Class *klass, PandaVector *tagged_fields, + PandaVector *fields64, PandaVector *fields32, + PandaVector *fields16, PandaVector *fields8, + PandaVector *ref_fields, bool is_static) { constexpr size_t SIZE_64 = sizeof(uint64_t); constexpr size_t SIZE_32 = sizeof(uint32_t); @@ -573,9 +582,9 @@ static size_t LayoutFieldsInBaseClassPadding(Class *klass, PandaList *t return align_offset; } -static size_t LayoutFields(Class *klass, PandaList *tagged_fields, PandaList *fields64, - PandaList *fields32, PandaList *fields16, PandaList *fields8, - PandaList *ref_fields, bool is_static) +static size_t LayoutFields(Class *klass, PandaVector *tagged_fields, PandaVector *fields64, + PandaVector *fields32, PandaVector *fields16, + PandaVector *fields8, PandaVector *ref_fields, bool is_static) { constexpr size_t SIZE_64 = sizeof(uint64_t); constexpr size_t SIZE_32 = sizeof(uint32_t); @@ -637,12 +646,19 @@ static size_t LayoutFields(Class *klass, PandaList *tagged_fields, Pand bool ClassLinker::LayoutFields(Class *klass, Span fields, bool is_static, [[maybe_unused]] ClassLinkerErrorHandler *error_handler) { - PandaList tagged_fields; - PandaList fields64; - PandaList fields32; - PandaList fields16; - PandaList fields8; - PandaList ref_fields; + // These containers must be optimized + PandaVector tagged_fields; + PandaVector fields64; + PandaVector fields32; + PandaVector fields16; + PandaVector fields8; + PandaVector ref_fields; + tagged_fields.reserve(fields.size()); + fields64.reserve(fields.size()); + fields32.reserve(fields.size()); + fields16.reserve(fields.size()); + fields8.reserve(fields.size()); + ref_fields.reserve(fields.size()); for (auto &field : fields) { auto type = field.GetType(); -- Gitee