| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 private: | 75 private: |
| 76 const char* data_; | 76 const char* data_; |
| 77 size_t length_; | 77 size_t length_; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 | 80 |
| 81 static void InitializeBuildingBlocks( | 81 static void InitializeBuildingBlocks( |
| 82 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { | 82 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { |
| 83 // A list of pointers that we don't have any interest in cleaning up. | 83 // A list of pointers that we don't have any interest in cleaning up. |
| 84 // If they are reachable from a root then leak detection won't complain. | 84 // If they are reachable from a root then leak detection won't complain. |
| 85 Zone* zone = Isolate::Current()->zone(); |
| 85 for (int i = 0; i < NUMBER_OF_BUILDING_BLOCKS; i++) { | 86 for (int i = 0; i < NUMBER_OF_BUILDING_BLOCKS; i++) { |
| 86 int len = gen() % 16; | 87 int len = gen() % 16; |
| 87 if (len > 14) { | 88 if (len > 14) { |
| 88 len += 1234; | 89 len += 1234; |
| 89 } | 90 } |
| 90 switch (gen() % 4) { | 91 switch (gen() % 4) { |
| 91 case 0: { | 92 case 0: { |
| 92 uc16 buf[2000]; | 93 uc16 buf[2000]; |
| 93 for (int j = 0; j < len; j++) { | 94 for (int j = 0; j < len; j++) { |
| 94 buf[j] = gen() % 65536; | 95 buf[j] = gen() % 65536; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 106 buf[j] = gen() % 128; | 107 buf[j] = gen() % 128; |
| 107 } | 108 } |
| 108 building_blocks[i] = | 109 building_blocks[i] = |
| 109 FACTORY->NewStringFromAscii(Vector<const char>(buf, len)); | 110 FACTORY->NewStringFromAscii(Vector<const char>(buf, len)); |
| 110 for (int j = 0; j < len; j++) { | 111 for (int j = 0; j < len; j++) { |
| 111 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 112 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 112 } | 113 } |
| 113 break; | 114 break; |
| 114 } | 115 } |
| 115 case 2: { | 116 case 2: { |
| 116 uc16* buf = ZONE->NewArray<uc16>(len); | 117 uc16* buf = zone->NewArray<uc16>(len); |
| 117 for (int j = 0; j < len; j++) { | 118 for (int j = 0; j < len; j++) { |
| 118 buf[j] = gen() % 65536; | 119 buf[j] = gen() % 65536; |
| 119 } | 120 } |
| 120 Resource* resource = new Resource(Vector<const uc16>(buf, len)); | 121 Resource* resource = new(zone) Resource(Vector<const uc16>(buf, len)); |
| 121 building_blocks[i] = FACTORY->NewExternalStringFromTwoByte(resource); | 122 building_blocks[i] = FACTORY->NewExternalStringFromTwoByte(resource); |
| 122 for (int j = 0; j < len; j++) { | 123 for (int j = 0; j < len; j++) { |
| 123 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 124 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 124 } | 125 } |
| 125 break; | 126 break; |
| 126 } | 127 } |
| 127 case 3: { | 128 case 3: { |
| 128 char* buf = NewArray<char>(len); | 129 char* buf = NewArray<char>(len); |
| 129 for (int j = 0; j < len; j++) { | 130 for (int j = 0; j < len; j++) { |
| 130 buf[j] = gen() % 128; | 131 buf[j] = gen() % 128; |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 for (int j = 0; j < lengths[i]; j++) | 342 for (int j = 0; j < lengths[i]; j++) |
| 342 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); | 343 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); |
| 343 // Check that the rest of the buffer hasn't been touched | 344 // Check that the rest of the buffer hasn't been touched |
| 344 for (int j = lengths[i]; j < 11; j++) | 345 for (int j = lengths[i]; j < 11; j++) |
| 345 CHECK_EQ(kNoChar, buffer[j]); | 346 CHECK_EQ(kNoChar, buffer[j]); |
| 346 } | 347 } |
| 347 } | 348 } |
| 348 | 349 |
| 349 | 350 |
| 350 TEST(ExternalShortStringAdd) { | 351 TEST(ExternalShortStringAdd) { |
| 351 ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT); | 352 ZoneScope zonescope(Isolate::Current(), DELETE_ON_EXIT); |
| 352 | 353 |
| 353 InitializeVM(); | 354 InitializeVM(); |
| 354 v8::HandleScope handle_scope; | 355 v8::HandleScope handle_scope; |
| 356 Zone* zone = Isolate::Current()->zone(); |
| 355 | 357 |
| 356 // Make sure we cover all always-flat lengths and at least one above. | 358 // Make sure we cover all always-flat lengths and at least one above. |
| 357 static const int kMaxLength = 20; | 359 static const int kMaxLength = 20; |
| 358 CHECK_GT(kMaxLength, i::ConsString::kMinLength); | 360 CHECK_GT(kMaxLength, i::ConsString::kMinLength); |
| 359 | 361 |
| 360 // Allocate two JavaScript arrays for holding short strings. | 362 // Allocate two JavaScript arrays for holding short strings. |
| 361 v8::Handle<v8::Array> ascii_external_strings = | 363 v8::Handle<v8::Array> ascii_external_strings = |
| 362 v8::Array::New(kMaxLength + 1); | 364 v8::Array::New(kMaxLength + 1); |
| 363 v8::Handle<v8::Array> non_ascii_external_strings = | 365 v8::Handle<v8::Array> non_ascii_external_strings = |
| 364 v8::Array::New(kMaxLength + 1); | 366 v8::Array::New(kMaxLength + 1); |
| 365 | 367 |
| 366 // Generate short ascii and non-ascii external strings. | 368 // Generate short ascii and non-ascii external strings. |
| 367 for (int i = 0; i <= kMaxLength; i++) { | 369 for (int i = 0; i <= kMaxLength; i++) { |
| 368 char* ascii = ZONE->NewArray<char>(i + 1); | 370 char* ascii = zone->NewArray<char>(i + 1); |
| 369 for (int j = 0; j < i; j++) { | 371 for (int j = 0; j < i; j++) { |
| 370 ascii[j] = 'a'; | 372 ascii[j] = 'a'; |
| 371 } | 373 } |
| 372 // Terminating '\0' is left out on purpose. It is not required for external | 374 // Terminating '\0' is left out on purpose. It is not required for external |
| 373 // string data. | 375 // string data. |
| 374 AsciiResource* ascii_resource = | 376 AsciiResource* ascii_resource = |
| 375 new AsciiResource(Vector<const char>(ascii, i)); | 377 new(zone) AsciiResource(Vector<const char>(ascii, i)); |
| 376 v8::Local<v8::String> ascii_external_string = | 378 v8::Local<v8::String> ascii_external_string = |
| 377 v8::String::NewExternal(ascii_resource); | 379 v8::String::NewExternal(ascii_resource); |
| 378 | 380 |
| 379 ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); | 381 ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); |
| 380 uc16* non_ascii = ZONE->NewArray<uc16>(i + 1); | 382 uc16* non_ascii = zone->NewArray<uc16>(i + 1); |
| 381 for (int j = 0; j < i; j++) { | 383 for (int j = 0; j < i; j++) { |
| 382 non_ascii[j] = 0x1234; | 384 non_ascii[j] = 0x1234; |
| 383 } | 385 } |
| 384 // Terminating '\0' is left out on purpose. It is not required for external | 386 // Terminating '\0' is left out on purpose. It is not required for external |
| 385 // string data. | 387 // string data. |
| 386 Resource* resource = new Resource(Vector<const uc16>(non_ascii, i)); | 388 Resource* resource = new(zone) Resource(Vector<const uc16>(non_ascii, i)); |
| 387 v8::Local<v8::String> non_ascii_external_string = | 389 v8::Local<v8::String> non_ascii_external_string = |
| 388 v8::String::NewExternal(resource); | 390 v8::String::NewExternal(resource); |
| 389 non_ascii_external_strings->Set(v8::Integer::New(i), | 391 non_ascii_external_strings->Set(v8::Integer::New(i), |
| 390 non_ascii_external_string); | 392 non_ascii_external_string); |
| 391 } | 393 } |
| 392 | 394 |
| 393 // Add the arrays with the short external strings in the global object. | 395 // Add the arrays with the short external strings in the global object. |
| 394 v8::Handle<v8::Object> global = env->Global(); | 396 v8::Handle<v8::Object> global = env->Global(); |
| 395 global->Set(v8_str("external_ascii"), ascii_external_strings); | 397 global->Set(v8_str("external_ascii"), ascii_external_strings); |
| 396 global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); | 398 global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 v8::V8::IgnoreOutOfMemoryException(); | 684 v8::V8::IgnoreOutOfMemoryException(); |
| 683 v8::Local<v8::Value> result = CompileRun( | 685 v8::Local<v8::Value> result = CompileRun( |
| 684 "var a = 'a'; " | 686 "var a = 'a'; " |
| 685 "for (var i = 0; i < 16; i++) { " | 687 "for (var i = 0; i < 16; i++) { " |
| 686 " a += a; " | 688 " a += a; " |
| 687 "} " | 689 "} " |
| 688 "a.replace(/a/g, a); "); | 690 "a.replace(/a/g, a); "); |
| 689 CHECK(result.IsEmpty()); | 691 CHECK(result.IsEmpty()); |
| 690 CHECK(context->HasOutOfMemoryException()); | 692 CHECK(context->HasOutOfMemoryException()); |
| 691 } | 693 } |
| OLD | NEW |