summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-01-04 12:50:03 +0000
committerSteve Block <steveblock@google.com>2010-01-04 14:28:06 +0000
commit10ceded39bd4b259c4921d2a07d322d5e1244ba6 (patch)
treef917de3f73ffaf1f3a468856b78770e1614f204b /JavaScriptCore/runtime
parent84a4799558b021d8ab6c19a7fa787e2731aa1fe3 (diff)
downloadexternal_webkit-10ceded39bd4b259c4921d2a07d322d5e1244ba6.zip
external_webkit-10ceded39bd4b259c4921d2a07d322d5e1244ba6.tar.gz
external_webkit-10ceded39bd4b259c4921d2a07d322d5e1244ba6.tar.bz2
Cherry-picks a WebKit change to revert recent changes to String addition for JSC.
WebKit change http://trac.webkit.org/changeset/51975 modified String addition in JSC to use ropes. However, the change was incorrect, so was rolled back in http://trac.webkit.org/changeset/51978. The last WebKit merge was to revision r51976, so picked up the initial, broken change only. This change cherry-picks http://trac.webkit.org/changeset/51978 to revert the original change. Bug: 2336856 Change-Id: I7f48bce6a7f605779424ba0a7601524ab3a71990
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/JSString.h35
-rw-r--r--JavaScriptCore/runtime/Operations.cpp11
-rw-r--r--JavaScriptCore/runtime/Operations.h69
3 files changed, 28 insertions, 87 deletions
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 1867b17..93b11f1 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -203,32 +203,6 @@ namespace JSC {
appendStringInConstruct(index, s2);
ASSERT(ropeLength == index);
}
- // This constructor constructs a new string by concatenating s1 & s2.
- // This should only be called with ropeLength <= 3.
- JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, const UString& u2)
- : JSCell(globalData->stringStructure.get())
- , m_stringLength(s1->length() + u2.size())
- , m_ropeLength(ropeLength)
- {
- ASSERT(ropeLength <= s_maxInternalRopeLength);
- unsigned index = 0;
- appendStringInConstruct(index, s1);
- appendStringInConstruct(index, u2);
- ASSERT(ropeLength == index);
- }
- // This constructor constructs a new string by concatenating s1 & s2.
- // This should only be called with ropeLength <= 3.
- JSString(JSGlobalData* globalData, unsigned ropeLength, const UString& u1, JSString* s2)
- : JSCell(globalData->stringStructure.get())
- , m_stringLength(u1.size() + s2->length())
- , m_ropeLength(ropeLength)
- {
- ASSERT(ropeLength <= s_maxInternalRopeLength);
- unsigned index = 0;
- appendStringInConstruct(index, u1);
- appendStringInConstruct(index, s2);
- ASSERT(ropeLength == index);
- }
// This constructor constructs a new string by concatenating v1, v2 & v3.
// This should only be called with ropeLength <= 3 ... which since every
// value must require a ropeLength of at least one implies that the length
@@ -284,18 +258,13 @@ namespace JSC {
void resolveRope(ExecState*) const;
- void appendStringInConstruct(unsigned& index, const UString& string)
- {
- m_fibers[index++] = Rope::Fiber(string.rep()->ref());
- }
-
void appendStringInConstruct(unsigned& index, JSString* jsString)
{
if (jsString->isRope()) {
for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
m_fibers[index++] = jsString->m_fibers[i].ref();
} else
- appendStringInConstruct(index, jsString->string());
+ m_fibers[index++] = Rope::Fiber(jsString->string().rep()->ref());
}
void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v)
@@ -342,8 +311,6 @@ namespace JSC {
unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; }
friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
- friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
- friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
};
diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index 0e1887c..139c7b8 100644
--- a/JavaScriptCore/runtime/Operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -54,13 +54,12 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
JSValue p1 = v1.toPrimitive(callFrame);
JSValue p2 = v2.toPrimitive(callFrame);
- if (p1.isString()) {
- return p2.isString()
- ? jsString(callFrame, asString(p1), asString(p2))
- : jsString(callFrame, asString(p1), p2.toString(callFrame));
+ if (p1.isString() || p2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
}
- if (p2.isString())
- return jsString(callFrame, p1.toString(callFrame), asString(p2));
return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index 0289ac2..1cab06d 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -37,11 +37,6 @@ namespace JSC {
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
{
- if (!s1->length())
- return s2;
- if (!s2->length())
- return s1;
-
unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
JSGlobalData* globalData = &exec->globalData();
@@ -58,42 +53,6 @@ namespace JSC {
return new (globalData) JSString(globalData, rope.release());
}
- ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
- {
- unsigned ropeLength = 1 + s2->ropeLength();
- JSGlobalData* globalData = &exec->globalData();
-
- if (ropeLength <= JSString::s_maxInternalRopeLength)
- return new (globalData) JSString(globalData, ropeLength, u1, s2);
-
- unsigned index = 0;
- RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
- if (UNLIKELY(!rope))
- return throwOutOfMemoryError(exec);
- rope->append(index, u1);
- rope->append(index, s2);
- ASSERT(index == ropeLength);
- return new (globalData) JSString(globalData, rope.release());
- }
-
- ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
- {
- unsigned ropeLength = s1->ropeLength() + 1;
- JSGlobalData* globalData = &exec->globalData();
-
- if (ropeLength <= JSString::s_maxInternalRopeLength)
- return new (globalData) JSString(globalData, ropeLength, s1, u2);
-
- unsigned index = 0;
- RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
- if (UNLIKELY(!rope))
- return throwOutOfMemoryError(exec);
- rope->append(index, s1);
- rope->append(index, u2);
- ASSERT(index == ropeLength);
- return new (globalData) JSString(globalData, rope.release());
- }
-
ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
{
ASSERT(count >= 3);
@@ -288,14 +247,30 @@ namespace JSC {
ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
{
- double left = 0.0, right;
- if (v1.getNumber(left), v2.getNumber(right))
+ double left;
+ double right = 0.0;
+
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
return jsNumber(callFrame, left + right);
- if (v1.isString()) {
- return v2.isString()
- ? jsString(callFrame, asString(v1), asString(v2))
- : jsString(callFrame, asString(v1), v2.toString(callFrame));
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
+ if (!asString(v1)->length())
+ return asString(v2);
+ if (!asString(v2)->length())
+ return asString(v1);
+ return jsString(callFrame, asString(v1), asString(v2));
+ }
+
+ if (rightIsNumber & leftIsString) {
+ RefPtr<UString::Rep> value = v2.isInt32() ?
+ concatenate(asString(v1)->value(callFrame).rep(), v2.asInt32()) :
+ concatenate(asString(v1)->value(callFrame).rep(), right);
+
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
}
// All other cases are pretty uncommon