diff options
author | Steve Block <steveblock@google.com> | 2010-01-04 12:50:03 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-01-04 14:28:06 +0000 |
commit | 10ceded39bd4b259c4921d2a07d322d5e1244ba6 (patch) | |
tree | f917de3f73ffaf1f3a468856b78770e1614f204b | |
parent | 84a4799558b021d8ab6c19a7fa787e2731aa1fe3 (diff) | |
download | external_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
-rw-r--r-- | JavaScriptCore/ChangeLog | 16 | ||||
-rw-r--r-- | JavaScriptCore/jit/JITStubs.cpp | 29 | ||||
-rw-r--r-- | JavaScriptCore/runtime/JSString.h | 35 | ||||
-rw-r--r-- | JavaScriptCore/runtime/Operations.cpp | 11 | ||||
-rw-r--r-- | JavaScriptCore/runtime/Operations.h | 69 |
5 files changed, 66 insertions, 94 deletions
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 3e9187b..829cc98 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,19 @@ +2009-12-10 Adam Barth <abarth@webkit.org> + + No review, rolling out r51975. + http://trac.webkit.org/changeset/51975 + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/JSString.h: + (JSC::JSString::JSString): + (JSC::JSString::appendStringInConstruct): + * runtime/Operations.cpp: + (JSC::jsAddSlowCase): + * runtime/Operations.h: + (JSC::jsString): + (JSC::jsAdd): + 2009-12-10 Oliver Hunt <oliver@apple.com> Reviewed by Gavin Barraclough. diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index 8dd7a97..cace8b2 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -1033,19 +1033,34 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) JSValue v1 = stackFrame.args[0].jsValue(); JSValue v2 = stackFrame.args[1].jsValue(); + + double left; + double right = 0.0; + + bool rightIsNumber = v2.getNumber(right); + if (rightIsNumber && v1.getNumber(left)) + return JSValue::encode(jsNumber(stackFrame.globalData, left + right)); + CallFrame* callFrame = stackFrame.callFrame; - if (v1.isString()) { - JSValue result = v2.isString() - ? jsString(callFrame, asString(v1), asString(v2)) - : jsString(callFrame, asString(v1), v2.toString(callFrame)); + bool leftIsString = v1.isString(); + if (leftIsString && v2.isString()) { + JSValue result = jsString(callFrame, asString(v1), asString(v2)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } - double left = 0.0, right; - if (v1.getNumber(left) && v2.getNumber(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left + right)); + 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 (UNLIKELY(!value)) { + throwOutOfMemoryError(callFrame); + VM_THROW_EXCEPTION(); + } + return JSValue::encode(jsString(stackFrame.globalData, value.release())); + } // All other cases are pretty uncommon JSValue result = jsAddSlowCase(callFrame, v1, v2); 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 |