Commit f6f33f6f authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[asm] Use ZoneVector instead of std::vector

This CL replaces the last usages of std::vector in the AsmJsParser by
ZoneVector. This allows to also measure the memory consumption of these
vectors, since it is now contained in the zone memory.
ZoneVectors are reused to avoid accumulating lots of unused memory.

This also saves 2.6% performance (avg over 1000 runs) on my local
workstation.

R=mstarzinger@chromium.org

Change-Id: I04c96db558d9c362b1494ddd9e975edf2783403c
Reviewed-on: https://chromium-review.googlesource.com/516985Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45591}
parent 74df916b
...@@ -144,8 +144,8 @@ void AsmJsParser::InitializeStdlibTypes() { ...@@ -144,8 +144,8 @@ void AsmJsParser::InitializeStdlibTypes() {
stdlib_fround_ = AsmType::FroundType(zone()); stdlib_fround_ = AsmType::FroundType(zone());
} }
FunctionSig* AsmJsParser::ConvertSignature( FunctionSig* AsmJsParser::ConvertSignature(AsmType* return_type,
AsmType* return_type, const std::vector<AsmType*>& params) { const ZoneVector<AsmType*>& params) {
FunctionSig::Builder sig_builder( FunctionSig::Builder sig_builder(
zone(), !return_type->IsA(AsmType::Void()) ? 1 : 0, params.size()); zone(), !return_type->IsA(AsmType::Void()) ? 1 : 0, params.size());
for (auto param : params) { for (auto param : params) {
...@@ -730,9 +730,9 @@ void AsmJsParser::ValidateFunction() { ...@@ -730,9 +730,9 @@ void AsmJsParser::ValidateFunction() {
int start_position = static_cast<int>(scanner_.Position()); int start_position = static_cast<int>(scanner_.Position());
current_function_builder_->SetAsmFunctionStartPosition(start_position); current_function_builder_->SetAsmFunctionStartPosition(start_position);
std::vector<AsmType*> params; CachedVector<AsmType*> params(cached_asm_type_p_vectors_);
ValidateFunctionParams(&params); ValidateFunctionParams(&params);
std::vector<ValueType> locals; CachedVector<ValueType> locals(cached_valuetype_vectors_);
ValidateFunctionLocals(params.size(), &locals); ValidateFunctionLocals(params.size(), &locals);
function_temp_locals_offset_ = static_cast<uint32_t>( function_temp_locals_offset_ = static_cast<uint32_t>(
...@@ -792,13 +792,14 @@ void AsmJsParser::ValidateFunction() { ...@@ -792,13 +792,14 @@ void AsmJsParser::ValidateFunction() {
} }
// 6.4 ValidateFunction // 6.4 ValidateFunction
void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) { void AsmJsParser::ValidateFunctionParams(ZoneVector<AsmType*>* params) {
// TODO(bradnelson): Do this differently so that the scanner doesn't need to // TODO(bradnelson): Do this differently so that the scanner doesn't need to
// have a state transition that needs knowledge of how the scanner works // have a state transition that needs knowledge of how the scanner works
// inside. // inside.
scanner_.EnterLocalScope(); scanner_.EnterLocalScope();
EXPECT_TOKEN('('); EXPECT_TOKEN('(');
std::vector<AsmJsScanner::token_t> function_parameters; CachedVector<AsmJsScanner::token_t> function_parameters(
cached_token_t_vectors_);
while (!failed_ && !Peek(')')) { while (!failed_ && !Peek(')')) {
if (!scanner_.IsLocal()) { if (!scanner_.IsLocal()) {
FAIL("Expected parameter name"); FAIL("Expected parameter name");
...@@ -852,8 +853,8 @@ void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) { ...@@ -852,8 +853,8 @@ void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) {
} }
// 6.4 ValidateFunction - locals // 6.4 ValidateFunction - locals
void AsmJsParser::ValidateFunctionLocals( void AsmJsParser::ValidateFunctionLocals(size_t param_count,
size_t param_count, std::vector<ValueType>* locals) { ZoneVector<ValueType>* locals) {
// Local Variables. // Local Variables.
while (Peek(TOK(var))) { while (Peek(TOK(var))) {
scanner_.EnterLocalScope(); scanner_.EnterLocalScope();
...@@ -1267,7 +1268,7 @@ void AsmJsParser::SwitchStatement() { ...@@ -1267,7 +1268,7 @@ void AsmJsParser::SwitchStatement() {
Begin(pending_label_); Begin(pending_label_);
pending_label_ = 0; pending_label_ = 0;
// TODO(bradnelson): Make less weird. // TODO(bradnelson): Make less weird.
std::vector<int32_t> cases; CachedVector<int32_t> cases(cached_int_vectors_);
GatherCases(&cases); GatherCases(&cases);
EXPECT_TOKEN('{'); EXPECT_TOKEN('{');
size_t count = cases.size() + 1; size_t count = cases.size() + 1;
...@@ -2074,8 +2075,8 @@ AsmType* AsmJsParser::ValidateCall() { ...@@ -2074,8 +2075,8 @@ AsmType* AsmJsParser::ValidateCall() {
} }
// Parse argument list and gather types. // Parse argument list and gather types.
std::vector<AsmType*> param_types; CachedVector<AsmType*> param_types(cached_asm_type_p_vectors_);
ZoneVector<AsmType*> param_specific_types(zone()); CachedVector<AsmType*> param_specific_types(cached_asm_type_p_vectors_);
EXPECT_TOKENn('('); EXPECT_TOKENn('(');
while (!failed_ && !Peek(')')) { while (!failed_ && !Peek(')')) {
AsmType* t; AsmType* t;
...@@ -2426,7 +2427,7 @@ void AsmJsParser::ScanToClosingParenthesis() { ...@@ -2426,7 +2427,7 @@ void AsmJsParser::ScanToClosingParenthesis() {
} }
} }
void AsmJsParser::GatherCases(std::vector<int32_t>* cases) { void AsmJsParser::GatherCases(ZoneVector<int32_t>* cases) {
size_t start = scanner_.Position(); size_t start = scanner_.Position();
int depth = 0; int depth = 0;
for (;;) { for (;;) {
......
...@@ -105,6 +105,41 @@ class AsmJsParser { ...@@ -105,6 +105,41 @@ class AsmJsParser {
// Helper class to make {TempVariable} safe for nesting. // Helper class to make {TempVariable} safe for nesting.
class TemporaryVariableScope; class TemporaryVariableScope;
template <typename T>
class CachedVectors {
public:
explicit CachedVectors(Zone* zone) : reusable_vectors_(zone) {}
Zone* zone() const { return reusable_vectors_.get_allocator().zone(); }
inline void fill(ZoneVector<T>* vec) {
if (reusable_vectors_.empty()) return;
reusable_vectors_.back().swap(*vec);
reusable_vectors_.pop_back();
vec->clear();
}
inline void reuse(ZoneVector<T>* vec) {
reusable_vectors_.emplace_back(std::move(*vec));
}
private:
ZoneVector<ZoneVector<T>> reusable_vectors_;
};
template <typename T>
class CachedVector final : public ZoneVector<T> {
public:
explicit CachedVector(CachedVectors<T>& cache)
: ZoneVector<T>(cache.zone()), cache_(&cache) {
cache.fill(this);
}
~CachedVector() { cache_->reuse(this); }
private:
CachedVectors<T>* cache_;
};
Zone* zone_; Zone* zone_;
AsmJsScanner scanner_; AsmJsScanner scanner_;
WasmModuleBuilder* module_builder_; WasmModuleBuilder* module_builder_;
...@@ -115,6 +150,11 @@ class AsmJsParser { ...@@ -115,6 +150,11 @@ class AsmJsParser {
ZoneVector<VarInfo> global_var_info_; ZoneVector<VarInfo> global_var_info_;
ZoneVector<VarInfo> local_var_info_; ZoneVector<VarInfo> local_var_info_;
CachedVectors<ValueType> cached_valuetype_vectors_{zone_};
CachedVectors<AsmType*> cached_asm_type_p_vectors_{zone_};
CachedVectors<AsmJsScanner::token_t> cached_token_t_vectors_{zone_};
CachedVectors<int32_t> cached_int_vectors_{zone_};
int function_temp_locals_offset_; int function_temp_locals_offset_;
int function_temp_locals_used_; int function_temp_locals_used_;
int function_temp_locals_depth_; int function_temp_locals_depth_;
...@@ -267,7 +307,7 @@ class AsmJsParser { ...@@ -267,7 +307,7 @@ class AsmJsParser {
void InitializeStdlibTypes(); void InitializeStdlibTypes();
FunctionSig* ConvertSignature(AsmType* return_type, FunctionSig* ConvertSignature(AsmType* return_type,
const std::vector<AsmType*>& params); const ZoneVector<AsmType*>& params);
void ValidateModule(); // 6.1 ValidateModule void ValidateModule(); // 6.1 ValidateModule
void ValidateModuleParameters(); // 6.1 ValidateModule - parameters void ValidateModuleParameters(); // 6.1 ValidateModule - parameters
...@@ -281,9 +321,9 @@ class AsmJsParser { ...@@ -281,9 +321,9 @@ class AsmJsParser {
void ValidateExport(); // 6.2 ValidateExport void ValidateExport(); // 6.2 ValidateExport
void ValidateFunctionTable(); // 6.3 ValidateFunctionTable void ValidateFunctionTable(); // 6.3 ValidateFunctionTable
void ValidateFunction(); // 6.4 ValidateFunction void ValidateFunction(); // 6.4 ValidateFunction
void ValidateFunctionParams(std::vector<AsmType*>* params); void ValidateFunctionParams(ZoneVector<AsmType*>* params);
void ValidateFunctionLocals(size_t param_count, void ValidateFunctionLocals(size_t param_count,
std::vector<ValueType>* locals); ZoneVector<ValueType>* locals);
void ValidateStatement(); // 6.5 ValidateStatement void ValidateStatement(); // 6.5 ValidateStatement
void Block(); // 6.5.1 Block void Block(); // 6.5.1 Block
void ExpressionStatement(); // 6.5.2 ExpressionStatement void ExpressionStatement(); // 6.5.2 ExpressionStatement
...@@ -331,7 +371,7 @@ class AsmJsParser { ...@@ -331,7 +371,7 @@ class AsmJsParser {
// Used as part of {SwitchStatement}. Collects all case labels in the current // Used as part of {SwitchStatement}. Collects all case labels in the current
// switch-statement, then resets the scanner position. This is one piece that // switch-statement, then resets the scanner position. This is one piece that
// makes this parser not be a pure single-pass. // makes this parser not be a pure single-pass.
void GatherCases(std::vector<int32_t>* cases); void GatherCases(ZoneVector<int32_t>* cases);
}; };
} // namespace wasm } // namespace wasm
......
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