Diff
Modified: trunk/Source/WTF/ChangeLog (123688 => 123689)
--- trunk/Source/WTF/ChangeLog 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/ChangeLog 2012-07-26 01:05:23 UTC (rev 123689)
@@ -1,3 +1,30 @@
+2012-07-25 Benjamin Poulain <[email protected]>
+
+ Initialize QualifiedName's strings from the read only data segment
+ https://bugs.webkit.org/show_bug.cgi?id=92226
+
+ Reviewed by Anders Carlsson.
+
+ Add constructors for StringImpl and AtomicString to be able to create
+ the strings from the literal in read only memory.
+
+ * wtf/text/AtomicString.cpp:
+ (HashTranslatorCharBuffer):
+ (WTF::LCharBufferFromLiteralDataTranslator::hash):
+ (LCharBufferFromLiteralDataTranslator):
+ (WTF::LCharBufferFromLiteralDataTranslator::equal):
+ (WTF::LCharBufferFromLiteralDataTranslator::translate):
+ (WTF::AtomicString::addFromLiteralData):
+ * wtf/text/AtomicString.h:
+ (WTF::AtomicString::AtomicString):
+ (AtomicString):
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::createFromLiteral):
+ * wtf/text/StringImpl.h:
+ (WTF):
+ (StringImpl):
+ (WTF::StringImpl::createFromLiteral):
+
2012-07-25 Michael Saboff <[email protected]>
Convert HTML parser to handle 8-bit resources without converting to UChar*
Modified: trunk/Source/WTF/wtf/text/AtomicString.cpp (123688 => 123689)
--- trunk/Source/WTF/wtf/text/AtomicString.cpp 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/AtomicString.cpp 2012-07-26 01:05:23 UTC (rev 123689)
@@ -114,11 +114,13 @@
return addToStringTable<const LChar*, CStringTranslator>(c);
}
-struct UCharBuffer {
- const UChar* s;
+template<typename CharacterType>
+struct HashTranslatorCharBuffer {
+ const CharacterType* s;
unsigned length;
};
+typedef HashTranslatorCharBuffer<UChar> UCharBuffer;
struct UCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
@@ -295,6 +297,35 @@
return addToStringTable<SubstringLocation, SubstringTranslator>(buffer);
}
+typedef HashTranslatorCharBuffer<LChar> LCharBuffer;
+struct LCharBufferFromLiteralDataTranslator {
+ static unsigned hash(const LCharBuffer& buf)
+ {
+ return StringHasher::computeHash(buf.s, buf.length);
+ }
+
+ static bool equal(StringImpl* const& str, const LCharBuffer& buf)
+ {
+ return WTF::equal(str, buf.s, buf.length);
+ }
+
+ static void translate(StringImpl*& location, const LCharBuffer& buf, unsigned hash)
+ {
+ location = StringImpl::createFromLiteral(buf.s, buf.length).leakRef();
+ location->setHash(hash);
+ location->setIsAtomic(true);
+ }
+};
+
+PassRefPtr<StringImpl> AtomicString::addFromLiteralData(const LChar *characters, unsigned length)
+{
+ ASSERT(characters);
+ ASSERT(length);
+
+ LCharBuffer buffer = { characters, length };
+ return addToStringTable<LCharBuffer, LCharBufferFromLiteralDataTranslator>(buffer);
+}
+
PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r)
{
if (!r->length())
Modified: trunk/Source/WTF/wtf/text/AtomicString.h (123688 => 123689)
--- trunk/Source/WTF/wtf/text/AtomicString.h 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/AtomicString.h 2012-07-26 01:05:23 UTC (rev 123689)
@@ -51,6 +51,19 @@
ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { }
AtomicString(StringImpl* baseString, unsigned start, unsigned length) : m_string(add(baseString, start, length)) { }
+ enum ConstructFromLiteralTag { ConstructFromLiteral };
+ AtomicString(const char* characters, unsigned length, ConstructFromLiteralTag)
+ : m_string(addFromLiteralData(reinterpret_cast<const LChar*>(characters), length))
+ {
+ }
+ template<unsigned charactersCount>
+ ALWAYS_INLINE AtomicString(const char (&characters)[charactersCount], ConstructFromLiteralTag)
+ : m_string(addFromLiteralData(reinterpret_cast<const LChar*>(characters), charactersCount - 1))
+ {
+ COMPILE_ASSERT(charactersCount > 1, AtomicStringFromLiteralNotEmpty);
+ COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), AtomicStringFromLiteralCannotOverflow);
+ }
+
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
// We have to declare the copy constructor and copy assignment operator as well, otherwise
// they'll be implicitly deleted by adding the move constructor and move assignment operator.
@@ -156,6 +169,7 @@
return r;
return addSlowCase(r);
}
+ WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> addFromLiteralData(const LChar *characters, unsigned length);
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
WTF_EXPORT_PRIVATE static AtomicString fromUTF8Internal(const char*, const char*);
};
Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (123688 => 123689)
--- trunk/Source/WTF/wtf/text/StringImpl.cpp 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp 2012-07-26 01:05:23 UTC (rev 123689)
@@ -82,6 +82,12 @@
m_substringBuffer->deref();
}
+PassRefPtr<StringImpl> StringImpl::createFromLiteral(const LChar* characters, unsigned length)
+{
+ ASSERT(charactersAreAllASCII<LChar>(characters, length));
+ return adoptRef(new StringImpl(characters, length));
+}
+
PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
{
if (!length) {
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (123688 => 123689)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2012-07-26 01:05:23 UTC (rev 123689)
@@ -58,6 +58,7 @@
struct CStringTranslator;
struct HashAndCharactersTranslator;
struct HashAndUTF8CharactersTranslator;
+struct LCharBufferFromLiteralDataTranslator;
struct SubstringTranslator;
struct UCharBufferTranslator;
@@ -75,6 +76,7 @@
friend struct WTF::CStringTranslator;
friend struct WTF::HashAndCharactersTranslator;
friend struct WTF::HashAndUTF8CharactersTranslator;
+ friend struct WTF::LCharBufferFromLiteralDataTranslator;
friend struct WTF::SubstringTranslator;
friend struct WTF::UCharBufferTranslator;
friend class AtomicStringImpl;
@@ -282,6 +284,16 @@
return adoptRef(new StringImpl(rep->m_data16 + offset, length, ownerRep));
}
+ WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createFromLiteral(const LChar* characters, unsigned length);
+ template<unsigned charactersCount>
+ ALWAYS_INLINE static PassRefPtr<StringImpl> createFromLiteral(const char (&characters)[charactersCount])
+ {
+ COMPILE_ASSERT(charactersCount > 1, StringImplFromLiteralNotEmpty);
+ COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), StringImplFromLiteralCannotOverflow);
+
+ return createFromLiteral(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
+ }
+
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data);
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
template <typename T> static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, T*& output)
Modified: trunk/Source/WebCore/ChangeLog (123688 => 123689)
--- trunk/Source/WebCore/ChangeLog 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/ChangeLog 2012-07-26 01:05:23 UTC (rev 123689)
@@ -1,3 +1,33 @@
+2012-07-25 Benjamin Poulain <[email protected]>
+
+ Initialize QualifiedName's strings from the read only data segment
+ https://bugs.webkit.org/show_bug.cgi?id=92226
+
+ Reviewed by Anders Carlsson.
+
+ Modify the initialization of static QualifiedName to initialize the AtomicString
+ with the data from the read only memory.
+
+ Overall, HTMLNames::init() gets 10% faster.
+
+ * dom/QualifiedName.cpp:
+ (WebCore::QualifiedName::QualifiedName):
+ * dom/QualifiedName.h:
+ (QualifiedName):
+ Remove the useless constructor taking a char* and get rid of the init() function.
+ The AtomicString representing the name should be constructed by the caller of QualifiedName.
+
+ Because the init() code is relatively large and is only executed once, it is important to
+ keep the AtomicString construction separate. The function createQualifiedName() was added
+ to improve the cache use. The short version let us reduce the code one more instruction per
+ call.
+
+ * dom/make_names.pl:
+ (printQualifiedNameMaker):
+ (printShortQualifiedNameMaker):
+ (printNamesCppFile):
+ (printDefinitions):
+
2012-07-25 Yoshifumi Inoue <[email protected]>
[Forms] Move HTMLInputElement::updateInnerTextValue to InputType class
Modified: trunk/Source/WebCore/dom/QualifiedName.cpp (123688 => 123689)
--- trunk/Source/WebCore/dom/QualifiedName.cpp 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/QualifiedName.cpp 2012-07-26 01:05:23 UTC (rev 123689)
@@ -78,7 +78,7 @@
static QNameSet* gNameCache;
-void QualifiedName::init(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
if (!gNameCache)
gNameCache = new QNameSet;
@@ -89,16 +89,6 @@
m_impl->ref();
}
-QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
-{
- init(p, l, n);
-}
-
-QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n)
-{
- init(p, AtomicString(l), n);
-}
-
QualifiedName::~QualifiedName()
{
deref();
@@ -151,4 +141,16 @@
return m_impl->m_localNameUpper;
}
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength, const AtomicString& nameNamespace)
+{
+ AtomicString atomicName(name, nameLength, AtomicString::ConstructFromLiteral);
+ new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, atomicName, nameNamespace);
}
+
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength)
+{
+ AtomicString atomicName(name, nameLength, AtomicString::ConstructFromLiteral);
+ new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, atomicName, nullAtom);
+}
+
+}
Modified: trunk/Source/WebCore/dom/QualifiedName.h (123688 => 123689)
--- trunk/Source/WebCore/dom/QualifiedName.h 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/QualifiedName.h 2012-07-26 01:05:23 UTC (rev 123689)
@@ -69,7 +69,6 @@
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
- QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
~QualifiedName();
@@ -108,7 +107,6 @@
info.addInstrumentedMember(m_impl);
}
private:
- void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
void ref() const { m_impl->ref(); }
void deref();
@@ -147,6 +145,9 @@
static const bool safeToCompareToEmptyOrDeleted = false;
};
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength);
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength, const AtomicString& nameNamespace);
+
}
namespace WTF {
Modified: trunk/Source/WebCore/dom/make_names.pl (123688 => 123689)
--- trunk/Source/WebCore/dom/make_names.pl 2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/make_names.pl 2012-07-26 01:05:23 UTC (rev 123689)
@@ -116,7 +116,7 @@
printCppHead($F, "CSS", $familyNamesFileBase, "WTF");
while ( my ($name, $identifier) = each %parameters ) {
- print F "DEFINE_GLOBAL(AtomicString, $name, \"$identifier\")\n";
+ print F "DEFINE_GLOBAL(AtomicString, $name)\n";
}
printInit($F, 0);
@@ -624,12 +624,12 @@
my $lowerNamespace = lc($parameters{namespacePrefix});
- print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{namespaceURI}\")\n\n";
+ print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI)\n\n";
if (keys %allTags) {
print F "// Tags\n";
for my $name (sort keys %allTags) {
- print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI)\n";
+ print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag)\n";
}
print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Tags(size_t* size)\n";
@@ -646,7 +646,7 @@
if (keys %allAttrs) {
print F "\n// Attributes\n";
for my $name (sort keys %allAttrs) {
- print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI)\n";
+ print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
}
print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Attrs(size_t* size)\n";
print F "{\n static WebCore::QualifiedName* $parameters{namespace}Attr[] = {\n";
@@ -660,9 +660,9 @@
}
printInit($F, 0);
-
- print(F " AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\");\n\n");
+ print(F " AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
+
print(F " // Namespace\n");
print(F " new ((void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n\n");
if (keys %allTags) {
@@ -771,7 +771,13 @@
$realName = $name;
$realName =~ s/_/-/g;
}
- print F " new ((void*)&$name","${shortCamelType}) QualifiedName(nullAtom, \"$realName\", $namespaceURI);\n";
+
+ # To generate less code in init(), the common case of nullAtom for the namespace, we call createQualifiedName() without passing $namespaceURI.
+ if ($namespaceURI eq "nullAtom") {
+ print F " createQualifiedName((void*)&$name","${shortCamelType}, \"$realName\", ", length $realName ,");\n";
+ } else {
+ print F " createQualifiedName((void*)&$name","${shortCamelType}, \"$realName\", ", length $realName ,", $namespaceURI);\n";
+ }
}
}