Commit 125dfb2a authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Use std::vector and cache top in State in FuncNameInferrer

It's unnecessary to buffer in the zone, and using a deque is more expensive
than an std::vector as a stack since we reuse areas very frequently. The
top-of-stack that the State keeps track of is now simply tracked in the state,
with a scope_depth_ counter to figure out if the fni_ is "open" (has an active
state).

Change-Id: I29ad3db7520340b8fe035feed400178bd50785bc
Reviewed-on: https://chromium-review.googlesource.com/c/1298894Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56974}
parent 0e097608
......@@ -11,13 +11,8 @@
namespace v8 {
namespace internal {
FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory,
Zone* zone)
: ast_value_factory_(ast_value_factory),
entries_stack_(zone),
names_stack_(zone),
funcs_to_infer_(zone),
zone_(zone) {}
FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory)
: ast_value_factory_(ast_value_factory) {}
void FuncNameInferrer::PushEnclosingName(const AstRawString* name) {
// Enclosing name is a name of a constructor function. To check
......@@ -50,15 +45,10 @@ void FuncNameInferrer::RemoveAsyncKeywordFromEnd() {
}
}
void FuncNameInferrer::Leave() {
DCHECK(IsOpen());
size_t last_entry = entries_stack_.back();
entries_stack_.pop_back();
names_stack_.Rewind(last_entry);
if (entries_stack_.is_empty()) funcs_to_infer_.Rewind();
}
const AstConsString* FuncNameInferrer::MakeNameFromStack() {
if (names_stack_.size() == 0) {
return ast_value_factory_->empty_cons_string();
}
AstConsString* result = ast_value_factory_->NewConsString();
auto it = names_stack_.begin();
while (it != names_stack_.end()) {
......@@ -70,10 +60,11 @@ const AstConsString* FuncNameInferrer::MakeNameFromStack() {
continue;
}
// Add name. Separate names with ".".
Zone* zone = ast_value_factory_->zone();
if (!result->IsEmpty()) {
result->AddString(zone(), ast_value_factory_->dot_string());
result->AddString(zone, ast_value_factory_->dot_string());
}
result->AddString(zone(), current->name());
result->AddString(zone, current->name());
}
return result;
}
......@@ -83,7 +74,7 @@ void FuncNameInferrer::InferFunctionsNames() {
for (FunctionLiteral* func : funcs_to_infer_) {
func->set_raw_inferred_name(func_name);
}
funcs_to_infer_.Rewind(0);
funcs_to_infer_.resize(0);
}
......
......@@ -5,9 +5,10 @@
#ifndef V8_PARSING_FUNC_NAME_INFERRER_H_
#define V8_PARSING_FUNC_NAME_INFERRER_H_
#include <vector>
#include "src/base/macros.h"
#include "src/pointer-with-payload.h"
#include "src/zone/zone-chunk-list.h"
#include "src/zone/zone.h"
namespace v8 {
namespace internal {
......@@ -34,25 +35,33 @@ struct PointerWithPayloadTraits<AstRawString> {
// and during parsing of the RHS, a function literal can be collected. After
// parsing the RHS we can infer a name for function literals that do not have
// a name.
class FuncNameInferrer : public ZoneObject {
class FuncNameInferrer {
public:
FuncNameInferrer(AstValueFactory* ast_value_factory, Zone* zone);
explicit FuncNameInferrer(AstValueFactory* ast_value_factory);
// To enter function name inference state, put a FuncNameInferrer::State
// on the stack.
class State {
public:
explicit State(FuncNameInferrer* fni) : fni_(fni) { fni_->Enter(); }
~State() { fni_->Leave(); }
explicit State(FuncNameInferrer* fni)
: fni_(fni), top_(fni->names_stack_.size()) {
++fni_->scope_depth_;
}
~State() {
DCHECK(fni_->IsOpen());
fni_->names_stack_.resize(top_);
--fni_->scope_depth_;
}
private:
FuncNameInferrer* fni_;
size_t top_;
DISALLOW_COPY_AND_ASSIGN(State);
};
// Returns whether we have entered name collection state.
bool IsOpen() const { return !entries_stack_.is_empty(); }
bool IsOpen() const { return scope_depth_ > 0; }
// Pushes an enclosing the name of enclosing function onto names stack.
void PushEnclosingName(const AstRawString* name);
......@@ -70,9 +79,7 @@ class FuncNameInferrer : public ZoneObject {
}
void RemoveLastFunction() {
if (IsOpen() && !funcs_to_infer_.is_empty()) {
funcs_to_infer_.pop_back();
}
if (IsOpen() && !funcs_to_infer_.empty()) funcs_to_infer_.pop_back();
}
void RemoveAsyncKeywordFromEnd();
......@@ -80,9 +87,7 @@ class FuncNameInferrer : public ZoneObject {
// Infers a function name and leaves names collection state.
void Infer() {
DCHECK(IsOpen());
if (!funcs_to_infer_.is_empty()) {
InferFunctionsNames();
}
if (!funcs_to_infer_.empty()) InferFunctionsNames();
}
private:
......@@ -92,6 +97,8 @@ class FuncNameInferrer : public ZoneObject {
kVariableName
};
struct Name {
// Needed for names_stack_.resize()
Name() { UNREACHABLE(); }
Name(const AstRawString* name, NameType type)
: name_and_type_(name, type) {}
......@@ -102,12 +109,6 @@ class FuncNameInferrer : public ZoneObject {
inline NameType type() const { return name_and_type_.GetPayload(); }
};
void Enter() { entries_stack_.push_back(names_stack_.size()); }
void Leave();
Zone* zone() const { return zone_; }
// Constructs a full name in dotted notation from gathered names.
const AstConsString* MakeNameFromStack();
......@@ -115,10 +116,9 @@ class FuncNameInferrer : public ZoneObject {
void InferFunctionsNames();
AstValueFactory* ast_value_factory_;
ZoneChunkList<size_t> entries_stack_;
ZoneChunkList<Name> names_stack_;
ZoneChunkList<FunctionLiteral*> funcs_to_infer_;
Zone* zone_;
std::vector<Name> names_stack_;
std::vector<FunctionLiteral*> funcs_to_infer_;
size_t scope_depth_ = 0;
DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
};
......
......@@ -236,7 +236,7 @@ class ParserBase {
original_scope_(nullptr),
function_state_(nullptr),
extension_(extension),
fni_(ast_value_factory, zone),
fni_(ast_value_factory),
ast_value_factory_(ast_value_factory),
ast_node_factory_(ast_value_factory, zone),
runtime_call_stats_(runtime_call_stats),
......
......@@ -852,7 +852,7 @@ class PreParserTargetScope {
class PreParserFuncNameInferrer {
public:
PreParserFuncNameInferrer(AstValueFactory* avf, Zone* zone) {}
explicit PreParserFuncNameInferrer(AstValueFactory* avf) {}
void RemoveAsyncKeywordFromEnd() const {}
void Infer() const {}
void RemoveLastFunction() const {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment