- 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;
};