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() {
should_eager_compile_ = false;
was_lazily_parsed_ = false;
is_skipped_function_ = false;
produced_preparsed_scope_data_ = nullptr;
preparsed_scope_data_builder_ = nullptr;
#ifdef DEBUG
DeclarationScope* outer_declaration_scope =
outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
......@@ -1532,7 +1532,7 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
void Scope::SavePreParsedScopeData() {
DCHECK(FLAG_preparser_scope_analysis);
if (ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(this)) {
if (PreParsedScopeDataBuilder::ScopeIsSkippableFunctionScope(this)) {
AsDeclarationScope()->SavePreParsedScopeDataForDeclarationScope();
}
......@@ -1542,9 +1542,9 @@ void Scope::SavePreParsedScopeData() {
}
void DeclarationScope::SavePreParsedScopeDataForDeclarationScope() {
if (produced_preparsed_scope_data_ != nullptr) {
if (preparsed_scope_data_builder_ != nullptr) {
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) {
if (!outer_scope_->is_script_scope() ||
(FLAG_preparser_scope_analysis &&
produced_preparsed_scope_data_ != nullptr &&
produced_preparsed_scope_data_->ContainsInnerFunctions())) {
preparsed_scope_data_builder_ != nullptr &&
preparsed_scope_data_builder_->ContainsInnerFunctions())) {
// 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
// them in the outer Scopes here, because they are incomplete.
......
......@@ -20,8 +20,7 @@ class AstValueFactory;
class AstRawString;
class Declaration;
class ParseInfo;
class PreParsedScopeData;
class ProducedPreParsedScopeData;
class PreParsedScopeDataBuilder;
class SloppyBlockFunctionStatement;
class Statement;
class StringSet;
......@@ -919,13 +918,13 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// saved in produced_preparsed_scope_data_.
void SavePreParsedScopeDataForDeclarationScope();
void set_produced_preparsed_scope_data(
ProducedPreParsedScopeData* produced_preparsed_scope_data) {
produced_preparsed_scope_data_ = produced_preparsed_scope_data;
void set_preparsed_scope_data_builder(
PreParsedScopeDataBuilder* preparsed_scope_data_builder) {
preparsed_scope_data_builder_ = preparsed_scope_data_builder;
}
ProducedPreParsedScopeData* produced_preparsed_scope_data() const {
return produced_preparsed_scope_data_;
PreParsedScopeDataBuilder* preparsed_scope_data_builder() const {
return preparsed_scope_data_builder_;
}
private:
......@@ -981,7 +980,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
Variable* arguments_;
// For producing the scope allocation data during preparsing.
ProducedPreParsedScopeData* produced_preparsed_scope_data_;
PreParsedScopeDataBuilder* preparsed_scope_data_builder_;
struct RareData : public ZoneObject {
// Convenience variable; Subclass constructor only
......
......@@ -33,7 +33,7 @@ struct PreParsedScopeByteDataConstants {
4 * kUint32Size + 1 * kUint8Size;
};
class ProducedPreParsedScopeData::ByteData
class PreParsedScopeDataBuilder::ByteData
: public ZoneObject,
public PreParsedScopeByteDataConstants {
public:
......
This diff is collapsed.
......@@ -62,23 +62,15 @@ class ZonePreParsedScopeData;
*/
class ProducedPreParsedScopeData : public ZoneObject {
class PreParsedScopeDataBuilder : public ZoneObject {
public:
class ByteData;
// Create a ProducedPreParsedScopeData object which will collect data as we
// Create a PreParsedScopeDataBuilder object which will collect data as we
// parse.
ProducedPreParsedScopeData(Zone* zone, ProducedPreParsedScopeData* 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);
PreParsedScopeDataBuilder(Zone* zone, PreParsedScopeDataBuilder* parent);
ProducedPreParsedScopeData* parent() const { return parent_; }
PreParsedScopeDataBuilder* parent() const { return parent_; }
// For gathering the inner function data and splitting it up according to the
// laziness boundaries. Each lazy function gets its own
......@@ -93,7 +85,7 @@ class ProducedPreParsedScopeData : public ZoneObject {
private:
DeclarationScope* function_scope_;
PreParser* preparser_;
ProducedPreParsedScopeData* produced_preparsed_scope_data_;
PreParsedScopeDataBuilder* builder_;
DISALLOW_COPY_AND_ASSIGN(DataGatheringScope);
};
......@@ -129,20 +121,15 @@ class ProducedPreParsedScopeData : public ZoneObject {
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 ScopeIsSkippableFunctionScope(Scope* scope);
private:
friend class BuilderProducedPreParsedScopeData;
virtual MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate);
virtual ZonePreParsedScopeData* Serialize(Zone* zone);
void AddSkippableFunction(int start_position, int end_position,
int num_parameters, int num_inner_functions,
LanguageMode language_mode,
......@@ -152,27 +139,43 @@ class ProducedPreParsedScopeData : public ZoneObject {
void SaveDataForVariable(Variable* var);
void SaveDataForInnerScopes(Scope* scope);
ProducedPreParsedScopeData* parent_;
PreParsedScopeDataBuilder* parent_;
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.
bool bailed_out_;
// ProducedPreParsedScopeData can also hold a Handle<PreParsedScopeData>
// 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_;
DISALLOW_COPY_AND_ASSIGN(PreParsedScopeDataBuilder);
};
// ProducedPreParsedScopeData can also hold a ZonePreParsedScopeData*
// 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.
ZonePreParsedScopeData* previously_produced_zone_preparsed_scope_data_;
class ProducedPreParsedScopeData : public ZoneObject {
public:
// 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.
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 {
......
......@@ -134,13 +134,13 @@ PreParser::PreParseResult PreParser::PreParseFunction(
// Start collecting data for a new function which might contain skippable
// functions.
std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope>
produced_preparsed_scope_data_scope;
std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
preparsed_scope_data_builder_scope;
if (FLAG_preparser_scope_analysis && !IsArrowFunction(kind)) {
DCHECK(track_unresolved_variables_);
produced_preparsed_scope_data_scope.reset(
new ProducedPreParsedScopeData::DataGatheringScope(function_scope,
this));
preparsed_scope_data_builder_scope.reset(
new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this));
}
// In the preparser, we use the function literal ids to count how many
......@@ -239,7 +239,8 @@ PreParser::PreParseResult PreParser::PreParseFunction(
allow_duplicate_parameters,
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())) {
......@@ -292,15 +293,15 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Start collecting data for a new function which might contain skippable
// functions.
std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope>
produced_preparsed_scope_data_scope;
std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
preparsed_scope_data_builder_scope;
if (!function_state_->next_function_is_likely_called() &&
produced_preparsed_scope_data_ != nullptr) {
preparsed_scope_data_builder_ != nullptr) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK(track_unresolved_variables_);
produced_preparsed_scope_data_scope.reset(
new ProducedPreParsedScopeData::DataGatheringScope(function_scope,
this));
preparsed_scope_data_builder_scope.reset(
new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this));
}
FunctionState function_state(&function_state_, &scope_, function_scope);
......@@ -348,8 +349,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
}
if (produced_preparsed_scope_data_scope) {
produced_preparsed_scope_data_scope->MarkFunctionAsSkippable(
if (preparsed_scope_data_builder_scope) {
preparsed_scope_data_builder_scope->MarkFunctionAsSkippable(
end_position, GetLastFunctionLiteralId() - func_id);
}
if (V8_UNLIKELY(FLAG_log_function_events)) {
......@@ -396,19 +397,19 @@ PreParserStatement PreParser::BuildParameterInitializationBlock(
DCHECK(scope()->is_function_scope());
if (FLAG_preparser_scope_analysis &&
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,
// because we've lost information whether each individual parameter was
// 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
// cannot contain skippable functions is the parent function. (Its inner
// functions cannot either; they are implicitly bailed out.)
produced_preparsed_scope_data_->parent()->Bailout();
preparsed_scope_data_builder_->parent()->Bailout();
} else {
// Lazy parsing started at the current function; it cannot contain
// skippable functions.
produced_preparsed_scope_data_->Bailout();
preparsed_scope_data_builder_->Bailout();
}
}
......
......@@ -22,7 +22,7 @@ namespace internal {
// interface as AstNodeFactory, so ParserBase doesn't need to care which one is
// used.
class ProducedPreParsedScopeData;
class PreParsedScopeDataBuilder;
class PreParserIdentifier {
public:
......@@ -958,7 +958,7 @@ class PreParser : public ParserBase<PreParser> {
parsing_module, parsing_on_main_thread),
use_counts_(nullptr),
track_unresolved_variables_(false),
produced_preparsed_scope_data_(nullptr) {}
preparsed_scope_data_builder_(nullptr) {}
static bool IsPreParser() { return true; }
......@@ -990,13 +990,13 @@ class PreParser : public ParserBase<PreParser> {
return FLAG_preparser_scope_analysis || is_inner_function;
}
ProducedPreParsedScopeData* produced_preparsed_scope_data() const {
return produced_preparsed_scope_data_;
PreParsedScopeDataBuilder* preparsed_scope_data_builder() const {
return preparsed_scope_data_builder_;
}
void set_produced_preparsed_scope_data(
ProducedPreParsedScopeData* produced_preparsed_scope_data) {
produced_preparsed_scope_data_ = produced_preparsed_scope_data;
void set_preparsed_scope_data_builder(
PreParsedScopeDataBuilder* preparsed_scope_data_builder) {
preparsed_scope_data_builder_ = preparsed_scope_data_builder;
}
private:
......@@ -1769,7 +1769,7 @@ class PreParser : public ParserBase<PreParser> {
bool track_unresolved_variables_;
PreParserLogger log_;
ProducedPreParsedScopeData* produced_preparsed_scope_data_;
PreParsedScopeDataBuilder* preparsed_scope_data_builder_;
};
PreParserExpression PreParser::SpreadCall(const PreParserExpression& function,
......
......@@ -815,7 +815,7 @@ TEST(ProducingAndConsumingByteData) {
LocalContext env;
i::Zone zone(isolate->allocator(), ZONE_NAME);
i::ProducedPreParsedScopeData::ByteData bytes(&zone);
i::PreParsedScopeDataBuilder::ByteData bytes(&zone);
// Write some data.
bytes.WriteUint32(1983); // This will be overwritten.
bytes.WriteUint32(2147483647);
......
......@@ -24,7 +24,7 @@ class ScopeTestHelper {
baseline->AsDeclarationScope()->function_kind() ==
scope->AsDeclarationScope()->function_kind());
if (!ProducedPreParsedScopeData::ScopeNeedsData(baseline)) {
if (!PreParsedScopeDataBuilder::ScopeNeedsData(baseline)) {
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