Commit 150887a1 authored by hajimehoshi's avatar hajimehoshi Committed by Commit bot

Add Add ExternalStringResourceBase::IsCompressible

This CL introduces ExternalStringResourceBase::IsCompressible.

This CL is a preparation for CompressibleString, which can
be compressed for memory reduction in Blink. We've found that
JavaScript strings account for a relatively large part of Blink
memory usage, and we are now trying to replace JavaScript String/
AtomicString with CompressibleString.

When a string is compressed, the original char data is deleted
and V8 pointer cache becomes invalid. This CL introduces
isCompressible  property and if an external string's isCompressble
return true, this is stored short_external_*_map instead of
external_*_map so that V8 always requires the char pointer whenever
V8 needs the string data.

BUG=chromium:574317
LOG=n

Review URL: https://codereview.chromium.org/1490193002

Cr-Commit-Position: refs/heads/master@{#33224}
parent 2bd9bdbe
......@@ -2198,6 +2198,8 @@ class V8_EXPORT String : public Name {
public:
virtual ~ExternalStringResourceBase() {}
virtual bool IsCompressible() const { return false; }
protected:
ExternalStringResourceBase() {}
......
......@@ -670,7 +670,13 @@ MaybeHandle<String> Factory::NewExternalStringFromOneByte(
THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
}
Handle<Map> map = external_one_byte_string_map();
Handle<Map> map;
if (resource->IsCompressible()) {
// TODO(hajimehoshi): Rename this to 'uncached_external_one_byte_string_map'
map = short_external_one_byte_string_map();
} else {
map = external_one_byte_string_map();
}
Handle<ExternalOneByteString> external_string =
New<ExternalOneByteString>(map, NEW_SPACE);
external_string->set_length(static_cast<int>(length));
......@@ -693,8 +699,15 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
static const size_t kOneByteCheckLengthLimit = 32;
bool is_one_byte = length <= kOneByteCheckLengthLimit &&
String::IsOneByte(resource->data(), static_cast<int>(length));
Handle<Map> map = is_one_byte ?
external_string_with_one_byte_data_map() : external_string_map();
Handle<Map> map;
if (resource->IsCompressible()) {
// TODO(hajimehoshi): Rename these to 'uncached_external_string_...'.
map = is_one_byte ? short_external_string_with_one_byte_data_map()
: short_external_string_map();
} else {
map = is_one_byte ? external_string_with_one_byte_data_map()
: external_string_map();
}
Handle<ExternalTwoByteString> external_string =
New<ExternalTwoByteString>(map, NEW_SPACE);
external_string->set_length(static_cast<int>(length));
......
......@@ -1748,6 +1748,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Externalizing twice leaks the external resource, so it's
// prohibited by the API.
DCHECK(!this->IsExternalString());
DCHECK(!resource->IsCompressible());
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
// Assert that the resource and the string are equivalent.
......@@ -1810,6 +1811,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
// Externalizing twice leaks the external resource, so it's
// prohibited by the API.
DCHECK(!this->IsExternalString());
DCHECK(!resource->IsCompressible());
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
// Assert that the resource and the string are equivalent.
......
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