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 AstValueFactory; |
114 friend class AstRawStringInternalizationKey; | 115 friend class AstRawStringInternalizationKey; |
115 friend class AstStringConstants; | |
116 friend class AstValueFactory; | |
117 | 116 |
118 AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes, | 117 AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes, |
119 uint32_t hash) | 118 uint32_t hash) |
120 : AstString(true), hash_(hash), literal_bytes_(literal_bytes) { | 119 : AstString(true), hash_(hash), literal_bytes_(literal_bytes) { |
121 bit_field_ |= IsOneByteBits::encode(is_one_byte); | 120 bit_field_ |= IsOneByteBits::encode(is_one_byte); |
122 } | 121 } |
123 | 122 |
124 AstRawString() : AstString(true), hash_(0) { | 123 AstRawString() : AstString(true), hash_(0) { |
125 bit_field_ |= IsOneByteBits::encode(true); | 124 bit_field_ |= IsOneByteBits::encode(true); |
126 } | 125 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 // Uninternalized value. | 285 // Uninternalized value. |
287 union { | 286 union { |
288 const AstRawString* string_; | 287 const AstRawString* string_; |
289 double number_; | 288 double number_; |
290 int smi_; | 289 int smi_; |
291 bool bool_; | 290 bool bool_; |
292 const char* symbol_name_; | 291 const char* symbol_name_; |
293 }; | 292 }; |
294 }; | 293 }; |
295 | 294 |
| 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 | |
374 #define OTHER_CONSTANTS(F) \ | 335 #define OTHER_CONSTANTS(F) \ |
375 F(true_value) \ | 336 F(true_value) \ |
376 F(false_value) \ | 337 F(false_value) \ |
377 F(null_value) \ | 338 F(null_value) \ |
378 F(undefined_value) \ | 339 F(undefined_value) \ |
379 F(the_hole_value) | 340 F(the_hole_value) |
380 | 341 |
381 class AstValueFactory { | 342 class AstValueFactory { |
382 public: | 343 public: |
383 AstValueFactory(Zone* zone, AstStringConstants* string_constants, | 344 AstValueFactory(Zone* zone, uint32_t hash_seed) |
384 uint32_t hash_seed) | |
385 : string_table_(AstRawStringCompare), | 345 : string_table_(AstRawStringCompare), |
386 values_(nullptr), | 346 values_(nullptr), |
387 strings_(nullptr), | 347 strings_(nullptr), |
388 strings_end_(&strings_), | 348 strings_end_(&strings_), |
389 string_constants_(string_constants), | |
390 zone_(zone), | 349 zone_(zone), |
391 hash_seed_(hash_seed) { | 350 hash_seed_(hash_seed) { |
392 #define F(name) name##_ = nullptr; | 351 #define F(name, str) name##_string_ = NULL; |
| 352 STRING_CONSTANTS(F) |
| 353 #undef F |
| 354 #define F(name) name##_ = NULL; |
393 OTHER_CONSTANTS(F) | 355 OTHER_CONSTANTS(F) |
394 #undef F | 356 #undef F |
395 DCHECK_EQ(hash_seed, string_constants->hash_seed()); | |
396 std::fill(smis_, smis_ + arraysize(smis_), nullptr); | 357 std::fill(smis_, smis_ + arraysize(smis_), nullptr); |
397 std::fill(one_character_strings_, | 358 std::fill(one_character_strings_, |
398 one_character_strings_ + arraysize(one_character_strings_), | 359 one_character_strings_ + arraysize(one_character_strings_), |
399 nullptr); | 360 nullptr); |
400 InitializeStringConstants(); | |
401 } | 361 } |
402 | 362 |
403 Zone* zone() const { return zone_; } | 363 Zone* zone() const { return zone_; } |
404 | 364 |
405 const AstRawString* GetOneByteString(Vector<const uint8_t> literal) { | 365 const AstRawString* GetOneByteString(Vector<const uint8_t> literal) { |
406 return GetOneByteStringInternal(literal); | 366 return GetOneByteStringInternal(literal); |
407 } | 367 } |
408 const AstRawString* GetOneByteString(const char* string) { | 368 const AstRawString* GetOneByteString(const char* string) { |
409 return GetOneByteString(Vector<const uint8_t>( | 369 return GetOneByteString(Vector<const uint8_t>( |
410 reinterpret_cast<const uint8_t*>(string), StrLength(string))); | 370 reinterpret_cast<const uint8_t*>(string), StrLength(string))); |
411 } | 371 } |
412 const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) { | 372 const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) { |
413 return GetTwoByteStringInternal(literal); | 373 return GetTwoByteStringInternal(literal); |
414 } | 374 } |
415 const AstRawString* GetString(Handle<String> literal); | 375 const AstRawString* GetString(Handle<String> literal); |
416 const AstConsString* NewConsString(const AstString* left, | 376 const AstConsString* NewConsString(const AstString* left, |
417 const AstString* right); | 377 const AstString* right); |
418 | 378 |
419 void Internalize(Isolate* isolate); | 379 void Internalize(Isolate* isolate); |
420 | 380 |
421 #define F(name, str) \ | 381 #define F(name, str) \ |
422 const AstRawString* name##_string() { \ | 382 const AstRawString* name##_string() { \ |
423 return string_constants_->name##_string(); \ | 383 if (name##_string_ == NULL) { \ |
| 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_; \ |
424 } | 390 } |
425 STRING_CONSTANTS(F) | 391 STRING_CONSTANTS(F) |
426 #undef F | 392 #undef F |
427 | 393 |
428 const AstValue* NewString(const AstRawString* string); | 394 const AstValue* NewString(const AstRawString* string); |
429 // A JavaScript symbol (ECMA-262 edition 6). | 395 // A JavaScript symbol (ECMA-262 edition 6). |
430 const AstValue* NewSymbol(const char* name); | 396 const AstValue* NewSymbol(const char* name); |
431 const AstValue* NewNumber(double number, bool with_dot = false); | 397 const AstValue* NewNumber(double number, bool with_dot = false); |
432 const AstValue* NewSmi(uint32_t number); | 398 const AstValue* NewSmi(uint32_t number); |
433 const AstValue* NewBoolean(bool b); | 399 const AstValue* NewBoolean(bool b); |
(...skipping 20 matching lines...) Expand all Loading... |
454 void ResetStrings() { | 420 void ResetStrings() { |
455 strings_ = nullptr; | 421 strings_ = nullptr; |
456 strings_end_ = &strings_; | 422 strings_end_ = &strings_; |
457 } | 423 } |
458 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( | 424 V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( |
459 Vector<const uint8_t> literal); | 425 Vector<const uint8_t> literal); |
460 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); | 426 AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal); |
461 AstRawString* GetString(uint32_t hash, bool is_one_byte, | 427 AstRawString* GetString(uint32_t hash, bool is_one_byte, |
462 Vector<const byte> literal_bytes); | 428 Vector<const byte> literal_bytes); |
463 | 429 |
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 | |
475 static bool AstRawStringCompare(void* a, void* b); | 430 static bool AstRawStringCompare(void* a, void* b); |
476 | 431 |
477 // All strings are copied here, one after another (no NULLs inbetween). | 432 // All strings are copied here, one after another (no NULLs inbetween). |
478 base::CustomMatcherHashMap string_table_; | 433 base::CustomMatcherHashMap string_table_; |
479 // For keeping track of all AstValues and AstRawStrings we've created (so that | 434 // For keeping track of all AstValues and AstRawStrings we've created (so that |
480 // they can be internalized later). | 435 // they can be internalized later). |
481 AstValue* values_; | 436 AstValue* values_; |
482 | 437 |
483 // We need to keep track of strings_ in order since cons strings require their | 438 // We need to keep track of strings_ in order since cons strings require their |
484 // members to be internalized first. | 439 // members to be internalized first. |
485 AstString* strings_; | 440 AstString* strings_; |
486 AstString** strings_end_; | 441 AstString** strings_end_; |
487 | 442 |
488 // Holds constant string values which are shared across the isolate. | |
489 AstStringConstants* string_constants_; | |
490 | |
491 // Caches for faster access: small numbers, one character lowercase strings | 443 // Caches for faster access: small numbers, one character lowercase strings |
492 // (for minified code). | 444 // (for minified code). |
493 AstValue* smis_[kMaxCachedSmi + 1]; | 445 AstValue* smis_[kMaxCachedSmi + 1]; |
494 AstRawString* one_character_strings_[26]; | 446 AstRawString* one_character_strings_[26]; |
495 | 447 |
496 Zone* zone_; | 448 Zone* zone_; |
497 | 449 |
498 uint32_t hash_seed_; | 450 uint32_t hash_seed_; |
499 | 451 |
| 452 #define F(name, str) const AstRawString* name##_string_; |
| 453 STRING_CONSTANTS(F) |
| 454 #undef F |
| 455 |
500 #define F(name) AstValue* name##_; | 456 #define F(name) AstValue* name##_; |
501 OTHER_CONSTANTS(F) | 457 OTHER_CONSTANTS(F) |
502 #undef F | 458 #undef F |
503 }; | 459 }; |
504 } // namespace internal | 460 } // namespace internal |
505 } // namespace v8 | 461 } // namespace v8 |
506 | 462 |
507 #undef STRING_CONSTANTS | 463 #undef STRING_CONSTANTS |
508 #undef OTHER_CONSTANTS | 464 #undef OTHER_CONSTANTS |
509 | 465 |
510 #endif // V8_AST_AST_VALUE_FACTORY_H_ | 466 #endif // V8_AST_AST_VALUE_FACTORY_H_ |
OLD | NEW |