Title: [111433] trunk/Source/_javascript_Core
Revision
111433
Author
[email protected]
Date
2012-03-20 13:22:57 -0700 (Tue, 20 Mar 2012)

Log Message

Cache the type string of _javascript_ object
https://bugs.webkit.org/show_bug.cgi?id=81446

Patch by Benjamin Poulain <[email protected]> on 2012-03-20
Reviewed by Geoffrey Garen.

Instead of creating the JSString every time, we create
lazily the strings in JSGlobalData.

This avoid the construction of the StringImpl and of the JSString,
which gives some performance improvements.

* runtime/CommonIdentifiers.h:
* runtime/JSValue.cpp:
(JSC::JSValue::toStringSlowCase):
* runtime/Operations.cpp:
(JSC::jsTypeStringForValue):
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::SmallStrings):
(JSC::SmallStrings::finalizeSmallStrings):
(JSC::SmallStrings::initialize):
(JSC):
* runtime/SmallStrings.h:
(SmallStrings):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (111432 => 111433)


--- trunk/Source/_javascript_Core/ChangeLog	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-03-20 20:22:57 UTC (rev 111433)
@@ -1,3 +1,29 @@
+2012-03-20  Benjamin Poulain  <[email protected]>
+
+        Cache the type string of _javascript_ object
+        https://bugs.webkit.org/show_bug.cgi?id=81446
+
+        Reviewed by Geoffrey Garen.
+
+        Instead of creating the JSString every time, we create
+        lazily the strings in JSGlobalData.
+
+        This avoid the construction of the StringImpl and of the JSString,
+        which gives some performance improvements.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSValue.cpp:
+        (JSC::JSValue::toStringSlowCase):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::SmallStrings):
+        (JSC::SmallStrings::finalizeSmallStrings):
+        (JSC::SmallStrings::initialize):
+        (JSC):
+        * runtime/SmallStrings.h:
+        (SmallStrings):
+
 2012-03-20  Oliver Hunt  <[email protected]>
 
         Allow LLINT to work even when executable allocation fails.

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (111432 => 111433)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-03-20 20:22:57 UTC (rev 111433)
@@ -72,8 +72,7 @@
     macro(value) \
     macro(valueOf) \
     macro(writable) \
-    macro(displayName) \
-    macro(undefined)
+    macro(displayName)
 
 #define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
     macro(null) \

Modified: trunk/Source/_javascript_Core/runtime/JSValue.cpp (111432 => 111433)


--- trunk/Source/_javascript_Core/runtime/JSValue.cpp	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/runtime/JSValue.cpp	2012-03-20 20:22:57 UTC (rev 111433)
@@ -260,19 +260,20 @@
 
 JSString* JSValue::toStringSlowCase(ExecState* exec) const
 {
+    JSGlobalData& globalData = exec->globalData();
     ASSERT(!isString());
     if (isInt32())
-        return jsString(&exec->globalData(), exec->globalData().numericStrings.add(asInt32()));
+        return jsString(&globalData, globalData.numericStrings.add(asInt32()));
     if (isDouble())
-        return jsString(&exec->globalData(), exec->globalData().numericStrings.add(asDouble()));
+        return jsString(&globalData, globalData.numericStrings.add(asDouble()));
     if (isTrue())
-        return jsNontrivialString(exec, exec->propertyNames().trueKeyword.ustring());
+        return globalData.smallStrings.trueString(&globalData);
     if (isFalse())
-        return jsNontrivialString(exec, exec->propertyNames().falseKeyword.ustring());
+        return globalData.smallStrings.falseString(&globalData);
     if (isNull())
-        return jsNontrivialString(exec, exec->propertyNames().nullKeyword.ustring());
+        return globalData.smallStrings.nullString(&globalData);
     if (isUndefined())
-        return jsNontrivialString(exec, exec->propertyNames().undefined.ustring());
+        return globalData.smallStrings.undefinedString(&globalData);
 
     ASSERT(isCell());
     JSValue value = asCell()->toPrimitive(exec, PreferString);

Modified: trunk/Source/_javascript_Core/runtime/Operations.cpp (111432 => 111433)


--- trunk/Source/_javascript_Core/runtime/Operations.cpp	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp	2012-03-20 20:22:57 UTC (rev 111433)
@@ -58,25 +58,26 @@
 
 JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
 {
+    JSGlobalData& globalData = callFrame->globalData();
     if (v.isUndefined())
-        return jsNontrivialString(callFrame, "undefined");
+        return globalData.smallStrings.undefinedString(&globalData);
     if (v.isBoolean())
-        return jsNontrivialString(callFrame, "boolean");
+        return globalData.smallStrings.booleanString(&globalData);
     if (v.isNumber())
-        return jsNontrivialString(callFrame, "number");
+        return globalData.smallStrings.numberString(&globalData);
     if (v.isString())
-        return jsNontrivialString(callFrame, "string");
+        return globalData.smallStrings.stringString(&globalData);
     if (v.isObject()) {
         // Return "undefined" for objects that should be treated
         // as null when doing comparisons.
         if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
-            return jsNontrivialString(callFrame, "undefined");
+            return globalData.smallStrings.undefinedString(&globalData);
         CallData callData;
         JSObject* object = asObject(v);
         if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
-            return jsNontrivialString(callFrame, "function");
+            return globalData.smallStrings.functionString(&globalData);
     }
-    return jsNontrivialString(callFrame, "object");
+    return globalData.smallStrings.objectString(&globalData);
 }
 
 bool jsIsObjectType(JSValue v)

Modified: trunk/Source/_javascript_Core/runtime/SmallStrings.cpp (111432 => 111433)


--- trunk/Source/_javascript_Core/runtime/SmallStrings.cpp	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/runtime/SmallStrings.cpp	2012-03-20 20:22:57 UTC (rev 111433)
@@ -68,10 +68,13 @@
 }
 
 SmallStrings::SmallStrings()
