diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 696841c7b6690c9523e924f1eacafff0fc336eb3..9b4d36c5c1d22c6df0ee70fc38038a39ca707ba3 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -154,14 +154,28 @@ std::string AstNode::DumpDecl() const void AstNode::SetOriginalNode(AstNode *originalNode) noexcept { - if (OriginalNode() != originalNode) { - GetOrCreateHistoryNode()->originalNode_ = originalNode; + if (originalNode == nullptr) { + return; + } + GetHistoryNode()->AddModifier(ModifierFlags::HAS_ORIGINAL_NODE); + GetHistoryNode()->InitHistory(); + if (GetHistoryNode()->HistoryInitialized()) { + GetHistoryNode()->historyOrOriginal_.history->Set(originalNode, compiler::GetPhaseManager()->PreviousPhaseId()); + return; } + GetHistoryNode()->historyOrOriginal_.originalNode = originalNode; } AstNode *AstNode::OriginalNode() const noexcept { - return GetHistoryNode()->originalNode_; + if ((GetHistoryNode()->Modifiers() & ModifierFlags::HAS_ORIGINAL_NODE) == 0) { + return nullptr; + } + if (HistoryInitialized()) { + return GetHistoryNode()->historyOrOriginal_.history->Get( + GetHistoryNode()->historyOrOriginal_.history->FirstCreated()); + } + return GetHistoryNode()->historyOrOriginal_.originalNode; } void AstNode::SetTransformedNode([[maybe_unused]] std::string_view const transformationName, AstNode *transformedNode) @@ -229,9 +243,8 @@ void AstNode::CopyTo(AstNode *other) const other->range_ = range_; other->flags_ = flags_; other->astNodeFlags_ = astNodeFlags_; - other->history_ = history_; + other->historyOrOriginal_ = historyOrOriginal_; other->variable_ = variable_; - other->originalNode_ = originalNode_; } AstNode *AstNode::Construct([[maybe_unused]] ArenaAllocator *allocator) @@ -249,13 +262,14 @@ bool AstNode::IsValidInCurrentPhase() const compiler::PhaseId AstNode::GetFirstCreated() const { - return history_->FirstCreated(); + ES2PANDA_ASSERT(HistoryInitialized()); + return historyOrOriginal_.history->FirstCreated(); } AstNode *AstNode::GetFromExistingHistory() const { - ES2PANDA_ASSERT(HistoryInitialized()); - auto node = history_->Get(compiler::GetPhaseManager()->CurrentPhaseId()); + ES2PANDA_ASSERT((historyOrOriginal_.history != nullptr) && g_enableContextHistory); + auto node = historyOrOriginal_.history->Get(compiler::GetPhaseManager()->CurrentPhaseId()); if (UNLIKELY(node == nullptr)) { // the callee assumes the nullptr might be returned, but // the caller asserts it is not possible, so the explicit check is inserted @@ -268,13 +282,13 @@ AstNode *AstNode::GetOrCreateHistoryNode() const { AstNode *node = nullptr; - if (HistoryInitialized()) { - node = history_->At(compiler::GetPhaseManager()->CurrentPhaseId()); + if ((historyOrOriginal_.history != nullptr) && g_enableContextHistory) { + node = historyOrOriginal_.history->At(compiler::GetPhaseManager()->CurrentPhaseId()); if (node == nullptr) { - node = history_->Get(compiler::GetPhaseManager()->PreviousPhaseId()); + node = historyOrOriginal_.history->Get(compiler::GetPhaseManager()->PreviousPhaseId()); ES2PANDA_ASSERT(node != nullptr); node = node->ShallowClone(compiler::GetPhaseManager()->Allocator()); - history_->Set(node, compiler::GetPhaseManager()->CurrentPhaseId()); + historyOrOriginal_.history->Set(node, compiler::GetPhaseManager()->CurrentPhaseId()); } } else { node = const_cast(this); @@ -303,13 +317,8 @@ void AstNode::InitHistory() return; } - history_ = compiler::GetPhaseManager()->Allocator()->New( + historyOrOriginal_.history = compiler::GetPhaseManager()->Allocator()->New( this, compiler::GetPhaseManager()->CurrentPhaseId(), compiler::GetPhaseManager()->Allocator()); } -bool AstNode::HistoryInitialized() const -{ - return history_ != nullptr; -} - } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 3f5a8edd9a3f9e08266302b9827d362f1b13d625..07bf49e9cce4dc2a76eb634bc307b53f8ab03675 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -682,7 +682,7 @@ public: AstNode *GetHistoryNode() const { - if (UNLIKELY(history_ != nullptr)) { + if (UNLIKELY(historyOrOriginal_.history != nullptr) && g_enableContextHistory) { return GetFromExistingHistory(); } return const_cast(this); @@ -705,7 +705,10 @@ protected: } void InitHistory(); - bool HistoryInitialized() const; + inline bool HistoryInitialized() const noexcept + { + return (historyOrOriginal_.history != nullptr) && g_enableContextHistory; + } AstNode *GetFromExistingHistory() const; @@ -724,7 +727,10 @@ protected: friend class SizeOfNodeTest; // NOLINTBEGIN(misc-non-private-member-variables-in-classes) AstNode *parent_ {}; - AstNodeHistory *history_ {nullptr}; + union { + AstNodeHistory *history; + AstNode *originalNode; + } historyOrOriginal_ {nullptr}; lexer::CompressedSourceRange range_ {}; ModifierFlags flags_ {}; mutable AstNodeFlags astNodeFlags_ {}; @@ -736,7 +742,6 @@ private: AstNode &operator=(const AstNode &) = default; varbinder::Variable *variable_ {}; - AstNode *originalNode_ = nullptr; }; template diff --git a/ets2panda/ir/astNodeFlags.h b/ets2panda/ir/astNodeFlags.h index ea8783348a459dc4a81adc8a5e8cf43c9cd7bc04..987330ed899a58a4011868d72f8eaa32e9d12730 100644 --- a/ets2panda/ir/astNodeFlags.h +++ b/ets2panda/ir/astNodeFlags.h @@ -72,6 +72,7 @@ enum class ModifierFlags : uint32_t { ANNOTATION_USAGE = 1U << 28U, READONLY_PARAMETER = 1U << 29U, ARRAY_SETTER = 1U << 30U, + HAS_ORIGINAL_NODE = 1U << 31U, ACCESS = PUBLIC | PROTECTED | PRIVATE | INTERNAL, ALL = STATIC | ASYNC | ACCESS | DECLARE | READONLY | ABSTRACT, ALLOWED_IN_CTOR_PARAMETER = ACCESS | READONLY, diff --git a/ets2panda/ir/base/classDefinition.cpp b/ets2panda/ir/base/classDefinition.cpp index 5fe57979b3febc8c29b9a88686744169729a3a5f..7247e25180c980f049f8da8e59abbeb60a326bb0 100644 --- a/ets2panda/ir/base/classDefinition.cpp +++ b/ets2panda/ir/base/classDefinition.cpp @@ -471,7 +471,7 @@ ClassDefinition *ClassDefinition::Construct(ArenaAllocator *allocator) { ArenaVector body {allocator->Adapter()}; return allocator->New(allocator, nullptr, std::move(body), ClassDefinitionModifiers::NONE, - ModifierFlags::NONE, Language::Id::COUNT, history_); + ModifierFlags::NONE, Language::Id::COUNT, historyOrOriginal_.history); } void ClassDefinition::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/base/classDefinition.h b/ets2panda/ir/base/classDefinition.h index d1a6f415bbd0019cdd85d0163919c7b11460fb3c..8d69dd42a31d69994bec92c640c3ca13c4b56367 100644 --- a/ets2panda/ir/base/classDefinition.h +++ b/ets2panda/ir/base/classDefinition.h @@ -156,8 +156,8 @@ public: localPrefix_("$" + std::to_string(localIndex_)), exportedClasses_(body_.get_allocator()) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/base/classElement.h b/ets2panda/ir/base/classElement.h index 45101a888b954d2572312277fcc91a058e44d166..d87eb75e982919e34d8b555af6aa368e26da221c 100644 --- a/ets2panda/ir/base/classElement.h +++ b/ets2panda/ir/base/classElement.h @@ -51,8 +51,8 @@ public: decorators_(allocator->Adapter()), isComputed_(isComputed) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index af54efb58022800c1306774fb87f4d9ec2426714..8ccfe4b18e002d05309ffff0442489ed3125b2b3 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -79,8 +79,8 @@ public: baseOverloadMethod_(nullptr), asyncPairMethod_(nullptr) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index 71fe36ba69d9ead1439534435835a77178d1bcfd..aefee0c7a9f737e4e39015135b429c0caf39f845 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -150,8 +150,8 @@ ScriptFunction::ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&d if (auto *typeParams = irSignature_.TypeParams(); typeParams != nullptr) { typeParams->SetParent(this); } - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ets/etsModule.h b/ets2panda/ir/ets/etsModule.h index 8f2bb0ecd83ef700ef8d553809331e461decad78..1371772a662ec781104e8c344ed92b3d93f29046 100644 --- a/ets2panda/ir/ets/etsModule.h +++ b/ets2panda/ir/ets/etsModule.h @@ -66,8 +66,8 @@ public: program_(program) { type_ = AstNodeType::ETS_MODULE; - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 300573755bbaca5882dd11d55b2a13e4d9249b52..60ae8178aa87cd6f945e1e0d3a9c4caade5deba8 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -65,8 +65,8 @@ ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identO ES2PANDA_UNREACHABLE(); } - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } @@ -84,8 +84,8 @@ ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identO { SetInitializer(initializer); - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ets/etsStructDeclaration.h b/ets2panda/ir/ets/etsStructDeclaration.h index 1ee72040a3a7e34c29eff1cb38679020a8ecdefe..e20981ca64652871a519b36c1c433b07c96f1dd9 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.h +++ b/ets2panda/ir/ets/etsStructDeclaration.h @@ -36,8 +36,8 @@ public: explicit ETSStructDeclaration(ClassDefinition *const def, ArenaAllocator *const allocator, AstNodeHistory *history) : ClassDeclaration(AstNodeType::STRUCT_DECLARATION, def, allocator) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ets/etsTypeReference.h b/ets2panda/ir/ets/etsTypeReference.h index a69e3679fe4f8969e809befd9706345f0e86bd23..987243e818805ba7a69be89e4ab12ccc64e1a1ea 100644 --- a/ets2panda/ir/ets/etsTypeReference.h +++ b/ets2panda/ir/ets/etsTypeReference.h @@ -31,8 +31,8 @@ public: explicit ETSTypeReference(ir::ETSTypeReferencePart *part, ArenaAllocator *const allocator, AstNodeHistory *history) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE, allocator), part_(part) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index 40af6ab2b6e6690d97ee297a0d4452ca6e3f6c9b..1fde367810b62e42c7bd8bff0daf2612491f089f 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -38,8 +38,8 @@ public: explicit ETSTypeReferencePart(ir::Expression *name, ArenaAllocator *const allocator, AstNodeHistory *history) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } @@ -50,8 +50,8 @@ public: AstNodeHistory *history) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name), typeParams_(typeParams), prev_(prev) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/module/importDeclaration.h b/ets2panda/ir/module/importDeclaration.h index 2da6374989c9541c10731ccc600647b9fbf5dcf1..365c7d39f9388db4c5268434eb2bf54ee22c0ee4 100644 --- a/ets2panda/ir/module/importDeclaration.h +++ b/ets2panda/ir/module/importDeclaration.h @@ -47,8 +47,8 @@ public: specifiers_(std::move(specifiers)), importKinds_(importKinds) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/statements/classDeclaration.h b/ets2panda/ir/statements/classDeclaration.h index 5ea6d0e8d01f3ca3d9c240541138d807d62e1308..3a5480fdf5656aec37f13b32a152bee99b2be6f4 100644 --- a/ets2panda/ir/statements/classDeclaration.h +++ b/ets2panda/ir/statements/classDeclaration.h @@ -30,8 +30,8 @@ public: explicit ClassDeclaration(ClassDefinition *def, ArenaAllocator *allocator, AstNodeHistory *history) : Statement(AstNodeType::CLASS_DECLARATION), def_(def), decorators_(allocator->Adapter()) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/statements/functionDeclaration.h b/ets2panda/ir/statements/functionDeclaration.h index 25a69766e6442b306627baa746d5c9000a74a99d..cb95ab66438eb72b2e98064ff6bc0326265a3e68 100644 --- a/ets2panda/ir/statements/functionDeclaration.h +++ b/ets2panda/ir/statements/functionDeclaration.h @@ -61,8 +61,8 @@ public: func_(func), isAnonymous_(isAnonymous) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/statements/variableDeclaration.cpp b/ets2panda/ir/statements/variableDeclaration.cpp index adbe853c541c2bd7ec89bbdbb15de828f6b06f90..92403b608d2df90fde021c678899b1ee11a6217e 100644 --- a/ets2panda/ir/statements/variableDeclaration.cpp +++ b/ets2panda/ir/statements/variableDeclaration.cpp @@ -236,8 +236,8 @@ VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, Variabl declarators_.back()->SetParent(this); } - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/statements/variableDeclaration.h b/ets2panda/ir/statements/variableDeclaration.h index cb3703b27dfa0ba9f5f2b21f31870225c77e6ee4..3cd41fd38ed83e94290ac82aa60919048e00b4c1 100644 --- a/ets2panda/ir/statements/variableDeclaration.h +++ b/ets2panda/ir/statements/variableDeclaration.h @@ -50,8 +50,8 @@ public: decorators_(allocator->Adapter()), declarators_(std::move(declarators)) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index 87bb7c13fd632094d09a98eb9d4f1f3a6b2fc229..d71719558b958526d887b65062bf938881819eab 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -69,8 +69,8 @@ public: if (flags.isDeclare) { AddModifier(ModifierFlags::DECLARE); } - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.h b/ets2panda/ir/ts/tsInterfaceDeclaration.h index 64e6a30e70d85b726d640aee252c352144b97b3b..b92e29abaab209ea9e50598e3745bbb4c7510d36 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.h +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.h @@ -76,8 +76,8 @@ public: if (isStatic_) { AddModifier(ir::ModifierFlags::STATIC); } - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ts/tsTypeParameter.h b/ets2panda/ir/ts/tsTypeParameter.h index edb12492099ef658616d05ad3685bbb391414b55..a9a5693f68537bbdd75ca6898e29b52905a3bd18 100644 --- a/ets2panda/ir/ts/tsTypeParameter.h +++ b/ets2panda/ir/ts/tsTypeParameter.h @@ -54,8 +54,8 @@ public: defaultType_(defaultType) { ES2PANDA_ASSERT(flags == ModifierFlags::NONE || flags == ModifierFlags::IN || flags == ModifierFlags::OUT); - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } @@ -68,8 +68,8 @@ public: constraint_(constraint), defaultType_(defaultType) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.h b/ets2panda/ir/ts/tsTypeParameterDeclaration.h index 282d0a2f2e68e6810ced507af27f901994fdd516..5feba0d1b0e789d82c1cabd61ef4489027a929e7 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.h +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.h @@ -38,8 +38,8 @@ public: params_(std::move(params)), requiredParams_(requiredParams) { - if (history != nullptr) { - history_ = history; + if (HistoryInitialized()) { + historyOrOriginal_.history = history; } else { InitHistory(); } diff --git a/ets2panda/test/unit/sizeof_node_test.cpp b/ets2panda/test/unit/sizeof_node_test.cpp index 5f150147f1120426098672c1ee84daa396532c32..f0d3cc7b2bc6a95985935c9aeb9975db844046d7 100644 --- a/ets2panda/test/unit/sizeof_node_test.cpp +++ b/ets2panda/test/unit/sizeof_node_test.cpp @@ -68,9 +68,8 @@ size_t SizeOfNodeTest::SizeOf() sizeof(node->type_) + sizeof(node->flags_) + sizeof(node->astNodeFlags_) + - sizeof(node->history_) + - sizeof(node->variable_) + - sizeof(node->originalNode_)); + sizeof(node->historyOrOriginal_) + + sizeof(node->variable_)); // clang-format on }