- Revision
- 184575
- Author
- akl...@apple.com
- Date
- 2015-05-19 10:06:23 -0700 (Tue, 19 May 2015)
Log Message
Give JSString a StringView getter and start using it.
<https://webkit.org/b/145131>
Reviewed by Anders Carlsson.
When JSString is a substring internally, calling value(ExecState*) on it
will reify the baseString/start/length tuple into a new StringImpl.
For clients that only want to look at the characters of a JSString, but
don't actually need a reffable StringImpl, adding a light-weight StringView
getter lets them avoid constructing anything.
This patch adds JSString::view(ExecState*) and uses it in a few places.
There are many more opportunities to use this API, but let's do a few things
at a time.
* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::decode):
(JSC::parseInt):
(JSC::jsToNumber):
(JSC::parseFloat):
(JSC::globalFuncParseInt):
(JSC::globalFuncParseFloat):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):
* runtime/JSGlobalObjectFunctions.h:
* runtime/JSONObject.cpp:
(JSC::JSONProtoFuncParse):
* runtime/JSString.cpp:
(JSC::JSString::getPrimitiveNumber):
(JSC::JSString::toNumber):
* runtime/JSString.h:
(JSC::JSRopeString::view):
(JSC::JSString::view):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (184574 => 184575)
--- trunk/Source/_javascript_Core/ChangeLog 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-05-19 17:06:23 UTC (rev 184575)
@@ -1,3 +1,42 @@
+2015-05-19 Andreas Kling <akl...@apple.com>
+
+ Give JSString a StringView getter and start using it.
+ <https://webkit.org/b/145131>
+
+ Reviewed by Anders Carlsson.
+
+ When JSString is a substring internally, calling value(ExecState*) on it
+ will reify the baseString/start/length tuple into a new StringImpl.
+
+ For clients that only want to look at the characters of a JSString, but
+ don't actually need a reffable StringImpl, adding a light-weight StringView
+ getter lets them avoid constructing anything.
+
+ This patch adds JSString::view(ExecState*) and uses it in a few places.
+ There are many more opportunities to use this API, but let's do a few things
+ at a time.
+
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunctionSkippingEvalEnabledCheck):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::decode):
+ (JSC::parseInt):
+ (JSC::jsToNumber):
+ (JSC::parseFloat):
+ (JSC::globalFuncParseInt):
+ (JSC::globalFuncParseFloat):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSONObject.cpp:
+ (JSC::JSONProtoFuncParse):
+ * runtime/JSString.cpp:
+ (JSC::JSString::getPrimitiveNumber):
+ (JSC::JSString::toNumber):
+ * runtime/JSString.h:
+ (JSC::JSRopeString::view):
+ (JSC::JSString::view):
+
2015-05-18 Filip Pizlo <fpi...@apple.com>
Better optimize 'if' with ternaries conditional tests.
Modified: trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp 2015-05-19 17:06:23 UTC (rev 184575)
@@ -103,13 +103,13 @@
builder.appendLiteral("{function ");
builder.append(functionName.string());
builder.append('(');
- builder.append(args.at(0).toString(exec)->value(exec));
+ builder.append(args.at(0).toString(exec)->view(exec));
for (size_t i = 1; i < args.size() - 1; i++) {
builder.appendLiteral(", ");
- builder.append(args.at(i).toString(exec)->value(exec));
+ builder.append(args.at(i).toString(exec)->view(exec));
}
builder.appendLiteral(") {\n");
- builder.append(args.at(args.size() - 1).toString(exec)->value(exec));
+ builder.append(args.at(args.size() - 1).toString(exec)->view(exec));
builder.appendLiteral("\n}}");
program = builder.toString();
}
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2015-05-19 17:06:23 UTC (rev 184575)
@@ -150,7 +150,7 @@
static JSValue decode(ExecState* exec, const Bitmap<256>& doNotUnescape, bool strict)
{
- String str = exec->argument(0).toString(exec)->value(exec);
+ StringView str = exec->argument(0).toString(exec)->view(exec);
if (str.is8Bit())
return decode(exec, str.characters8(), str.length(), doNotUnescape, strict);
@@ -248,7 +248,7 @@
// ES5.1 15.1.2.2
template <typename CharType>
ALWAYS_INLINE
-static double parseInt(const String& s, const CharType* data, int radix)
+static double parseInt(StringView s, const CharType* data, int radix)
{
// 1. Let inputString be ToString(string).
// 2. Let S be a newly created substring of inputString consisting of the first character that is not a
@@ -320,16 +320,16 @@
if (number >= mantissaOverflowLowerBound) {
if (radix == 10) {
size_t parsedLength;
- number = parseDouble(StringView(s).substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
+ number = parseDouble(s.substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
} else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
- number = parseIntOverflow(StringView(s).substring(firstDigitPosition, p - firstDigitPosition), radix);
+ number = parseIntOverflow(s.substring(firstDigitPosition, p - firstDigitPosition), radix);
}
// 15. Return sign x number.
return sign * number;
}
-static double parseInt(const String& s, int radix)
+static double parseInt(StringView s, int radix)
{
if (s.is8Bit())
return parseInt(s, s.characters8(), radix);
@@ -499,7 +499,7 @@
}
// See ecma-262 6th 11.8.3
-double jsToNumber(const String& s)
+double jsToNumber(StringView s)
{
unsigned size = s.length();
@@ -517,7 +517,7 @@
return toDouble(s.characters16(), size);
}
-static double parseFloat(const String& s)
+static double parseFloat(StringView s)
{
unsigned size = s.length();
@@ -610,7 +610,7 @@
}
// If ToString throws, we shouldn't call ToInt32.
- String s = value.toString(exec)->value(exec);
+ StringView s = value.toString(exec)->view(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
@@ -619,7 +619,7 @@
EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
{
- return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->value(exec))));
+ return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->view(exec))));
}
EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec)
@@ -682,7 +682,7 @@
);
JSStringBuilder builder;
- String str = exec->argument(0).toString(exec)->value(exec);
+ StringView str = exec->argument(0).toString(exec)->view(exec);
if (str.is8Bit()) {
const LChar* c = str.characters8();
for (unsigned k = 0; k < str.length(); k++, c++) {
@@ -720,7 +720,7 @@
EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
{
StringBuilder builder;
- String str = exec->argument(0).toString(exec)->value(exec);
+ StringView str = exec->argument(0).toString(exec)->view(exec);
int k = 0;
int len = str.length();
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2015-05-19 17:06:23 UTC (rev 184575)
@@ -60,7 +60,7 @@
static const double mantissaOverflowLowerBound = 9007199254740992.0;
double parseIntOverflow(const LChar*, unsigned length, int radix);
bool isStrWhiteSpace(UChar);
-double jsToNumber(const WTF::String&);
+double jsToNumber(StringView);
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp 2015-05-19 17:06:23 UTC (rev 184575)
@@ -719,7 +719,7 @@
{
if (!exec->argumentCount())
return throwVMError(exec, createError(exec, ASCIILiteral("JSON.parse requires at least one parameter")));
- String source = exec->uncheckedArgument(0).toString(exec)->value(exec);
+ StringView source = exec->uncheckedArgument(0).toString(exec)->view(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
Modified: trunk/Source/_javascript_Core/runtime/JSString.cpp (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/JSString.cpp 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/JSString.cpp 2015-05-19 17:06:23 UTC (rev 184575)
@@ -385,7 +385,7 @@
bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) const
{
result = this;
- number = jsToNumber(value(exec));
+ number = jsToNumber(view(exec));
return false;
}
@@ -396,7 +396,7 @@
double JSString::toNumber(ExecState* exec) const
{
- return jsToNumber(value(exec));
+ return jsToNumber(view(exec));
}
inline StringObject* StringObject::create(VM& vm, JSGlobalObject* globalObject, JSString* string)
Modified: trunk/Source/_javascript_Core/runtime/JSString.h (184574 => 184575)
--- trunk/Source/_javascript_Core/runtime/JSString.h 2015-05-19 16:46:52 UTC (rev 184574)
+++ trunk/Source/_javascript_Core/runtime/JSString.h 2015-05-19 17:06:23 UTC (rev 184575)
@@ -30,6 +30,7 @@
#include "PropertySlot.h"
#include "Structure.h"
#include <array>
+#include <wtf/text/StringView.h>
namespace JSC {
@@ -143,6 +144,7 @@
Identifier toIdentifier(ExecState*) const;
AtomicString toAtomicString(ExecState*) const;
AtomicStringImpl* toExistingAtomicString(ExecState*) const;
+ StringView view(ExecState*) const;
const String& value(ExecState*) const;
const String& tryGetValue() const;
const StringImpl* tryGetValueImpl() const;
@@ -369,6 +371,7 @@
void resolveRopeInternal16(UChar*) const;
void resolveRopeInternal16NoSubstring(UChar*) const;
void clearFibers() const;
+ StringView view(ExecState*) const;
JS_EXPORT_PRIVATE JSString* getIndexSlowCase(ExecState*, unsigned);
@@ -698,6 +701,24 @@
return inlineJSValueNotStringtoString(*this, exec);
}
+ALWAYS_INLINE StringView JSRopeString::view(ExecState* exec) const
+{
+ if (isSubstring()) {
+ if (is8Bit())
+ return StringView(substringBase()->m_value.characters8() + substringOffset(), m_length);
+ return StringView(substringBase()->m_value.characters16() + substringOffset(), m_length);
+ }
+ resolveRope(exec);
+ return StringView(m_value);
+}
+
+ALWAYS_INLINE StringView JSString::view(ExecState* exec) const
+{
+ if (isRope())
+ return static_cast<const JSRopeString*>(this)->view(exec);
+ return StringView(m_value);
+}
+
} // namespace JSC
#endif // JSString_h