OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 | 2 |
3 // Check that we can traverse very deep stacks of ConsStrings using | 3 // Check that we can traverse very deep stacks of ConsStrings using |
4 // StringInputBuffer. Check that Get(int) works on very deep stacks | 4 // StringInputBuffer. Check that Get(int) works on very deep stacks |
5 // of ConsStrings. These operations may not be very fast, but they | 5 // of ConsStrings. These operations may not be very fast, but they |
6 // should be possible without getting errors due to too deep recursion. | 6 // should be possible without getting errors due to too deep recursion. |
7 | 7 |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include "v8.h" | 10 #include "v8.h" |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 | 424 |
425 // Setup lengths that guarantee we'll get slices instead of simple | 425 // Setup lengths that guarantee we'll get slices instead of simple |
426 // flat strings. | 426 // flat strings. |
427 static const int kFullStringLength = String::kMinNonFlatLength * 2; | 427 static const int kFullStringLength = String::kMinNonFlatLength * 2; |
428 static const int kSliceStringLength = String::kMinNonFlatLength + 1; | 428 static const int kSliceStringLength = String::kMinNonFlatLength + 1; |
429 | 429 |
430 uint16_t* source = new uint16_t[kFullStringLength]; | 430 uint16_t* source = new uint16_t[kFullStringLength]; |
431 for (int i = 0; i < kFullStringLength; i++) source[i] = '1'; | 431 for (int i = 0; i < kFullStringLength; i++) source[i] = '1'; |
432 char* key = new char[kSliceStringLength]; | 432 char* key = new char[kSliceStringLength]; |
433 for (int i = 0; i < kSliceStringLength; i++) key[i] = '1'; | 433 for (int i = 0; i < kSliceStringLength; i++) key[i] = '1'; |
| 434 Vector<const char> key_vector(key, kSliceStringLength); |
434 | 435 |
435 // Allocate an external string resource that keeps track of when it | 436 // Allocate an external string resource that keeps track of when it |
436 // is destructed. | 437 // is destructed. |
437 bool resource_destructed = false; | 438 bool resource_destructed = false; |
438 TwoByteResource* resource = | 439 TwoByteResource* resource = |
439 new TwoByteResource(source, kFullStringLength, &resource_destructed); | 440 new TwoByteResource(source, kFullStringLength, &resource_destructed); |
440 | 441 |
441 { | 442 { |
442 v8::HandleScope scope; | 443 v8::HandleScope scope; |
443 | 444 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 Handle<JSObject> wrapper = GetScriptWrapper(script); | 476 Handle<JSObject> wrapper = GetScriptWrapper(script); |
476 } | 477 } |
477 | 478 |
478 // When we collect all garbage, we cannot get rid of the sliced | 479 // When we collect all garbage, we cannot get rid of the sliced |
479 // symbol entry in the symbol table because it is used by the script | 480 // symbol entry in the symbol table because it is used by the script |
480 // kept alive by the weak wrapper. Make sure we don't destruct the | 481 // kept alive by the weak wrapper. Make sure we don't destruct the |
481 // external string. | 482 // external string. |
482 Heap::CollectAllGarbage(); | 483 Heap::CollectAllGarbage(); |
483 CHECK(!resource_destructed); | 484 CHECK(!resource_destructed); |
484 | 485 |
485 // Make sure the sliced symbol is still in the table. | 486 { |
| 487 v8::HandleScope scope; |
| 488 |
| 489 // Make sure the sliced symbol is still in the table. |
| 490 Handle<String> symbol = Factory::LookupSymbol(key_vector); |
| 491 CHECK(StringShape(*symbol).IsSliced()); |
| 492 |
| 493 // Make sure the buffer is still a two-byte external string. |
| 494 Handle<String> buffer(Handle<SlicedString>::cast(symbol)->buffer()); |
| 495 CHECK(StringShape(*buffer).IsExternal()); |
| 496 CHECK(buffer->IsTwoByteRepresentation()); |
| 497 } |
| 498 |
| 499 // Forcing another garbage collection should let us get rid of the |
| 500 // slice from the symbol table. The external string remains in the |
| 501 // heap until the next GC. |
| 502 Heap::CollectAllGarbage(); |
| 503 CHECK(!resource_destructed); |
486 v8::HandleScope scope; | 504 v8::HandleScope scope; |
487 Vector<const char> vector(key, kSliceStringLength); | 505 Handle<String> key_string = Factory::NewStringFromAscii(key_vector); |
488 Handle<String> symbol = Factory::LookupSymbol(vector); | 506 String* out; |
489 CHECK(StringShape(*symbol).IsSliced()); | 507 CHECK(!Heap::LookupSymbolIfExists(*key_string, &out)); |
490 | 508 |
491 // Make sure the buffer is still a two-byte external string. | 509 // Forcing yet another garbage collection must allow us to finally |
492 Handle<String> buffer(Handle<SlicedString>::cast(symbol)->buffer()); | 510 // get rid of the external string. |
493 CHECK(StringShape(*buffer).IsExternal()); | 511 Heap::CollectAllGarbage(); |
494 CHECK(buffer->IsTwoByteRepresentation()); | 512 CHECK(resource_destructed); |
495 | 513 |
496 delete[] source; | 514 delete[] source; |
497 delete[] key; | 515 delete[] key; |
498 } | 516 } |
OLD | NEW |