Changeset 59161 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- May 11, 2010, 11:42:46 AM (15 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSString.cpp
r57912 r59161 76 76 unsigned fiberCountMinusOne = rope->fiberCount() - 1; 77 77 for (unsigned i = 0; i < fiberCountMinusOne; ++i) 78 workQueue.append(rope->fibers( i));79 currentFiber = rope->fibers( fiberCountMinusOne);78 workQueue.append(rope->fibers()[i]); 79 currentFiber = rope->fibers()[fiberCountMinusOne]; 80 80 } else { 81 81 UStringImpl* string = static_cast<UStringImpl*>(currentFiber); … … 105 105 } 106 106 107 JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement) 108 { 109 if (!isRope()) { 110 size_t matchPosition = m_value.find(character); 111 if (matchPosition == notFound) 112 return JSValue(this); 113 return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1)); 114 } 115 116 RopeIterator end; 117 118 // Count total fibers and find matching string. 119 size_t fiberCount = 0; 120 UStringImpl* matchString = 0; 121 size_t matchPosition = notFound; 122 for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { 123 ++fiberCount; 124 if (matchString) 125 continue; 126 127 UStringImpl* string = *it; 128 matchPosition = string->find(character); 129 if (matchPosition == notFound) 130 continue; 131 matchString = string; 132 } 133 134 if (!matchString) 135 return this; 136 137 RopeBuilder builder(replacement.size() ? fiberCount + 2 : fiberCount + 1); 138 if (UNLIKELY(builder.isOutOfMemory())) 139 return throwOutOfMemoryError(exec); 140 141 for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { 142 UStringImpl* string = *it; 143 if (string != matchString) { 144 builder.append(UString(string)); 145 continue; 146 } 147 148 builder.append(UString(string).substr(0, matchPosition)); 149 if (replacement.size()) 150 builder.append(replacement); 151 builder.append(UString(string).substr(matchPosition + 1)); 152 } 153 154 JSGlobalData* globalData = &exec->globalData(); 155 return JSValue(new (globalData) JSString(globalData, builder.release())); 156 } 157 107 158 JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i) 108 159 { -
trunk/JavaScriptCore/runtime/JSString.h
r58286 r59161 112 112 }; 113 113 114 class RopeIterator { 115 public: 116 RopeIterator() { } 117 118 RopeIterator(RopeImpl::Fiber* fibers, size_t fiberCount) 119 { 120 ASSERT(fiberCount); 121 m_workQueue.append(WorkItem(fibers, fiberCount)); 122 skipRopes(); 123 } 124 125 RopeIterator& operator++() 126 { 127 WorkItem& item = m_workQueue.last(); 128 ASSERT(!RopeImpl::isRope(item.fibers[item.i])); 129 if (++item.i == item.fiberCount) 130 m_workQueue.removeLast(); 131 skipRopes(); 132 return *this; 133 } 134 135 UStringImpl* operator*() 136 { 137 WorkItem& item = m_workQueue.last(); 138 RopeImpl::Fiber fiber = item.fibers[item.i]; 139 ASSERT(!RopeImpl::isRope(fiber)); 140 return static_cast<UStringImpl*>(fiber); 141 } 142 143 bool operator!=(const RopeIterator& other) const 144 { 145 return m_workQueue != other.m_workQueue; 146 } 147 148 private: 149 struct WorkItem { 150 WorkItem(RopeImpl::Fiber* fibers, size_t fiberCount) 151 : fibers(fibers) 152 , fiberCount(fiberCount) 153 , i(0) 154 { 155 } 156 157 bool operator!=(const WorkItem& other) const 158 { 159 return fibers != other.fibers || fiberCount != other.fiberCount || i != other.i; 160 } 161 162 RopeImpl::Fiber* fibers; 163 size_t fiberCount; 164 size_t i; 165 }; 166 167 void skipRopes() 168 { 169 if (m_workQueue.isEmpty()) 170 return; 171 172 while (1) { 173 WorkItem& item = m_workQueue.last(); 174 RopeImpl::Fiber fiber = item.fibers[item.i]; 175 if (!RopeImpl::isRope(fiber)) 176 break; 177 RopeImpl* rope = static_cast<RopeImpl*>(fiber); 178 if (++item.i == item.fiberCount) 179 m_workQueue.removeLast(); 180 m_workQueue.append(WorkItem(rope->fibers(), rope->fiberCount())); 181 } 182 } 183 184 Vector<WorkItem, 16> m_workQueue; 185 }; 186 114 187 ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value) 115 188 : JSCell(globalData->stringStructure.get()) … … 131 204 ASSERT(!m_value.isNull()); 132 205 } 133 JSString(JSGlobalData* globalData, PassRefPtr<UString ::Rep> value, HasOtherOwnerType)206 JSString(JSGlobalData* globalData, PassRefPtr<UStringImpl> value, HasOtherOwnerType) 134 207 : JSCell(globalData->stringStructure.get()) 135 208 , m_length(value->length()) … … 201 274 } 202 275 276 // This constructor constructs a new string by concatenating u1 & u2. 277 JSString(JSGlobalData* globalData, const UString& u1, const UString& u2) 278 : JSCell(globalData->stringStructure.get()) 279 , m_length(u1.size() + u2.size()) 280 , m_fiberCount(2) 281 { 282 unsigned index = 0; 283 appendStringInConstruct(index, u1); 284 appendStringInConstruct(index, u2); 285 ASSERT(index <= s_maxInternalRopeLength); 286 } 287 288 // This constructor constructs a new string by concatenating u1, u2 & u3. 289 JSString(JSGlobalData* globalData, const UString& u1, const UString& u2, const UString& u3) 290 : JSCell(globalData->stringStructure.get()) 291 , m_length(u1.size() + u2.size() + u3.size()) 292 , m_fiberCount(s_maxInternalRopeLength) 293 { 294 unsigned index = 0; 295 appendStringInConstruct(index, u1); 296 appendStringInConstruct(index, u2); 297 appendStringInConstruct(index, u3); 298 ASSERT(index <= s_maxInternalRopeLength); 299 } 300 203 301 JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context) 204 302 : JSCell(globalData->stringStructure.get()) … … 246 344 JSString* getIndex(ExecState*, unsigned); 247 345 JSString* getIndexSlowCase(ExecState*, unsigned); 346 347 JSValue replaceCharacter(ExecState*, UChar, const UString& replacement); 248 348 249 349 static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); } … … 283 383 ASSERT(asCell(v)->isString()); 284 384 JSString* s = static_cast<JSString*>(asCell(v)); 285 ASSERT(s-> fiberCount() == 1);385 ASSERT(s->size() == 1); 286 386 appendStringInConstruct(index, s); 287 387 m_length += s->length(); … … 329 429 bool isRope() const { return m_fiberCount; } 330 430 UString& string() { ASSERT(!isRope()); return m_value; } 331 unsigned fiberCount() { return m_fiberCount ? m_fiberCount : 1; }431 unsigned size() { return m_fiberCount ? m_fiberCount : 1; } 332 432 333 433 friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2); … … 376 476 if (c <= 0xFF) 377 477 return globalData->smallStrings.singleCharacterString(globalData, c); 378 return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString ::Rep::create(s.rep(), offset, 1))));478 return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, 1)))); 379 479 } 380 480 … … 434 534 return globalData->smallStrings.singleCharacterString(globalData, c); 435 535 } 436 return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString ::Rep::create(s.rep(), offset, length)), JSString::HasOtherOwner));536 return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, length)), JSString::HasOtherOwner)); 437 537 } 438 538 -
trunk/JavaScriptCore/runtime/Operations.h
r54925 r59161 47 47 return throwOutOfMemoryError(exec); 48 48 49 unsigned fiberCount = s1-> fiberCount() + s2->fiberCount();49 unsigned fiberCount = s1->size() + s2->size(); 50 50 JSGlobalData* globalData = &exec->globalData(); 51 51 … … 72 72 return throwOutOfMemoryError(exec); 73 73 74 unsigned fiberCount = 1 + s2-> fiberCount();74 unsigned fiberCount = 1 + s2->size(); 75 75 JSGlobalData* globalData = &exec->globalData(); 76 76 … … 97 97 return throwOutOfMemoryError(exec); 98 98 99 unsigned fiberCount = s1-> fiberCount() + 1;99 unsigned fiberCount = s1->size() + 1; 100 100 JSGlobalData* globalData = &exec->globalData(); 101 101 … … 109 109 ropeBuilder.append(u2); 110 110 return new (globalData) JSString(globalData, ropeBuilder.release()); 111 } 112 113 ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2) 114 { 115 unsigned length1 = u1.size(); 116 if (!length1) 117 return jsString(exec, u2); 118 unsigned length2 = u2.size(); 119 if (!length2) 120 return jsString(exec, u1); 121 if ((length1 + length2) < length1) 122 return throwOutOfMemoryError(exec); 123 124 JSGlobalData* globalData = &exec->globalData(); 125 return new (globalData) JSString(globalData, u1, u2); 126 } 127 128 ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3) 129 { 130 unsigned length1 = u1.size(); 131 unsigned length2 = u2.size(); 132 unsigned length3 = u3.size(); 133 if (!length1) 134 return jsString(exec, u2, u3); 135 if (!length2) 136 return jsString(exec, u1, u3); 137 if (!length3) 138 return jsString(exec, u1, u2); 139 140 if ((length1 + length2) < length1) 141 return throwOutOfMemoryError(exec); 142 if ((length1 + length2 + length3) < length3) 143 return throwOutOfMemoryError(exec); 144 145 JSGlobalData* globalData = &exec->globalData(); 146 return new (globalData) JSString(globalData, u1, u2, u3); 111 147 } 112 148 … … 119 155 JSValue v = strings[i].jsValue(); 120 156 if (LIKELY(v.isString())) 121 fiberCount += asString(v)-> fiberCount();157 fiberCount += asString(v)->size(); 122 158 else 123 159 ++fiberCount; … … 158 194 unsigned fiberCount = 0; 159 195 if (LIKELY(thisValue.isString())) 160 fiberCount += asString(thisValue)-> fiberCount();196 fiberCount += asString(thisValue)->size(); 161 197 else 162 198 ++fiberCount; … … 164 200 JSValue v = args.at(i); 165 201 if (LIKELY(v.isString())) 166 fiberCount += asString(v)-> fiberCount();202 fiberCount += asString(v)->size(); 167 203 else 168 204 ++fiberCount; -
trunk/JavaScriptCore/runtime/RopeImpl.cpp
r57912 r59161 31 31 void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue) 32 32 { 33 unsigned length =fiberCount();34 for (unsigned i = 0; i < length; ++i) {35 Fiber& fiber = fibers(i);33 unsigned fiberCount = this->fiberCount(); 34 for (unsigned i = 0; i < fiberCount; ++i) { 35 Fiber& fiber = m_fibers[i]; 36 36 if (isRope(fiber)) { 37 37 RopeImpl* nextRope = static_cast<RopeImpl*>(fiber); -
trunk/JavaScriptCore/runtime/RopeImpl.h
r57932 r59161 47 47 } 48 48 49 void initializeFiber(unsigned &index, Fiber fiber)50 {51 m_fibers[index++] = fiber;52 fiber->ref();53 m_length += fiber->length();54 }55 56 unsigned fiberCount() { return m_fiberCount; }57 Fiber& fibers(unsigned index) { return m_fibers[index]; }58 59 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); }60 61 49 static bool isRope(Fiber fiber) 62 50 { … … 72 60 } 73 61 62 void initializeFiber(unsigned &index, Fiber fiber) 63 { 64 m_fibers[index++] = fiber; 65 fiber->ref(); 66 m_length += fiber->length(); 67 } 68 69 unsigned fiberCount() { return m_size; } 70 Fiber* fibers() { return m_fibers; } 71 72 ALWAYS_INLINE void deref() 73 { 74 m_refCountAndFlags -= s_refCountIncrement; 75 if (!(m_refCountAndFlags & s_refCountMask)) 76 destructNonRecursive(); 77 } 78 74 79 private: 75 RopeImpl(unsigned fiberCount) : StringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {} 80 RopeImpl(unsigned fiberCount) 81 : StringImplBase(ConstructNonStringImpl) 82 , m_size(fiberCount) 83 { 84 } 76 85 77 86 void destructNonRecursive(); … … 80 89 bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; } 81 90 82 unsigned m_ fiberCount;91 unsigned m_size; 83 92 Fiber m_fibers[1]; 84 93 }; -
trunk/JavaScriptCore/runtime/StringPrototype.cpp
r57978 r59161 289 289 } 290 290 291 JSValue jsReplaceRange(ExecState* exec, const UString& source, int rangeStart, int rangeLength, const UString& replacement);292 JSValue jsReplaceRange(ExecState* exec, const UString& source, int rangeStart, int rangeLength, const UString& replacement)293 {294 int replacementLength = replacement.size();295 int totalLength = source.size() - rangeLength + replacementLength;296 if (totalLength == 0)297 return jsString(exec, "");298 299 UChar* buffer;300 PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(totalLength, buffer);301 if (!impl)302 return throwOutOfMemoryError(exec);303 304 UStringImpl::copyChars(buffer, source.data(), rangeStart);305 UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength);306 int rangeEnd = rangeStart + rangeLength;307 UStringImpl::copyChars(buffer + rangeStart + replacementLength, source.data() + rangeEnd, source.size() - rangeEnd);308 309 return jsString(exec, impl);310 }311 312 291 JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) 313 292 { 314 293 JSString* sourceVal = thisValue.toThisJSString(exec); 315 const UString& source = sourceVal->value(exec);316 317 294 JSValue pattern = args.at(0); 318 319 295 JSValue replacement = args.at(1); 296 320 297 UString replacementString; 321 298 CallData callData; … … 325 302 326 303 if (pattern.inherits(&RegExpObject::info)) { 304 const UString& source = sourceVal->value(exec); 327 305 RegExp* reg = asRegExpObject(pattern)->regExp(); 328 306 bool global = reg->global(); … … 443 421 444 422 UString patternString = pattern.toString(exec); 423 if (patternString.size() == 1 && callType == CallTypeNone) 424 return sourceVal->replaceCharacter(exec, patternString[0], replacementString); 425 426 const UString& source = sourceVal->value(exec); 445 427 unsigned matchPos = source.find(patternString); 446 428 … … 457 439 replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec); 458 440 } 459 460 int ovector[2] = { matchPos, matchPos + matchLen }; 461 return jsReplaceRange(exec, source, matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)); 441 442 size_t matchEnd = matchPos + matchLen; 443 int ovector[2] = { matchPos, matchEnd }; 444 return jsString(exec, source.substr(0, matchPos), substituteBackreferences(replacementString, source, ovector, 0), source.substr(matchEnd)); 462 445 } 463 446
Note:
See TracChangeset
for help on using the changeset viewer.