| 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 |