Commit 1d43d1f5 authored by Albert J. Wong's avatar Albert J. Wong Committed by Commit Bot

Add StringView conversion operator on V8StringResource.

This allows APIs, such as DOM gettings, to take a StringView instead
of an AtomicString. On platforms where externalization isn't supported
for short strings, this will yield a speed benefit as there will be
no AtomicString created. This can especially affect (questionably
useful) microbenchmarks like blink_perf.binding get-attribute.html
which can hammer the non-externalized path on some platforms.

Usages of this API will come in a follow-up CL.

This is partially broken out of
  https://chromium-review.googlesource.com/c/chromium/src/+/2204539

which in turn is broken out of
  https://chromium-review.googlesource.com/c/chromium/src/+/1557854

Bug: 1083392
Change-Id: I44d36dadcb341042e7eaf84395be7cc4a069b392
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2261270
Auto-Submit: Albert J. Wong <ajwong@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Commit-Queue: Albert J. Wong <ajwong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782108}
parent 1261e8f6
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/bindings/string_resource.h" #include "third_party/blink/renderer/platform/bindings/string_resource.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/threading.h" #include "third_party/blink/renderer/platform/wtf/threading.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
...@@ -83,9 +84,24 @@ class V8StringResource { ...@@ -83,9 +84,24 @@ class V8StringResource {
PrepareSlow(v8::Isolate::GetCurrent(), exception_state); PrepareSlow(v8::Isolate::GetCurrent(), exception_state);
} }
// Implicit conversions needed to make Blink bindings easier to use.
// NOLINTNEXTLINE(google-explicit-constructor)
operator String() const { return ToString<String>(); } operator String() const { return ToString<String>(); }
// NOLINTNEXTLINE(google-explicit-constructor)
operator AtomicString() const { return ToString<AtomicString>(); } operator AtomicString() const { return ToString<AtomicString>(); }
// NOLINTNEXTLINE(google-explicit-constructor)
operator StringView() const {
if (LIKELY(!v8_object_.IsEmpty())) {
return ToBlinkStringView(v8_object_.As<v8::String>(), backing_store_,
mode_);
}
return g_null_atom;
}
private: private:
bool PrepareFast() { bool PrepareFast() {
if (v8_object_.IsEmpty()) if (v8_object_.IsEmpty())
...@@ -129,9 +145,7 @@ class V8StringResource { ...@@ -129,9 +145,7 @@ class V8StringResource {
template <class StringType> template <class StringType>
StringType ToString() const { StringType ToString() const {
if (LIKELY(!v8_object_.IsEmpty())) if (LIKELY(!v8_object_.IsEmpty()))
return ToBlinkString<StringType>( return ToBlinkString<StringType>(v8_object_.As<v8::String>(), mode_);
const_cast<v8::Local<v8::Value>*>(&v8_object_)->As<v8::String>(),
mode_);
return StringType(string_); return StringType(string_);
} }
...@@ -139,6 +153,8 @@ class V8StringResource { ...@@ -139,6 +153,8 @@ class V8StringResource {
v8::Local<v8::Value> v8_object_; v8::Local<v8::Value> v8_object_;
ExternalMode mode_; ExternalMode mode_;
String string_; String string_;
mutable WTF::StringView::StackBackingStore backing_store_;
}; };
template <> template <>
......
...@@ -86,8 +86,7 @@ AtomicString StringTraits<AtomicString>::FromV8String( ...@@ -86,8 +86,7 @@ AtomicString StringTraits<AtomicString>::FromV8String(
} }
template <typename StringType> template <typename StringType>
StringType ToBlinkString(v8::Local<v8::String> v8_string, StringType ToBlinkString(v8::Local<v8::String> v8_string, ExternalMode mode) {
ExternalMode external) {
{ {
// This portion of this function is very hot in certain Dromeao benchmarks. // This portion of this function is very hot in certain Dromeao benchmarks.
v8::String::Encoding encoding; v8::String::Encoding encoding;
...@@ -132,7 +131,7 @@ StringType ToBlinkString(v8::Local<v8::String> v8_string, ...@@ -132,7 +131,7 @@ StringType ToBlinkString(v8::Local<v8::String> v8_string,
: StringTraits<StringType>::template FromV8String< : StringTraits<StringType>::template FromV8String<
V8StringTwoBytesTrait>(isolate, v8_string, length)); V8StringTwoBytesTrait>(isolate, v8_string, length));
if (external != kExternalize || !v8_string->CanMakeExternal()) if (mode != kExternalize || !v8_string->CanMakeExternal())
return result; return result;
if (result.Is8Bit()) { if (result.Is8Bit()) {
...@@ -154,6 +153,33 @@ template String ToBlinkString<String>(v8::Local<v8::String>, ExternalMode); ...@@ -154,6 +153,33 @@ template String ToBlinkString<String>(v8::Local<v8::String>, ExternalMode);
template AtomicString ToBlinkString<AtomicString>(v8::Local<v8::String>, template AtomicString ToBlinkString<AtomicString>(v8::Local<v8::String>,
ExternalMode); ExternalMode);
StringView ToBlinkStringView(v8::Local<v8::String> v8_string,
StringView::StackBackingStore& backing_store,
ExternalMode mode) {
AtomicString result = ToBlinkString<AtomicString>(v8_string, mode);
// IsExternal() only checks for 2-byte external.
if (v8_string->IsExternal() || v8_string->IsExternalOneByte()) {
// The string has been externalized so v8_string will keep the StringImpl
// underlying |result| allow making it safe to just return it as the
// StringView.
return result;
}
// Externalization has failed meaning |result| cannot be counted on to exist
// after this function exits. Copy data in |backing_store| so the returned
// StringView can have a well defined lifetime.
int length = v8_string->Length();
if (result.Is8Bit()) {
LChar* lchar = backing_store.Realloc<LChar>(length);
memcpy(lchar, result.Characters8(), result.CharactersSizeInBytes());
return StringView(lchar, length);
} else {
UChar* uchar = backing_store.Realloc<UChar>(length);
memcpy(uchar, result.Characters16(), result.CharactersSizeInBytes());
return StringView(uchar, length);
}
}
// Fast but non thread-safe version. // Fast but non thread-safe version.
static String ToBlinkStringFast(int value) { static String ToBlinkStringFast(int value) {
// Caching of small strings below is not thread safe: newly constructed // Caching of small strings below is not thread safe: newly constructed
......
...@@ -242,6 +242,16 @@ enum ExternalMode { kExternalize, kDoNotExternalize }; ...@@ -242,6 +242,16 @@ enum ExternalMode { kExternalize, kDoNotExternalize };
template <typename StringType> template <typename StringType>
PLATFORM_EXPORT StringType ToBlinkString(v8::Local<v8::String>, ExternalMode); PLATFORM_EXPORT StringType ToBlinkString(v8::Local<v8::String>, ExternalMode);
// This method is similar to ToBlinkString() except when the underlying
// v8::String cannot be externalized (often happens with short strings like "id"
// on 64-bit platforms where V8 uses pointer compression) the v8::String is
// copied into the given StringView::StackBackingStore which avoids creating an
// AtomicString unnecessarily.
PLATFORM_EXPORT StringView ToBlinkStringView(v8::Local<v8::String>,
StringView::StackBackingStore&,
ExternalMode);
PLATFORM_EXPORT String ToBlinkString(int value); PLATFORM_EXPORT String ToBlinkString(int value);
} // namespace blink } // namespace blink
......
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