+    : m_emptyString(0)
+#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) , m_##name(0)
+    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE)
+#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE
 {
     COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
 
-    m_emptyString = 0;
     for (unsigned i = 0; i < singleCharacterStringCount; ++i)
         m_singleCharacterStrings[i] = 0;
 }
@@ -85,6 +88,9 @@
     finalize(m_emptyString);
     for (unsigned i = 0; i < singleCharacterStringCount; ++i)
         finalize(m_singleCharacterStrings[i]);
+#define JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE(name) finalize(m_##name);
+    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE)
+#undef JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE
 }
 
 void SmallStrings::createEmptyString(JSGlobalData* globalData)
@@ -108,4 +114,9 @@
     return m_storage->rep(character);
 }
 
+void SmallStrings::initialize(JSGlobalData* globalData, JSString*& string, const char* value) const
+{
+    string = JSString::create(*globalData, StringImpl::create(value));
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/SmallStrings.h (111432 => 111433)


--- trunk/Source/_javascript_Core/runtime/SmallStrings.h	2012-03-20 20:07:01 UTC (rev 111432)
+++ trunk/Source/_javascript_Core/runtime/SmallStrings.h	2012-03-20 20:22:57 UTC (rev 111433)
@@ -30,6 +30,17 @@
 #include <wtf/FixedArray.h>
 #include <wtf/OwnPtr.h>
 
+#define JSC_COMMON_STRINGS_EACH_NAME(macro) \
+    macro(boolean) \
+    macro(false) \
+    macro(function) \
+    macro(number) \
+    macro(null) \
+    macro(object) \
+    macro(undefined) \
+    macro(string) \
+    macro(true)
+
 namespace JSC {
 
     class HeapRootVisitor;
@@ -66,13 +77,28 @@
 
         JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
 
+#define JSC_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
+        JSString* name##String(JSGlobalData* globalData) const \
+        { \
+            if (!m_##name) \
+                initialize(globalData, m_##name, #name); \
+            return m_##name; \
+        }
+        JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
+#undef JSC_COMMON_STRINGS_ACCESSOR_DEFINITION
+
     private:
         static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
 
         JS_EXPORT_PRIVATE void createEmptyString(JSGlobalData*);
         JS_EXPORT_PRIVATE void createSingleCharacterString(JSGlobalData*, unsigned char);
 
+        void initialize(JSGlobalData* globalData, JSString*& string, const char* value) const;
+
         JSString* m_emptyString;
+#define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) mutable JSString* m_##name;
+        JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
+#undef JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION
         JSString* m_singleCharacterStrings[singleCharacterStringCount];
         OwnPtr<SmallStringsStorage> m_storage;
     };
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to