Commit da3e2225 authored by heimbuef's avatar heimbuef Committed by Commit bot

[Parser] Added SMI cache

With the very same SMIs making up a big chunk
of the parser zone (especially for asm.js) it
makes sense to cache the AstValues for them.
This is not ideal yet, but already saves
hundreds (sic!) MBs of memory for Unity games.

Review-Url: https://codereview.chromium.org/2485423002
Cr-Commit-Position: refs/heads/master@{#40866}
parent d91bed67
......@@ -330,10 +330,12 @@ const AstValue* AstValueFactory::NewNumber(double number, bool with_dot) {
return AddValue(value);
}
const AstValue* AstValueFactory::NewSmi(uint32_t number) {
bool cacheable_smi = number <= kMaxCachedSmi;
if (cacheable_smi && smis_[number] != nullptr) return smis_[number];
const AstValue* AstValueFactory::NewSmi(int number) {
AstValue* value =
new (zone_) AstValue(AstValue::SMI, number);
AstValue* value = new (zone_) AstValue(AstValue::SMI, number);
if (cacheable_smi) smis_[number] = value;
return AddValue(value);
}
......
......@@ -332,6 +332,7 @@ class AstValueFactory {
AstValueFactory(Zone* zone, uint32_t hash_seed)
: string_table_(AstRawStringCompare),
values_(nullptr),
smis_(),
strings_(nullptr),
strings_end_(&strings_),
zone_(zone),
......@@ -342,6 +343,7 @@ class AstValueFactory {
#define F(name) name##_ = NULL;
OTHER_CONSTANTS(F)
#undef F
std::fill(smis_, smis_ + arraysize(smis_), nullptr);
}
Zone* zone() const { return zone_; }
......@@ -381,7 +383,7 @@ class AstValueFactory {
// A JavaScript symbol (ECMA-262 edition 6).
const AstValue* NewSymbol(const char* name);
const AstValue* NewNumber(double number, bool with_dot = false);
const AstValue* NewSmi(int number);
const AstValue* NewSmi(uint32_t number);
const AstValue* NewBoolean(bool b);
const AstValue* NewStringList(ZoneList<const AstRawString*>* strings);
const AstValue* NewNull();
......@@ -389,6 +391,10 @@ class AstValueFactory {
const AstValue* NewTheHole();
private:
static const uint32_t kMaxCachedSmi = 1 << 10;
STATIC_ASSERT(kMaxCachedSmi <= Smi::kMaxValue);
AstValue* AddValue(AstValue* value) {
value->set_next(values_);
values_ = value;
......@@ -416,6 +422,8 @@ class AstValueFactory {
// For keeping track of all AstValues and AstRawStrings we've created (so that
// they can be internalized later).
AstValue* values_;
AstValue* smis_[kMaxCachedSmi + 1];
// We need to keep track of strings_ in order since cons strings require their
// members to be internalized first.
AstString* strings_;
......
......@@ -3283,7 +3283,7 @@ class AstNodeFactory final BASE_EMBEDDED {
Literal(ast_value_factory_->NewNumber(number, with_dot), pos);
}
Literal* NewSmiLiteral(int number, int pos) {
Literal* NewSmiLiteral(uint32_t number, int pos) {
return new (zone_) Literal(ast_value_factory_->NewSmi(number), pos);
}
......
......@@ -503,7 +503,7 @@ Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
case Token::FALSE_LITERAL:
return factory()->NewBooleanLiteral(false, pos);
case Token::SMI: {
int value = scanner()->smi_value();
uint32_t value = scanner()->smi_value();
return factory()->NewSmiLiteral(value, pos);
}
case Token::NUMBER: {
......@@ -3923,9 +3923,9 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
zone());
// Ensure hash is suitable as a Smi value
// Truncate hash to Smi-range.
Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
Expression* call_site = factory()->NewCallRuntime(
Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
......
......@@ -1153,7 +1153,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
if (next_.literal_chars->one_byte_literal().length() <= 10 &&
value <= Smi::kMaxValue && c0_ != '.' && c0_ != 'e' && c0_ != 'E') {
next_.smi_value_ = static_cast<int>(value);
next_.smi_value_ = static_cast<uint32_t>(value);
literal.Complete();
HandleLeadSurrogate();
......
......@@ -284,7 +284,7 @@ class Scanner {
}
// Returns the value of the last smi that was scanned.
int smi_value() const { return current_.smi_value_; }
uint32_t smi_value() const { return current_.smi_value_; }
// Seek forward to the given position. This operation does not
// work in general, for instance when there are pushed back
......@@ -487,7 +487,7 @@ class Scanner {
Location location;
LiteralBuffer* literal_chars;
LiteralBuffer* raw_literal_chars;
int smi_value_;
uint32_t smi_value_;
Token::Value token;
};
......
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