Commit a12f2445 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[parser] Micro-optimize Scanner::Scan()

Use a flag int instead of bit fields in LiteralBuffer, so that

cache the output of next() in Scanner::Scan() so that it doesn't get
reloaded between LiteralBuffer::Drop() calls.

LiteralBuffer: :Drop can set a single value rather than masking. Also,
Change-Id: I977703488ac41e3b091f46ce0840e7c464639073
Reviewed-on: https://chromium-review.googlesource.com/c/1331548Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57463}
parent 1cc5bb6a
......@@ -589,14 +589,15 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() {
}
void Scanner::Scan() {
next().literal_chars.Drop();
next().raw_literal_chars.Drop();
next().contextual_token = Token::UNINITIALIZED;
next().invalid_template_escape_message = MessageTemplate::kNone;
next().token = ScanSingleToken();
DCHECK_IMPLIES(has_parser_error(), next().token == Token::ILLEGAL);
next().location.end_pos = source_pos();
TokenDesc& next_desc = next();
next_desc.literal_chars.Drop();
next_desc.raw_literal_chars.Drop();
next_desc.contextual_token = Token::UNINITIALIZED;
next_desc.invalid_template_escape_message = MessageTemplate::kNone;
next_desc.token = ScanSingleToken();
DCHECK_IMPLIES(has_parser_error(), next_desc.token == Token::ILLEGAL);
next_desc.location.end_pos = source_pos();
#ifdef DEBUG
SanityCheckTokenDesc(current());
......
......@@ -58,7 +58,7 @@ class Scanner::ErrorState {
// Scanner::LiteralBuffer
Handle<String> Scanner::LiteralBuffer::Internalize(Isolate* isolate) const {
DCHECK(is_used_);
DCHECK(is_used());
if (is_one_byte()) {
return isolate->factory()->InternalizeOneByteString(one_byte_literal());
}
......@@ -79,7 +79,7 @@ void Scanner::LiteralBuffer::ExpandBuffer() {
}
void Scanner::LiteralBuffer::ConvertToTwoByte() {
DCHECK(is_one_byte_);
DCHECK(is_one_byte());
Vector<byte> new_store;
int new_content_size = position_ * kUC16Size;
if (new_content_size >= backing_store_.length()) {
......@@ -99,11 +99,11 @@ void Scanner::LiteralBuffer::ConvertToTwoByte() {
backing_store_ = new_store;
}
position_ = new_content_size;
is_one_byte_ = false;
flags_ = IsOneByte::update(flags_, false);
}
void Scanner::LiteralBuffer::AddTwoByteChar(uc32 code_unit) {
DCHECK(!is_one_byte_);
DCHECK(!is_one_byte());
if (position_ >= backing_store_.length()) ExpandBuffer();
if (code_unit <=
static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) {
......
......@@ -453,19 +453,21 @@ class Scanner {
class LiteralBuffer {
public:
LiteralBuffer()
: backing_store_(), position_(0), is_one_byte_(true), is_used_(false) {}
: backing_store_(),
position_(0),
flags_(IsOneByte::encode(true) | IsUsedByte::encode(false)) {}
~LiteralBuffer() { backing_store_.Dispose(); }
V8_INLINE void AddChar(char code_unit) {
DCHECK(is_used_);
DCHECK(is_used());
DCHECK(IsValidAscii(code_unit));
AddOneByteChar(static_cast<byte>(code_unit));
}
V8_INLINE void AddChar(uc32 code_unit) {
DCHECK(is_used_);
if (is_one_byte_) {
DCHECK(is_used());
if (is_one_byte()) {
if (code_unit <= static_cast<uc32>(unibrow::Latin1::kMaxChar)) {
AddOneByteChar(static_cast<byte>(code_unit));
return;
......@@ -475,17 +477,17 @@ class Scanner {
AddTwoByteChar(code_unit);
}
bool is_one_byte() const { return is_one_byte_; }
bool is_one_byte() const { return IsOneByte::decode(flags_); }
bool Equals(Vector<const char> keyword) const {
DCHECK(is_used_);
DCHECK(is_used());
return is_one_byte() && keyword.length() == position_ &&
(memcmp(keyword.start(), backing_store_.start(), position_) == 0);
}
Vector<const uint16_t> two_byte_literal() const {
DCHECK(!is_one_byte_);
DCHECK(is_used_);
DCHECK(!is_one_byte());
DCHECK(is_used());
DCHECK_EQ(position_ & 0x1, 0);
return Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(backing_store_.start()),
......@@ -493,26 +495,25 @@ class Scanner {
}
Vector<const uint8_t> one_byte_literal() const {
DCHECK(is_one_byte_);
DCHECK(is_used_);
DCHECK(is_one_byte());
DCHECK(is_used());
return Vector<const uint8_t>(
reinterpret_cast<const uint8_t*>(backing_store_.start()), position_);
}
int length() const { return is_one_byte_ ? position_ : (position_ >> 1); }
int length() const { return is_one_byte() ? position_ : (position_ >> 1); }
void Start() {
DCHECK(!is_used_);
DCHECK(!is_used());
DCHECK_EQ(0, position_);
is_used_ = true;
flags_ = IsUsedByte::update(flags_, true);
}
bool is_used() const { return is_used_; }
bool is_used() const { return IsUsedByte::decode(flags_); }
void Drop() {
is_used_ = false;
position_ = 0;
is_one_byte_ = true;
flags_ = IsOneByte::encode(true) | IsUsedByte::encode(false);
}
Handle<String> Internalize(Isolate* isolate) const;
......@@ -532,7 +533,7 @@ class Scanner {
}
V8_INLINE void AddOneByteChar(byte one_byte_char) {
DCHECK(is_one_byte_);
DCHECK(is_one_byte());
if (position_ >= backing_store_.length()) ExpandBuffer();
backing_store_[position_] = one_byte_char;
position_ += kOneByteSize;
......@@ -545,8 +546,11 @@ class Scanner {
Vector<byte> backing_store_;
int position_;
bool is_one_byte_ : 1;
bool is_used_ : 1;
uint8_t flags_;
// Flags
typedef BitField8<bool, 0, 1> IsOneByte;
typedef BitField8<bool, 1, 2> IsUsedByte;
DISALLOW_COPY_AND_ASSIGN(LiteralBuffer);
};
......
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