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 |