Changeset 27859 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 16, 2007, 2:43:36 PM (18 years ago)
Author:
[email protected]
Message:

2007-11-16 Mark Rowe <[email protected]>

Reviewed by Eric.

Replace strings, identifier, buffer8 and buffer16 members of Lexer with vectors.
SunSpider claims this is a 0.7% speedup.

  • kjs/lexer.cpp: (KJS::Lexer::Lexer): (KJS::Lexer::lex): (KJS::Lexer::record8): (KJS::Lexer::record16): (KJS::Lexer::scanRegExp): (KJS::Lexer::clear): (KJS::Lexer::makeIdentifier): (KJS::Lexer::makeUString):
  • kjs/lexer.h:
  • kjs/ustring.cpp: (KJS::UString::UString): Add a convenience constructor that takes a const Vector<UChar>&.
  • kjs/ustring.h:
Location:
trunk/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27857 r27859  
     12007-11-16  Mark Rowe  <[email protected]>
     2
     3        Reviewed by Eric.
     4
     5        Replace strings, identifier, buffer8 and buffer16 members of Lexer with vectors.
     6        SunSpider claims this is a 0.7% speedup.
     7
     8        * kjs/lexer.cpp:
     9        (KJS::Lexer::Lexer):
     10        (KJS::Lexer::lex):
     11        (KJS::Lexer::record8):
     12        (KJS::Lexer::record16):
     13        (KJS::Lexer::scanRegExp):
     14        (KJS::Lexer::clear):
     15        (KJS::Lexer::makeIdentifier):
     16        (KJS::Lexer::makeUString):
     17        * kjs/lexer.h:
     18        * kjs/ustring.cpp:
     19        (KJS::UString::UString): Add a convenience constructor that takes a const Vector<UChar>&.
     20        * kjs/ustring.h:
     21
    1222007-11-16  Adam Roben  <[email protected]>
    223
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r27842 r27859  
    5959static bool isDecimalDigit(int);
    6060
     61static const size_t initialReadBufferCapacity = 32;
     62static const size_t initialStringTableCapacity = 64;
     63
    6164Lexer& lexer()
    6265{
     
    7174
    7275Lexer::Lexer()
    73   : yylineno(1),
    74     size8(128), size16(128), restrKeyword(false),
    75     eatNextIdentifier(false), stackToken(-1), lastToken(-1), pos(0),
    76     code(0), length(0),
     76  : yylineno(1)
     77  , restrKeyword(false)
     78  , eatNextIdentifier(false)
     79  , stackToken(-1)
     80  , lastToken(-1)
     81  , pos(0)
     82  , code(0)
     83  , length(0)
    7784#ifndef KJS_PURE_ECMA
    78     bol(true),
     85  , bol(true)
    7986#endif
    80     current(0), next1(0), next2(0), next3(0),
    81     strings(0), numStrings(0), stringsCapacity(0),
    82     identifiers(0), numIdentifiers(0), identifiersCapacity(0)
    83 {
    84   // allocate space for read buffers
    85   buffer8 = new char[size8];
    86   buffer16 = new KJS::UChar[size16];
    87 }
    88 
    89 Lexer::~Lexer()
    90 {
    91   delete [] buffer8;
    92   delete [] buffer16;
     87  , current(0)
     88  , next1(0)
     89  , next2(0)
     90  , next3(0)
     91{
     92    m_buffer8.reserveCapacity(initialReadBufferCapacity);
     93    m_buffer16.reserveCapacity(initialReadBufferCapacity);
     94    m_strings.reserveCapacity(initialStringTableCapacity);
     95    m_identifiers.reserveCapacity(initialStringTableCapacity);
    9396}
    9497
     
    152155  state = Start;
    153156  unsigned short stringType = 0; // either single or double quotes
    154   pos8 = pos16 = 0;
     157  m_buffer8.clear();
     158  m_buffer16.clear();
    155159  done = false;
    156160  terminator = false;
     
    448452
    449453  // terminate string
    450   buffer8[pos8] = '\0';
     454  m_buffer8.append('\0');
    451455
    452456#ifdef KJS_DEBUG_LEX
    453457  fprintf(stderr, "line: %d ", lineNo());
    454   fprintf(stderr, "yytext (%x): ", buffer8[0]);
    455   fprintf(stderr, "%s ", buffer8);
     458  fprintf(stderr, "yytext (%x): ", m_buffer8[0]);
     459  fprintf(stderr, "%s ", buffer8.data());
    456460#endif
    457461
    458462  double dval = 0;
    459463  if (state == Number) {
    460     dval = strtod(buffer8, 0L);
     464    dval = strtod(m_buffer8.data(), 0L);
    461465  } else if (state == Hex) { // scan hex numbers
    462     const char *p = buffer8 + 2;
     466    const char* p = m_buffer8.data() + 2;
    463467    while (char c = *p++) {
    464468      dval *= 16;
     
    467471
    468472    if (dval >= mantissaOverflowLowerBound)
    469       dval = parseIntOverflow(buffer8 + 2, p - (buffer8 + 3), 16);
     473      dval = parseIntOverflow(m_buffer8.data() + 2, p - (m_buffer8.data() + 3), 16);
    470474
    471475    state = Number;
    472476  } else if (state == Octal) {   // scan octal number
    473     const char *p = buffer8 + 1;
     477    const char* p = m_buffer8.data() + 1;
    474478    while (char c = *p++) {
    475479      dval *= 8;
     
    478482
    479483    if (dval >= mantissaOverflowLowerBound)
    480       dval = parseIntOverflow(buffer8 + 1, p - (buffer8 + 2), 8);
     484      dval = parseIntOverflow(m_buffer8.data() + 1, p - (m_buffer8.data() + 2), 8);
    481485
    482486    state = Number;
     
    523527    break;
    524528  case IdentifierOrKeyword:
    525     if ((token = Lookup::find(&mainTable, buffer16, pos16)) < 0) {
     529    if ((token = Lookup::find(&mainTable, m_buffer16.data(), m_buffer16.size())) < 0) {
    526530  case Identifier:
    527531      // Lookup for keyword failed, means this is an identifier
     
    532536        break;
    533537      }
    534       kjsyylval.ident = makeIdentifier(buffer16, pos16);
     538      kjsyylval.ident = makeIdentifier(m_buffer16);
    535539      token = IDENT;
    536540      break;
     
    547551    break;
    548552  case String:
    549     kjsyylval.string = makeUString(buffer16, pos16);
     553    kjsyylval.string = makeUString(m_buffer16);
    550554    token = STRING;
    551555    break;
     
    783787void Lexer::record8(int c)
    784788{
    785   ASSERT(c >= 0);
    786   ASSERT(c <= 0xff);
    787 
    788   // enlarge buffer if full
    789   if (pos8 >= size8 - 1) {
    790     char *tmp = new char[2 * size8];
    791     memcpy(tmp, buffer8, size8 * sizeof(char));
    792     delete [] buffer8;
    793     buffer8 = tmp;
    794     size8 *= 2;
    795   }
    796 
    797   buffer8[pos8++] = (char) c;
     789    ASSERT(c >= 0);
     790    ASSERT(c <= 0xff);
     791    m_buffer8.append(c);
    798792}
    799793
    800794void Lexer::record16(int c)
    801795{
    802   ASSERT(c >= 0);
    803   ASSERT(c <= USHRT_MAX);
    804   record16(UChar(static_cast<unsigned short>(c)));
     796    ASSERT(c >= 0);
     797    ASSERT(c <= USHRT_MAX);
     798    record16(UChar(static_cast<unsigned short>(c)));
    805799}
    806800
    807801void Lexer::record16(KJS::UChar c)
    808802{
    809   // enlarge buffer if full
    810   if (pos16 >= size16 - 1) {
    811     KJS::UChar *tmp = new KJS::UChar[2 * size16];
    812     memcpy(tmp, buffer16, size16 * sizeof(KJS::UChar));
    813     delete [] buffer16;
    814     buffer16 = tmp;
    815     size16 *= 2;
    816   }
    817 
    818   buffer16[pos16++] = c;
     803    m_buffer16.append(c);
    819804}
    820805
    821806bool Lexer::scanRegExp()
    822807{
    823   pos16 = 0;
     808  m_buffer16.clear();
    824809  bool lastWasEscape = false;
    825810  bool inBrackets = false;
     
    840825        lastWasEscape =
    841826            !lastWasEscape && (current == '\\');
    842     }
    843     else { // end of regexp
    844       m_pattern = UString(buffer16, pos16);
    845       pos16 = 0;
    846       shift(1);
    847       break;
     827    } else { // end of regexp
     828        m_pattern = UString(m_buffer16);
     829        m_buffer16.clear();
     830        shift(1);
     831        break;
    848832    }
    849833    shift(1);
     
    854838    shift(1);
    855839  }
    856   m_flags = UString(buffer16, pos16);
     840  m_flags = UString(m_buffer16);
    857841
    858842  return true;
     
    861845void Lexer::clear()
    862846{
    863   for (unsigned i = 0; i < numIdentifiers; i++)
    864     delete identifiers[i];
    865   fastFree(identifiers);
    866   identifiers = 0;
    867   numIdentifiers = 0;
    868   identifiersCapacity = 0;
    869 
    870   for (unsigned i = 0; i < numStrings; i++)
    871     delete strings[i];
    872   fastFree(strings);
    873   strings = 0;
    874   numStrings = 0;
    875   stringsCapacity = 0;
    876  
    877   m_pattern = 0;
    878   m_flags = 0;
    879   m_sourceURL = 0;
    880 }
    881 
    882 const int initialCapacity = 64;
    883 const int growthFactor = 2;
    884 
    885 Identifier* Lexer::makeIdentifier(KJS::UChar* buffer, unsigned int pos)
    886 {
    887   if (numIdentifiers == identifiersCapacity) {
    888     identifiersCapacity = (identifiersCapacity == 0) ? initialCapacity : identifiersCapacity *growthFactor;
    889     identifiers = (KJS::Identifier **)fastRealloc(identifiers, sizeof(KJS::Identifier *) * identifiersCapacity);
    890   }
    891 
    892   KJS::Identifier *identifier = new KJS::Identifier(buffer, pos);
    893   identifiers[numIdentifiers++] = identifier;
    894   return identifier;
     847    deleteAllValues(m_strings);
     848    Vector<UString*> newStrings;
     849    newStrings.reserveCapacity(initialStringTableCapacity);
     850    m_strings.swap(newStrings);
     851
     852    deleteAllValues(m_identifiers);
     853    Vector<KJS::Identifier*> newIdentifiers;
     854    newIdentifiers.reserveCapacity(initialStringTableCapacity);
     855    m_identifiers.swap(newIdentifiers);
     856
     857    Vector<char> newBuffer8;
     858    newBuffer8.reserveCapacity(initialReadBufferCapacity);
     859    m_buffer8.swap(newBuffer8);
     860
     861    Vector<UChar> newBuffer16;
     862    newBuffer16.reserveCapacity(initialReadBufferCapacity);
     863    m_buffer16.swap(newBuffer16);
     864
     865    m_pattern = 0;
     866    m_flags = 0;
     867    m_sourceURL = 0;
     868}
     869
     870Identifier* Lexer::makeIdentifier(const Vector<KJS::UChar>& buffer)
     871{
     872    KJS::Identifier* identifier = new KJS::Identifier(buffer.data(), buffer.size());
     873    m_identifiers.append(identifier);
     874    return identifier;
    895875}
    896876 
    897 UString* Lexer::makeUString(KJS::UChar* buffer, unsigned int pos)
    898 {
    899   if (numStrings == stringsCapacity) {
    900     stringsCapacity = (stringsCapacity == 0) ? initialCapacity : stringsCapacity *growthFactor;
    901     strings = (UString **)fastRealloc(strings, sizeof(UString *) * stringsCapacity);
    902   }
    903 
    904   UString *string = new UString(buffer, pos);
    905   strings[numStrings++] = string;
    906   return string;
     877UString* Lexer::makeUString(const Vector<KJS::UChar>& buffer)
     878{
     879    UString* string = new UString(buffer);
     880    m_strings.append(string);
     881    return string;
    907882}
    908883
  • trunk/JavaScriptCore/kjs/lexer.h

    r27842 r27859  
    2626
    2727#include "ustring.h"
     28#include <wtf/Vector.h>
    2829
    2930namespace KJS {
     
    8889    friend Lexer& lexer();
    8990    Lexer();
    90     ~Lexer();
    91    
     91
    9292    int yylineno;
    9393    UString m_sourceURL;
    9494    bool done;
    95     char *buffer8; // FIXME: This buffer is never deallocated.
    96     UChar *buffer16; // FIXME: This buffer is never deallocated.
    97     unsigned int size8, size16;
    98     unsigned int pos8, pos16;
     95    Vector<char> m_buffer8;
     96    Vector<UChar> m_buffer16;
    9997    bool terminator;
    10098    bool restrKeyword;
     
    126124    void record16(UChar);
    127125
    128     KJS::Identifier *makeIdentifier(UChar *buffer, unsigned int pos);
    129     UString *makeUString(UChar *buffer, unsigned int pos);
     126    KJS::Identifier* makeIdentifier(const Vector<UChar>& buffer);
     127    UString* makeUString(const Vector<UChar>& buffer);
    130128
    131129    const UChar *code;
     
    140138    int current, next1, next2, next3;
    141139
    142     UString **strings;
    143     unsigned int numStrings;
    144     unsigned int stringsCapacity;
    145 
    146     KJS::Identifier **identifiers;
    147     unsigned int numIdentifiers;
    148     unsigned int identifiersCapacity;
     140    Vector<UString*> m_strings;
     141    Vector<KJS::Identifier*> m_identifiers;
    149142   
    150143    UString m_pattern;
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r27842 r27859  
    459459    m_rep = Rep::create(c, length);
    460460}
     461
     462UString::UString(const Vector<UChar>& buffer)
     463{
     464    if (!buffer.size())
     465        m_rep = &Rep::empty;
     466    else
     467        m_rep = Rep::createCopying(buffer.data(), buffer.size());
     468}
     469
    461470
    462471UString::UString(const UString &a, const UString &b)
  • trunk/JavaScriptCore/kjs/ustring.h

    r27842 r27859  
    3131#include <wtf/PassRefPtr.h>
    3232#include <wtf/RefPtr.h>
     33#include <wtf/Vector.h>
    3334
    3435/* On some ARM platforms GCC won't pack structures by default so sizeof(UChar)
     
    203204     */
    204205    UString(const UString &s) : m_rep(s.m_rep) {}
     206
     207    UString(const Vector<UChar>& buffer);
     208
    205209    /**
    206210     * Convenience declaration only ! You'll be on your own to write the
Note: See TracChangeset for help on using the changeset viewer.