mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibCpp: Don't store entire ASTNode vector in each parser state
We previously stored the entire ASTNode vector in each parser state, and this vector was copied whenever a state was loaded or saved. We don't actually need to store the whole nodes list in each state because a new state can only add new nodes to this list, and won't mutate existing nodes. It would suffice to only hold a vector of the nodes that were created while parsing in the current state to keep a reference to them. This reduces the time it takes on my machine for the c++ language server to handle a file that #includes <LibGUI/Widget.h> from ~4sec to ~0.7sec.
This commit is contained in:
parent
eb6a15d52b
commit
42eb06f045
Notes:
sideshowbarker
2024-07-18 09:06:45 +09:00
Author: https://github.com/itamar8910 Commit: https://github.com/SerenityOS/serenity/commit/42eb06f0459 Pull-request: https://github.com/SerenityOS/serenity/pull/8731
2 changed files with 17 additions and 16 deletions
|
@ -851,6 +851,7 @@ Optional<Token> Parser::peek(Token::Type type) const
|
|||
void Parser::save_state()
|
||||
{
|
||||
m_saved_states.append(m_state);
|
||||
m_state.state_nodes.clear();
|
||||
}
|
||||
|
||||
void Parser::load_state()
|
||||
|
@ -897,7 +898,7 @@ void Parser::error(StringView message)
|
|||
|
||||
if (!m_saved_states.is_empty())
|
||||
return;
|
||||
|
||||
|
||||
if (message.is_null() || message.is_empty())
|
||||
message = "<empty>";
|
||||
String formatted_message;
|
||||
|
@ -941,23 +942,19 @@ Position Parser::position() const
|
|||
return peek().start();
|
||||
}
|
||||
|
||||
RefPtr<ASTNode> Parser::eof_node() const
|
||||
{
|
||||
VERIFY(m_tokens.size());
|
||||
return node_at(m_tokens.last().end());
|
||||
}
|
||||
|
||||
RefPtr<ASTNode> Parser::node_at(Position pos) const
|
||||
{
|
||||
VERIFY(m_saved_states.is_empty());
|
||||
auto index = index_of_node_at(pos);
|
||||
if (!index.has_value())
|
||||
return nullptr;
|
||||
return m_state.nodes[index.value()];
|
||||
return m_nodes[index.value()];
|
||||
}
|
||||
|
||||
Optional<size_t> Parser::index_of_node_at(Position pos) const
|
||||
{
|
||||
VERIFY(!m_tokens.is_empty());
|
||||
VERIFY(m_saved_states.is_empty());
|
||||
Optional<size_t> match_node_index;
|
||||
|
||||
auto node_span = [](const ASTNode& node) {
|
||||
|
@ -966,12 +963,12 @@ Optional<size_t> Parser::index_of_node_at(Position pos) const
|
|||
return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column };
|
||||
};
|
||||
|
||||
for (size_t node_index = 0; node_index < m_state.nodes.size(); ++node_index) {
|
||||
auto& node = m_state.nodes[node_index];
|
||||
for (size_t node_index = 0; node_index < m_nodes.size(); ++node_index) {
|
||||
auto& node = m_nodes[node_index];
|
||||
if (node.start() > pos || node.end() < pos)
|
||||
continue;
|
||||
|
||||
if (!match_node_index.has_value() || (node_span(node) <= node_span(m_state.nodes[match_node_index.value()])))
|
||||
if (!match_node_index.has_value() || (node_span(node) <= node_span(m_nodes[match_node_index.value()])))
|
||||
match_node_index = node_index;
|
||||
}
|
||||
return match_node_index;
|
||||
|
|
|
@ -24,7 +24,6 @@ public:
|
|||
NonnullRefPtr<TranslationUnit> parse();
|
||||
bool eof() const;
|
||||
|
||||
RefPtr<ASTNode> eof_node() const;
|
||||
RefPtr<ASTNode> node_at(Position) const;
|
||||
Optional<size_t> index_of_node_at(Position) const;
|
||||
Optional<Token> token_at(Position) const;
|
||||
|
@ -147,7 +146,7 @@ private:
|
|||
|
||||
struct State {
|
||||
size_t token_index { 0 };
|
||||
NonnullRefPtrVector<ASTNode> nodes;
|
||||
NonnullRefPtrVector<ASTNode> state_nodes;
|
||||
};
|
||||
|
||||
void error(StringView message = {});
|
||||
|
@ -157,9 +156,13 @@ private:
|
|||
create_ast_node(ASTNode& parent, const Position& start, Optional<Position> end, Args&&... args)
|
||||
{
|
||||
auto node = adopt_ref(*new T(&parent, start, end, m_filename, forward<Args>(args)...));
|
||||
if (!parent.is_dummy_node()) {
|
||||
m_state.nodes.append(node);
|
||||
|
||||
if (m_saved_states.is_empty()) {
|
||||
m_nodes.append(node);
|
||||
} else {
|
||||
m_state.state_nodes.append(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -167,7 +170,7 @@ private:
|
|||
create_root_ast_node(const Position& start, Position end)
|
||||
{
|
||||
auto node = adopt_ref(*new TranslationUnit(nullptr, start, end, m_filename));
|
||||
m_state.nodes.append(node);
|
||||
m_nodes.append(node);
|
||||
m_root_node = node;
|
||||
return node;
|
||||
}
|
||||
|
@ -200,6 +203,7 @@ private:
|
|||
Vector<State> m_saved_states;
|
||||
RefPtr<TranslationUnit> m_root_node;
|
||||
Vector<String> m_errors;
|
||||
NonnullRefPtrVector<ASTNode> m_nodes;
|
||||
|
||||
Vector<TokenAndPreprocessorDefinition> m_replaced_preprocessor_tokens;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue