Changeset 73433 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Dec 7, 2010, 3:11:08 AM (14 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSString.cpp
r70496 r73433 32 32 33 33 namespace JSC { 34 35 static const unsigned substringFromRopeCutoff = 4; 34 36 35 37 // Overview: this methods converts a JSString from holding a string in rope form … … 106 108 } 107 109 } 110 111 // This function construsts a substring out of a rope without flattening by reusing the existing fibers. 112 // This can reduce memory usage substantially. Since traversing ropes is slow the function will revert 113 // back to flattening if the rope turns out to be long. 114 JSString* JSString::substringFromRope(ExecState* exec, unsigned substringStart, unsigned substringLength) 115 { 116 ASSERT(isRope()); 117 ASSERT(substringLength); 118 119 JSGlobalData* globalData = &exec->globalData(); 120 121 UString substringFibers[3]; 122 123 unsigned fiberCount = 0; 124 unsigned substringFiberCount = 0; 125 unsigned substringEnd = substringStart + substringLength; 126 unsigned fiberEnd = 0; 127 128 RopeIterator end; 129 for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { 130 ++fiberCount; 131 StringImpl* fiberString = *it; 132 unsigned fiberStart = fiberEnd; 133 fiberEnd = fiberStart + fiberString->length(); 134 if (fiberEnd <= substringStart) 135 continue; 136 unsigned copyStart = std::max(substringStart, fiberStart); 137 unsigned copyEnd = std::min(substringEnd, fiberEnd); 138 if (copyStart == fiberStart && copyEnd == fiberEnd) 139 substringFibers[substringFiberCount++] = UString(fiberString); 140 else 141 substringFibers[substringFiberCount++] = UString(StringImpl::create(fiberString, copyStart - fiberStart, copyEnd - copyStart)); 142 if (fiberEnd >= substringEnd) 143 break; 144 if (fiberCount > substringFromRopeCutoff || substringFiberCount >= 3) { 145 // This turned out to be a really inefficient rope. Just flatten it. 146 resolveRope(exec); 147 return jsSubstring(&exec->globalData(), m_value, substringStart, substringLength); 148 } 149 } 150 ASSERT(substringFiberCount && substringFiberCount <= 3); 151 152 if (substringLength == 1) { 153 ASSERT(substringFiberCount == 1); 154 UChar c = substringFibers[0].characters()[0]; 155 if (c <= 0xFF) 156 return globalData->smallStrings.singleCharacterString(globalData, c); 157 } 158 if (substringFiberCount == 1) 159 return new (globalData) JSString(globalData, substringFibers[0]); 160 if (substringFiberCount == 2) 161 return new (globalData) JSString(globalData, substringFibers[0], substringFibers[1]); 162 return new (globalData) JSString(globalData, substringFibers[0], substringFibers[1], substringFibers[2]); 163 } 108 164 109 165 JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement) -
trunk/JavaScriptCore/runtime/JSString.h
r71375 r73433 357 357 358 358 void resolveRope(ExecState*) const; 359 JSString* substringFromRope(ExecState*, unsigned offset, unsigned length); 359 360 360 361 void appendStringInConstruct(unsigned& index, const UString& string) … … 436 437 friend JSValue jsString(ExecState* exec, JSValue thisValue); 437 438 friend JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context); 439 friend JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length); 438 440 }; 439 441 … … 519 521 JSGlobalData* globalData = &exec->globalData(); 520 522 return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context)); 523 } 524 525 inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length) 526 { 527 ASSERT(offset <= static_cast<unsigned>(s->length())); 528 ASSERT(length <= static_cast<unsigned>(s->length())); 529 ASSERT(offset + length <= static_cast<unsigned>(s->length())); 530 JSGlobalData* globalData = &exec->globalData(); 531 if (!length) 532 return globalData->smallStrings.emptyString(globalData); 533 if (s->isRope()) 534 return s->substringFromRope(exec, offset, length); 535 return jsSubstring(globalData, s->m_value, offset, length); 521 536 } 522 537 -
trunk/JavaScriptCore/runtime/StringPrototype.cpp
r70703 r73433 773 773 if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible 774 774 return throwVMTypeError(exec); 775 UString s = thisValue.toThisString(exec); 776 int len = s.length(); 775 unsigned len; 776 JSString* jsString = 0; 777 UString uString; 778 if (thisValue.isString()) { 779 jsString = static_cast<JSString*>(thisValue.asCell()); 780 len = jsString->length(); 781 } else { 782 uString = thisValue.toThisObject(exec)->toString(exec); 783 len = uString.length(); 784 } 777 785 778 786 JSValue a0 = exec->argument(0); … … 790 798 if (start + length > len) 791 799 length = len - start; 792 return JSValue::encode(jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length))); 800 unsigned substringStart = static_cast<unsigned>(start); 801 unsigned substringLength = static_cast<unsigned>(length); 802 if (jsString) 803 return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength)); 804 return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength)); 793 805 } 794 806 … … 798 810 if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible 799 811 return throwVMTypeError(exec); 800 UString s = thisValue.toThisString(exec); 801 int len = s.length(); 812 int len; 813 JSString* jsString = 0; 814 UString uString; 815 if (thisValue.isString()) { 816 jsString = static_cast<JSString*>(thisValue.asCell()); 817 len = jsString->length(); 818 } else { 819 uString = thisValue.toThisObject(exec)->toString(exec); 820 len = uString.length(); 821 } 802 822 803 823 JSValue a0 = exec->argument(0); … … 824 844 start = temp; 825 845 } 826 return JSValue::encode(jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start))); 846 unsigned substringStart = static_cast<unsigned>(start); 847 unsigned substringLength = static_cast<unsigned>(end) - substringStart; 848 if (jsString) 849 return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength)); 850 return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength)); 827 851 } 828 852
Note:
See TracChangeset
for help on using the changeset viewer.