Changeset 19434 in webkit
- Timestamp:
- Feb 6, 2007 11:42:35 AM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r19393 r19434 1 2007-02-06 Darin Adler <darin@apple.com> 2 3 Reviewed by John. 4 5 - fix <rdar://problem/4687840> 9A241: JavaScript RegExp 25-30x slower than on 10.4.7 6 7 I used Shark to figure out what to do. The test case is now 15% faster than with 8 stock Safari. Some other regular expression cases might still be a few % slower 9 than before, but the >10x slowdown is now completely gone. 10 11 1) Fix slowness caused by setjmp/longjmp by using computed goto instead. 12 13 Use GCC extensions - locally declared labels, labels as values, and computed goto - 14 instead of using setjmp/longjmp to implemement non-recursive version of the regular 15 expression system. We could probably make this even faster if we reduced the use 16 of malloc a bit too. 17 18 2) Fix slowness caused by allocating heapframe objects by allocating the first 19 16 of them from the stack. 20 21 3) Speed up use of malloc and free in PCRE by making it use fastMalloc and fastFree. 22 23 4) Speed up the test case by adding a special case to a UString function. 24 25 5) Made a small improvement to the innermost hottest loop of match by hoisting 26 the conversion from int to pcre_uchar out of the loop. 27 28 * JavaScriptCore.xcodeproj/project.pbxproj: Compile FastMallocPCRE.cpp, and don't 29 compile pcre_globals.c. 30 31 * wtf/FastMallocPCRE.cpp: Added. A copy of pcre_globals.c that uses FastMalloc.h. 32 This is better than code that sets the PCRE allocation globals because by doing it 33 this way there's guaranteed to be no problem with order of initialization. 34 35 * kjs/ustring.cpp: (KJS::UString::spliceSubstringsWithSeparators): Add a fast 36 special case when this is called for only one subrange and no seaprators. This 37 was happening a lot in the test case and it seems quite reasonable to optimize this. 38 39 * pcre/pcre_exec.c: Create a copy of the RMATCH and RRETURN macros that use goto 40 instead of setjmp/longjmp. Change code that calls pcre_stack_malloc to first use 41 storage on the stack inside the match function. 42 (match): Move initialization of utf8 up a couple lines to avoid "possibly used 43 uninitialized" warning. Use a local variable so we compare with pcre_uchar instead 44 of with int inside the inner "find a character" loop. 45 1 46 2007-02-03 George Staikos <staikos@kde.org> 2 47 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r19302 r19434 120 120 65FB3F5109D11B2400F49DEB /* grammar.h in Headers */ = {isa = PBXBuildFile; fileRef = 65FB3F4909D11B2400F49DEB /* grammar.h */; }; 121 121 65FB3F5409D11B2400F49DEB /* regexp_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65FB3F4C09D11B2400F49DEB /* regexp_object.lut.h */; }; 122 9302043B0B790750000C6115 /* FastMallocPCRE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9302043A0B790750000C6115 /* FastMallocPCRE.cpp */; }; 122 123 9303F568099118FA00AD71B8 /* OwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F567099118FA00AD71B8 /* OwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; }; 123 124 9303F56A0991190000AD71B8 /* Noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5690991190000AD71B8 /* Noncopyable.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 125 126 930754C108B0F68000AB3056 /* pcre_compile.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754BF08B0F68000AB3056 /* pcre_compile.c */; }; 126 127 930754D008B0F74600AB3056 /* pcre_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754CE08B0F74500AB3056 /* pcre_tables.c */; }; 127 930754D308B0F76300AB3056 /* pcre_globals.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754D108B0F76200AB3056 /* pcre_globals.c */; };128 128 930754E808B0F77700AB3056 /* pcre_fullinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754E608B0F77700AB3056 /* pcre_fullinfo.c */; }; 129 129 930754EB08B0F78500AB3056 /* pcre_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754E908B0F78500AB3056 /* pcre_exec.c */; }; … … 566 566 70B16A270569A10900DB756D /* runtime_object.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = runtime_object.h; path = bindings/runtime_object.h; sourceTree = "<group>"; tabWidth = 8; }; 567 567 84ABF1DE070B628C00A3AC05 /* npruntime_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = npruntime_impl.h; path = bindings/npruntime_impl.h; sourceTree = "<group>"; tabWidth = 8; }; 568 9302043A0B790750000C6115 /* FastMallocPCRE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastMallocPCRE.cpp; sourceTree = "<group>"; }; 568 569 9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; }; 569 570 9303F5690991190000AD71B8 /* Noncopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Noncopyable.h; sourceTree = "<group>"; }; … … 571 572 930754BF08B0F68000AB3056 /* pcre_compile.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_compile.c; path = pcre/pcre_compile.c; sourceTree = "<group>"; tabWidth = 8; }; 572 573 930754CE08B0F74500AB3056 /* pcre_tables.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_tables.c; path = pcre/pcre_tables.c; sourceTree = "<group>"; tabWidth = 8; }; 573 930754D108B0F76200AB3056 /* pcre_globals.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_globals.c; path = pcre/pcre_globals.c; sourceTree = "<group>"; tabWidth = 8; };574 574 930754E608B0F77700AB3056 /* pcre_fullinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_fullinfo.c; path = pcre/pcre_fullinfo.c; sourceTree = "<group>"; tabWidth = 8; }; 575 575 930754E908B0F78500AB3056 /* pcre_exec.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_exec.c; path = pcre/pcre_exec.c; sourceTree = "<group>"; tabWidth = 8; }; … … 890 890 isa = PBXGroup; 891 891 children = ( 892 657EB7450B708F540063461B /* ListHashSet.h */,893 892 E195678D09E7CF1200B89D13 /* unicode */, 894 893 93AA4F770957251F0084B3A7 /* AlwaysInline.h */, … … 898 897 65E217BA08E7EECC0023E5F6 /* FastMalloc.h */, 899 898 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */, 899 9302043A0B790750000C6115 /* FastMallocPCRE.cpp */, 900 900 935AF46909E9D9DB00ACD1D8 /* Forward.h */, 901 901 93B6A0DE0AA64DA40076DE27 /* GetPtr.h */, … … 907 907 65DFC92E08EA173A00F7300B /* HashTable.h */, 908 908 65DFC92F08EA173A00F7300B /* HashTraits.h */, 909 657EB7450B708F540063461B /* ListHashSet.h */, 909 910 148A1626095D16BB00666D0D /* ListRefPtr.h */, 910 911 BCF6553B0A2048DE0038A194 /* MathExtras.h */, … … 1031 1032 930754E608B0F77700AB3056 /* pcre_fullinfo.c */, 1032 1033 93E26CF608B29A1C00F85226 /* pcre_get.c */, 1033 930754D108B0F76200AB3056 /* pcre_globals.c */,1034 1034 93E26BE508B1517100F85226 /* pcre_internal.h */, 1035 1035 93E26BC908B1511900F85226 /* pcre_ord2utf8.c */, … … 1492 1492 930754C108B0F68000AB3056 /* pcre_compile.c in Sources */, 1493 1493 930754D008B0F74600AB3056 /* pcre_tables.c in Sources */, 1494 930754D308B0F76300AB3056 /* pcre_globals.c in Sources */,1495 1494 930754E808B0F77700AB3056 /* pcre_fullinfo.c in Sources */, 1496 1495 930754EB08B0F78500AB3056 /* pcre_exec.c in Sources */, … … 1523 1522 D212022A0AD4310D00ED79B6 /* DateMath.cpp in Sources */, 1524 1523 146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */, 1524 9302043B0B790750000C6115 /* FastMallocPCRE.cpp in Sources */, 1525 1525 ); 1526 1526 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/kjs/ustring.cpp
r19178 r19434 44 44 45 45 using std::max; 46 using std::min; 46 47 47 48 namespace KJS { … … 617 618 } 618 619 619 UString UString::spliceSubstringsWithSeparators(const Range *substringRanges, int rangeCount, const UString *separators, int separatorCount) const 620 { 620 UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const 621 { 622 if (rangeCount == 1 && separatorCount == 0) { 623 int thisSize = size(); 624 int position = substringRanges[0].position; 625 int length = substringRanges[0].length; 626 if (position <= 0 && length >= thisSize) 627 return *this; 628 return UString::Rep::create(m_rep, max(0, position), min(thisSize, length)); 629 } 630 621 631 int totalLength = 0; 622 623 for (int i = 0; i < rangeCount; i++) { 632 for (int i = 0; i < rangeCount; i++) 624 633 totalLength += substringRanges[i].length; 625 } 626 for (int i = 0; i < separatorCount; i++) { 634 for (int i = 0; i < separatorCount; i++) 627 635 totalLength += separators[i].size(); 628 } 629 630 UChar *buffer = static_cast<UChar *>(fastMalloc(totalLength * sizeof(UChar))); 636 637 UChar* buffer = static_cast<UChar*>(fastMalloc(totalLength * sizeof(UChar))); 631 638 632 639 int maxCount = max(rangeCount, separatorCount); … … 643 650 } 644 651 645 return UString(UString::Rep::create(buffer, totalLength)); 646 } 647 648 652 return UString::Rep::create(buffer, totalLength); 653 } 649 654 650 655 UString &UString::append(const UString &t) -
trunk/JavaScriptCore/pcre/pcre_exec.c
r18498 r19434 8 8 Written by Philip Hazel 9 9 Copyright (c) 1997-2005 University of Cambridge 10 11 Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved. 10 12 11 13 ----------------------------------------------------------------------------- … … 213 215 #define REGISTER 214 216 217 #ifndef __GNUC__ 218 219 /* Use setjmp/longjmp. */ 220 215 221 #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\ 216 222 {\ 217 heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\ 223 heapframe *newframe;\ 224 if (frame >= stackframes && frame + 1 < stackframesend)\ 225 newframe = frame + 1;\ 226 else\ 227 newframe = (pcre_stack_malloc)(sizeof(heapframe));\ 218 228 if (setjmp(frame->Xwhere) == 0)\ 219 229 {\ … … 241 251 heapframe *newframe = frame;\ 242 252 frame = newframe->Xprevframe;\ 243 (pcre_stack_free)(newframe);\ 253 if (!(newframe >= stackframes && newframe < stackframesend))\ 254 (pcre_stack_free)(newframe);\ 244 255 if (frame != NULL)\ 245 256 {\ … … 251 262 } 252 263 264 #else 265 266 /* Use locally declared labels, labels as values, and computed goto. */ 267 268 #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\ 269 {\ 270 __label__ where;\ 271 heapframe *newframe;\ 272 if (frame >= stackframes && frame + 1 < stackframesend)\ 273 newframe = frame + 1;\ 274 else\ 275 newframe = (pcre_stack_malloc)(sizeof(heapframe));\ 276 frame->Xwhere = &&where;\ 277 newframe->Xeptr = ra;\ 278 newframe->Xecode = rb;\ 279 newframe->Xoffset_top = rc;\ 280 newframe->Xims = re;\ 281 newframe->Xeptrb = rf;\ 282 newframe->Xflags = rg;\ 283 newframe->Xprevframe = frame;\ 284 frame = newframe;\ 285 DPRINTF(("restarting from line %d\n", __LINE__));\ 286 goto HEAP_RECURSE;\ 287 where:\ 288 DPRINTF(("did a goto back to line %d\n", __LINE__));\ 289 frame = md->thisframe;\ 290 rx = frame->Xresult;\ 291 } 292 293 #define RRETURN(ra)\ 294 {\ 295 heapframe *newframe = frame;\ 296 frame = newframe->Xprevframe;\ 297 if (!(newframe >= stackframes && newframe < stackframesend))\ 298 (pcre_stack_free)(newframe);\ 299 if (frame != NULL)\ 300 {\ 301 frame->Xresult = ra;\ 302 md->thisframe = frame;\ 303 goto *frame->Xwhere;\ 304 }\ 305 return ra;\ 306 } 307 308 #endif 253 309 254 310 /* Structure for remembering the local variables in a private frame */ … … 313 369 314 370 int Xresult; 371 #ifndef __GNUC__ 315 372 jmp_buf Xwhere; 373 #else 374 void *Xwhere; 375 #endif 316 376 317 377 } heapframe; … … 379 439 380 440 #ifdef NO_RECURSE 381 heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe)); 441 442 /* The value 16 here is large enough that most regular expressions don't require 443 any calls to pcre_stack_malloc, yet the amount of stack used for the array is 444 modest enough that we don't run out of stack. */ 445 heapframe stackframes[16]; 446 heapframe *stackframesend = stackframes + sizeof(stackframes) / sizeof(stackframes[0]); 447 448 heapframe *frame = stackframes; 382 449 frame->Xprevframe = NULL; /* Marks the top level */ 383 450 … … 522 589 performance when true recursion is being used. */ 523 590 591 utf8 = md->utf8; /* Local copy of the flag */ 592 524 593 if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); 525 594 526 595 original_ims = ims; /* Save for resetting on ')' */ 527 utf8 = md->utf8; /* Local copy of the flag */528 596 529 597 /* At the start of a bracketed group, add the current subject pointer to the … … 3611 3679 if (first_byte >= 0) 3612 3680 { 3681 pcre_uchar first_char = first_byte; 3613 3682 if (first_byte_caseless) 3614 3683 while (start_match < end_subject) … … 3619 3688 break; 3620 3689 #endif 3621 if (match_block.lcc[sm] == first_ byte)3690 if (match_block.lcc[sm] == first_char) 3622 3691 break; 3623 3692 start_match++; 3624 3693 } 3625 3694 else 3626 while (start_match < end_subject && *start_match != first_ byte)3695 while (start_match < end_subject && *start_match != first_char) 3627 3696 start_match++; 3628 3697 }
Note: See TracChangeset
for help on using the changeset viewer.