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() {
stdlib_fround_ = AsmType::FroundType(zone());
}
FunctionSig* AsmJsParser::ConvertSignature(
AsmType* return_type, const std::vector<AsmType*>& params) {
FunctionSig* AsmJsParser::ConvertSignature(AsmType* return_type,
const ZoneVector<AsmType*>& params) {
FunctionSig::Builder sig_builder(
zone(), !return_type->IsA(AsmType::Void()) ? 1 : 0, params.size());
for (auto param : params) {
......@@ -730,9 +730,9 @@ void AsmJsParser::ValidateFunction() {
int start_position = static_cast<int>(scanner_.Position());
current_function_builder_->SetAsmFunctionStartPosition(start_position);
std::vector<AsmType*> params;
CachedVector<AsmType*> params(cached_asm_type_p_vectors_);
ValidateFunctionParams(&params);
std::vector<ValueType> locals;
CachedVector<ValueType> locals(cached_valuetype_vectors_);
ValidateFunctionLocals(params.size(), &locals);
function_temp_locals_offset_ = static_cast<uint32_t>(
......@@ -792,13 +792,14 @@ void AsmJsParser::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
// have a state transition that needs knowledge of how the scanner works
// inside.
scanner_.EnterLocalScope();
EXPECT_TOKEN('(');
std::vector<AsmJsScanner::token_t> function_parameters;
CachedVector<AsmJsScanner::token_t> function_parameters(
cached_token_t_vectors_);
while (!failed_ && !Peek(')')) {
if (!scanner_.IsLocal()) {
FAIL("Expected parameter name");
......@@ -852,8 +853,8 @@ void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) {
}
// 6.4 ValidateFunction - locals
void AsmJsParser::ValidateFunctionLocals(
size_t param_count, std::vector<ValueType>* locals) {
void AsmJsParser::ValidateFunctionLocals(size_t param_count,
ZoneVector<ValueType>* locals) {
// Local Variables.
while (Peek(TOK(var))) {
scanner_.EnterLocalScope();
......@@ -1267,7 +1268,7 @@ void AsmJsParser::SwitchStatement() {
Begin(pending_label_);
pending_label_ = 0;
// TODO(bradnelson): Make less weird.
std::vector<int32_t> cases;
CachedVector<int32_t> cases(cached_int_vectors_);
GatherCases(&cases);
EXPECT_TOKEN('{');
size_t count = cases.size() + 1;
......@@ -2074,8 +2075,8 @@ AsmType* AsmJsParser::ValidateCall() {
}
// Parse argument list and gather types.
std::vector<AsmType*> param_types;
ZoneVector<AsmType*> param_specific_types(zone());
CachedVector<AsmType*> param_types(cached_asm_type_p_vectors_);
CachedVector<AsmType*> param_specific_types(cached_asm_type_p_vectors_);
EXPECT_TOKENn('(');
while (!failed_ && !Peek(')')) {
AsmType* t;
......@@ -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();
int depth = 0;
for (;;) {
......
......@@ -105,6 +105,41 @@ class AsmJsParser {
// Helper class to make {TempVariable} safe for nesting.
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_;
AsmJsScanner scanner_;
WasmModuleBuilder* module_builder_;
......@@ -115,6 +150,11 @@ class AsmJsParser {
ZoneVector<VarInfo> global_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_used_;
int function_temp_locals_depth_;
......@@ -267,7 +307,7 @@ class AsmJsParser {
void InitializeStdlibTypes();
FunctionSig* ConvertSignature(AsmType* return_type,
const std::vector<AsmType*>& params);
const ZoneVector<AsmType*>& params);
void ValidateModule(); // 6.1 ValidateModule
void ValidateModuleParameters(); // 6.1 ValidateModule - parameters
......@@ -281,9 +321,9 @@ class AsmJsParser {
void ValidateExport(); // 6.2 ValidateExport
void ValidateFunctionTable(); // 6.3 ValidateFunctionTable
void ValidateFunction(); // 6.4 ValidateFunction
void ValidateFunctionParams(std::vector<AsmType*>* params);
void ValidateFunctionParams(ZoneVector<AsmType*>* params);
void ValidateFunctionLocals(size_t param_count,
std::vector<ValueType>* locals);
ZoneVector<ValueType>* locals);
void ValidateStatement(); // 6.5 ValidateStatement
void Block(); // 6.5.1 Block
void ExpressionStatement(); // 6.5.2 ExpressionStatement
......@@ -331,7 +371,7 @@ class AsmJsParser {
// Used as part of {SwitchStatement}. Collects all case labels in the current
// switch-statement, then resets the scanner position. This is one piece that
// makes this parser not be a pure single-pass.
void GatherCases(std::vector<int32_t>* cases);
void GatherCases(ZoneVector<int32_t>* cases);
};
} // 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