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 { ...@@ -58,7 +58,7 @@ class AstRawStringInternalizationKey : public HashTableKey {
: string_(string) {} : string_(string) {}
bool IsMatch(Object* other) override { 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)->IsOneByteEqualTo(string_->literal_bytes_);
return String::cast(other)->IsTwoByteEqualTo( return String::cast(other)->IsTwoByteEqualTo(
Vector<const uint16_t>::cast(string_->literal_bytes_)); Vector<const uint16_t>::cast(string_->literal_bytes_));
...@@ -71,7 +71,7 @@ class AstRawStringInternalizationKey : public HashTableKey { ...@@ -71,7 +71,7 @@ class AstRawStringInternalizationKey : public HashTableKey {
} }
Handle<Object> AsHandle(Isolate* isolate) override { Handle<Object> AsHandle(Isolate* isolate) override {
if (string_->is_one_byte_) if (string_->is_one_byte())
return isolate->factory()->NewOneByteInternalizedString( return isolate->factory()->NewOneByteInternalizedString(
string_->literal_bytes_, string_->hash()); string_->literal_bytes_, string_->hash());
return isolate->factory()->NewTwoByteInternalizedString( return isolate->factory()->NewTwoByteInternalizedString(
...@@ -82,6 +82,19 @@ class AstRawStringInternalizationKey : public HashTableKey { ...@@ -82,6 +82,19 @@ class AstRawStringInternalizationKey : public HashTableKey {
const AstRawString* string_; 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) { void AstRawString::Internalize(Isolate* isolate) {
if (!string_.is_null()) return; if (!string_.is_null()) return;
...@@ -97,7 +110,7 @@ void AstRawString::Internalize(Isolate* isolate) { ...@@ -97,7 +110,7 @@ void AstRawString::Internalize(Isolate* isolate) {
bool AstRawString::AsArrayIndex(uint32_t* index) const { bool AstRawString::AsArrayIndex(uint32_t* index) const {
if (!string_.is_null()) if (!string_.is_null())
return string_->AsArrayIndex(index); 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) literal_bytes_.length() > String::kMaxArrayIndexSize)
return false; return false;
OneByteStringStream stream(literal_bytes_); OneByteStringStream stream(literal_bytes_);
...@@ -107,7 +120,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const { ...@@ -107,7 +120,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
bool AstRawString::IsOneByteEqualTo(const char* data) const { bool AstRawString::IsOneByteEqualTo(const char* data) const {
int length = static_cast<int>(strlen(data)); 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()); const char* token = reinterpret_cast<const char*>(literal_bytes_.start());
return !strncmp(token, data, length); return !strncmp(token, data, length);
} }
......
...@@ -42,13 +42,16 @@ namespace internal { ...@@ -42,13 +42,16 @@ namespace internal {
class AstString : public ZoneObject { class AstString : public ZoneObject {
public: 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; } bool IsEmpty() const { return length() == 0; }
// Puts the string into the V8 heap. // Puts the string into the V8 heap.
virtual void Internalize(Isolate* isolate) = 0; void Internalize(Isolate* isolate);
// This function can be called after internalizing. // This function can be called after internalizing.
V8_INLINE Handle<String> string() const { V8_INLINE Handle<String> string() const {
...@@ -59,20 +62,23 @@ class AstString : public ZoneObject { ...@@ -59,20 +62,23 @@ class AstString : public ZoneObject {
protected: protected:
// This is null until the string is internalized. // This is null until the string is internalized.
Handle<String> string_; 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 { class AstRawString final : public AstString {
public: public:
int length() const override { int length() const {
if (is_one_byte_) if (is_one_byte()) return literal_bytes_.length();
return literal_bytes_.length();
return literal_bytes_.length() / 2; return literal_bytes_.length() / 2;
} }
int byte_length() const { return literal_bytes_.length(); } int byte_length() const { return literal_bytes_.length(); }
void Internalize(Isolate* isolate) override; void Internalize(Isolate* isolate);
bool AsArrayIndex(uint32_t* index) const; bool AsArrayIndex(uint32_t* index) const;
...@@ -80,11 +86,12 @@ class AstRawString final : public AstString { ...@@ -80,11 +86,12 @@ class AstRawString final : public AstString {
const unsigned char* raw_data() const { const unsigned char* raw_data() const {
return literal_bytes_.start(); 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; bool IsOneByteEqualTo(const char* data) const;
uint16_t FirstCharacter() const { uint16_t FirstCharacter() const {
if (is_one_byte_) if (is_one_byte()) return literal_bytes_[0];
return literal_bytes_[0];
const uint16_t* c = const uint16_t* c =
reinterpret_cast<const uint16_t*>(literal_bytes_.start()); reinterpret_cast<const uint16_t*>(literal_bytes_.start());
return *c; return *c;
...@@ -100,29 +107,34 @@ class AstRawString final : public AstString { ...@@ -100,29 +107,34 @@ class AstRawString final : public AstString {
friend class AstRawStringInternalizationKey; friend class AstRawStringInternalizationKey;
AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes, AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
uint32_t hash) 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() AstRawString() : AstString(true), hash_(0) {
: is_one_byte_(true), bit_field_ |= IsOneByteBits::encode(true);
hash_(0) {} }
bool is_one_byte_; class IsOneByteBits : public BitField<bool, IsRawStringBits::kNext, 1> {};
uint32_t hash_;
// Points to memory owned by Zone. // Points to memory owned by Zone.
Vector<const byte> literal_bytes_; Vector<const byte> literal_bytes_;
uint32_t hash_;
}; };
class AstConsString final : public AstString { class AstConsString final : public AstString {
public: public:
AstConsString(const AstString* left, const AstString* right) 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: private:
const int length_; 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