OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 17 matching lines...) Expand all Loading... |
28 #ifndef V8_PREPARSE_DATA_H_ | 28 #ifndef V8_PREPARSE_DATA_H_ |
29 #define V8_PREPARSE_DATA_H_ | 29 #define V8_PREPARSE_DATA_H_ |
30 | 30 |
31 #include "allocation.h" | 31 #include "allocation.h" |
32 #include "hashmap.h" | 32 #include "hashmap.h" |
33 #include "utils-inl.h" | 33 #include "utils-inl.h" |
34 | 34 |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // ---------------------------------------------------------------------------- | |
39 // ParserRecorder - Logging of preparser data. | |
40 | 38 |
41 // Abstract interface for preparse data recorder. | 39 // Abstract interface for preparse data recorder. |
42 class ParserRecorder { | 40 class ParserRecorder { |
43 public: | 41 public: |
44 ParserRecorder() { } | 42 ParserRecorder() : should_log_symbols_(false) { } |
45 virtual ~ParserRecorder() { } | 43 virtual ~ParserRecorder() { } |
46 | 44 |
47 // Logs the scope and some details of a function literal in the source. | 45 // Logs the scope and some details of a function literal in the source. |
48 virtual void LogFunction(int start, | 46 virtual void LogFunction(int start, |
49 int end, | 47 int end, |
50 int literals, | 48 int literals, |
51 int properties, | 49 int properties, |
52 StrictMode strict_mode) = 0; | 50 StrictMode strict_mode) = 0; |
53 | 51 |
54 // Logs a symbol creation of a literal or identifier. | |
55 virtual void LogOneByteSymbol(int start, Vector<const uint8_t> literal) = 0; | |
56 virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> literal) = 0; | |
57 | |
58 // Logs an error message and marks the log as containing an error. | 52 // Logs an error message and marks the log as containing an error. |
59 // Further logging will be ignored, and ExtractData will return a vector | 53 // Further logging will be ignored, and ExtractData will return a vector |
60 // representing the error only. | 54 // representing the error only. |
61 virtual void LogMessage(int start, | 55 virtual void LogMessage(int start, |
62 int end, | 56 int end, |
63 const char* message, | 57 const char* message, |
64 const char* argument_opt) = 0; | 58 const char* argument_opt) = 0; |
65 | 59 |
66 virtual int function_position() = 0; | 60 // Logs a symbol creation of a literal or identifier. |
| 61 bool ShouldLogSymbols() { return should_log_symbols_; } |
| 62 // The following functions are only callable on CompleteParserRecorder |
| 63 // and are guarded by calls to ShouldLogSymbols. |
| 64 virtual void LogOneByteSymbol(int start, Vector<const uint8_t> literal) { |
| 65 UNREACHABLE(); |
| 66 } |
| 67 virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> literal) { |
| 68 UNREACHABLE(); |
| 69 } |
| 70 virtual void PauseRecording() { UNREACHABLE(); } |
| 71 virtual void ResumeRecording() { UNREACHABLE(); } |
67 | 72 |
68 virtual int symbol_position() = 0; | 73 protected: |
| 74 bool should_log_symbols_; |
69 | 75 |
70 virtual int symbol_ids() = 0; | 76 private: |
71 | 77 DISALLOW_COPY_AND_ASSIGN(ParserRecorder); |
72 virtual Vector<unsigned> ExtractData() = 0; | |
73 | |
74 virtual void PauseRecording() = 0; | |
75 | |
76 virtual void ResumeRecording() = 0; | |
77 }; | 78 }; |
78 | 79 |
79 | 80 |
80 // ---------------------------------------------------------------------------- | 81 class SingletonLogger : public ParserRecorder { |
81 // FunctionLoggingParserRecorder - Record only function entries | 82 public: |
| 83 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } |
| 84 virtual ~SingletonLogger() { } |
82 | 85 |
83 class FunctionLoggingParserRecorder : public ParserRecorder { | 86 void Reset() { has_error_ = false; } |
84 public: | |
85 FunctionLoggingParserRecorder(); | |
86 virtual ~FunctionLoggingParserRecorder() {} | |
87 | 87 |
88 virtual void LogFunction(int start, | 88 virtual void LogFunction(int start, |
89 int end, | 89 int end, |
| 90 int literals, |
| 91 int properties, |
| 92 StrictMode strict_mode) { |
| 93 ASSERT(!has_error_); |
| 94 start_ = start; |
| 95 end_ = end; |
| 96 literals_ = literals; |
| 97 properties_ = properties; |
| 98 strict_mode_ = strict_mode; |
| 99 }; |
| 100 |
| 101 // Logs an error message and marks the log as containing an error. |
| 102 // Further logging will be ignored, and ExtractData will return a vector |
| 103 // representing the error only. |
| 104 virtual void LogMessage(int start, |
| 105 int end, |
| 106 const char* message, |
| 107 const char* argument_opt) { |
| 108 if (has_error_) return; |
| 109 has_error_ = true; |
| 110 start_ = start; |
| 111 end_ = end; |
| 112 message_ = message; |
| 113 argument_opt_ = argument_opt; |
| 114 } |
| 115 |
| 116 bool has_error() { return has_error_; } |
| 117 |
| 118 int start() { return start_; } |
| 119 int end() { return end_; } |
| 120 int literals() { |
| 121 ASSERT(!has_error_); |
| 122 return literals_; |
| 123 } |
| 124 int properties() { |
| 125 ASSERT(!has_error_); |
| 126 return properties_; |
| 127 } |
| 128 StrictMode strict_mode() { |
| 129 ASSERT(!has_error_); |
| 130 return strict_mode_; |
| 131 } |
| 132 const char* message() { |
| 133 ASSERT(has_error_); |
| 134 return message_; |
| 135 } |
| 136 const char* argument_opt() { |
| 137 ASSERT(has_error_); |
| 138 return argument_opt_; |
| 139 } |
| 140 |
| 141 private: |
| 142 bool has_error_; |
| 143 int start_; |
| 144 int end_; |
| 145 // For function entries. |
| 146 int literals_; |
| 147 int properties_; |
| 148 StrictMode strict_mode_; |
| 149 // For error messages. |
| 150 const char* message_; |
| 151 const char* argument_opt_; |
| 152 }; |
| 153 |
| 154 |
| 155 class CompleteParserRecorder : public ParserRecorder { |
| 156 public: |
| 157 struct Key { |
| 158 bool is_one_byte; |
| 159 Vector<const byte> literal_bytes; |
| 160 }; |
| 161 |
| 162 CompleteParserRecorder(); |
| 163 virtual ~CompleteParserRecorder() {} |
| 164 |
| 165 virtual void LogFunction(int start, |
| 166 int end, |
90 int literals, | 167 int literals, |
91 int properties, | 168 int properties, |
92 StrictMode strict_mode) { | 169 StrictMode strict_mode) { |
93 function_store_.Add(start); | 170 function_store_.Add(start); |
94 function_store_.Add(end); | 171 function_store_.Add(end); |
95 function_store_.Add(literals); | 172 function_store_.Add(literals); |
96 function_store_.Add(properties); | 173 function_store_.Add(properties); |
97 function_store_.Add(strict_mode); | 174 function_store_.Add(strict_mode); |
98 } | 175 } |
99 | 176 |
100 // Logs an error message and marks the log as containing an error. | 177 // Logs an error message and marks the log as containing an error. |
101 // Further logging will be ignored, and ExtractData will return a vector | 178 // Further logging will be ignored, and ExtractData will return a vector |
102 // representing the error only. | 179 // representing the error only. |
103 virtual void LogMessage(int start, | 180 virtual void LogMessage(int start, |
104 int end, | 181 int end, |
105 const char* message, | 182 const char* message, |
106 const char* argument_opt); | 183 const char* argument_opt); |
107 | 184 |
108 virtual int function_position() { return function_store_.size(); } | |
109 | |
110 | |
111 virtual Vector<unsigned> ExtractData() = 0; | |
112 | |
113 virtual void PauseRecording() { | 185 virtual void PauseRecording() { |
114 pause_count_++; | 186 ASSERT(should_log_symbols_); |
115 is_recording_ = false; | 187 should_log_symbols_ = false; |
116 } | 188 } |
117 | 189 |
118 virtual void ResumeRecording() { | 190 virtual void ResumeRecording() { |
119 ASSERT(pause_count_ > 0); | 191 ASSERT(!should_log_symbols_); |
120 if (--pause_count_ == 0) is_recording_ = !has_error(); | 192 should_log_symbols_ = !has_error(); |
121 } | 193 } |
122 | 194 |
123 protected: | 195 virtual void LogOneByteSymbol(int start, Vector<const uint8_t> literal); |
| 196 virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> literal); |
| 197 Vector<unsigned> ExtractData(); |
| 198 |
| 199 private: |
124 bool has_error() { | 200 bool has_error() { |
125 return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]); | 201 return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]); |
126 } | 202 } |
127 | 203 |
128 bool is_recording() { | 204 void WriteString(Vector<const char> str); |
129 return is_recording_; | |
130 } | |
131 | 205 |
132 void WriteString(Vector<const char> str); | 206 // For testing. Defined in test-parsing.cc. |
| 207 friend struct CompleteParserRecorderFriend; |
| 208 |
| 209 void LogSymbol(int start, |
| 210 int hash, |
| 211 bool is_one_byte, |
| 212 Vector<const byte> literal); |
| 213 |
| 214 // Write a non-negative number to the symbol store. |
| 215 void WriteNumber(int number); |
133 | 216 |
134 Collector<unsigned> function_store_; | 217 Collector<unsigned> function_store_; |
135 unsigned preamble_[PreparseDataConstants::kHeaderSize]; | 218 unsigned preamble_[PreparseDataConstants::kHeaderSize]; |
136 bool is_recording_; | |
137 int pause_count_; | |
138 | 219 |
139 #ifdef DEBUG | 220 #ifdef DEBUG |
140 int prev_start_; | 221 int prev_start_; |
141 #endif | 222 #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 LogOneByteSymbol(int start, Vector<const uint8_t> literal) { } | |
152 virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> 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 LogOneByteSymbol(int start, Vector<const uint8_t> literal) { | |
169 if (!is_recording_) return; | |
170 int hash = vector_hash(literal); | |
171 LogSymbol(start, hash, true, literal); | |
172 } | |
173 | |
174 virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> 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 // For testing. Defined in test-parsing.cc. | |
187 friend void FakeWritingSymbolIdInPreParseData(CompleteParserRecorder* log, | |
188 int number); | |
189 | |
190 struct Key { | |
191 bool is_ascii; | |
192 Vector<const byte> literal_bytes; | |
193 }; | |
194 | |
195 virtual void LogSymbol(int start, | |
196 int hash, | |
197 bool is_ascii, | |
198 Vector<const byte> literal); | |
199 | |
200 template <typename Char> | |
201 static int vector_hash(Vector<const Char> string) { | |
202 int hash = 0; | |
203 for (int i = 0; i < string.length(); i++) { | |
204 int c = static_cast<int>(string[i]); | |
205 hash += c; | |
206 hash += (hash << 10); | |
207 hash ^= (hash >> 6); | |
208 } | |
209 return hash; | |
210 } | |
211 | |
212 static bool vector_compare(void* a, void* b) { | |
213 Key* string1 = reinterpret_cast<Key*>(a); | |
214 Key* string2 = reinterpret_cast<Key*>(b); | |
215 if (string1->is_ascii != string2->is_ascii) return false; | |
216 int length = string1->literal_bytes.length(); | |
217 if (string2->literal_bytes.length() != length) return false; | |
218 return memcmp(string1->literal_bytes.start(), | |
219 string2->literal_bytes.start(), length) == 0; | |
220 } | |
221 | |
222 // Write a non-negative number to the symbol store. | |
223 void WriteNumber(int number); | |
224 | 223 |
225 Collector<byte> literal_chars_; | 224 Collector<byte> literal_chars_; |
226 Collector<byte> symbol_store_; | 225 Collector<byte> symbol_store_; |
227 Collector<Key> symbol_keys_; | 226 Collector<Key> symbol_keys_; |
228 HashMap string_table_; | 227 HashMap string_table_; |
229 int symbol_id_; | 228 int symbol_id_; |
230 }; | 229 }; |
231 | 230 |
232 | 231 |
233 } } // namespace v8::internal. | 232 } } // namespace v8::internal. |
234 | 233 |
235 #endif // V8_PREPARSE_DATA_H_ | 234 #endif // V8_PREPARSE_DATA_H_ |
OLD | NEW |