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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 reinterpret_cast<const uint16_t*>(literal_bytes_.start()); | 104 reinterpret_cast<const uint16_t*>(literal_bytes_.start()); |
105 return *c; | 105 return *c; |
106 } | 106 } |
107 | 107 |
108 // For storing AstRawStrings in a hash map. | 108 // For storing AstRawStrings in a hash map. |
109 uint32_t hash() const { | 109 uint32_t hash() const { |
110 return hash_; | 110 return hash_; |
111 } | 111 } |
112 | 112 |
113 private: | 113 private: |
| 114 friend class AstRawStringInternalizationKey; |
| 115 friend class AstStringConstants; |
114 friend class AstValueFactory; | 116 friend class AstValueFactory; |
115 friend class AstRawStringInternalizationKey; | |
116 | 117 |
117 AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes, | 118 AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes, |
118 uint32_t hash) | 119 uint32_t hash) |
119 : AstString(true), hash_(hash), literal_bytes_(literal_bytes) { | 120 : AstString(true), hash_(hash), literal_bytes_(literal_bytes) { |
120 bit_field_ |= IsOneByteBits::encode(is_one_byte); | 121 bit_field_ |= IsOneByteBits::encode(is_one_byte); |
121 } | 122 } |
122 | 123 |
123 AstRawString() : AstString(true), hash_(0) { | 124 AstRawString() : AstString(true), hash_(0) { |
124 bit_field_ |= IsOneByteBits::encode(true); | 125 bit_field_ |= IsOneByteBits::encode(true); |
125 } | 126 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 // Uninternalized value. | 286 // Uninternalized value. |
286 union { | 287 union { |
287 const AstRawString* string_; | 288 const AstRawString* string_; |
288 double number_; | 289 double number_; |
289 int smi_; | 290 int smi_; |
290 bool bool_; | 291 bool bool_; |
291 const char* symbol_name_; | 292 const char* symbol_name_; |
292 }; | 293 }; |
293 }; | 294 }; |
294 | 295 |
295 | |
296 // For generating constants. | 296 // For generating constants. |
297 #define STRING_CONSTANTS(F) \ | 297 #define STRING_CONSTANTS(F) \ |
298 F(anonymous_function, "(anonymous function)") \ | 298 F(anonymous_function, "(anonymous function)") \ |
299 F(arguments, "arguments") \ | 299 F(arguments, "arguments") \ |
300 F(async, "async") \ | 300 F(async, "async") \ |
301 F(await, "await") \ | 301 F(await, "await") \ |
302 F(constructor, "constructor") \ | 302 F(constructor, "constructor") \ |
303 F(default, "default") \ | 303 F(default, "default") \ |
304 F(done, "done") \ | 304 F(done, "done") \ |
305 F(dot, ".") \ | 305 F(dot, ".") \ |
(...skipping 19 matching lines...) Expand all Loading... |
325 F(set_space, "set ") \ | 325 F(set_space, "set ") \ |
326 F(star_default_star, "*default*") \ | 326 F(star_default_star, "*default*") \ |
327 F(this, "this") \ | 327 F(this, "this") \ |
328 F(this_function, ".this_function") \ | 328 F(this_function, ".this_function") \ |
329 F(throw, "throw") \ | 329 F(throw, "throw") \ |
330 F(undefined, "undefined") \ | 330 F(undefined, "undefined") \ |
331 F(use_asm, "use asm") \ | 331 F(use_asm, "use asm") \ |
332 F(use_strict, "use strict") \ | 332 F(use_strict, "use strict") \ |
333 F(value, "value") | 333 F(value, "value") |
334 | 334 |
| 335 class AstStringConstants final { |
| 336 public: |
| 337 AstStringConstants(Isolate* isolate, uint32_t hash_seed) |
| 338 : zone_(isolate->allocator(), ZONE_NAME), hash_seed_(hash_seed) { |
| 339 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
| 340 #define F(name, str) \ |
| 341 { \ |
| 342 const char* data = str; \ |
| 343 Vector<const uint8_t> literal(reinterpret_cast<const uint8_t*>(data), \ |
| 344 static_cast<int>(strlen(data))); \ |
| 345 uint32_t hash = StringHasher::HashSequentialString<uint8_t>( \ |
| 346 literal.start(), literal.length(), hash_seed_); \ |
| 347 name##_string_ = new (&zone_) AstRawString(true, literal, hash); \ |
| 348 /* The Handle returned by the factory is located on the roots */ \ |
| 349 /* array, not on the temporary HandleScope, so this is safe. */ \ |
| 350 name##_string_->set_string(isolate->factory()->name##_string()); \ |
| 351 } |
| 352 STRING_CONSTANTS(F) |
| 353 #undef F |
| 354 } |
| 355 |
| 356 #define F(name, str) \ |
| 357 AstRawString* name##_string() { return name##_string_; } |
| 358 STRING_CONSTANTS(F) |
| 359 #undef F |
| 360 |
| 361 uint32_t hash_seed() const { return hash_seed_; } |
| 362 |
| 363 private: |
| 364 Zone zone_; |
| 365 uint32_t hash_seed_; |
| 366 |
| 367 #define F(name, str) AstRawString* name##_string_; |
| 368 STRING_CONSTANTS(F) |
| 369 #undef F |
| 370 |
| 371 DISALLOW_COPY_AND_ASSIGN(AstStringConstants); |
| 372 }; |
| 373 |
335 #define OTHER_CONSTANTS(F) \ | 374 #define OTHER_CONSTANTS(F) \ |
336 F(true_value) \ | 375 F(true_value) \ |
337 F(false_value) \ | 376 F(false_value) \ |
338 F(null_value) \ | 377 F(null_value) \ |
339 F(undefined_value) \ | 378 F(undefined_value) \ |
340 F(the_hole_value) | 379 F(the_hole_value) |
341 | 380 |
342 class AstValueFactory { | 381 class AstValueFactory { |
343 public: | 382 public: |
344 AstValueFactory(Zone* zone, uint32_t hash_seed) | 383 AstValueFactory(Zone* zone, AstStringConstants* string_constants, |
| 384 uint32_t hash_seed) |
345 : string_table_(AstRawStringCompare), | 385 : string_table_(AstRawStringCompare), |
346 values_(nullptr), | 386 values_(nullptr), |
347 strings_(nullptr), | 387 strings_(nullptr), |
348 strings_end_(&strings_), | 388 strings_end_(&strings_), |
| 389 string_constants_(string_constants), |
349 zone_(zone), | 390 zone_(zone), |
350 hash_seed_(hash_seed) { | 391 hash_seed_(hash_seed) { |
351 #define F(name, str) name##_string_ = NULL; | 392 #define F(name) name##_ = nullptr; |
352 STRING_CONSTANTS(F) | |
353 #undef F | |
354 #define F(name) name##_ = NULL; | |
355 OTHER_CONSTANTS(F) | 393 OTHER_CONSTANTS(F) |
356 #undef F | 394 #undef F |
| 395 DCHECK_EQ(hash_seed, string_constants->hash_seed()); |
357 std::fill(smis_, smis_ + arraysize(smis_), nullptr); | 396 std::fill(smis_, smis_ + arraysize(smis_), nullptr); |
358 std::fill(one_character_strings_, | 397 std::fill(one_character_strings_, |
359 one_character_strings_ + arraysize(one_character_strings_), | 398 one_character_strings_ + arraysize(one_character_strings_), |
360 nullptr); | 399 nullptr); |
| 400 InitializeStringConstants(); |
361 } | 401 } |
362 | 402 |
363 Zone* zone() const { return zone_; } | 403 Zone* zone() const { return zone_; } |
364 | 404 |
365 const AstRawString* GetOneByteString(Vector<const uint8_t> literal) { | 405 const AstRawString* GetOneByteString(Vector<const uint8_t> literal) { |
366 return GetOneByteStringInternal(literal); | 406 return GetOneByteStringInternal(literal); |
367 } | 407 } |
368 const AstRawString* GetOneByteString(const char* string) { | 408 const AstRawString* GetOneByteString(const char* string) { |
369 return GetOneByteString(Vector<const uint8_t>( | 409 return GetOneByteString(Vector<const uint8_t>( |
370 reinterpret_cast<const uint8_t*>(string), StrLength(string))); | 410 reinterpret_cast<const uint8_t*>(string), StrLength(string))); |
371 } | 411 } |
372 const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) { | 412 const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) { |
373 return GetTwoByteStringInternal(literal); | 413 return GetTwoByteStringInternal(literal); |
374 } | 414 } |
375 const AstRawString* GetString(Handle<String> literal); | 415 const AstRawString* GetString(Handle<String> literal); |
376 const AstConsString* NewConsString(const AstString* left, | 416 const AstConsString* NewConsString(const AstString* left, |
377 const AstString* right); | 417 const AstString* right); |
378 | 418 |
379 void Internalize(Isolate* isolate); | 419 void Internalize(Isolate* isolate); |
380 | 420 |
381 #define F(name, str) \ | 421 #define F(name, str) \ |
382 const AstRawString* name##_string() { \ | 422 const AstRawString* name##_string() { \ |
383 if (name##_string_ == NULL) { \ | 423 return string_constants_->name##_string(); \ |
384 const char* data = str; \ | |
385 name##_string_ = GetOneByteString( \ | |
386 Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \ | |
387 static_cast<int>(strlen(data)))); \ | |
388 } \ | |
389 return name##_string_; \ | |
390 } | 424 } |
391 STRING_CONSTANTS(F) | 425 STRING_CONSTANTS(F) |
392 #undef F | 426 #undef F |
393 | 427 |
394 const AstValue* NewString(const AstRawString* string); | 428 const AstValue* NewString(const AstRawString* string); |
395 // A JavaScript symbol (ECMA-262 edition 6). | 429 // A JavaScript symbol (ECMA-262 edition 6). |
396 const AstValue* NewSymbol(const char* name); | 430 const AstValue* NewSymbol(const char* name); |
397 const AstValue* NewNumber(double number, bool with_dot = false); | 431 const AstValue* NewNumber(double number, bool with_dot = false); |
398 const AstValue* NewSmi(uint32_t number); | 432 const AstValue* NewSmi(uint32_t number); |
399 const AstValue* NewBoolean(bool b); | 433 const AstValue* NewBoolean(bool b); |
(...skipping 20 matching lines...) Expand all Loading... |
420 void ResetStrings() { | 454 void ResetStrings() { |
421 strings_ = nullptr; | 455 strings_ = nullptr; |
422 strings_end_ = &strings_; | 456 strings_end_ = &strings_; |
423 } | 457 } |
424 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( | 458 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( |
425 Vector<const uint8_t> literal); | 459 Vector<const uint8_t> literal); |
426 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); | 460 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); |
427 AstRawString* GetString(uint32_t hash, bool is_one_byte, | 461 AstRawString* GetString(uint32_t hash, bool is_one_byte, |
428 Vector<const byte> literal_bytes); | 462 Vector<const byte> literal_bytes); |
429 | 463 |
| 464 void InitializeStringConstants() { |
| 465 #define F(name, str) \ |
| 466 AstRawString* raw_string_##name = string_constants_->name##_string(); \ |
| 467 base::HashMap::Entry* entry_##name = string_table_.LookupOrInsert( \ |
| 468 raw_string_##name, raw_string_##name->hash()); \ |
| 469 DCHECK(entry_##name->value == nullptr); \ |
| 470 entry_##name->value = reinterpret_cast<void*>(1); |
| 471 STRING_CONSTANTS(F) |
| 472 #undef F |
| 473 } |
| 474 |
430 static bool AstRawStringCompare(void* a, void* b); | 475 static bool AstRawStringCompare(void* a, void* b); |
431 | 476 |
432 // All strings are copied here, one after another (no NULLs inbetween). | 477 // All strings are copied here, one after another (no NULLs inbetween). |
433 base::CustomMatcherHashMap string_table_; | 478 base::CustomMatcherHashMap string_table_; |
434 // For keeping track of all AstValues and AstRawStrings we've created (so that | 479 // For keeping track of all AstValues and AstRawStrings we've created (so that |
435 // they can be internalized later). | 480 // they can be internalized later). |
436 AstValue* values_; | 481 AstValue* values_; |
437 | 482 |
438 // We need to keep track of strings_ in order since cons strings require their | 483 // We need to keep track of strings_ in order since cons strings require their |
439 // members to be internalized first. | 484 // members to be internalized first. |
440 AstString* strings_; | 485 AstString* strings_; |
441 AstString** strings_end_; | 486 AstString** strings_end_; |
442 | 487 |
| 488 // Holds constant string values which are shared across the isolate. |
| 489 AstStringConstants* string_constants_; |
| 490 |
443 // Caches for faster access: small numbers, one character lowercase strings | 491 // Caches for faster access: small numbers, one character lowercase strings |
444 // (for minified code). | 492 // (for minified code). |
445 AstValue* smis_[kMaxCachedSmi + 1]; | 493 AstValue* smis_[kMaxCachedSmi + 1]; |
446 AstRawString* one_character_strings_[26]; | 494 AstRawString* one_character_strings_[26]; |
447 | 495 |
448 Zone* zone_; | 496 Zone* zone_; |
449 | 497 |
450 uint32_t hash_seed_; | 498 uint32_t hash_seed_; |
451 | 499 |
452 #define F(name, str) const AstRawString* name##_string_; | |
453 STRING_CONSTANTS(F) | |
454 #undef F | |
455 | |
456 #define F(name) AstValue* name##_; | 500 #define F(name) AstValue* name##_; |
457 OTHER_CONSTANTS(F) | 501 OTHER_CONSTANTS(F) |
458 #undef F | 502 #undef F |
459 }; | 503 }; |
460 } // namespace internal | 504 } // namespace internal |
461 } // namespace v8 | 505 } // namespace v8 |
462 | 506 |
463 #undef STRING_CONSTANTS | 507 #undef STRING_CONSTANTS |
464 #undef OTHER_CONSTANTS | 508 #undef OTHER_CONSTANTS |
465 | 509 |
466 #endif // V8_AST_AST_VALUE_FACTORY_H_ | 510 #endif // V8_AST_AST_VALUE_FACTORY_H_ |
OLD | NEW |