Commit 228ffc08 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner funcs: add num_inner_funcs.

Moved recording data about functions to PreParser, since it knows the
num_inner_funcs. Recording used to be done in AnalyzePartially and then it was
too late, since at that point we only have the Scope and have lost all other
info about the function.

BUG=v8:5516
R=vogelheim@chromium.org

Change-Id: Icb379149882629f2181a1400781d31d653e300ba
Reviewed-on: https://chromium-review.googlesource.com/475833
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44682}
parent 199e543f
......@@ -20,6 +20,7 @@
namespace v8 {
namespace internal {
class PreParsedScopeData;
enum FunctionNameValidity {
kFunctionNameIsStrictReserved,
......@@ -200,6 +201,7 @@ class ParserBase {
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
RuntimeCallStats* runtime_call_stats,
PreParsedScopeData* preparsed_scope_data,
bool parsing_on_main_thread = true)
: scope_(nullptr),
original_scope_(nullptr),
......@@ -212,6 +214,7 @@ class ParserBase {
parsing_on_main_thread_(parsing_on_main_thread),
parsing_module_(false),
stack_limit_(stack_limit),
preparsed_scope_data_(preparsed_scope_data),
zone_(zone),
classifier_(nullptr),
scanner_(scanner),
......@@ -1486,6 +1489,7 @@ class ParserBase {
bool parsing_on_main_thread_;
bool parsing_module_;
uintptr_t stack_limit_;
PreParsedScopeData* preparsed_scope_data_;
// Parser base's private field members.
......
......@@ -503,7 +503,8 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
Parser::Parser(ParseInfo* info)
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
info->extension(), info->ast_value_factory(),
info->runtime_call_stats(), true),
info->runtime_call_stats(),
info->preparsed_scope_data(), true),
scanner_(info->unicode_cache()),
reusable_preparser_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
......@@ -513,7 +514,6 @@ Parser::Parser(ParseInfo* info)
total_preparse_skipped_(0),
temp_zoned_(false),
log_(nullptr),
preparsed_scope_data_(info->preparsed_scope_data()),
parameters_end_pos_(info->parameters_end_pos()) {
// Even though we were passed ParseInfo, we should not store it in
// Parser - this makes sure that Isolate is not accidentally accessed via
......
......@@ -295,7 +295,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
reusable_preparser_ =
new PreParser(zone(), &scanner_, stack_limit_, ast_value_factory(),
&pending_error_handler_, runtime_call_stats_,
parsing_on_main_thread_);
preparsed_scope_data_, parsing_on_main_thread_);
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
SET_ALLOW(natives);
SET_ALLOW(tailcalls);
......@@ -1175,8 +1175,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
bool temp_zoned_;
ParserLogger* log_;
PreParsedScopeData* preparsed_scope_data_;
// If not kNoSourcePosition, indicates that the first function literal
// encountered is a dynamic function, see CreateDynamicFunction(). This field
// indicates the correct position of the ')' that closes the parameter list.
......
......@@ -52,19 +52,12 @@ const int kFunctionDataSize = 8;
void PreParsedScopeData::SaveData(Scope* scope) {
DCHECK(!has_data_);
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE &&
!scope->AsDeclarationScope()->is_arrow_scope()) {
// This cast is OK since we're not going to have more than 2^32 elements in
// the data. FIXME(marja): Implement limits for the data size.
function_data_positions_[scope->start_position()] =
static_cast<uint32_t>(backing_store_.size());
// FIXME(marja): Fill in the missing field num_inner_functions.
function_index_.AddFunctionData(
scope->start_position(),
PreParseData::FunctionData(
scope->end_position(), scope->num_parameters(), -1,
scope->language_mode(),
scope->AsDeclarationScope()->uses_super_property(),
scope->calls_eval()));
}
if (!ScopeNeedsData(scope)) {
......@@ -94,6 +87,11 @@ void PreParsedScopeData::SaveData(Scope* scope) {
backing_store_[data_end_index] = backing_store_.size();
}
void PreParsedScopeData::AddFunction(
int start_position, const PreParseData::FunctionData& function_data) {
function_index_.AddFunctionData(start_position, function_data);
}
void PreParsedScopeData::RestoreData(DeclarationScope* scope) const {
int index = -1;
......@@ -118,9 +116,8 @@ void PreParsedScopeData::RestoreData(Scope* scope, int* index_ptr) const {
#ifdef DEBUG
// Data integrity check.
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
// FIXME(marja): Compare the missing fields too (function length,
// num_inner_functions).
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE &&
!scope->AsDeclarationScope()->is_arrow_scope()) {
const PreParseData::FunctionData& data =
FindFunction(scope->start_position());
DCHECK_EQ(data.end, scope->end_position());
......
......@@ -65,6 +65,18 @@ class PreParsedScopeData {
// subscopes') variables.
void SaveData(Scope* scope);
// Saves data for a function that can be later skipped, or a function for
// which we save variable allocation data.
// FIXME(marja): We need different kinds of data for the two types of
// functions. For a skippable function we need the end position + the data
// needed for creating a FunctionLiteral. For a function which contains
// skippable functions, we need the data affecting context allocation status
// of the variables (but e.g., no end position). Currently we just save the
// same data for both. Here we can save less data.
void AddFunction(int start_position,
const PreParseData::FunctionData& function_data);
// Restores the information needed for allocating the Scopes's (and its
// subscopes') variables.
void RestoreData(Scope* scope, int* index_ptr) const;
......@@ -95,7 +107,8 @@ class PreParsedScopeData {
// what data is needed.
std::vector<byte> backing_store_;
// Start pos -> FunctionData.
// Start pos -> FunctionData. Used for creating FunctionLiterals for skipped
// functions (when they're actually skipped).
PreParseData function_index_;
// Start pos -> position in backing_store_.
std::unordered_map<uint32_t, uint32_t> function_data_positions_;
......
......@@ -14,6 +14,7 @@
#include "src/parsing/parser-base.h"
#include "src/parsing/preparse-data-format.h"
#include "src/parsing/preparse-data.h"
#include "src/parsing/preparsed-scope-data.h"
#include "src/parsing/preparser.h"
#include "src/unicode.h"
#include "src/utils.h"
......@@ -213,6 +214,16 @@ PreParser::PreParseResult PreParser::PreParseFunction(
// masks the arguments object. Declare arguments before declaring the
// function var since the arguments object masks 'function arguments'.
function_scope->DeclareArguments(ast_value_factory());
if (FLAG_preparser_scope_analysis && preparsed_scope_data_ != nullptr) {
preparsed_scope_data_->AddFunction(
scope()->start_position(),
PreParseData::FunctionData(
scanner()->peek_location().end_pos, scope()->num_parameters(),
GetLastFunctionLiteralId(), scope()->language_mode(),
scope()->AsDeclarationScope()->uses_super_property(),
scope()->calls_eval()));
}
}
use_counts_ = nullptr;
......@@ -343,6 +354,15 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
}
}
if (FLAG_preparser_scope_analysis && preparsed_scope_data_ != nullptr) {
preparsed_scope_data_->AddFunction(
start_position,
PreParseData::FunctionData(
end_position, scope()->num_parameters(),
GetLastFunctionLiteralId() - func_id, scope()->language_mode(),
scope()->AsDeclarationScope()->uses_super_property(),
scope()->calls_eval()));
}
if (FLAG_trace_preparse) {
PrintF(" [%s]: %i-%i\n",
track_unresolved_variables_ ? "Preparse resolution"
......
......@@ -889,10 +889,11 @@ class PreParser : public ParserBase<PreParser> {
AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats,
PreParsedScopeData* preparsed_scope_data = nullptr,
bool parsing_on_main_thread = true)
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
ast_value_factory, runtime_call_stats,
parsing_on_main_thread),
preparsed_scope_data, parsing_on_main_thread),
use_counts_(nullptr),
preparse_data_(FLAG_use_parse_tasks ? new PreParseData() : nullptr),
track_unresolved_variables_(false),
......
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