Commit 83dee31e authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Parser] Split building logic out of ProducedPreParserScopeData.

Splits PreParsedScopeDataBuilder out of ProducedPreParserScopeData to make the split between
building PreParsedScopeData and using already build PreParserScopeData more explicit.

BUG=v8:8041

Change-Id: Iab42cab84c247152c14ac39f3136f985753160ec
Reviewed-on: https://chromium-review.googlesource.com/1202104
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55718}
parent ce589362
...@@ -319,7 +319,7 @@ void DeclarationScope::SetDefaults() { ...@@ -319,7 +319,7 @@ void DeclarationScope::SetDefaults() {
should_eager_compile_ = false; should_eager_compile_ = false;
was_lazily_parsed_ = false; was_lazily_parsed_ = false;
is_skipped_function_ = false; is_skipped_function_ = false;
produced_preparsed_scope_data_ = nullptr; preparsed_scope_data_builder_ = nullptr;
#ifdef DEBUG #ifdef DEBUG
DeclarationScope* outer_declaration_scope = DeclarationScope* outer_declaration_scope =
outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr; outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
...@@ -1532,7 +1532,7 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, ...@@ -1532,7 +1532,7 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
void Scope::SavePreParsedScopeData() { void Scope::SavePreParsedScopeData() {
DCHECK(FLAG_preparser_scope_analysis); DCHECK(FLAG_preparser_scope_analysis);
if (ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(this)) { if (PreParsedScopeDataBuilder::ScopeIsSkippableFunctionScope(this)) {
AsDeclarationScope()->SavePreParsedScopeDataForDeclarationScope(); AsDeclarationScope()->SavePreParsedScopeDataForDeclarationScope();
} }
...@@ -1542,9 +1542,9 @@ void Scope::SavePreParsedScopeData() { ...@@ -1542,9 +1542,9 @@ void Scope::SavePreParsedScopeData() {
} }
void DeclarationScope::SavePreParsedScopeDataForDeclarationScope() { void DeclarationScope::SavePreParsedScopeDataForDeclarationScope() {
if (produced_preparsed_scope_data_ != nullptr) { if (preparsed_scope_data_builder_ != nullptr) {
DCHECK(FLAG_preparser_scope_analysis); DCHECK(FLAG_preparser_scope_analysis);
produced_preparsed_scope_data_->SaveScopeAllocationData(this); preparsed_scope_data_builder_->SaveScopeAllocationData(this);
} }
} }
...@@ -1554,8 +1554,8 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { ...@@ -1554,8 +1554,8 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
if (!outer_scope_->is_script_scope() || if (!outer_scope_->is_script_scope() ||
(FLAG_preparser_scope_analysis && (FLAG_preparser_scope_analysis &&
produced_preparsed_scope_data_ != nullptr && preparsed_scope_data_builder_ != nullptr &&
produced_preparsed_scope_data_->ContainsInnerFunctions())) { preparsed_scope_data_builder_->ContainsInnerFunctions())) {
// Try to resolve unresolved variables for this Scope and migrate those // Try to resolve unresolved variables for this Scope and migrate those
// which cannot be resolved inside. It doesn't make sense to try to resolve // which cannot be resolved inside. It doesn't make sense to try to resolve
// them in the outer Scopes here, because they are incomplete. // them in the outer Scopes here, because they are incomplete.
......
...@@ -20,8 +20,7 @@ class AstValueFactory; ...@@ -20,8 +20,7 @@ class AstValueFactory;
class AstRawString; class AstRawString;
class Declaration; class Declaration;
class ParseInfo; class ParseInfo;
class PreParsedScopeData; class PreParsedScopeDataBuilder;
class ProducedPreParsedScopeData;
class SloppyBlockFunctionStatement; class SloppyBlockFunctionStatement;
class Statement; class Statement;
class StringSet; class StringSet;
...@@ -919,13 +918,13 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { ...@@ -919,13 +918,13 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// saved in produced_preparsed_scope_data_. // saved in produced_preparsed_scope_data_.
void SavePreParsedScopeDataForDeclarationScope(); void SavePreParsedScopeDataForDeclarationScope();
void set_produced_preparsed_scope_data( void set_preparsed_scope_data_builder(
ProducedPreParsedScopeData* produced_preparsed_scope_data) { PreParsedScopeDataBuilder* preparsed_scope_data_builder) {
produced_preparsed_scope_data_ = produced_preparsed_scope_data; preparsed_scope_data_builder_ = preparsed_scope_data_builder;
} }
ProducedPreParsedScopeData* produced_preparsed_scope_data() const { PreParsedScopeDataBuilder* preparsed_scope_data_builder() const {
return produced_preparsed_scope_data_; return preparsed_scope_data_builder_;
} }
private: private:
...@@ -981,7 +980,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { ...@@ -981,7 +980,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
Variable* arguments_; Variable* arguments_;
// For producing the scope allocation data during preparsing. // For producing the scope allocation data during preparsing.
ProducedPreParsedScopeData* produced_preparsed_scope_data_; PreParsedScopeDataBuilder* preparsed_scope_data_builder_;
struct RareData : public ZoneObject { struct RareData : public ZoneObject {
// Convenience variable; Subclass constructor only // Convenience variable; Subclass constructor only
......
...@@ -33,7 +33,7 @@ struct PreParsedScopeByteDataConstants { ...@@ -33,7 +33,7 @@ struct PreParsedScopeByteDataConstants {
4 * kUint32Size + 1 * kUint8Size; 4 * kUint32Size + 1 * kUint8Size;
}; };
class ProducedPreParsedScopeData::ByteData class PreParsedScopeDataBuilder::ByteData
: public ZoneObject, : public ZoneObject,
public PreParsedScopeByteDataConstants { public PreParsedScopeByteDataConstants {
public: public:
......
...@@ -35,7 +35,7 @@ STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues); ...@@ -35,7 +35,7 @@ STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
/* /*
Internal data format for the backing store of ProducedPreparsedScopeData and Internal data format for the backing store of PreParsedScopeDataBuilder and
PreParsedScopeData::scope_data (on the heap): PreParsedScopeData::scope_data (on the heap):
(Skippable function data:) (Skippable function data:)
...@@ -78,7 +78,7 @@ STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues); ...@@ -78,7 +78,7 @@ STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
*/ */
void ProducedPreParsedScopeData::ByteData::WriteUint32(uint32_t data) { void PreParsedScopeDataBuilder::ByteData::WriteUint32(uint32_t data) {
#ifdef DEBUG #ifdef DEBUG
// Save expected item size in debug mode. // Save expected item size in debug mode.
backing_store_.push_back(kUint32Size); backing_store_.push_back(kUint32Size);
...@@ -91,7 +91,7 @@ void ProducedPreParsedScopeData::ByteData::WriteUint32(uint32_t data) { ...@@ -91,7 +91,7 @@ void ProducedPreParsedScopeData::ByteData::WriteUint32(uint32_t data) {
} }
#ifdef DEBUG #ifdef DEBUG
void ProducedPreParsedScopeData::ByteData::OverwriteFirstUint32(uint32_t data) { void PreParsedScopeDataBuilder::ByteData::OverwriteFirstUint32(uint32_t data) {
auto it = backing_store_.begin(); auto it = backing_store_.begin();
// Check that that position already holds an item of the expected size. // Check that that position already holds an item of the expected size.
DCHECK_GE(backing_store_.size(), kUint32Size); DCHECK_GE(backing_store_.size(), kUint32Size);
...@@ -104,7 +104,7 @@ void ProducedPreParsedScopeData::ByteData::OverwriteFirstUint32(uint32_t data) { ...@@ -104,7 +104,7 @@ void ProducedPreParsedScopeData::ByteData::OverwriteFirstUint32(uint32_t data) {
} }
#endif #endif
void ProducedPreParsedScopeData::ByteData::WriteUint8(uint8_t data) { void PreParsedScopeDataBuilder::ByteData::WriteUint8(uint8_t data) {
#ifdef DEBUG #ifdef DEBUG
// Save expected item size in debug mode. // Save expected item size in debug mode.
backing_store_.push_back(kUint8Size); backing_store_.push_back(kUint8Size);
...@@ -113,7 +113,7 @@ void ProducedPreParsedScopeData::ByteData::WriteUint8(uint8_t data) { ...@@ -113,7 +113,7 @@ void ProducedPreParsedScopeData::ByteData::WriteUint8(uint8_t data) {
free_quarters_in_last_byte_ = 0; free_quarters_in_last_byte_ = 0;
} }
void ProducedPreParsedScopeData::ByteData::WriteQuarter(uint8_t data) { void PreParsedScopeDataBuilder::ByteData::WriteQuarter(uint8_t data) {
DCHECK_LE(data, 3); DCHECK_LE(data, 3);
if (free_quarters_in_last_byte_ == 0) { if (free_quarters_in_last_byte_ == 0) {
#ifdef DEBUG #ifdef DEBUG
...@@ -131,7 +131,7 @@ void ProducedPreParsedScopeData::ByteData::WriteQuarter(uint8_t data) { ...@@ -131,7 +131,7 @@ void ProducedPreParsedScopeData::ByteData::WriteQuarter(uint8_t data) {
backing_store_.back() |= (data << shift_amount); backing_store_.back() |= (data << shift_amount);
} }
Handle<PodArray<uint8_t>> ProducedPreParsedScopeData::ByteData::Serialize( Handle<PodArray<uint8_t>> PreParsedScopeDataBuilder::ByteData::Serialize(
Isolate* isolate) { Isolate* isolate) {
Handle<PodArray<uint8_t>> array = PodArray<uint8_t>::New( Handle<PodArray<uint8_t>> array = PodArray<uint8_t>::New(
isolate, static_cast<int>(backing_store_.size()), TENURED); isolate, static_cast<int>(backing_store_.size()), TENURED);
...@@ -146,13 +146,13 @@ Handle<PodArray<uint8_t>> ProducedPreParsedScopeData::ByteData::Serialize( ...@@ -146,13 +146,13 @@ Handle<PodArray<uint8_t>> ProducedPreParsedScopeData::ByteData::Serialize(
return array; return array;
} }
ProducedPreParsedScopeData::ProducedPreParsedScopeData( PreParsedScopeDataBuilder::PreParsedScopeDataBuilder(
Zone* zone, ProducedPreParsedScopeData* parent) Zone* zone, PreParsedScopeDataBuilder* parent)
: parent_(parent), : parent_(parent),
byte_data_(new (zone) ByteData(zone)), byte_data_(new (zone) ByteData(zone)),
data_for_inner_functions_(zone), data_for_inner_functions_(zone),
bailed_out_(false), bailed_out_(false) {
previously_produced_zone_preparsed_scope_data_(nullptr) { DCHECK(FLAG_preparser_scope_analysis);
if (parent != nullptr) { if (parent != nullptr) {
parent->data_for_inner_functions_.push_back(this); parent->data_for_inner_functions_.push_back(this);
} }
...@@ -162,71 +162,43 @@ ProducedPreParsedScopeData::ProducedPreParsedScopeData( ...@@ -162,71 +162,43 @@ ProducedPreParsedScopeData::ProducedPreParsedScopeData(
#endif #endif
} }
// Create a ProducedPreParsedScopeData which is just a proxy for a previous PreParsedScopeDataBuilder::DataGatheringScope::DataGatheringScope(
// produced PreParsedScopeData.
ProducedPreParsedScopeData::ProducedPreParsedScopeData(
Handle<PreParsedScopeData> data, Zone* zone)
: parent_(nullptr),
byte_data_(nullptr),
data_for_inner_functions_(zone),
bailed_out_(false),
previously_produced_on_heap_preparsed_scope_data_(data),
previously_produced_zone_preparsed_scope_data_(nullptr) {}
// Create a ProducedPreParsedScopeData which is just a proxy for a previous
// produced PreParsedScopeData.
ProducedPreParsedScopeData::ProducedPreParsedScopeData(
ZonePreParsedScopeData* data, Zone* zone)
: parent_(nullptr),
byte_data_(nullptr),
data_for_inner_functions_(zone),
bailed_out_(false),
previously_produced_zone_preparsed_scope_data_(data) {}
ProducedPreParsedScopeData::DataGatheringScope::DataGatheringScope(
DeclarationScope* function_scope, PreParser* preparser) DeclarationScope* function_scope, PreParser* preparser)
: function_scope_(function_scope), : function_scope_(function_scope),
preparser_(preparser), preparser_(preparser),
produced_preparsed_scope_data_(nullptr) { builder_(nullptr) {
if (FLAG_preparser_scope_analysis) { if (FLAG_preparser_scope_analysis) {
ProducedPreParsedScopeData* parent = PreParsedScopeDataBuilder* parent =
preparser->produced_preparsed_scope_data(); preparser->preparsed_scope_data_builder();
Zone* main_zone = preparser->main_zone(); Zone* main_zone = preparser->main_zone();
produced_preparsed_scope_data_ = builder_ = new (main_zone) PreParsedScopeDataBuilder(main_zone, parent);
new (main_zone) ProducedPreParsedScopeData(main_zone, parent); preparser->set_preparsed_scope_data_builder(builder_);
preparser->set_produced_preparsed_scope_data( function_scope->set_preparsed_scope_data_builder(builder_);
produced_preparsed_scope_data_);
function_scope->set_produced_preparsed_scope_data(
produced_preparsed_scope_data_);
} }
} }
ProducedPreParsedScopeData::DataGatheringScope::~DataGatheringScope() { PreParsedScopeDataBuilder::DataGatheringScope::~DataGatheringScope() {
if (FLAG_preparser_scope_analysis) { if (builder_) {
preparser_->set_produced_preparsed_scope_data( preparser_->set_preparsed_scope_data_builder(builder_->parent_);
produced_preparsed_scope_data_->parent_);
} }
} }
void ProducedPreParsedScopeData::DataGatheringScope::MarkFunctionAsSkippable( void PreParsedScopeDataBuilder::DataGatheringScope::MarkFunctionAsSkippable(
int end_position, int num_inner_functions) { int end_position, int num_inner_functions) {
DCHECK(FLAG_preparser_scope_analysis); DCHECK_NOT_NULL(builder_);
DCHECK_NOT_NULL(produced_preparsed_scope_data_); DCHECK_NOT_NULL(builder_->parent_);
DCHECK_NOT_NULL(produced_preparsed_scope_data_->parent_); builder_->parent_->AddSkippableFunction(
produced_preparsed_scope_data_->parent_->AddSkippableFunction(
function_scope_->start_position(), end_position, function_scope_->start_position(), end_position,
function_scope_->num_parameters(), num_inner_functions, function_scope_->num_parameters(), num_inner_functions,
function_scope_->language_mode(), function_scope_->NeedsHomeObject()); function_scope_->language_mode(), function_scope_->NeedsHomeObject());
} }
void ProducedPreParsedScopeData::AddSkippableFunction( void PreParsedScopeDataBuilder::AddSkippableFunction(int start_position,
int start_position, int end_position, int num_parameters, int end_position,
int num_inner_functions, LanguageMode language_mode, int num_parameters,
int num_inner_functions,
LanguageMode language_mode,
bool uses_super_property) { bool uses_super_property) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK(previously_produced_on_heap_preparsed_scope_data_.is_null());
DCHECK_NULL(previously_produced_zone_preparsed_scope_data_);
if (bailed_out_) { if (bailed_out_) {
return; return;
} }
...@@ -245,11 +217,8 @@ void ProducedPreParsedScopeData::AddSkippableFunction( ...@@ -245,11 +217,8 @@ void ProducedPreParsedScopeData::AddSkippableFunction(
byte_data_->WriteQuarter(language_and_super); byte_data_->WriteQuarter(language_and_super);
} }
void ProducedPreParsedScopeData::SaveScopeAllocationData( void PreParsedScopeDataBuilder::SaveScopeAllocationData(
DeclarationScope* scope) { DeclarationScope* scope) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK(previously_produced_on_heap_preparsed_scope_data_.is_null());
DCHECK_NULL(previously_produced_zone_preparsed_scope_data_);
// The data contains a uint32 (reserved space for scope_data_start) and // The data contains a uint32 (reserved space for scope_data_start) and
// function data items, kSkippableFunctionDataSize each. // function data items, kSkippableFunctionDataSize each.
DCHECK_GE(byte_data_->size(), ByteData::kPlaceholderSize); DCHECK_GE(byte_data_->size(), ByteData::kPlaceholderSize);
...@@ -281,24 +250,12 @@ void ProducedPreParsedScopeData::SaveScopeAllocationData( ...@@ -281,24 +250,12 @@ void ProducedPreParsedScopeData::SaveScopeAllocationData(
SaveDataForScope(scope); SaveDataForScope(scope);
} }
bool ProducedPreParsedScopeData::ContainsInnerFunctions() const { bool PreParsedScopeDataBuilder::ContainsInnerFunctions() const {
return byte_data_->size() > ByteData::kPlaceholderSize; return byte_data_->size() > ByteData::kPlaceholderSize;
} }
MaybeHandle<PreParsedScopeData> ProducedPreParsedScopeData::Serialize( MaybeHandle<PreParsedScopeData> PreParsedScopeDataBuilder::Serialize(
Isolate* isolate) { Isolate* isolate) {
if (!previously_produced_on_heap_preparsed_scope_data_.is_null()) {
DCHECK(!bailed_out_);
DCHECK_EQ(data_for_inner_functions_.size(), 0);
return previously_produced_on_heap_preparsed_scope_data_;
} else if (previously_produced_zone_preparsed_scope_data_ != nullptr) {
DCHECK(!bailed_out_);
DCHECK_EQ(data_for_inner_functions_.size(), 0);
previously_produced_on_heap_preparsed_scope_data_ =
previously_produced_zone_preparsed_scope_data_->Serialize(isolate);
return previously_produced_on_heap_preparsed_scope_data_;
}
if (bailed_out_) { if (bailed_out_) {
return MaybeHandle<PreParsedScopeData>(); return MaybeHandle<PreParsedScopeData>();
} }
...@@ -331,15 +288,7 @@ MaybeHandle<PreParsedScopeData> ProducedPreParsedScopeData::Serialize( ...@@ -331,15 +288,7 @@ MaybeHandle<PreParsedScopeData> ProducedPreParsedScopeData::Serialize(
return data; return data;
} }
ZonePreParsedScopeData* ProducedPreParsedScopeData::Serialize(Zone* zone) { ZonePreParsedScopeData* PreParsedScopeDataBuilder::Serialize(Zone* zone) {
DCHECK(previously_produced_on_heap_preparsed_scope_data_.is_null());
if (previously_produced_zone_preparsed_scope_data_ != nullptr) {
DCHECK(!bailed_out_);
DCHECK_EQ(data_for_inner_functions_.size(), 0);
return previously_produced_zone_preparsed_scope_data_;
}
if (bailed_out_) { if (bailed_out_) {
return nullptr; return nullptr;
} }
...@@ -365,7 +314,7 @@ ZonePreParsedScopeData* ProducedPreParsedScopeData::Serialize(Zone* zone) { ...@@ -365,7 +314,7 @@ ZonePreParsedScopeData* ProducedPreParsedScopeData::Serialize(Zone* zone) {
return result; return result;
} }
bool ProducedPreParsedScopeData::ScopeNeedsData(Scope* scope) { bool PreParsedScopeDataBuilder::ScopeNeedsData(Scope* scope) {
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) { if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
// Default constructors don't need data (they cannot contain inner functions // Default constructors don't need data (they cannot contain inner functions
// defined by the user). Other functions do. // defined by the user). Other functions do.
...@@ -387,9 +336,9 @@ bool ProducedPreParsedScopeData::ScopeNeedsData(Scope* scope) { ...@@ -387,9 +336,9 @@ bool ProducedPreParsedScopeData::ScopeNeedsData(Scope* scope) {
return false; return false;
} }
bool ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(Scope* scope) { bool PreParsedScopeDataBuilder::ScopeIsSkippableFunctionScope(Scope* scope) {
// Lazy non-arrow function scopes are skippable. Lazy functions are exactly // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
// those Scopes which have their own ProducedPreParsedScopeData object. This // those Scopes which have their own PreParsedScopeDataBuilder object. This
// logic ensures that the scope allocation data is consistent with the // logic ensures that the scope allocation data is consistent with the
// skippable function data (both agree on where the lazy function boundaries // skippable function data (both agree on where the lazy function boundaries
// are). // are).
...@@ -398,10 +347,10 @@ bool ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(Scope* scope) { ...@@ -398,10 +347,10 @@ bool ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(Scope* scope) {
} }
DeclarationScope* declaration_scope = scope->AsDeclarationScope(); DeclarationScope* declaration_scope = scope->AsDeclarationScope();
return !declaration_scope->is_arrow_scope() && return !declaration_scope->is_arrow_scope() &&
declaration_scope->produced_preparsed_scope_data() != nullptr; declaration_scope->preparsed_scope_data_builder() != nullptr;
} }
void ProducedPreParsedScopeData::SaveDataForScope(Scope* scope) { void PreParsedScopeDataBuilder::SaveDataForScope(Scope* scope) {
DCHECK_NE(scope->end_position(), kNoSourcePosition); DCHECK_NE(scope->end_position(), kNoSourcePosition);
if (!ScopeNeedsData(scope)) { if (!ScopeNeedsData(scope)) {
...@@ -435,7 +384,7 @@ void ProducedPreParsedScopeData::SaveDataForScope(Scope* scope) { ...@@ -435,7 +384,7 @@ void ProducedPreParsedScopeData::SaveDataForScope(Scope* scope) {
SaveDataForInnerScopes(scope); SaveDataForInnerScopes(scope);
} }
void ProducedPreParsedScopeData::SaveDataForVariable(Variable* var) { void PreParsedScopeDataBuilder::SaveDataForVariable(Variable* var) {
#ifdef DEBUG #ifdef DEBUG
// Store the variable name in debug mode; this way we can check that we // Store the variable name in debug mode; this way we can check that we
// restore data to the correct variable. // restore data to the correct variable.
...@@ -453,7 +402,7 @@ void ProducedPreParsedScopeData::SaveDataForVariable(Variable* var) { ...@@ -453,7 +402,7 @@ void ProducedPreParsedScopeData::SaveDataForVariable(Variable* var) {
byte_data_->WriteQuarter(variable_data); byte_data_->WriteQuarter(variable_data);
} }
void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) { void PreParsedScopeDataBuilder::SaveDataForInnerScopes(Scope* scope) {
// Inner scopes are stored in the reverse order, but we'd like to write the // Inner scopes are stored in the reverse order, but we'd like to write the
// data in the logical order. There might be many inner scopes, so we don't // data in the logical order. There might be many inner scopes, so we don't
// want to recurse here. // want to recurse here.
...@@ -462,9 +411,9 @@ void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) { ...@@ -462,9 +411,9 @@ void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) {
inner = inner->sibling()) { inner = inner->sibling()) {
if (ScopeIsSkippableFunctionScope(inner)) { if (ScopeIsSkippableFunctionScope(inner)) {
// Don't save data about function scopes, since they'll have their own // Don't save data about function scopes, since they'll have their own
// ProducedPreParsedScopeData where their data is saved. // PreParsedScopeDataBuilder where their data is saved.
DCHECK_NOT_NULL( DCHECK_NOT_NULL(
inner->AsDeclarationScope()->produced_preparsed_scope_data()); inner->AsDeclarationScope()->preparsed_scope_data_builder());
continue; continue;
} }
scopes.push_back(inner); scopes.push_back(inner);
...@@ -474,6 +423,73 @@ void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) { ...@@ -474,6 +423,73 @@ void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) {
} }
} }
class BuilderProducedPreParsedScopeData final
: public ProducedPreParsedScopeData {
public:
explicit BuilderProducedPreParsedScopeData(PreParsedScopeDataBuilder* builder)
: builder_(builder) {}
MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate) final {
return builder_->Serialize(isolate);
}
ZonePreParsedScopeData* Serialize(Zone* zone) final {
return builder_->Serialize(zone);
};
private:
PreParsedScopeDataBuilder* builder_;
};
class OnHeapProducedPreParsedScopeData final
: public ProducedPreParsedScopeData {
public:
explicit OnHeapProducedPreParsedScopeData(Handle<PreParsedScopeData> data)
: data_(data) {}
MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate) final {
return data_;
}
ZonePreParsedScopeData* Serialize(Zone* zone) final {
// Not required.
UNREACHABLE();
};
private:
Handle<PreParsedScopeData> data_;
};
class ZoneProducedPreParsedScopeData final : public ProducedPreParsedScopeData {
public:
explicit ZoneProducedPreParsedScopeData(ZonePreParsedScopeData* data)
: data_(data) {}
MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate) final {
return data_->Serialize(isolate);
}
ZonePreParsedScopeData* Serialize(Zone* zone) final { return data_; };
private:
ZonePreParsedScopeData* data_;
};
ProducedPreParsedScopeData* ProducedPreParsedScopeData::For(
PreParsedScopeDataBuilder* builder, Zone* zone) {
return new (zone) BuilderProducedPreParsedScopeData(builder);
}
ProducedPreParsedScopeData* ProducedPreParsedScopeData::For(
Handle<PreParsedScopeData> data, Zone* zone) {
return new (zone) OnHeapProducedPreParsedScopeData(data);
}
ProducedPreParsedScopeData* ProducedPreParsedScopeData::For(
ZonePreParsedScopeData* data, Zone* zone) {
return new (zone) ZoneProducedPreParsedScopeData(data);
}
template <class Data> template <class Data>
ProducedPreParsedScopeData* ProducedPreParsedScopeData*
BaseConsumedPreParsedScopeData<Data>::GetDataForSkippableFunction( BaseConsumedPreParsedScopeData<Data>::GetDataForSkippableFunction(
...@@ -505,7 +521,6 @@ BaseConsumedPreParsedScopeData<Data>::GetDataForSkippableFunction( ...@@ -505,7 +521,6 @@ BaseConsumedPreParsedScopeData<Data>::GetDataForSkippableFunction(
template <class Data> template <class Data>
void BaseConsumedPreParsedScopeData<Data>::RestoreScopeAllocationData( void BaseConsumedPreParsedScopeData<Data>::RestoreScopeAllocationData(
DeclarationScope* scope) { DeclarationScope* scope) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE); DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
typename ByteData::ReadingScope reading_scope(this); typename ByteData::ReadingScope reading_scope(this);
...@@ -536,7 +551,7 @@ void BaseConsumedPreParsedScopeData<Data>::RestoreData(Scope* scope) { ...@@ -536,7 +551,7 @@ void BaseConsumedPreParsedScopeData<Data>::RestoreData(Scope* scope) {
// It's possible that scope is not present in the data at all (since PreParser // It's possible that scope is not present in the data at all (since PreParser
// doesn't create the corresponding scope). In this case, the Scope won't // doesn't create the corresponding scope). In this case, the Scope won't
// contain any variables for which we need the data. // contain any variables for which we need the data.
if (!ProducedPreParsedScopeData::ScopeNeedsData(scope)) { if (!PreParsedScopeDataBuilder::ScopeNeedsData(scope)) {
return; return;
} }
...@@ -642,7 +657,7 @@ ProducedPreParsedScopeData* OnHeapConsumedPreParsedScopeData::GetChildData( ...@@ -642,7 +657,7 @@ ProducedPreParsedScopeData* OnHeapConsumedPreParsedScopeData::GetChildData(
} }
Handle<PreParsedScopeData> child_data_handle( Handle<PreParsedScopeData> child_data_handle(
PreParsedScopeData::cast(child_data), isolate_); PreParsedScopeData::cast(child_data), isolate_);
return new (zone) ProducedPreParsedScopeData(child_data_handle, zone); return ProducedPreParsedScopeData::For(child_data_handle, zone);
} }
OnHeapConsumedPreParsedScopeData::OnHeapConsumedPreParsedScopeData( OnHeapConsumedPreParsedScopeData::OnHeapConsumedPreParsedScopeData(
...@@ -703,7 +718,7 @@ ProducedPreParsedScopeData* ZoneConsumedPreParsedScopeData::GetChildData( ...@@ -703,7 +718,7 @@ ProducedPreParsedScopeData* ZoneConsumedPreParsedScopeData::GetChildData(
if (child_data == nullptr) { if (child_data == nullptr) {
return nullptr; return nullptr;
} }
return new (zone) ProducedPreParsedScopeData(child_data, zone); return ProducedPreParsedScopeData::For(child_data, zone);
} }
std::unique_ptr<ConsumedPreParsedScopeData> ConsumedPreParsedScopeData::For( std::unique_ptr<ConsumedPreParsedScopeData> ConsumedPreParsedScopeData::For(
......
...@@ -62,23 +62,15 @@ class ZonePreParsedScopeData; ...@@ -62,23 +62,15 @@ class ZonePreParsedScopeData;
*/ */
class ProducedPreParsedScopeData : public ZoneObject { class PreParsedScopeDataBuilder : public ZoneObject {
public: public:
class ByteData; class ByteData;
// Create a ProducedPreParsedScopeData object which will collect data as we // Create a PreParsedScopeDataBuilder object which will collect data as we
// parse. // parse.
ProducedPreParsedScopeData(Zone* zone, ProducedPreParsedScopeData* parent); PreParsedScopeDataBuilder(Zone* zone, PreParsedScopeDataBuilder* parent);
// Create a ProducedPreParsedScopeData which is just a proxy for a previous
// produced PreParsedScopeData on the heap.
ProducedPreParsedScopeData(Handle<PreParsedScopeData> data, Zone* zone);
// Create a ProducedPreParsedScopeData which is just a proxy for a previous
// produced PreParsedScopeData in zone.
ProducedPreParsedScopeData(ZonePreParsedScopeData* data, Zone* zone);
ProducedPreParsedScopeData* parent() const { return parent_; } PreParsedScopeDataBuilder* parent() const { return parent_; }
// For gathering the inner function data and splitting it up according to the // For gathering the inner function data and splitting it up according to the
// laziness boundaries. Each lazy function gets its own // laziness boundaries. Each lazy function gets its own
...@@ -93,7 +85,7 @@ class ProducedPreParsedScopeData : public ZoneObject { ...@@ -93,7 +85,7 @@ class ProducedPreParsedScopeData : public ZoneObject {
private: private:
DeclarationScope* function_scope_; DeclarationScope* function_scope_;
PreParser* preparser_; PreParser* preparser_;
ProducedPreParsedScopeData* produced_preparsed_scope_data_; PreParsedScopeDataBuilder* builder_;
DISALLOW_COPY_AND_ASSIGN(DataGatheringScope); DISALLOW_COPY_AND_ASSIGN(DataGatheringScope);
}; };
...@@ -129,20 +121,15 @@ class ProducedPreParsedScopeData : public ZoneObject { ...@@ -129,20 +121,15 @@ class ProducedPreParsedScopeData : public ZoneObject {
bool ContainsInnerFunctions() const; bool ContainsInnerFunctions() const;
// If there is data (if the Scope contains skippable inner functions), move
// the data into the heap and return a Handle to it; otherwise return a null
// MaybeHandle.
MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate);
// If there is data (if the Scope contains skippable inner functions), return
// an off-heap ZonePreParsedScopeData representing the data; otherwise
// return nullptr.
ZonePreParsedScopeData* Serialize(Zone* zone);
static bool ScopeNeedsData(Scope* scope); static bool ScopeNeedsData(Scope* scope);
static bool ScopeIsSkippableFunctionScope(Scope* scope); static bool ScopeIsSkippableFunctionScope(Scope* scope);
private: private:
friend class BuilderProducedPreParsedScopeData;
virtual MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate);
virtual ZonePreParsedScopeData* Serialize(Zone* zone);
void AddSkippableFunction(int start_position, int end_position, void AddSkippableFunction(int start_position, int end_position,
int num_parameters, int num_inner_functions, int num_parameters, int num_inner_functions,
LanguageMode language_mode, LanguageMode language_mode,
...@@ -152,27 +139,43 @@ class ProducedPreParsedScopeData : public ZoneObject { ...@@ -152,27 +139,43 @@ class ProducedPreParsedScopeData : public ZoneObject {
void SaveDataForVariable(Variable* var); void SaveDataForVariable(Variable* var);
void SaveDataForInnerScopes(Scope* scope); void SaveDataForInnerScopes(Scope* scope);
ProducedPreParsedScopeData* parent_; PreParsedScopeDataBuilder* parent_;
ByteData* byte_data_; ByteData* byte_data_;
ZoneChunkList<ProducedPreParsedScopeData*> data_for_inner_functions_; ZoneChunkList<PreParsedScopeDataBuilder*> data_for_inner_functions_;
// Whether we've given up producing the data for this function. // Whether we've given up producing the data for this function.
bool bailed_out_; bool bailed_out_;
// ProducedPreParsedScopeData can also hold a Handle<PreParsedScopeData> DISALLOW_COPY_AND_ASSIGN(PreParsedScopeDataBuilder);
// which was produced already earlier. This happens for deeper lazy functions. };
// TODO(rmcilroy): Split apart ProducedPreParsedScopeData into different
// classes for situations where it has already been produced.
Handle<PreParsedScopeData> previously_produced_on_heap_preparsed_scope_data_;
// ProducedPreParsedScopeData can also hold a ZonePreParsedScopeData* class ProducedPreParsedScopeData : public ZoneObject {
// which was produced already earlier. This happens for deeper lazy functions. public:
// TODO(rmcilroy): Split apart ProducedPreParsedScopeData into different // If there is data (if the Scope contains skippable inner functions), move
// classes for situations where it has already been produced. // the data into the heap and return a Handle to it; otherwise return a null
ZonePreParsedScopeData* previously_produced_zone_preparsed_scope_data_; // MaybeHandle.
virtual MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate) = 0;
DISALLOW_COPY_AND_ASSIGN(ProducedPreParsedScopeData); // If there is data (if the Scope contains skippable inner functions), return
// an off-heap ZonePreParsedScopeData representing the data; otherwise
// return nullptr.
virtual ZonePreParsedScopeData* Serialize(Zone* zone) = 0;
// Create a ProducedPreParsedScopeData which is a proxy for a previous
// produced PreParsedScopeData in zone.
static ProducedPreParsedScopeData* For(PreParsedScopeDataBuilder* builder,
Zone* zone);
// Create a ProducedPreParsedScopeData which is a proxy for a previous
// produced PreParsedScopeData on the heap.
static ProducedPreParsedScopeData* For(Handle<PreParsedScopeData> data,
Zone* zone);
// Create a ProducedPreParsedScopeData which is a proxy for a previous
// produced PreParsedScopeData in zone.
static ProducedPreParsedScopeData* For(ZonePreParsedScopeData* data,
Zone* zone);
}; };
class ConsumedPreParsedScopeData { class ConsumedPreParsedScopeData {
......
...@@ -134,12 +134,12 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -134,12 +134,12 @@ PreParser::PreParseResult PreParser::PreParseFunction(
// Start collecting data for a new function which might contain skippable // Start collecting data for a new function which might contain skippable
// functions. // functions.
std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope> std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
produced_preparsed_scope_data_scope; preparsed_scope_data_builder_scope;
if (FLAG_preparser_scope_analysis && !IsArrowFunction(kind)) { if (FLAG_preparser_scope_analysis && !IsArrowFunction(kind)) {
DCHECK(track_unresolved_variables_); DCHECK(track_unresolved_variables_);
produced_preparsed_scope_data_scope.reset( preparsed_scope_data_builder_scope.reset(
new ProducedPreParsedScopeData::DataGatheringScope(function_scope, new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this)); this));
} }
...@@ -239,7 +239,8 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -239,7 +239,8 @@ PreParser::PreParseResult PreParser::PreParseFunction(
allow_duplicate_parameters, allow_duplicate_parameters,
CHECK_OK_VALUE(kPreParseSuccess)); CHECK_OK_VALUE(kPreParseSuccess));
*produced_preparsed_scope_data = produced_preparsed_scope_data_; *produced_preparsed_scope_data = ProducedPreParsedScopeData::For(
preparsed_scope_data_builder_, main_zone());
} }
if (is_strict(function_scope->language_mode())) { if (is_strict(function_scope->language_mode())) {
...@@ -292,14 +293,14 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -292,14 +293,14 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Start collecting data for a new function which might contain skippable // Start collecting data for a new function which might contain skippable
// functions. // functions.
std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope> std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
produced_preparsed_scope_data_scope; preparsed_scope_data_builder_scope;
if (!function_state_->next_function_is_likely_called() && if (!function_state_->next_function_is_likely_called() &&
produced_preparsed_scope_data_ != nullptr) { preparsed_scope_data_builder_ != nullptr) {
DCHECK(FLAG_preparser_scope_analysis); DCHECK(FLAG_preparser_scope_analysis);
DCHECK(track_unresolved_variables_); DCHECK(track_unresolved_variables_);
produced_preparsed_scope_data_scope.reset( preparsed_scope_data_builder_scope.reset(
new ProducedPreParsedScopeData::DataGatheringScope(function_scope, new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this)); this));
} }
...@@ -348,8 +349,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -348,8 +349,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
} }
if (produced_preparsed_scope_data_scope) { if (preparsed_scope_data_builder_scope) {
produced_preparsed_scope_data_scope->MarkFunctionAsSkippable( preparsed_scope_data_builder_scope->MarkFunctionAsSkippable(
end_position, GetLastFunctionLiteralId() - func_id); end_position, GetLastFunctionLiteralId() - func_id);
} }
if (V8_UNLIKELY(FLAG_log_function_events)) { if (V8_UNLIKELY(FLAG_log_function_events)) {
...@@ -396,19 +397,19 @@ PreParserStatement PreParser::BuildParameterInitializationBlock( ...@@ -396,19 +397,19 @@ PreParserStatement PreParser::BuildParameterInitializationBlock(
DCHECK(scope()->is_function_scope()); DCHECK(scope()->is_function_scope());
if (FLAG_preparser_scope_analysis && if (FLAG_preparser_scope_analysis &&
scope()->AsDeclarationScope()->calls_sloppy_eval() && scope()->AsDeclarationScope()->calls_sloppy_eval() &&
produced_preparsed_scope_data_ != nullptr) { preparsed_scope_data_builder_ != nullptr) {
// We cannot replicate the Scope structure constructed by the Parser, // We cannot replicate the Scope structure constructed by the Parser,
// because we've lost information whether each individual parameter was // because we've lost information whether each individual parameter was
// simple or not. Give up trying to produce data to skip inner functions. // simple or not. Give up trying to produce data to skip inner functions.
if (produced_preparsed_scope_data_->parent() != nullptr) { if (preparsed_scope_data_builder_->parent() != nullptr) {
// Lazy parsing started before the current function; the function which // Lazy parsing started before the current function; the function which
// cannot contain skippable functions is the parent function. (Its inner // cannot contain skippable functions is the parent function. (Its inner
// functions cannot either; they are implicitly bailed out.) // functions cannot either; they are implicitly bailed out.)
produced_preparsed_scope_data_->parent()->Bailout(); preparsed_scope_data_builder_->parent()->Bailout();
} else { } else {
// Lazy parsing started at the current function; it cannot contain // Lazy parsing started at the current function; it cannot contain
// skippable functions. // skippable functions.
produced_preparsed_scope_data_->Bailout(); preparsed_scope_data_builder_->Bailout();
} }
} }
......
...@@ -22,7 +22,7 @@ namespace internal { ...@@ -22,7 +22,7 @@ namespace internal {
// interface as AstNodeFactory, so ParserBase doesn't need to care which one is // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
// used. // used.
class ProducedPreParsedScopeData; class PreParsedScopeDataBuilder;
class PreParserIdentifier { class PreParserIdentifier {
public: public:
...@@ -958,7 +958,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -958,7 +958,7 @@ class PreParser : public ParserBase<PreParser> {
parsing_module, parsing_on_main_thread), parsing_module, parsing_on_main_thread),
use_counts_(nullptr), use_counts_(nullptr),
track_unresolved_variables_(false), track_unresolved_variables_(false),
produced_preparsed_scope_data_(nullptr) {} preparsed_scope_data_builder_(nullptr) {}
static bool IsPreParser() { return true; } static bool IsPreParser() { return true; }
...@@ -990,13 +990,13 @@ class PreParser : public ParserBase<PreParser> { ...@@ -990,13 +990,13 @@ class PreParser : public ParserBase<PreParser> {
return FLAG_preparser_scope_analysis || is_inner_function; return FLAG_preparser_scope_analysis || is_inner_function;
} }
ProducedPreParsedScopeData* produced_preparsed_scope_data() const { PreParsedScopeDataBuilder* preparsed_scope_data_builder() const {
return produced_preparsed_scope_data_; return preparsed_scope_data_builder_;
} }
void set_produced_preparsed_scope_data( void set_preparsed_scope_data_builder(
ProducedPreParsedScopeData* produced_preparsed_scope_data) { PreParsedScopeDataBuilder* preparsed_scope_data_builder) {
produced_preparsed_scope_data_ = produced_preparsed_scope_data; preparsed_scope_data_builder_ = preparsed_scope_data_builder;
} }
private: private:
...@@ -1769,7 +1769,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1769,7 +1769,7 @@ class PreParser : public ParserBase<PreParser> {
bool track_unresolved_variables_; bool track_unresolved_variables_;
PreParserLogger log_; PreParserLogger log_;
ProducedPreParsedScopeData* produced_preparsed_scope_data_; PreParsedScopeDataBuilder* preparsed_scope_data_builder_;
}; };
PreParserExpression PreParser::SpreadCall(const PreParserExpression& function, PreParserExpression PreParser::SpreadCall(const PreParserExpression& function,
......
...@@ -815,7 +815,7 @@ TEST(ProducingAndConsumingByteData) { ...@@ -815,7 +815,7 @@ TEST(ProducingAndConsumingByteData) {
LocalContext env; LocalContext env;
i::Zone zone(isolate->allocator(), ZONE_NAME); i::Zone zone(isolate->allocator(), ZONE_NAME);
i::ProducedPreParsedScopeData::ByteData bytes(&zone); i::PreParsedScopeDataBuilder::ByteData bytes(&zone);
// Write some data. // Write some data.
bytes.WriteUint32(1983); // This will be overwritten. bytes.WriteUint32(1983); // This will be overwritten.
bytes.WriteUint32(2147483647); bytes.WriteUint32(2147483647);
......
...@@ -24,7 +24,7 @@ class ScopeTestHelper { ...@@ -24,7 +24,7 @@ class ScopeTestHelper {
baseline->AsDeclarationScope()->function_kind() == baseline->AsDeclarationScope()->function_kind() ==
scope->AsDeclarationScope()->function_kind()); scope->AsDeclarationScope()->function_kind());
if (!ProducedPreParsedScopeData::ScopeNeedsData(baseline)) { if (!PreParsedScopeDataBuilder::ScopeNeedsData(baseline)) {
return; return;
} }
......
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