Commit a1c333e4 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[parser] Don't store empty inner function preparse_data

Using a single bit in the inner function description preparse data of the
parent function we can avoid storing many NULL values for empty inner function
data.

This saves roughly 40KB out of 140KB PreparseScopeData on cnn.com.

Change-Id: Ib6019a8ceb99e772b398198074e171f635c0556e
Reviewed-on: https://chromium-review.googlesource.com/c/1405038
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58708}
parent 6c2cc582
...@@ -27,6 +27,10 @@ class VariableMaybeAssignedField : public BitField8<bool, 0, 1> {}; ...@@ -27,6 +27,10 @@ class VariableMaybeAssignedField : public BitField8<bool, 0, 1> {};
class VariableContextAllocatedField class VariableContextAllocatedField
: public BitField8<bool, VariableMaybeAssignedField::kNext, 1> {}; : public BitField8<bool, VariableMaybeAssignedField::kNext, 1> {};
class HasDataField : public BitField<bool, 0, 1> {};
class NumberOfParametersField
: public BitField<uint16_t, HasDataField::kNext, 16> {};
class LanguageField : public BitField8<LanguageMode, 0, 1> {}; class LanguageField : public BitField8<LanguageMode, 0, 1> {};
class UsesSuperField : public BitField8<bool, LanguageField::kNext, 1> {}; class UsesSuperField : public BitField8<bool, LanguageField::kNext, 1> {};
STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues); STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
...@@ -170,9 +174,8 @@ void PreparseDataBuilder::DataGatheringScope::Start( ...@@ -170,9 +174,8 @@ void PreparseDataBuilder::DataGatheringScope::Start(
PreparseDataBuilder::DataGatheringScope::~DataGatheringScope() { PreparseDataBuilder::DataGatheringScope::~DataGatheringScope() {
if (builder_ == nullptr) return; if (builder_ == nullptr) return;
PreparseDataBuilder* parent = builder_->parent_; PreparseDataBuilder* parent = builder_->parent_;
if (parent != nullptr) { if (parent != nullptr && builder_->HasData()) {
parent->data_for_inner_functions_.push_back(builder_->HasData() ? builder_ parent->data_for_inner_functions_.push_back(builder_);
: nullptr);
} }
preparser_->set_preparse_data_builder(parent); preparser_->set_preparse_data_builder(parent);
} }
...@@ -183,14 +186,13 @@ void PreparseDataBuilder::DataGatheringScope::AddSkippableFunction( ...@@ -183,14 +186,13 @@ void PreparseDataBuilder::DataGatheringScope::AddSkippableFunction(
builder_->parent_->AddSkippableFunction( builder_->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(), builder_->HasData(),
function_scope->NeedsHomeObject());
} }
void PreparseDataBuilder::AddSkippableFunction(int start_position, void PreparseDataBuilder::AddSkippableFunction(
int end_position, int start_position, int end_position, int num_parameters,
int num_parameters, int num_inner_functions, LanguageMode language_mode, bool has_data,
int num_inner_functions,
LanguageMode language_mode,
bool uses_super_property) { bool uses_super_property) {
if (bailed_out_) return; if (bailed_out_) return;
...@@ -199,7 +201,10 @@ void PreparseDataBuilder::AddSkippableFunction(int start_position, ...@@ -199,7 +201,10 @@ void PreparseDataBuilder::AddSkippableFunction(int start_position,
// at catching bugs in the wild so far. // at catching bugs in the wild so far.
byte_data_->WriteUint32(start_position); byte_data_->WriteUint32(start_position);
byte_data_->WriteUint32(end_position); byte_data_->WriteUint32(end_position);
byte_data_->WriteUint32(num_parameters); uint32_t has_data_and_num_parameters =
HasDataField::encode(has_data) |
NumberOfParametersField::encode(num_parameters);
byte_data_->WriteUint32(has_data_and_num_parameters);
byte_data_->WriteUint32(num_inner_functions); byte_data_->WriteUint32(num_inner_functions);
uint8_t language_and_super = LanguageField::encode(language_mode) | uint8_t language_and_super = LanguageField::encode(language_mode) |
...@@ -255,13 +260,9 @@ Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) { ...@@ -255,13 +260,9 @@ Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) {
int i = 0; int i = 0;
for (const auto& item : data_for_inner_functions_) { for (const auto& item : data_for_inner_functions_) {
if (item != nullptr) { DCHECK_NOT_NULL(item);
Handle<PreparseData> child_data = item->Serialize(isolate); Handle<PreparseData> child_data = item->Serialize(isolate);
data->set_child_data(i, *child_data); data->set_child_data(i++, *child_data);
} else {
DCHECK(data->child_data(i)->IsNull());
}
i++;
} }
return data; return data;
...@@ -277,11 +278,9 @@ ZonePreparseData* PreparseDataBuilder::Serialize(Zone* zone) { ...@@ -277,11 +278,9 @@ ZonePreparseData* PreparseDataBuilder::Serialize(Zone* zone) {
int i = 0; int i = 0;
for (const auto& item : data_for_inner_functions_) { for (const auto& item : data_for_inner_functions_) {
if (item != nullptr) { DCHECK_NOT_NULL(item);
ZonePreparseData* child = item->Serialize(zone); ZonePreparseData* child = item->Serialize(zone);
result->set_child(i, child); result->set_child(i++, child);
}
i++;
} }
return result; return result;
...@@ -458,16 +457,21 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction( ...@@ -458,16 +457,21 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
CHECK(scope_data_->HasRemainingBytes(ByteData::kSkippableFunctionDataSize)); CHECK(scope_data_->HasRemainingBytes(ByteData::kSkippableFunctionDataSize));
int start_position_from_data = scope_data_->ReadUint32(); int start_position_from_data = scope_data_->ReadUint32();
CHECK_EQ(start_position, start_position_from_data); CHECK_EQ(start_position, start_position_from_data);
*end_position = scope_data_->ReadUint32(); *end_position = scope_data_->ReadUint32();
DCHECK_GT(*end_position, start_position); DCHECK_GT(*end_position, start_position);
*num_parameters = scope_data_->ReadUint32();
uint32_t has_data_and_num_parameters = scope_data_->ReadUint32();
bool has_data = HasDataField::decode(has_data_and_num_parameters);
*num_parameters =
NumberOfParametersField::decode(has_data_and_num_parameters);
*num_inner_functions = scope_data_->ReadUint32(); *num_inner_functions = scope_data_->ReadUint32();
uint8_t language_and_super = scope_data_->ReadQuarter(); uint8_t language_and_super = scope_data_->ReadQuarter();
*language_mode = LanguageMode(LanguageField::decode(language_and_super)); *language_mode = LanguageMode(LanguageField::decode(language_and_super));
*uses_super_property = UsesSuperField::decode(language_and_super); *uses_super_property = UsesSuperField::decode(language_and_super);
if (!has_data) return nullptr;
// Retrieve the corresponding PreparseData and associate it to the // Retrieve the corresponding PreparseData and associate it to the
// skipped function. If the skipped functions contains inner functions, those // skipped function. If the skipped functions contains inner functions, those
// can be skipped when the skipped function is eagerly parsed. // can be skipped when the skipped function is eagerly parsed.
......
...@@ -123,7 +123,7 @@ class PreparseDataBuilder : public ZoneObject { ...@@ -123,7 +123,7 @@ class PreparseDataBuilder : public ZoneObject {
static bool ScopeIsSkippableFunctionScope(Scope* scope); static bool ScopeIsSkippableFunctionScope(Scope* scope);
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, bool has_data,
bool uses_super_property); bool uses_super_property);
private: private:
......
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