OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 26 matching lines...) Expand all Loading... |
37 // independent of the V8 heap and internalizing them later. During parsing, | 37 // independent of the V8 heap and internalizing them later. During parsing, |
38 // AstStrings and AstValues are created and stored outside the heap, in | 38 // AstStrings and AstValues are created and stored outside the heap, in |
39 // AstValueFactory. After parsing, the strings and values are internalized | 39 // AstValueFactory. After parsing, the strings and values are internalized |
40 // (moved into the V8 heap). | 40 // (moved into the V8 heap). |
41 namespace v8 { | 41 namespace v8 { |
42 namespace internal { | 42 namespace internal { |
43 | 43 |
44 class AstString : public ZoneObject { | 44 class AstString : public ZoneObject { |
45 public: | 45 public: |
46 explicit AstString(bool is_raw) | 46 explicit AstString(bool is_raw) |
47 : bit_field_(IsRawStringBits::encode(is_raw)) {} | 47 : next_(nullptr), bit_field_(IsRawStringBits::encode(is_raw)) {} |
48 | 48 |
49 int length() const; | 49 int length() const; |
50 bool IsEmpty() const { return length() == 0; } | 50 bool IsEmpty() const { return length() == 0; } |
51 | 51 |
52 // Puts the string into the V8 heap. | 52 // Puts the string into the V8 heap. |
53 void Internalize(Isolate* isolate); | 53 void Internalize(Isolate* isolate); |
54 | 54 |
55 // This function can be called after internalizing. | 55 // This function can be called after internalizing. |
56 V8_INLINE Handle<String> string() const { | 56 V8_INLINE Handle<String> string() const { |
57 DCHECK(!string_.is_null()); | 57 DCHECK_NOT_NULL(string_); |
58 return string_; | 58 return Handle<String>(string_); |
59 } | 59 } |
60 | 60 |
| 61 AstString* next() { return next_; } |
| 62 AstString** next_location() { return &next_; } |
| 63 |
61 protected: | 64 protected: |
62 // Handle<String>::null() until internalized. | 65 void set_string(Handle<String> string) { string_ = string.location(); } |
63 Handle<String> string_; | 66 // {string_} is stored as String** instead of a Handle<String> so it can be |
| 67 // stored in a union with {next_}. |
| 68 union { |
| 69 AstString* next_; |
| 70 String** string_; |
| 71 }; |
64 // Poor-man's virtual dispatch to AstRawString / AstConsString. Takes less | 72 // Poor-man's virtual dispatch to AstRawString / AstConsString. Takes less |
65 // memory. | 73 // memory. |
66 class IsRawStringBits : public BitField<bool, 0, 1> {}; | 74 class IsRawStringBits : public BitField<bool, 0, 1> {}; |
67 int bit_field_; | 75 int bit_field_; |
68 }; | 76 }; |
69 | 77 |
70 | 78 |
71 class AstRawString final : public AstString { | 79 class AstRawString final : public AstString { |
72 public: | 80 public: |
73 int length() const { | 81 int length() const { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 Vector<const byte> literal_bytes_; | 130 Vector<const byte> literal_bytes_; |
123 }; | 131 }; |
124 | 132 |
125 | 133 |
126 class AstConsString final : public AstString { | 134 class AstConsString final : public AstString { |
127 public: | 135 public: |
128 AstConsString(const AstString* left, const AstString* right) | 136 AstConsString(const AstString* left, const AstString* right) |
129 : AstString(false), | 137 : AstString(false), |
130 length_(left->length() + right->length()), | 138 length_(left->length() + right->length()), |
131 left_(left), | 139 left_(left), |
132 right_(right), | 140 right_(right) {} |
133 next_(nullptr) {} | |
134 | 141 |
135 int length() const { return length_; } | 142 int length() const { return length_; } |
136 | 143 |
137 void Internalize(Isolate* isolate); | 144 void Internalize(Isolate* isolate); |
138 | 145 |
139 AstConsString* next() { return next_; } | |
140 AstConsString** next_location() { return &next_; } | |
141 | |
142 private: | 146 private: |
143 const int length_; | 147 const int length_; |
144 const AstString* left_; | 148 const AstString* left_; |
145 const AstString* right_; | 149 const AstString* right_; |
146 AstConsString* next_; | |
147 }; | 150 }; |
148 | 151 |
149 | 152 |
150 // AstValue is either a string, a number, a string array, a boolean, or a | 153 // AstValue is either a string, a number, a string array, a boolean, or a |
151 // special value (null, undefined, the hole). | 154 // special value (null, undefined, the hole). |
152 class AstValue : public ZoneObject { | 155 class AstValue : public ZoneObject { |
153 public: | 156 public: |
154 bool IsString() const { | 157 bool IsString() const { |
155 return type_ == STRING; | 158 return type_ == STRING; |
156 } | 159 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 bool IsTheHole() const { return type_ == THE_HOLE; } | 201 bool IsTheHole() const { return type_ == THE_HOLE; } |
199 bool IsNull() const { return type_ == NULL_TYPE; } | 202 bool IsNull() const { return type_ == NULL_TYPE; } |
200 | 203 |
201 void Internalize(Isolate* isolate); | 204 void Internalize(Isolate* isolate); |
202 | 205 |
203 // Can be called after Internalize has been called. | 206 // Can be called after Internalize has been called. |
204 V8_INLINE Handle<Object> value() const { | 207 V8_INLINE Handle<Object> value() const { |
205 if (type_ == STRING) { | 208 if (type_ == STRING) { |
206 return string_->string(); | 209 return string_->string(); |
207 } | 210 } |
208 DCHECK(!value_.is_null()); | 211 DCHECK_NOT_NULL(value_); |
209 return value_; | 212 return Handle<Object>(value_); |
210 } | 213 } |
211 AstValue* next() const { return next_; } | 214 AstValue* next() const { return next_; } |
212 void set_next(AstValue* next) { next_ = next; } | 215 void set_next(AstValue* next) { next_ = next; } |
213 | 216 |
214 private: | 217 private: |
| 218 void set_value(Handle<Object> object) { value_ = object.location(); } |
215 friend class AstValueFactory; | 219 friend class AstValueFactory; |
216 | 220 |
217 enum Type { | 221 enum Type { |
218 STRING, | 222 STRING, |
219 SYMBOL, | 223 SYMBOL, |
220 NUMBER, | 224 NUMBER, |
221 NUMBER_WITH_DOT, | 225 NUMBER_WITH_DOT, |
222 SMI, | 226 SMI, |
223 SMI_WITH_DOT, | 227 SMI_WITH_DOT, |
224 BOOLEAN, | 228 BOOLEAN, |
(...skipping 27 matching lines...) Expand all Loading... |
252 } | 256 } |
253 | 257 |
254 explicit AstValue(bool b) : type_(BOOLEAN), next_(nullptr) { bool_ = b; } | 258 explicit AstValue(bool b) : type_(BOOLEAN), next_(nullptr) { bool_ = b; } |
255 | 259 |
256 explicit AstValue(Type t) : type_(t), next_(nullptr) { | 260 explicit AstValue(Type t) : type_(t), next_(nullptr) { |
257 DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE); | 261 DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE); |
258 } | 262 } |
259 | 263 |
260 Type type_; | 264 Type type_; |
261 | 265 |
| 266 // {value_} is stored as Object** instead of a Handle<Object> so it can be |
| 267 // stored in a union with {next_}. |
| 268 union { |
| 269 Object** value_; // if internalized |
| 270 AstValue* next_; // if !internalized |
| 271 }; |
| 272 |
262 // Uninternalized value. | 273 // Uninternalized value. |
263 union { | 274 union { |
264 const AstRawString* string_; | 275 const AstRawString* string_; |
265 double number_; | 276 double number_; |
266 int smi_; | 277 int smi_; |
267 bool bool_; | 278 bool bool_; |
268 const char* symbol_name_; | 279 const char* symbol_name_; |
269 }; | 280 }; |
270 | |
271 // Handle<String>::null() until internalized. | |
272 Handle<Object> value_; | |
273 AstValue* next_; | |
274 }; | 281 }; |
275 | 282 |
276 | 283 |
277 // For generating constants. | 284 // For generating constants. |
278 #define STRING_CONSTANTS(F) \ | 285 #define STRING_CONSTANTS(F) \ |
279 F(anonymous_function, "(anonymous function)") \ | 286 F(anonymous_function, "(anonymous function)") \ |
280 F(arguments, "arguments") \ | 287 F(arguments, "arguments") \ |
281 F(async, "async") \ | 288 F(async, "async") \ |
282 F(await, "await") \ | 289 F(await, "await") \ |
283 F(constructor, "constructor") \ | 290 F(constructor, "constructor") \ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 F(false_value) \ | 325 F(false_value) \ |
319 F(null_value) \ | 326 F(null_value) \ |
320 F(undefined_value) \ | 327 F(undefined_value) \ |
321 F(the_hole_value) | 328 F(the_hole_value) |
322 | 329 |
323 class AstValueFactory { | 330 class AstValueFactory { |
324 public: | 331 public: |
325 AstValueFactory(Zone* zone, uint32_t hash_seed) | 332 AstValueFactory(Zone* zone, uint32_t hash_seed) |
326 : string_table_(AstRawStringCompare), | 333 : string_table_(AstRawStringCompare), |
327 values_(nullptr), | 334 values_(nullptr), |
328 cons_strings_(nullptr), | 335 strings_(nullptr), |
329 cons_strings_end_(&cons_strings_), | 336 strings_end_(&strings_), |
330 zone_(zone), | 337 zone_(zone), |
331 hash_seed_(hash_seed) { | 338 hash_seed_(hash_seed) { |
332 #define F(name, str) name##_string_ = NULL; | 339 #define F(name, str) name##_string_ = NULL; |
333 STRING_CONSTANTS(F) | 340 STRING_CONSTANTS(F) |
334 #undef F | 341 #undef F |
335 #define F(name) name##_ = NULL; | 342 #define F(name) name##_ = NULL; |
336 OTHER_CONSTANTS(F) | 343 OTHER_CONSTANTS(F) |
337 #undef F | 344 #undef F |
338 } | 345 } |
339 | 346 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 const AstValue* NewNull(); | 387 const AstValue* NewNull(); |
381 const AstValue* NewUndefined(); | 388 const AstValue* NewUndefined(); |
382 const AstValue* NewTheHole(); | 389 const AstValue* NewTheHole(); |
383 | 390 |
384 private: | 391 private: |
385 AstValue* AddValue(AstValue* value) { | 392 AstValue* AddValue(AstValue* value) { |
386 value->set_next(values_); | 393 value->set_next(values_); |
387 values_ = value; | 394 values_ = value; |
388 return value; | 395 return value; |
389 } | 396 } |
390 AstConsString* AddConsString(AstConsString* string) { | 397 AstString* AddString(AstString* string) { |
391 *cons_strings_end_ = string; | 398 *strings_end_ = string; |
392 cons_strings_end_ = string->next_location(); | 399 strings_end_ = string->next_location(); |
393 return string; | 400 return string; |
394 } | 401 } |
395 void ResetConsStrings() { | 402 void ResetStrings() { |
396 cons_strings_ = nullptr; | 403 strings_ = nullptr; |
397 cons_strings_end_ = &cons_strings_; | 404 strings_end_ = &strings_; |
398 } | 405 } |
399 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( | 406 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( |
400 Vector<const uint8_t> literal); | 407 Vector<const uint8_t> literal); |
401 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); | 408 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); |
402 AstRawString* GetString(uint32_t hash, bool is_one_byte, | 409 AstRawString* GetString(uint32_t hash, bool is_one_byte, |
403 Vector<const byte> literal_bytes); | 410 Vector<const byte> literal_bytes); |
404 | 411 |
405 static bool AstRawStringCompare(void* a, void* b); | 412 static bool AstRawStringCompare(void* a, void* b); |
406 | 413 |
407 // All strings are copied here, one after another (no NULLs inbetween). | 414 // All strings are copied here, one after another (no NULLs inbetween). |
408 base::CustomMatcherHashMap string_table_; | 415 base::CustomMatcherHashMap string_table_; |
409 // For keeping track of all AstValues and AstRawStrings we've created (so that | 416 // For keeping track of all AstValues and AstRawStrings we've created (so that |
410 // they can be internalized later). | 417 // they can be internalized later). |
411 AstValue* values_; | 418 AstValue* values_; |
412 // We need to keep track of cons_strings_ in order since they require their | 419 // We need to keep track of strings_ in order since cons strings require their |
413 // members to be internalized first. | 420 // members to be internalized first. |
414 AstConsString* cons_strings_; | 421 AstString* strings_; |
415 AstConsString** cons_strings_end_; | 422 AstString** strings_end_; |
416 Zone* zone_; | 423 Zone* zone_; |
417 | 424 |
418 uint32_t hash_seed_; | 425 uint32_t hash_seed_; |
419 | 426 |
420 #define F(name, str) const AstRawString* name##_string_; | 427 #define F(name, str) const AstRawString* name##_string_; |
421 STRING_CONSTANTS(F) | 428 STRING_CONSTANTS(F) |
422 #undef F | 429 #undef F |
423 | 430 |
424 #define F(name) AstValue* name##_; | 431 #define F(name) AstValue* name##_; |
425 OTHER_CONSTANTS(F) | 432 OTHER_CONSTANTS(F) |
426 #undef F | 433 #undef F |
427 }; | 434 }; |
428 } // namespace internal | 435 } // namespace internal |
429 } // namespace v8 | 436 } // namespace v8 |
430 | 437 |
431 #undef STRING_CONSTANTS | 438 #undef STRING_CONSTANTS |
432 #undef OTHER_CONSTANTS | 439 #undef OTHER_CONSTANTS |
433 | 440 |
434 #endif // V8_AST_AST_VALUE_FACTORY_H_ | 441 #endif // V8_AST_AST_VALUE_FACTORY_H_ |
OLD | NEW |