Commit 79d9e18c authored by marja's avatar marja Committed by Commit bot

De-virtualize AstString & rearrange fields.

This saves memory when parsing.

BUG=

Review-Url: https://codereview.chromium.org/2220363002
Cr-Commit-Position: refs/heads/master@{#38434}
parent b920d5f3
......@@ -58,7 +58,7 @@ class AstRawStringInternalizationKey : public HashTableKey {
: string_(string) {}
bool IsMatch(Object* other) override {
if (string_->is_one_byte_)
if (string_->is_one_byte())
return String::cast(other)->IsOneByteEqualTo(string_->literal_bytes_);
return String::cast(other)->IsTwoByteEqualTo(
Vector<const uint16_t>::cast(string_->literal_bytes_));
......@@ -71,7 +71,7 @@ class AstRawStringInternalizationKey : public HashTableKey {
}
Handle<Object> AsHandle(Isolate* isolate) override {
if (string_->is_one_byte_)
if (string_->is_one_byte())
return isolate->factory()->NewOneByteInternalizedString(
string_->literal_bytes_, string_->hash());
return isolate->factory()->NewTwoByteInternalizedString(
......@@ -82,6 +82,19 @@ class AstRawStringInternalizationKey : public HashTableKey {
const AstRawString* string_;
};
int AstString::length() const {
if (IsRawStringBits::decode(bit_field_)) {
return reinterpret_cast<const AstRawString*>(this)->length();
}
return reinterpret_cast<const AstConsString*>(this)->length();
}
void AstString::Internalize(Isolate* isolate) {
if (IsRawStringBits::decode(bit_field_)) {
return reinterpret_cast<AstRawString*>(this)->Internalize(isolate);
}
return reinterpret_cast<AstConsString*>(this)->Internalize(isolate);
}
void AstRawString::Internalize(Isolate* isolate) {
if (!string_.is_null()) return;
......@@ -97,7 +110,7 @@ void AstRawString::Internalize(Isolate* isolate) {
bool AstRawString::AsArrayIndex(uint32_t* index) const {
if (!string_.is_null())
return string_->AsArrayIndex(index);
if (!is_one_byte_ || literal_bytes_.length() == 0 ||
if (!is_one_byte() || literal_bytes_.length() == 0 ||
literal_bytes_.length() > String::kMaxArrayIndexSize)
return false;
OneByteStringStream stream(literal_bytes_);
......@@ -107,7 +120,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
bool AstRawString::IsOneByteEqualTo(const char* data) const {
int length = static_cast<int>(strlen(data));
if (is_one_byte_ && literal_bytes_.length() == length) {
if (is_one_byte() && literal_bytes_.length() == length) {
const char* token = reinterpret_cast<const char*>(literal_bytes_.start());
return !strncmp(token, data, length);
}
......
......@@ -42,13 +42,16 @@ namespace internal {
class AstString : public ZoneObject {
public:
virtual ~AstString() {}
explicit AstString(bool is_raw)
: bit_field_(IsRawStringBits::encode(is_raw)) {}
virtual int length() const = 0;
~AstString() {}
int length() const;
bool IsEmpty() const { return length() == 0; }
// Puts the string into the V8 heap.
virtual void Internalize(Isolate* isolate) = 0;
void Internalize(Isolate* isolate);
// This function can be called after internalizing.
V8_INLINE Handle<String> string() const {
......@@ -59,20 +62,23 @@ class AstString : public ZoneObject {
protected:
// This is null until the string is internalized.
Handle<String> string_;
// Poor-man's virtual dispatch to AstRawString / AstConsString. Takes less
// memory.
class IsRawStringBits : public BitField<bool, 0, 1> {};
int bit_field_;
};
class AstRawString final : public AstString {
public:
int length() const override {
if (is_one_byte_)
return literal_bytes_.length();
int length() const {
if (is_one_byte()) return literal_bytes_.length();
return literal_bytes_.length() / 2;
}
int byte_length() const { return literal_bytes_.length(); }
void Internalize(Isolate* isolate) override;
void Internalize(Isolate* isolate);
bool AsArrayIndex(uint32_t* index) const;
......@@ -80,11 +86,12 @@ class AstRawString final : public AstString {
const unsigned char* raw_data() const {
return literal_bytes_.start();
}
bool is_one_byte() const { return is_one_byte_; }
bool is_one_byte() const { return IsOneByteBits::decode(bit_field_); }
bool IsOneByteEqualTo(const char* data) const;
uint16_t FirstCharacter() const {
if (is_one_byte_)
return literal_bytes_[0];
if (is_one_byte()) return literal_bytes_[0];
const uint16_t* c =
reinterpret_cast<const uint16_t*>(literal_bytes_.start());
return *c;
......@@ -101,28 +108,33 @@ class AstRawString final : public AstString {
AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
uint32_t hash)
: is_one_byte_(is_one_byte), literal_bytes_(literal_bytes), hash_(hash) {}
: AstString(true), hash_(hash), literal_bytes_(literal_bytes) {
bit_field_ |= IsOneByteBits::encode(is_one_byte);
}
AstRawString()
: is_one_byte_(true),
hash_(0) {}
AstRawString() : AstString(true), hash_(0) {
bit_field_ |= IsOneByteBits::encode(true);
}
bool is_one_byte_;
class IsOneByteBits : public BitField<bool, IsRawStringBits::kNext, 1> {};
uint32_t hash_;
// Points to memory owned by Zone.
Vector<const byte> literal_bytes_;
uint32_t hash_;
};
class AstConsString final : public AstString {
public:
AstConsString(const AstString* left, const AstString* right)
: length_(left->length() + right->length()), left_(left), right_(right) {}
: AstString(false),
length_(left->length() + right->length()),
left_(left),
right_(right) {}
int length() const override { return length_; }
int length() const { return length_; }
void Internalize(Isolate* isolate) override;
void Internalize(Isolate* isolate);
private:
const int length_;
......
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