Changeset 100314 in webkit
- Timestamp:
- Nov 15, 2011, 1:38:35 PM (15 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
runtime/JSString.h (modified) (3 diffs)
-
runtime/StringPrototype.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r100310 r100314 1 2011-11-15 Michael Saboff <msaboff@apple.com> 2 3 Towards 8 bit Strings - Initial JS String Tuning 4 https://bugs.webkit.org/show_bug.cgi?id=72326 5 6 Added 8 bit optimized paths for the methods below. 7 8 Reviewed by Geoffrey Garen. 9 10 * runtime/JSString.h: 11 (JSC::jsSubstring8): 12 * runtime/StringPrototype.cpp: 13 (JSC::jsSpliceSubstrings): 14 (JSC::jsSpliceSubstringsWithSeparators): 15 (JSC::stringProtoFuncReplace): 16 (JSC::stringProtoFuncCharCodeAt): 17 1 18 2011-11-15 Gavin Barraclough <barraclough@apple.com> 2 19 -
trunk/Source/JavaScriptCore/runtime/JSString.h
r100208 r100314 364 364 } 365 365 366 inline JSString* jsSubstring (JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)366 inline JSString* jsSubstring8(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) 367 367 { 368 368 ASSERT(offset <= static_cast<unsigned>(s.length())); … … 376 376 return globalData->smallStrings.singleCharacterString(globalData, c); 377 377 } 378 return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length))); 379 } 380 381 inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) 382 { 383 ASSERT(offset <= static_cast<unsigned>(s.length())); 384 ASSERT(length <= static_cast<unsigned>(s.length())); 385 ASSERT(offset + length <= static_cast<unsigned>(s.length())); 386 if (!length) 387 return globalData->smallStrings.emptyString(globalData); 388 if (length == 1) { 389 UChar c = s[offset]; 390 if (c <= maxSingleCharacterString) 391 return globalData->smallStrings.singleCharacterString(globalData, c); 392 } 378 393 return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length))); 379 394 } … … 400 415 inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } 401 416 inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } 417 inline JSString* jsSubstring8(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->globalData(), s, offset, length); } 402 418 inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); } 403 419 inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); } -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r100006 r100314 284 284 return jsString(exec, ""); 285 285 286 if (source.is8Bit()) { 287 LChar* buffer; 288 const LChar* sourceData = source.characters8(); 289 RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer); 290 if (!impl) 291 return throwOutOfMemoryError(exec); 292 293 int bufferPos = 0; 294 for (int i = 0; i < rangeCount; i++) { 295 if (int srcLen = substringRanges[i].length) { 296 StringImpl::copyChars(buffer + bufferPos, sourceData + substringRanges[i].position, srcLen); 297 bufferPos += srcLen; 298 } 299 } 300 301 return jsString(exec, impl.release()); 302 } 303 286 304 UChar* buffer; 305 const UChar* sourceData = source.characters16(); 306 287 307 RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer); 288 308 if (!impl) … … 292 312 for (int i = 0; i < rangeCount; i++) { 293 313 if (int srcLen = substringRanges[i].length) { 294 StringImpl::copyChars(buffer + bufferPos, source .characters()+ substringRanges[i].position, srcLen);314 StringImpl::copyChars(buffer + bufferPos, sourceData + substringRanges[i].position, srcLen); 295 315 bufferPos += srcLen; 296 316 } … … 313 333 314 334 int totalLength = 0; 335 bool allSeperators8Bit = true; 315 336 for (int i = 0; i < rangeCount; i++) 316 337 totalLength += substringRanges[i].length; 317 for (int i = 0; i < separatorCount; i++) 338 for (int i = 0; i < separatorCount; i++) { 318 339 totalLength += separators[i].length(); 340 if (separators[i].length() && !separators[i].is8Bit()) 341 allSeperators8Bit = false; 342 } 319 343 320 344 if (!totalLength) 321 345 return jsString(exec, ""); 346 347 if (source.is8Bit() && allSeperators8Bit) { 348 LChar* buffer; 349 const LChar* sourceData = source.characters8(); 350 351 RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer); 352 if (!impl) 353 return throwOutOfMemoryError(exec); 354 355 int maxCount = max(rangeCount, separatorCount); 356 int bufferPos = 0; 357 for (int i = 0; i < maxCount; i++) { 358 if (i < rangeCount) { 359 if (int srcLen = substringRanges[i].length) { 360 StringImpl::copyChars(buffer + bufferPos, sourceData + substringRanges[i].position, srcLen); 361 bufferPos += srcLen; 362 } 363 } 364 if (i < separatorCount) { 365 if (int sepLen = separators[i].length()) { 366 StringImpl::copyChars(buffer + bufferPos, separators[i].characters8(), sepLen); 367 bufferPos += sepLen; 368 } 369 } 370 } 371 372 return jsString(exec, impl.release()); 373 } 322 374 323 375 UChar* buffer; … … 331 383 if (i < rangeCount) { 332 384 if (int srcLen = substringRanges[i].length) { 333 StringImpl::copyChars(buffer + bufferPos, source.characters 16() + substringRanges[i].position, srcLen);385 StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, srcLen); 334 386 bufferPos += srcLen; 335 387 } … … 337 389 if (i < separatorCount) { 338 390 if (int sepLen = separators[i].length()) { 339 StringImpl::copyChars(buffer + bufferPos, separators[i].characters 16(), sepLen);391 StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), sepLen); 340 392 bufferPos += sepLen; 341 393 } … … 424 476 if (exec->hadException()) 425 477 return JSValue::encode(jsNull()); 426 while (true) { 427 int matchIndex; 428 int matchLen = 0; 429 int* ovector; 430 regExpConstructor->performMatch(*globalData, reg, source, startPosition, matchIndex, matchLen, &ovector); 431 if (matchIndex < 0) 432 break; 433 434 sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); 435 436 int completeMatchStart = ovector[0]; 437 unsigned i = 0; 438 for (; i < reg->numSubpatterns() + 1; ++i) { 439 int matchStart = ovector[i * 2]; 440 int matchLen = ovector[i * 2 + 1] - matchStart; 441 442 if (matchStart < 0) 443 cachedCall.setArgument(i, jsUndefined()); 478 if (source.is8Bit()) { 479 while (true) { 480 int matchIndex; 481 int matchLen = 0; 482 int* ovector; 483 regExpConstructor->performMatch(*globalData, reg, source, startPosition, matchIndex, matchLen, &ovector); 484 if (matchIndex < 0) 485 break; 486 487 sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); 488 489 int completeMatchStart = ovector[0]; 490 unsigned i = 0; 491 for (; i < reg->numSubpatterns() + 1; ++i) { 492 int matchStart = ovector[i * 2]; 493 int matchLen = ovector[i * 2 + 1] - matchStart; 494 495 if (matchStart < 0) 496 cachedCall.setArgument(i, jsUndefined()); 497 else 498 cachedCall.setArgument(i, jsSubstring8(globalData, source, matchStart, matchLen)); 499 } 500 501 cachedCall.setArgument(i++, jsNumber(completeMatchStart)); 502 cachedCall.setArgument(i++, sourceVal); 503 504 cachedCall.setThis(jsUndefined()); 505 JSValue result = cachedCall.call(); 506 if (LIKELY(result.isString())) 507 replacements.append(asString(result)->value(exec)); 444 508 else 445 cachedCall.setArgument(i, jsSubstring(exec, source, matchStart, matchLen)); 509 replacements.append(result.toString(cachedCall.newCallFrame(exec))); 510 if (exec->hadException()) 511 break; 512 513 lastIndex = matchIndex + matchLen; 514 startPosition = lastIndex; 515 516 // special case of empty match 517 if (!matchLen) { 518 startPosition++; 519 if (startPosition > sourceLen) 520 break; 521 } 446 522 } 447 448 cachedCall.setArgument(i++, jsNumber(completeMatchStart)); 449 cachedCall.setArgument(i++, sourceVal); 450 451 cachedCall.setThis(jsUndefined()); 452 JSValue result = cachedCall.call(); 453 if (LIKELY(result.isString())) 454 replacements.append(asString(result)->value(exec)); 455 else 456 replacements.append(result.toString(cachedCall.newCallFrame(exec))); 457 if (exec->hadException()) 458 break; 459 460 lastIndex = matchIndex + matchLen; 461 startPosition = lastIndex; 462 463 // special case of empty match 464 if (!matchLen) { 465 startPosition++; 466 if (startPosition > sourceLen) 523 } else { 524 while (true) { 525 int matchIndex; 526 int matchLen = 0; 527 int* ovector; 528 regExpConstructor->performMatch(*globalData, reg, source, startPosition, matchIndex, matchLen, &ovector); 529 if (matchIndex < 0) 467 530 break; 531 532 sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); 533 534 int completeMatchStart = ovector[0]; 535 unsigned i = 0; 536 for (; i < reg->numSubpatterns() + 1; ++i) { 537 int matchStart = ovector[i * 2]; 538 int matchLen = ovector[i * 2 + 1] - matchStart; 539 540 if (matchStart < 0) 541 cachedCall.setArgument(i, jsUndefined()); 542 else 543 cachedCall.setArgument(i, jsSubstring(globalData, source, matchStart, matchLen)); 544 } 545 546 cachedCall.setArgument(i++, jsNumber(completeMatchStart)); 547 cachedCall.setArgument(i++, sourceVal); 548 549 cachedCall.setThis(jsUndefined()); 550 JSValue result = cachedCall.call(); 551 if (LIKELY(result.isString())) 552 replacements.append(asString(result)->value(exec)); 553 else 554 replacements.append(result.toString(cachedCall.newCallFrame(exec))); 555 if (exec->hadException()) 556 break; 557 558 lastIndex = matchIndex + matchLen; 559 startPosition = lastIndex; 560 561 // special case of empty match 562 if (!matchLen) { 563 startPosition++; 564 if (startPosition > sourceLen) 565 break; 566 } 468 567 } 469 568 } … … 616 715 if (a0.isUInt32()) { 617 716 uint32_t i = a0.asUInt32(); 618 if (i < len) 619 return JSValue::encode(jsNumber(s.characters()[i])); 717 if (i < len) { 718 if (s.is8Bit()) 719 return JSValue::encode(jsNumber(s.characters8()[i])); 720 return JSValue::encode(jsNumber(s.characters16()[i])); 721 } 620 722 return JSValue::encode(jsNaN()); 621 723 }
Note:
See TracChangeset
for help on using the changeset viewer.