[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 v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory,
|
FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory)
|
||||||
Zone* zone)
|
: ast_value_factory_(ast_value_factory) {}
|
||||||
: ast_value_factory_(ast_value_factory),
|
|
||||||
entries_stack_(zone),
|
|
||||||
names_stack_(zone),
|
|
||||||
funcs_to_infer_(zone),
|
|
||||||
zone_(zone) {}
|
|
||||||
|
|
||||||
void FuncNameInferrer::PushEnclosingName(const AstRawString* name) {
|
void FuncNameInferrer::PushEnclosingName(const AstRawString* name) {
|
||||||
// Enclosing name is a name of a constructor function. To check
|
// 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() {
|
const AstConsString* FuncNameInferrer::MakeNameFromStack() {
|
||||||
|
if (names_stack_.size() == 0) {
|
||||||
|
return ast_value_factory_->empty_cons_string();
|
||||||
|
}
|
||||||
AstConsString* result = ast_value_factory_->NewConsString();
|
AstConsString* result = ast_value_factory_->NewConsString();
|
||||||
auto it = names_stack_.begin();
|
auto it = names_stack_.begin();
|
||||||
while (it != names_stack_.end()) {
|
while (it != names_stack_.end()) {
|
||||||
@ -70,10 +60,11 @@ const AstConsString* FuncNameInferrer::MakeNameFromStack() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Add name. Separate names with ".".
|
// Add name. Separate names with ".".
|
||||||
|
Zone* zone = ast_value_factory_->zone();
|
||||||
if (!result->IsEmpty()) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@ -83,7 +74,7 @@ void FuncNameInferrer::InferFunctionsNames() {
|
|||||||
for (FunctionLiteral* func : funcs_to_infer_) {
|
for (FunctionLiteral* func : funcs_to_infer_) {
|
||||||
func->set_raw_inferred_name(func_name);
|
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_
|
#ifndef V8_PARSING_FUNC_NAME_INFERRER_H_
|
||||||
#define 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/pointer-with-payload.h"
|
||||||
#include "src/zone/zone-chunk-list.h"
|
|
||||||
#include "src/zone/zone.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -34,25 +35,33 @@ struct PointerWithPayloadTraits<AstRawString> {
|
|||||||
// and during parsing of the RHS, a function literal can be collected. After
|
// 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
|
// parsing the RHS we can infer a name for function literals that do not have
|
||||||
// a name.
|
// a name.
|
||||||
class FuncNameInferrer : public ZoneObject {
|
class FuncNameInferrer {
|
||||||
public:
|
public:
|
||||||
FuncNameInferrer(AstValueFactory* ast_value_factory, Zone* zone);
|
explicit FuncNameInferrer(AstValueFactory* ast_value_factory);
|
||||||
|
|
||||||
// To enter function name inference state, put a FuncNameInferrer::State
|
// To enter function name inference state, put a FuncNameInferrer::State
|
||||||
// on the stack.
|
// on the stack.
|
||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
explicit State(FuncNameInferrer* fni) : fni_(fni) { fni_->Enter(); }
|
explicit State(FuncNameInferrer* fni)
|
||||||
~State() { fni_->Leave(); }
|
: fni_(fni), top_(fni->names_stack_.size()) {
|
||||||
|
++fni_->scope_depth_;
|
||||||
|
}
|
||||||
|
~State() {
|
||||||
|
DCHECK(fni_->IsOpen());
|
||||||
|
fni_->names_stack_.resize(top_);
|
||||||
|
--fni_->scope_depth_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FuncNameInferrer* fni_;
|
FuncNameInferrer* fni_;
|
||||||
|
size_t top_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(State);
|
DISALLOW_COPY_AND_ASSIGN(State);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns whether we have entered name collection 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.
|
// Pushes an enclosing the name of enclosing function onto names stack.
|
||||||
void PushEnclosingName(const AstRawString* name);
|
void PushEnclosingName(const AstRawString* name);
|
||||||
@ -70,9 +79,7 @@ class FuncNameInferrer : public ZoneObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RemoveLastFunction() {
|
void RemoveLastFunction() {
|
||||||
if (IsOpen() && !funcs_to_infer_.is_empty()) {
|
if (IsOpen() && !funcs_to_infer_.empty()) funcs_to_infer_.pop_back();
|
||||||
funcs_to_infer_.pop_back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveAsyncKeywordFromEnd();
|
void RemoveAsyncKeywordFromEnd();
|
||||||
@ -80,9 +87,7 @@ class FuncNameInferrer : public ZoneObject {
|
|||||||
// Infers a function name and leaves names collection state.
|
// Infers a function name and leaves names collection state.
|
||||||
void Infer() {
|
void Infer() {
|
||||||
DCHECK(IsOpen());
|
DCHECK(IsOpen());
|
||||||
if (!funcs_to_infer_.is_empty()) {
|
if (!funcs_to_infer_.empty()) InferFunctionsNames();
|
||||||
InferFunctionsNames();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -92,6 +97,8 @@ class FuncNameInferrer : public ZoneObject {
|
|||||||
kVariableName
|
kVariableName
|
||||||
};
|
};
|
||||||
struct Name {
|
struct Name {
|
||||||
|
// Needed for names_stack_.resize()
|
||||||
|
Name() { UNREACHABLE(); }
|
||||||
Name(const AstRawString* name, NameType type)
|
Name(const AstRawString* name, NameType type)
|
||||||
: name_and_type_(name, type) {}
|
: name_and_type_(name, type) {}
|
||||||
|
|
||||||
@ -102,12 +109,6 @@ class FuncNameInferrer : public ZoneObject {
|
|||||||
inline NameType type() const { return name_and_type_.GetPayload(); }
|
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.
|
// Constructs a full name in dotted notation from gathered names.
|
||||||
const AstConsString* MakeNameFromStack();
|
const AstConsString* MakeNameFromStack();
|
||||||
|
|
||||||
@ -115,10 +116,9 @@ class FuncNameInferrer : public ZoneObject {
|
|||||||
void InferFunctionsNames();
|
void InferFunctionsNames();
|
||||||
|
|
||||||
AstValueFactory* ast_value_factory_;
|
AstValueFactory* ast_value_factory_;
|
||||||
ZoneChunkList<size_t> entries_stack_;
|
std::vector<Name> names_stack_;
|
||||||
ZoneChunkList<Name> names_stack_;
|
std::vector<FunctionLiteral*> funcs_to_infer_;
|
||||||
ZoneChunkList<FunctionLiteral*> funcs_to_infer_;
|
size_t scope_depth_ = 0;
|
||||||
Zone* zone_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
|
DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
|
||||||
};
|
};
|
||||||
|
@ -236,7 +236,7 @@ class ParserBase {
|
|||||||
original_scope_(nullptr),
|
original_scope_(nullptr),
|
||||||
function_state_(nullptr),
|
function_state_(nullptr),
|
||||||
extension_(extension),
|
extension_(extension),
|
||||||
fni_(ast_value_factory, zone),
|
fni_(ast_value_factory),
|
||||||
ast_value_factory_(ast_value_factory),
|
ast_value_factory_(ast_value_factory),
|
||||||
ast_node_factory_(ast_value_factory, zone),
|
ast_node_factory_(ast_value_factory, zone),
|
||||||
runtime_call_stats_(runtime_call_stats),
|
runtime_call_stats_(runtime_call_stats),
|
||||||
|
@ -852,7 +852,7 @@ class PreParserTargetScope {
|
|||||||
|
|
||||||
class PreParserFuncNameInferrer {
|
class PreParserFuncNameInferrer {
|
||||||
public:
|
public:
|
||||||
PreParserFuncNameInferrer(AstValueFactory* avf, Zone* zone) {}
|
explicit PreParserFuncNameInferrer(AstValueFactory* avf) {}
|
||||||
void RemoveAsyncKeywordFromEnd() const {}
|
void RemoveAsyncKeywordFromEnd() const {}
|
||||||
void Infer() const {}
|
void Infer() const {}
|
||||||
void RemoveLastFunction() const {}
|
void RemoveLastFunction() const {}
|
||||||
|
Loading…
Reference in New Issue
Block a user