[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/1298894 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#56974}
This commit is contained in:
parent
0e09760881
commit
125dfb2a4e
@ -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 {}
|
||||
|
Loading…
Reference in New Issue
Block a user