Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_PREPARSE_DATA_H_
     29 #define V8_PREPARSE_DATA_H_
     30 
     31 #include "allocation.h"
     32 #include "hashmap.h"
     33 #include "utils-inl.h"
     34 
     35 namespace v8 {
     36 namespace internal {
     37 
     38 // ----------------------------------------------------------------------------
     39 // ParserRecorder - Logging of preparser data.
     40 
     41 // Abstract interface for preparse data recorder.
     42 class ParserRecorder {
     43  public:
     44   ParserRecorder() { }
     45   virtual ~ParserRecorder() { }
     46 
     47   // Logs the scope and some details of a function literal in the source.
     48   virtual void LogFunction(int start,
     49                            int end,
     50                            int literals,
     51                            int properties,
     52                            LanguageMode language_mode) = 0;
     53 
     54   // Logs a symbol creation of a literal or identifier.
     55   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
     56   virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
     57 
     58   // Logs an error message and marks the log as containing an error.
     59   // Further logging will be ignored, and ExtractData will return a vector
     60   // representing the error only.
     61   virtual void LogMessage(int start,
     62                           int end,
     63                           const char* message,
     64                           const char* argument_opt) = 0;
     65 
     66   virtual int function_position() = 0;
     67 
     68   virtual int symbol_position() = 0;
     69 
     70   virtual int symbol_ids() = 0;
     71 
     72   virtual Vector<unsigned> ExtractData() = 0;
     73 
     74   virtual void PauseRecording() = 0;
     75 
     76   virtual void ResumeRecording() = 0;
     77 };
     78 
     79 
     80 // ----------------------------------------------------------------------------
     81 // FunctionLoggingParserRecorder - Record only function entries
     82 
     83 class FunctionLoggingParserRecorder : public ParserRecorder {
     84  public:
     85   FunctionLoggingParserRecorder();
     86   virtual ~FunctionLoggingParserRecorder() {}
     87 
     88   virtual void LogFunction(int start,
     89                            int end,
     90                            int literals,
     91                            int properties,
     92                            LanguageMode language_mode) {
     93     function_store_.Add(start);
     94     function_store_.Add(end);
     95     function_store_.Add(literals);
     96     function_store_.Add(properties);
     97     function_store_.Add(language_mode);
     98   }
     99 
    100   // Logs an error message and marks the log as containing an error.
    101   // Further logging will be ignored, and ExtractData will return a vector
    102   // representing the error only.
    103   virtual void LogMessage(int start,
    104                           int end,
    105                           const char* message,
    106                           const char* argument_opt);
    107 
    108   virtual int function_position() { return function_store_.size(); }
    109 
    110 
    111   virtual Vector<unsigned> ExtractData() = 0;
    112 
    113   virtual void PauseRecording() {
    114     pause_count_++;
    115     is_recording_ = false;
    116   }
    117 
    118   virtual void ResumeRecording() {
    119     ASSERT(pause_count_ > 0);
    120     if (--pause_count_ == 0) is_recording_ = !has_error();
    121   }
    122 
    123  protected:
    124   bool has_error() {
    125     return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]);
    126   }
    127 
    128   bool is_recording() {
    129     return is_recording_;
    130   }
    131 
    132   void WriteString(Vector<const char> str);
    133 
    134   Collector<unsigned> function_store_;
    135   unsigned preamble_[PreparseDataConstants::kHeaderSize];
    136   bool is_recording_;
    137   int pause_count_;
    138 
    139 #ifdef DEBUG
    140   int prev_start_;
    141 #endif
    142 };
    143 
    144 
    145 // ----------------------------------------------------------------------------
    146 // PartialParserRecorder - Record only function entries
    147 
    148 class PartialParserRecorder : public FunctionLoggingParserRecorder {
    149  public:
    150   PartialParserRecorder() : FunctionLoggingParserRecorder() { }
    151   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
    152   virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
    153   virtual ~PartialParserRecorder() { }
    154   virtual Vector<unsigned> ExtractData();
    155   virtual int symbol_position() { return 0; }
    156   virtual int symbol_ids() { return 0; }
    157 };
    158 
    159 
    160 // ----------------------------------------------------------------------------
    161 // CompleteParserRecorder -  Record both function entries and symbols.
    162 
    163 class CompleteParserRecorder: public FunctionLoggingParserRecorder {
    164  public:
    165   CompleteParserRecorder();
    166   virtual ~CompleteParserRecorder() { }
    167 
    168   virtual void LogAsciiSymbol(int start, Vector<const char> literal) {
    169     if (!is_recording_) return;
    170     int hash = vector_hash(literal);
    171     LogSymbol(start, hash, true, Vector<const byte>::cast(literal));
    172   }
    173 
    174   virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) {
    175     if (!is_recording_) return;
    176     int hash = vector_hash(literal);
    177     LogSymbol(start, hash, false, Vector<const byte>::cast(literal));
    178   }
    179 
    180   virtual Vector<unsigned> ExtractData();
    181 
    182   virtual int symbol_position() { return symbol_store_.size(); }
    183   virtual int symbol_ids() { return symbol_id_; }
    184 
    185  private:
    186   struct Key {
    187     bool is_ascii;
    188     Vector<const byte> literal_bytes;
    189   };
    190 
    191   virtual void LogSymbol(int start,
    192                          int hash,
    193                          bool is_ascii,
    194                          Vector<const byte> literal);
    195 
    196   template <typename Char>
    197   static int vector_hash(Vector<const Char> string) {
    198     int hash = 0;
    199     for (int i = 0; i < string.length(); i++) {
    200       int c = static_cast<int>(string[i]);
    201       hash += c;
    202       hash += (hash << 10);
    203       hash ^= (hash >> 6);
    204     }
    205     return hash;
    206   }
    207 
    208   static bool vector_compare(void* a, void* b) {
    209     Key* string1 = reinterpret_cast<Key*>(a);
    210     Key* string2 = reinterpret_cast<Key*>(b);
    211     if (string1->is_ascii != string2->is_ascii) return false;
    212     int length = string1->literal_bytes.length();
    213     if (string2->literal_bytes.length() != length) return false;
    214     return memcmp(string1->literal_bytes.start(),
    215                   string2->literal_bytes.start(), length) == 0;
    216   }
    217 
    218   // Write a non-negative number to the symbol store.
    219   void WriteNumber(int number);
    220 
    221   Collector<byte> literal_chars_;
    222   Collector<byte> symbol_store_;
    223   Collector<Key> symbol_keys_;
    224   HashMap symbol_table_;
    225   int symbol_id_;
    226 };
    227 
    228 
    229 } }  // namespace v8::internal.
    230 
    231 #endif  // V8_PREPARSE_DATA_H_
    232