Changeset 63372 in webkit
- Timestamp:
- Jul 14, 2010 4:44:03 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r63370 r63372 1 2010-07-14 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 Avoid extra memcpy of character tokens 6 https://bugs.webkit.org/show_bug.cgi?id=42002 7 8 This patch is just some cleanup to make fixing this bug easier. 9 10 * html/HTMLTreeBuilder.cpp: 11 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer): 12 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::~ExternalCharacterTokenBuffer): 13 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::isEmpty): 14 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::skipLeadingWhitespace): 15 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeLeadingWhitespace): 16 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemaining): 17 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::giveRemainingTo): 18 (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemainingWhitespace): 19 (WebCore::HTMLTreeBuilder::processDoctypeToken): 20 (WebCore::HTMLTreeBuilder::processStartTag): 21 (WebCore::HTMLTreeBuilder::processEndTag): 22 (WebCore::HTMLTreeBuilder::processComment): 23 (WebCore::HTMLTreeBuilder::processCharacter): 24 (WebCore::HTMLTreeBuilder::processCharacterBuffer): 25 (WebCore::HTMLTreeBuilder::processEndOfFile): 26 (WebCore::HTMLTreeBuilder::defaultForInitial): 27 (WebCore::HTMLTreeBuilder::defaultForBeforeHTML): 28 (WebCore::HTMLTreeBuilder::defaultForBeforeHead): 29 (WebCore::HTMLTreeBuilder::defaultForInHead): 30 (WebCore::HTMLTreeBuilder::defaultForInHeadNoscript): 31 (WebCore::HTMLTreeBuilder::defaultForAfterHead): 32 (WebCore::HTMLTreeBuilder::defaultForInTableText): 33 * html/HTMLTreeBuilder.h: 34 1 35 2010-07-14 Andreas Kling <andreas.kling@nokia.com> 2 36 -
trunk/WebCore/html/HTMLTreeBuilder.cpp
r63338 r63372 65 65 return cc == '\t' || cc == '\x0A' || cc == '\x0C' || cc == '\x0D' || cc == ' '; 66 66 } 67 68 class ExternalCharacterTokenBuffer : public Noncopyable {69 public:70 explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)71 : m_current(token.characters().characters())72 , m_end(m_current + token.characters().length())73 {74 ASSERT(!isEmpty());75 }76 77 ~ExternalCharacterTokenBuffer()78 {79 ASSERT(isEmpty());80 }81 82 bool isEmpty() const { return m_current == m_end; }83 84 void skipLeadingWhitespace()85 {86 ASSERT(!isEmpty());87 while (isTreeBuilderWhitepace(*m_current)) {88 if (++m_current == m_end)89 return;90 }91 }92 93 String takeLeadingWhitespace()94 {95 ASSERT(!isEmpty());96 const UChar* start = m_current;97 skipLeadingWhitespace();98 if (start == m_current)99 return String();100 return String(start, m_current - start);101 }102 103 String takeRemaining()104 {105 ASSERT(!isEmpty());106 const UChar* start = m_current;107 m_current = m_end;108 return String(start, m_current - start);109 }110 111 void giveRemainingTo(Vector<UChar>& recipient)112 {113 recipient.append(m_current, m_end - m_current);114 m_current = m_end;115 }116 117 String takeRemainingWhitespace()118 {119 ASSERT(!isEmpty());120 Vector<UChar> whitespace;121 do {122 UChar cc = *m_current++;123 if (isTreeBuilderWhitepace(cc))124 whitespace.append(cc);125 } while (m_current < m_end);126 // Returning the null string when there aren't any whitespace127 // characters is slightly cleaner semantically because we don't want128 // to insert a text node (as opposed to inserting an empty text node).129 if (whitespace.isEmpty())130 return String();131 return String::adopt(whitespace);132 }133 134 private:135 const UChar* m_current;136 const UChar* m_end;137 };138 67 139 68 inline bool hasNonWhitespace(const String& string) … … 317 246 } // namespace 318 247 248 class HTMLTreeBuilder::ExternalCharacterTokenBuffer : public Noncopyable { 249 public: 250 explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token) 251 : m_current(token.characters().characters()) 252 , m_end(m_current + token.characters().length()) 253 { 254 ASSERT(!isEmpty()); 255 } 256 257 ~ExternalCharacterTokenBuffer() 258 { 259 ASSERT(isEmpty()); 260 } 261 262 bool isEmpty() const { return m_current == m_end; } 263 264 void skipLeadingWhitespace() 265 { 266 ASSERT(!isEmpty()); 267 while (isTreeBuilderWhitepace(*m_current)) { 268 if (++m_current == m_end) 269 return; 270 } 271 } 272 273 String takeLeadingWhitespace() 274 { 275 ASSERT(!isEmpty()); 276 const UChar* start = m_current; 277 skipLeadingWhitespace(); 278 if (start == m_current) 279 return String(); 280 return String(start, m_current - start); 281 } 282 283 String takeRemaining() 284 { 285 ASSERT(!isEmpty()); 286 const UChar* start = m_current; 287 m_current = m_end; 288 return String(start, m_current - start); 289 } 290 291 void giveRemainingTo(Vector<UChar>& recipient) 292 { 293 recipient.append(m_current, m_end - m_current); 294 m_current = m_end; 295 } 296 297 String takeRemainingWhitespace() 298 { 299 ASSERT(!isEmpty()); 300 Vector<UChar> whitespace; 301 do { 302 UChar cc = *m_current++; 303 if (isTreeBuilderWhitepace(cc)) 304 whitespace.append(cc); 305 } while (m_current < m_end); 306 // Returning the null string when there aren't any whitespace 307 // characters is slightly cleaner semantically because we don't want 308 // to insert a text node (as opposed to inserting an empty text node). 309 if (whitespace.isEmpty()) 310 return String(); 311 return String::adopt(whitespace); 312 } 313 314 private: 315 const UChar* m_current; 316 const UChar* m_end; 317 }; 318 319 319 320 HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* document, bool reportErrors) 320 321 : m_framesetOk(true) … … 543 544 } 544 545 if (m_insertionMode == InTableTextMode) { 545 processDefaultForInTableTextMode(token);546 defaultForInTableText(); 546 547 processDoctypeToken(token); 547 548 return; … … 1179 1180 case InitialMode: 1180 1181 ASSERT(insertionMode() == InitialMode); 1181 processDefaultForInitialMode(token);1182 defaultForInitial(); 1182 1183 // Fall through. 1183 1184 case BeforeHTMLMode: … … 1188 1189 return; 1189 1190 } 1190 processDefaultForBeforeHTMLMode(token);1191 defaultForBeforeHTML(); 1191 1192 // Fall through. 1192 1193 case BeforeHeadMode: … … 1201 1202 return; 1202 1203 } 1203 processDefaultForBeforeHeadMode(token);1204 defaultForBeforeHead(); 1204 1205 // Fall through. 1205 1206 case InHeadMode: … … 1207 1208 if (processStartTagForInHead(token)) 1208 1209 return; 1209 processDefaultForInHeadMode(token);1210 defaultForInHead(); 1210 1211 // Fall through. 1211 1212 case AfterHeadMode: … … 1244 1245 return; 1245 1246 } 1246 processDefaultForAfterHeadMode(token);1247 defaultForAfterHead(); 1247 1248 // Fall through 1248 1249 case InBodyMode: … … 1384 1385 return; 1385 1386 } 1386 processDefaultForInHeadNoscriptMode(token);1387 defaultForInHeadNoscript(); 1387 1388 processToken(token); 1388 1389 break; … … 1483 1484 break; 1484 1485 case InTableTextMode: 1485 processDefaultForInTableTextMode(token);1486 defaultForInTableText(); 1486 1487 processStartTag(token); 1487 1488 break; … … 2105 2106 case InitialMode: 2106 2107 ASSERT(insertionMode() == InitialMode); 2107 processDefaultForInitialMode(token);2108 defaultForInitial(); 2108 2109 // Fall through. 2109 2110 case BeforeHTMLMode: … … 2113 2114 return; 2114 2115 } 2115 processDefaultForBeforeHTMLMode(token);2116 defaultForBeforeHTML(); 2116 2117 // Fall through. 2117 2118 case BeforeHeadMode: … … 2121 2122 return; 2122 2123 } 2123 processDefaultForBeforeHeadMode(token);2124 defaultForBeforeHead(); 2124 2125 // Fall through. 2125 2126 case InHeadMode: … … 2134 2135 return; 2135 2136 } 2136 processDefaultForInHeadMode(token);2137 defaultForInHead(); 2137 2138 // Fall through. 2138 2139 case AfterHeadMode: … … 2142 2143 return; 2143 2144 } 2144 processDefaultForAfterHeadMode(token);2145 defaultForAfterHead(); 2145 2146 // Fall through 2146 2147 case InBodyMode: … … 2237 2238 return; 2238 2239 } 2239 processDefaultForInHeadNoscriptMode(token);2240 defaultForInHeadNoscript(); 2240 2241 processToken(token); 2241 2242 break; … … 2322 2323 break; 2323 2324 case InTableTextMode: 2324 processDefaultForInTableTextMode(token);2325 defaultForInTableText(); 2325 2326 processEndTag(token); 2326 2327 break; … … 2411 2412 } 2412 2413 if (m_insertionMode == InTableTextMode) { 2413 processDefaultForInTableTextMode(token);2414 defaultForInTableText(); 2414 2415 processComment(token); 2415 2416 return; … … 2421 2422 { 2422 2423 ASSERT(token.type() == HTMLToken::Character); 2423 2424 2424 // FIXME: Currently this design has an extra memcpy because we copy the 2425 2425 // characters out of the HTMLTokenizer's buffer into the AtomicHTMLToken … … 2427 2427 // from the HTMLTokenizer's buffer into the text node. 2428 2428 ExternalCharacterTokenBuffer buffer(token); 2429 2429 processCharacterBuffer(buffer); 2430 } 2431 2432 void HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer) 2433 { 2430 2434 ReprocessBuffer: 2431 2435 switch (insertionMode()) { … … 2435 2439 if (buffer.isEmpty()) 2436 2440 return; 2437 processDefaultForInitialMode(token);2441 defaultForInitial(); 2438 2442 // Fall through. 2439 2443 } … … 2443 2447 if (buffer.isEmpty()) 2444 2448 return; 2445 processDefaultForBeforeHTMLMode(token);2449 defaultForBeforeHTML(); 2446 2450 // Fall through. 2447 2451 } … … 2451 2455 if (buffer.isEmpty()) 2452 2456 return; 2453 processDefaultForBeforeHeadMode(token);2457 defaultForBeforeHead(); 2454 2458 // Fall through. 2455 2459 } … … 2461 2465 if (buffer.isEmpty()) 2462 2466 return; 2463 processDefaultForInHeadMode(token);2467 defaultForInHead(); 2464 2468 // Fall through. 2465 2469 } … … 2471 2475 if (buffer.isEmpty()) 2472 2476 return; 2473 processDefaultForAfterHeadMode(token);2477 defaultForAfterHead(); 2474 2478 // Fall through. 2475 2479 } … … 2514 2518 case AfterAfterBodyMode: { 2515 2519 ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode); 2516 parseError(token);2520 // FIXME: parse error 2517 2521 setInsertionMode(InBodyMode); 2518 2522 goto ReprocessBuffer; … … 2531 2535 if (buffer.isEmpty()) 2532 2536 return; 2533 processDefaultForInHeadNoscriptMode(token);2537 defaultForInHeadNoscript(); 2534 2538 goto ReprocessBuffer; 2535 2539 break; … … 2578 2582 case InitialMode: 2579 2583 ASSERT(insertionMode() == InitialMode); 2580 processDefaultForInitialMode(token);2584 defaultForInitial(); 2581 2585 // Fall through. 2582 2586 case BeforeHTMLMode: 2583 2587 ASSERT(insertionMode() == BeforeHTMLMode); 2584 processDefaultForBeforeHTMLMode(token);2588 defaultForBeforeHTML(); 2585 2589 // Fall through. 2586 2590 case BeforeHeadMode: 2587 2591 ASSERT(insertionMode() == BeforeHeadMode); 2588 processDefaultForBeforeHeadMode(token);2592 defaultForBeforeHead(); 2589 2593 // Fall through. 2590 2594 case InHeadMode: 2591 2595 ASSERT(insertionMode() == InHeadMode); 2592 processDefaultForInHeadMode(token);2596 defaultForInHead(); 2593 2597 // Fall through. 2594 2598 case AfterHeadMode: 2595 2599 ASSERT(insertionMode() == AfterHeadMode); 2596 processDefaultForAfterHeadMode(token);2600 defaultForAfterHead(); 2597 2601 // Fall through 2598 2602 case InBodyMode: … … 2608 2612 case InHeadNoscriptMode: 2609 2613 ASSERT(insertionMode() == InHeadNoscriptMode); 2610 processDefaultForInHeadNoscriptMode(token);2614 defaultForInHeadNoscript(); 2611 2615 processToken(token); 2612 2616 break; … … 2644 2648 break; 2645 2649 case InTableTextMode: 2646 processDefaultForInTableTextMode(token);2650 defaultForInTableText(); 2647 2651 processEndOfFile(token); 2648 2652 break; … … 2655 2659 } 2656 2660 2657 void HTMLTreeBuilder:: processDefaultForInitialMode(AtomicHTMLToken& token)2661 void HTMLTreeBuilder::defaultForInitial() 2658 2662 { 2659 2663 notImplemented(); 2660 parseError(token);2664 // FIXME: parse error 2661 2665 setInsertionMode(BeforeHTMLMode); 2662 2666 } 2663 2667 2664 void HTMLTreeBuilder:: processDefaultForBeforeHTMLMode(AtomicHTMLToken&)2668 void HTMLTreeBuilder::defaultForBeforeHTML() 2665 2669 { 2666 2670 AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName()); … … 2669 2673 } 2670 2674 2671 void HTMLTreeBuilder:: processDefaultForBeforeHeadMode(AtomicHTMLToken&)2675 void HTMLTreeBuilder::defaultForBeforeHead() 2672 2676 { 2673 2677 AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName()); … … 2675 2679 } 2676 2680 2677 void HTMLTreeBuilder:: processDefaultForInHeadMode(AtomicHTMLToken&)2681 void HTMLTreeBuilder::defaultForInHead() 2678 2682 { 2679 2683 AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName()); … … 2681 2685 } 2682 2686 2683 void HTMLTreeBuilder:: processDefaultForInHeadNoscriptMode(AtomicHTMLToken&)2687 void HTMLTreeBuilder::defaultForInHeadNoscript() 2684 2688 { 2685 2689 AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName()); … … 2687 2691 } 2688 2692 2689 void HTMLTreeBuilder:: processDefaultForAfterHeadMode(AtomicHTMLToken&)2693 void HTMLTreeBuilder::defaultForAfterHead() 2690 2694 { 2691 2695 AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName()); … … 2694 2698 } 2695 2699 2696 void HTMLTreeBuilder:: processDefaultForInTableTextMode(AtomicHTMLToken& token)2700 void HTMLTreeBuilder::defaultForInTableText() 2697 2701 { 2698 2702 String characters = String::adopt(m_pendingTableCharacters); 2699 2703 if (hasNonWhitespace(characters)) { 2700 parseError(token);2704 // FIXME: parse error 2701 2705 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree, requiresRedirectToFosterParent(m_tree.currentElement())); 2702 2706 m_tree.reconstructTheActiveFormattingElements(); -
trunk/WebCore/html/HTMLTreeBuilder.h
r63116 r63372 77 77 private: 78 78 class FakeInsertionMode; 79 class ExternalCharacterTokenBuffer; 79 80 // Represents HTML5 "insertion mode" 80 81 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode … … 135 136 void processAnyOtherEndTagForInBody(AtomicHTMLToken&); 136 137 138 void processCharacterBuffer(ExternalCharacterTokenBuffer&); 139 137 140 void processFakeStartTag(const QualifiedName&, PassRefPtr<NamedNodeMap> attributes = 0); 138 141 void processFakeEndTag(const QualifiedName&); … … 145 148 146 149 // Default processing for the different insertion modes. 147 // FIXME: These functions need to be renamed to remove "process" from their names. 148 void processDefaultForInitialMode(AtomicHTMLToken&); 149 void processDefaultForBeforeHTMLMode(AtomicHTMLToken&); 150 void processDefaultForBeforeHeadMode(AtomicHTMLToken&); 151 void processDefaultForInHeadMode(AtomicHTMLToken&); 152 void processDefaultForInHeadNoscriptMode(AtomicHTMLToken&); 153 void processDefaultForAfterHeadMode(AtomicHTMLToken&); 154 void processDefaultForInTableTextMode(AtomicHTMLToken&); 150 void defaultForInitial(); 151 void defaultForBeforeHTML(); 152 void defaultForBeforeHead(); 153 void defaultForInHead(); 154 void defaultForInHeadNoscript(); 155 void defaultForAfterHead(); 156 void defaultForInTableText(); 155 157 156 158 void processUsingSecondaryInsertionModeAndAdjustInsertionMode(AtomicHTMLToken&);
Note: See TracChangeset
for help on using the changeset viewer.