From f75c5acde7e76aebff758d4054826f19579e9a4e Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 30 Jan 2017 19:07:54 +0100 Subject: [PATCH] Bug 1334744 - Add a faster API for working with external strings. r=luke --HG-- extra : rebase_source : 99b93a6cb0dde0960d1d4349498dd3e61fefec56 --- js/src/jsfriendapi.h | 17 +++++++++++++++++ js/src/vm/String.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 56181b9f65db..d6b4e7e9bf56 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -567,6 +567,7 @@ struct String static const uint32_t INLINE_CHARS_BIT = JS_BIT(2); static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6); static const uint32_t ROPE_FLAGS = 0; + static const uint32_t EXTERNAL_FLAGS = JS_BIT(5); static const uint32_t TYPE_FLAGS_MASK = JS_BIT(6) - 1; uint32_t flags; uint32_t length; @@ -576,6 +577,7 @@ struct String JS::Latin1Char inlineStorageLatin1[1]; char16_t inlineStorageTwoByte[1]; }; + const JSStringFinalizer* externalFinalizer; }; } /* namespace shadow */ @@ -830,6 +832,21 @@ GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom)); } +MOZ_ALWAYS_INLINE bool +IsExternalString(JSString* str, const JSStringFinalizer** fin, const char16_t** chars) +{ + using shadow::String; + String* s = reinterpret_cast(str); + + if ((s->flags & String::TYPE_FLAGS_MASK) != String::EXTERNAL_FLAGS) + return false; + + MOZ_ASSERT(JS_IsExternalString(str)); + *fin = s->externalFinalizer; + *chars = s->nonInlineCharsTwoByte; + return true; +} + JS_FRIEND_API(JSLinearString*) StringToLinearStringSlow(JSContext* cx, JSString* str); diff --git a/js/src/vm/String.h b/js/src/vm/String.h index e76c96ccd64c..9d3a45cb3fed 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -302,6 +302,8 @@ class JSString : public js::gc::TenuredCell "shadow::String nonInlineChars offset must match JSString"); static_assert(offsetof(JSString, d.s.u2.nonInlineCharsTwoByte) == offsetof(String, nonInlineCharsTwoByte), "shadow::String nonInlineChars offset must match JSString"); + static_assert(offsetof(JSString, d.s.u3.externalFinalizer) == offsetof(String, externalFinalizer), + "shadow::String externalFinalizer offset must match JSString"); static_assert(offsetof(JSString, d.inlineStorageLatin1) == offsetof(String, inlineStorageLatin1), "shadow::String inlineStorage offset must match JSString"); static_assert(offsetof(JSString, d.inlineStorageTwoByte) == offsetof(String, inlineStorageTwoByte), @@ -314,6 +316,8 @@ class JSString : public js::gc::TenuredCell "shadow::String::TYPE_FLAGS_MASK must match JSString::TYPE_FLAGS_MASK"); static_assert(ROPE_FLAGS == String::ROPE_FLAGS, "shadow::String::ROPE_FLAGS must match JSString::ROPE_FLAGS"); + static_assert(EXTERNAL_FLAGS == String::EXTERNAL_FLAGS, + "shadow::String::EXTERNAL_FLAGS must match JSString::EXTERNAL_FLAGS"); } /* Avoid lame compile errors in JSRope::flatten */