| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 size_t length_; | 129 size_t length_; |
| 130 }; | 130 }; |
| 131 | 131 |
| 132 | 132 |
| 133 static void InitializeBuildingBlocks(Handle<String>* building_blocks, | 133 static void InitializeBuildingBlocks(Handle<String>* building_blocks, |
| 134 int bb_length, | 134 int bb_length, |
| 135 bool long_blocks, | 135 bool long_blocks, |
| 136 RandomNumberGenerator* rng) { | 136 RandomNumberGenerator* rng) { |
| 137 // A list of pointers that we don't have any interest in cleaning up. | 137 // A list of pointers that we don't have any interest in cleaning up. |
| 138 // If they are reachable from a root then leak detection won't complain. | 138 // If they are reachable from a root then leak detection won't complain. |
| 139 Zone* zone = Isolate::Current()->runtime_zone(); | 139 Isolate* isolate = Isolate::Current(); |
| 140 Factory* factory = isolate->factory(); |
| 141 Zone* zone = isolate->runtime_zone(); |
| 140 for (int i = 0; i < bb_length; i++) { | 142 for (int i = 0; i < bb_length; i++) { |
| 141 int len = rng->next(16); | 143 int len = rng->next(16); |
| 142 int slice_head_chars = 0; | 144 int slice_head_chars = 0; |
| 143 int slice_tail_chars = 0; | 145 int slice_tail_chars = 0; |
| 144 int slice_depth = 0; | 146 int slice_depth = 0; |
| 145 for (int j = 0; j < 3; j++) { | 147 for (int j = 0; j < 3; j++) { |
| 146 if (rng->next(0.35)) slice_depth++; | 148 if (rng->next(0.35)) slice_depth++; |
| 147 } | 149 } |
| 148 // Must truncate something for a slice string. Loop until | 150 // Must truncate something for a slice string. Loop until |
| 149 // at least one end will be sliced. | 151 // at least one end will be sliced. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 161 if (len == 0) slice_depth = 0; | 163 if (len == 0) slice_depth = 0; |
| 162 int slice_length = slice_depth*(slice_head_chars + slice_tail_chars); | 164 int slice_length = slice_depth*(slice_head_chars + slice_tail_chars); |
| 163 len += slice_length; | 165 len += slice_length; |
| 164 switch (rng->next(4)) { | 166 switch (rng->next(4)) { |
| 165 case 0: { | 167 case 0: { |
| 166 uc16 buf[2000]; | 168 uc16 buf[2000]; |
| 167 for (int j = 0; j < len; j++) { | 169 for (int j = 0; j < len; j++) { |
| 168 buf[j] = rng->next(0x10000); | 170 buf[j] = rng->next(0x10000); |
| 169 } | 171 } |
| 170 building_blocks[i] = | 172 building_blocks[i] = |
| 171 FACTORY->NewStringFromTwoByte(Vector<const uc16>(buf, len)); | 173 factory->NewStringFromTwoByte(Vector<const uc16>(buf, len)); |
| 172 for (int j = 0; j < len; j++) { | 174 for (int j = 0; j < len; j++) { |
| 173 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 175 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 174 } | 176 } |
| 175 break; | 177 break; |
| 176 } | 178 } |
| 177 case 1: { | 179 case 1: { |
| 178 char buf[2000]; | 180 char buf[2000]; |
| 179 for (int j = 0; j < len; j++) { | 181 for (int j = 0; j < len; j++) { |
| 180 buf[j] = rng->next(0x80); | 182 buf[j] = rng->next(0x80); |
| 181 } | 183 } |
| 182 building_blocks[i] = | 184 building_blocks[i] = |
| 183 FACTORY->NewStringFromAscii(Vector<const char>(buf, len)); | 185 factory->NewStringFromAscii(Vector<const char>(buf, len)); |
| 184 for (int j = 0; j < len; j++) { | 186 for (int j = 0; j < len; j++) { |
| 185 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 187 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 186 } | 188 } |
| 187 break; | 189 break; |
| 188 } | 190 } |
| 189 case 2: { | 191 case 2: { |
| 190 uc16* buf = zone->NewArray<uc16>(len); | 192 uc16* buf = zone->NewArray<uc16>(len); |
| 191 for (int j = 0; j < len; j++) { | 193 for (int j = 0; j < len; j++) { |
| 192 buf[j] = rng->next(0x10000); | 194 buf[j] = rng->next(0x10000); |
| 193 } | 195 } |
| 194 Resource* resource = new(zone) Resource(Vector<const uc16>(buf, len)); | 196 Resource* resource = new(zone) Resource(Vector<const uc16>(buf, len)); |
| 195 building_blocks[i] = FACTORY->NewExternalStringFromTwoByte(resource); | 197 building_blocks[i] = factory->NewExternalStringFromTwoByte(resource); |
| 196 for (int j = 0; j < len; j++) { | 198 for (int j = 0; j < len; j++) { |
| 197 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 199 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 198 } | 200 } |
| 199 break; | 201 break; |
| 200 } | 202 } |
| 201 case 3: { | 203 case 3: { |
| 202 char* buf = zone->NewArray<char>(len); | 204 char* buf = zone->NewArray<char>(len); |
| 203 for (int j = 0; j < len; j++) { | 205 for (int j = 0; j < len; j++) { |
| 204 buf[j] = rng->next(0x80); | 206 buf[j] = rng->next(0x80); |
| 205 } | 207 } |
| 206 AsciiResource* resource = | 208 AsciiResource* resource = |
| 207 new(zone) AsciiResource(Vector<const char>(buf, len)); | 209 new(zone) AsciiResource(Vector<const char>(buf, len)); |
| 208 building_blocks[i] = FACTORY->NewExternalStringFromAscii(resource); | 210 building_blocks[i] = factory->NewExternalStringFromAscii(resource); |
| 209 for (int j = 0; j < len; j++) { | 211 for (int j = 0; j < len; j++) { |
| 210 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 212 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
| 211 } | 213 } |
| 212 break; | 214 break; |
| 213 } | 215 } |
| 214 } | 216 } |
| 215 for (int j = slice_depth; j > 0; j--) { | 217 for (int j = slice_depth; j > 0; j--) { |
| 216 building_blocks[i] = FACTORY->NewSubString( | 218 building_blocks[i] = factory->NewSubString( |
| 217 building_blocks[i], | 219 building_blocks[i], |
| 218 slice_head_chars, | 220 slice_head_chars, |
| 219 building_blocks[i]->length() - slice_tail_chars); | 221 building_blocks[i]->length() - slice_tail_chars); |
| 220 } | 222 } |
| 221 CHECK(len == building_blocks[i]->length() + slice_length); | 223 CHECK(len == building_blocks[i]->length() + slice_length); |
| 222 } | 224 } |
| 223 } | 225 } |
| 224 | 226 |
| 225 | 227 |
| 226 class ConsStringStats { | 228 class ConsStringStats { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 stats.left_traversals_ = data->stats_.left_traversals_; | 395 stats.left_traversals_ = data->stats_.left_traversals_; |
| 394 stats.right_traversals_ = data->stats_.right_traversals_; | 396 stats.right_traversals_ = data->stats_.right_traversals_; |
| 395 // Adjust total leaves to compensate. | 397 // Adjust total leaves to compensate. |
| 396 stats.leaves_ += stats.empty_leaves_; | 398 stats.leaves_ += stats.empty_leaves_; |
| 397 stats.VerifyEqual(data->stats_); | 399 stats.VerifyEqual(data->stats_); |
| 398 } | 400 } |
| 399 | 401 |
| 400 | 402 |
| 401 static Handle<String> ConstructRandomString(ConsStringGenerationData* data, | 403 static Handle<String> ConstructRandomString(ConsStringGenerationData* data, |
| 402 unsigned max_recursion) { | 404 unsigned max_recursion) { |
| 405 Factory* factory = Isolate::Current()->factory(); |
| 403 // Compute termination characteristics. | 406 // Compute termination characteristics. |
| 404 bool terminate = false; | 407 bool terminate = false; |
| 405 bool flat = data->rng_.next(data->empty_leaf_threshold_); | 408 bool flat = data->rng_.next(data->empty_leaf_threshold_); |
| 406 bool terminate_early = data->rng_.next(data->early_termination_threshold_); | 409 bool terminate_early = data->rng_.next(data->early_termination_threshold_); |
| 407 if (terminate_early) data->early_terminations_++; | 410 if (terminate_early) data->early_terminations_++; |
| 408 // The obvious condition. | 411 // The obvious condition. |
| 409 terminate |= max_recursion == 0; | 412 terminate |= max_recursion == 0; |
| 410 // Flat cons string terminate by definition. | 413 // Flat cons string terminate by definition. |
| 411 terminate |= flat; | 414 terminate |= flat; |
| 412 // Cap for max leaves. | 415 // Cap for max leaves. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 439 // Need to balance generation fairly. | 442 // Need to balance generation fairly. |
| 440 if (!terminate_left && data->rng_.next(0.5)) { | 443 if (!terminate_left && data->rng_.next(0.5)) { |
| 441 left = ConstructRandomString(data, max_recursion - 1); | 444 left = ConstructRandomString(data, max_recursion - 1); |
| 442 } | 445 } |
| 443 right = ConstructRandomString(data, max_recursion - 1); | 446 right = ConstructRandomString(data, max_recursion - 1); |
| 444 } | 447 } |
| 445 if (!terminate_left && left.is_null()) { | 448 if (!terminate_left && left.is_null()) { |
| 446 left = ConstructRandomString(data, max_recursion - 1); | 449 left = ConstructRandomString(data, max_recursion - 1); |
| 447 } | 450 } |
| 448 // Build the cons string. | 451 // Build the cons string. |
| 449 Handle<String> root = FACTORY->NewConsString(left, right); | 452 Handle<String> root = factory->NewConsString(left, right); |
| 450 CHECK(root->IsConsString() && !root->IsFlat()); | 453 CHECK(root->IsConsString() && !root->IsFlat()); |
| 451 // Special work needed for flat string. | 454 // Special work needed for flat string. |
| 452 if (flat) { | 455 if (flat) { |
| 453 data->stats_.empty_leaves_++; | 456 data->stats_.empty_leaves_++; |
| 454 FlattenString(root); | 457 FlattenString(root); |
| 455 CHECK(root->IsConsString() && root->IsFlat()); | 458 CHECK(root->IsConsString() && root->IsFlat()); |
| 456 } | 459 } |
| 457 return root; | 460 return root; |
| 458 } | 461 } |
| 459 | 462 |
| 460 | 463 |
| 461 static Handle<String> ConstructLeft( | 464 static Handle<String> ConstructLeft( |
| 462 ConsStringGenerationData* data, | 465 ConsStringGenerationData* data, |
| 463 int depth) { | 466 int depth) { |
| 464 Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector("")); | 467 Factory* factory = Isolate::Current()->factory(); |
| 468 Handle<String> answer = factory->NewStringFromAscii(CStrVector("")); |
| 465 data->stats_.leaves_++; | 469 data->stats_.leaves_++; |
| 466 for (int i = 0; i < depth; i++) { | 470 for (int i = 0; i < depth; i++) { |
| 467 Handle<String> block = data->block(i); | 471 Handle<String> block = data->block(i); |
| 468 Handle<String> next = FACTORY->NewConsString(answer, block); | 472 Handle<String> next = factory->NewConsString(answer, block); |
| 469 if (next->IsConsString()) data->stats_.leaves_++; | 473 if (next->IsConsString()) data->stats_.leaves_++; |
| 470 data->stats_.chars_ += block->length(); | 474 data->stats_.chars_ += block->length(); |
| 471 answer = next; | 475 answer = next; |
| 472 } | 476 } |
| 473 data->stats_.left_traversals_ = data->stats_.leaves_ - 2; | 477 data->stats_.left_traversals_ = data->stats_.leaves_ - 2; |
| 474 return answer; | 478 return answer; |
| 475 } | 479 } |
| 476 | 480 |
| 477 | 481 |
| 478 static Handle<String> ConstructRight( | 482 static Handle<String> ConstructRight( |
| 479 ConsStringGenerationData* data, | 483 ConsStringGenerationData* data, |
| 480 int depth) { | 484 int depth) { |
| 481 Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector("")); | 485 Factory* factory = Isolate::Current()->factory(); |
| 486 Handle<String> answer = factory->NewStringFromAscii(CStrVector("")); |
| 482 data->stats_.leaves_++; | 487 data->stats_.leaves_++; |
| 483 for (int i = depth - 1; i >= 0; i--) { | 488 for (int i = depth - 1; i >= 0; i--) { |
| 484 Handle<String> block = data->block(i); | 489 Handle<String> block = data->block(i); |
| 485 Handle<String> next = FACTORY->NewConsString(block, answer); | 490 Handle<String> next = factory->NewConsString(block, answer); |
| 486 if (next->IsConsString()) data->stats_.leaves_++; | 491 if (next->IsConsString()) data->stats_.leaves_++; |
| 487 data->stats_.chars_ += block->length(); | 492 data->stats_.chars_ += block->length(); |
| 488 answer = next; | 493 answer = next; |
| 489 } | 494 } |
| 490 data->stats_.right_traversals_ = data->stats_.leaves_ - 2; | 495 data->stats_.right_traversals_ = data->stats_.leaves_ - 2; |
| 491 return answer; | 496 return answer; |
| 492 } | 497 } |
| 493 | 498 |
| 494 | 499 |
| 495 static Handle<String> ConstructBalancedHelper( | 500 static Handle<String> ConstructBalancedHelper( |
| 496 ConsStringGenerationData* data, | 501 ConsStringGenerationData* data, |
| 497 int from, | 502 int from, |
| 498 int to) { | 503 int to) { |
| 504 Factory* factory = Isolate::Current()->factory(); |
| 499 CHECK(to > from); | 505 CHECK(to > from); |
| 500 if (to - from == 1) { | 506 if (to - from == 1) { |
| 501 data->stats_.chars_ += data->block(from)->length(); | 507 data->stats_.chars_ += data->block(from)->length(); |
| 502 return data->block(from); | 508 return data->block(from); |
| 503 } | 509 } |
| 504 if (to - from == 2) { | 510 if (to - from == 2) { |
| 505 data->stats_.chars_ += data->block(from)->length(); | 511 data->stats_.chars_ += data->block(from)->length(); |
| 506 data->stats_.chars_ += data->block(from+1)->length(); | 512 data->stats_.chars_ += data->block(from+1)->length(); |
| 507 return FACTORY->NewConsString(data->block(from), data->block(from+1)); | 513 return factory->NewConsString(data->block(from), data->block(from+1)); |
| 508 } | 514 } |
| 509 Handle<String> part1 = | 515 Handle<String> part1 = |
| 510 ConstructBalancedHelper(data, from, from + ((to - from) / 2)); | 516 ConstructBalancedHelper(data, from, from + ((to - from) / 2)); |
| 511 Handle<String> part2 = | 517 Handle<String> part2 = |
| 512 ConstructBalancedHelper(data, from + ((to - from) / 2), to); | 518 ConstructBalancedHelper(data, from + ((to - from) / 2), to); |
| 513 if (part1->IsConsString()) data->stats_.left_traversals_++; | 519 if (part1->IsConsString()) data->stats_.left_traversals_++; |
| 514 if (part2->IsConsString()) data->stats_.right_traversals_++; | 520 if (part2->IsConsString()) data->stats_.right_traversals_++; |
| 515 return FACTORY->NewConsString(part1, part2); | 521 return factory->NewConsString(part1, part2); |
| 516 } | 522 } |
| 517 | 523 |
| 518 | 524 |
| 519 static Handle<String> ConstructBalanced( | 525 static Handle<String> ConstructBalanced( |
| 520 ConsStringGenerationData* data, int depth = DEEP_DEPTH) { | 526 ConsStringGenerationData* data, int depth = DEEP_DEPTH) { |
| 521 Handle<String> string = ConstructBalancedHelper(data, 0, depth); | 527 Handle<String> string = ConstructBalancedHelper(data, 0, depth); |
| 522 data->stats_.leaves_ = | 528 data->stats_.leaves_ = |
| 523 data->stats_.left_traversals_ + data->stats_.right_traversals_ + 2; | 529 data->stats_.left_traversals_ + data->stats_.right_traversals_ + 2; |
| 524 return string; | 530 return string; |
| 525 } | 531 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 VerifyCharacterStream(flat_string_ptr, *cons_string); | 689 VerifyCharacterStream(flat_string_ptr, *cons_string); |
| 684 } | 690 } |
| 685 } | 691 } |
| 686 | 692 |
| 687 | 693 |
| 688 static const int kCharacterStreamNonRandomCases = 8; | 694 static const int kCharacterStreamNonRandomCases = 8; |
| 689 | 695 |
| 690 | 696 |
| 691 static Handle<String> BuildEdgeCaseConsString( | 697 static Handle<String> BuildEdgeCaseConsString( |
| 692 int test_case, ConsStringGenerationData* data) { | 698 int test_case, ConsStringGenerationData* data) { |
| 699 Factory* factory = Isolate::Current()->factory(); |
| 693 data->Reset(); | 700 data->Reset(); |
| 694 switch (test_case) { | 701 switch (test_case) { |
| 695 case 0: | 702 case 0: |
| 696 return ConstructBalanced(data, 71); | 703 return ConstructBalanced(data, 71); |
| 697 case 1: | 704 case 1: |
| 698 return ConstructLeft(data, 71); | 705 return ConstructLeft(data, 71); |
| 699 case 2: | 706 case 2: |
| 700 return ConstructRight(data, 71); | 707 return ConstructRight(data, 71); |
| 701 case 3: | 708 case 3: |
| 702 return ConstructLeft(data, 10); | 709 return ConstructLeft(data, 10); |
| 703 case 4: | 710 case 4: |
| 704 return ConstructRight(data, 10); | 711 return ConstructRight(data, 10); |
| 705 case 5: | 712 case 5: |
| 706 // 2 element balanced tree. | 713 // 2 element balanced tree. |
| 707 data->stats_.chars_ += data->block(0)->length(); | 714 data->stats_.chars_ += data->block(0)->length(); |
| 708 data->stats_.chars_ += data->block(1)->length(); | 715 data->stats_.chars_ += data->block(1)->length(); |
| 709 data->stats_.leaves_ += 2; | 716 data->stats_.leaves_ += 2; |
| 710 return FACTORY->NewConsString(data->block(0), data->block(1)); | 717 return factory->NewConsString(data->block(0), data->block(1)); |
| 711 case 6: | 718 case 6: |
| 712 // Simple flattened tree. | 719 // Simple flattened tree. |
| 713 data->stats_.chars_ += data->block(0)->length(); | 720 data->stats_.chars_ += data->block(0)->length(); |
| 714 data->stats_.chars_ += data->block(1)->length(); | 721 data->stats_.chars_ += data->block(1)->length(); |
| 715 data->stats_.leaves_ += 2; | 722 data->stats_.leaves_ += 2; |
| 716 data->stats_.empty_leaves_ += 1; | 723 data->stats_.empty_leaves_ += 1; |
| 717 { | 724 { |
| 718 Handle<String> string = | 725 Handle<String> string = |
| 719 FACTORY->NewConsString(data->block(0), data->block(1)); | 726 factory->NewConsString(data->block(0), data->block(1)); |
| 720 FlattenString(string); | 727 FlattenString(string); |
| 721 return string; | 728 return string; |
| 722 } | 729 } |
| 723 case 7: | 730 case 7: |
| 724 // Left node flattened. | 731 // Left node flattened. |
| 725 data->stats_.chars_ += data->block(0)->length(); | 732 data->stats_.chars_ += data->block(0)->length(); |
| 726 data->stats_.chars_ += data->block(1)->length(); | 733 data->stats_.chars_ += data->block(1)->length(); |
| 727 data->stats_.chars_ += data->block(2)->length(); | 734 data->stats_.chars_ += data->block(2)->length(); |
| 728 data->stats_.leaves_ += 3; | 735 data->stats_.leaves_ += 3; |
| 729 data->stats_.empty_leaves_ += 1; | 736 data->stats_.empty_leaves_ += 1; |
| 730 data->stats_.left_traversals_ += 1; | 737 data->stats_.left_traversals_ += 1; |
| 731 { | 738 { |
| 732 Handle<String> left = | 739 Handle<String> left = |
| 733 FACTORY->NewConsString(data->block(0), data->block(1)); | 740 factory->NewConsString(data->block(0), data->block(1)); |
| 734 FlattenString(left); | 741 FlattenString(left); |
| 735 return FACTORY->NewConsString(left, data->block(2)); | 742 return factory->NewConsString(left, data->block(2)); |
| 736 } | 743 } |
| 737 case 8: | 744 case 8: |
| 738 // Left node and right node flattened. | 745 // Left node and right node flattened. |
| 739 data->stats_.chars_ += data->block(0)->length(); | 746 data->stats_.chars_ += data->block(0)->length(); |
| 740 data->stats_.chars_ += data->block(1)->length(); | 747 data->stats_.chars_ += data->block(1)->length(); |
| 741 data->stats_.chars_ += data->block(2)->length(); | 748 data->stats_.chars_ += data->block(2)->length(); |
| 742 data->stats_.chars_ += data->block(3)->length(); | 749 data->stats_.chars_ += data->block(3)->length(); |
| 743 data->stats_.leaves_ += 4; | 750 data->stats_.leaves_ += 4; |
| 744 data->stats_.empty_leaves_ += 2; | 751 data->stats_.empty_leaves_ += 2; |
| 745 data->stats_.left_traversals_ += 1; | 752 data->stats_.left_traversals_ += 1; |
| 746 data->stats_.right_traversals_ += 1; | 753 data->stats_.right_traversals_ += 1; |
| 747 { | 754 { |
| 748 Handle<String> left = | 755 Handle<String> left = |
| 749 FACTORY->NewConsString(data->block(0), data->block(1)); | 756 factory->NewConsString(data->block(0), data->block(1)); |
| 750 FlattenString(left); | 757 FlattenString(left); |
| 751 Handle<String> right = | 758 Handle<String> right = |
| 752 FACTORY->NewConsString(data->block(2), data->block(2)); | 759 factory->NewConsString(data->block(2), data->block(2)); |
| 753 FlattenString(right); | 760 FlattenString(right); |
| 754 return FACTORY->NewConsString(left, right); | 761 return factory->NewConsString(left, right); |
| 755 } | 762 } |
| 756 } | 763 } |
| 757 UNREACHABLE(); | 764 UNREACHABLE(); |
| 758 return Handle<String>(); | 765 return Handle<String>(); |
| 759 } | 766 } |
| 760 | 767 |
| 761 | 768 |
| 762 TEST(StringCharacterStreamEdgeCases) { | 769 TEST(StringCharacterStreamEdgeCases) { |
| 763 printf("TestStringCharacterStreamEdgeCases\n"); | 770 printf("TestStringCharacterStreamEdgeCases\n"); |
| 764 TestStringCharacterStream( | 771 TestStringCharacterStream( |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); | 852 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); |
| 846 } | 853 } |
| 847 | 854 |
| 848 | 855 |
| 849 static const int DEEP_ASCII_DEPTH = 100000; | 856 static const int DEEP_ASCII_DEPTH = 100000; |
| 850 | 857 |
| 851 | 858 |
| 852 TEST(DeepAscii) { | 859 TEST(DeepAscii) { |
| 853 printf("TestDeepAscii\n"); | 860 printf("TestDeepAscii\n"); |
| 854 CcTest::InitializeVM(); | 861 CcTest::InitializeVM(); |
| 862 Factory* factory = Isolate::Current()->factory(); |
| 855 v8::HandleScope scope(CcTest::isolate()); | 863 v8::HandleScope scope(CcTest::isolate()); |
| 856 | 864 |
| 857 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); | 865 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); |
| 858 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { | 866 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { |
| 859 foo[i] = "foo "[i % 4]; | 867 foo[i] = "foo "[i % 4]; |
| 860 } | 868 } |
| 861 Handle<String> string = | 869 Handle<String> string = |
| 862 FACTORY->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); | 870 factory->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); |
| 863 Handle<String> foo_string = FACTORY->NewStringFromAscii(CStrVector("foo")); | 871 Handle<String> foo_string = factory->NewStringFromAscii(CStrVector("foo")); |
| 864 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { | 872 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { |
| 865 string = FACTORY->NewConsString(string, foo_string); | 873 string = factory->NewConsString(string, foo_string); |
| 866 } | 874 } |
| 867 Handle<String> flat_string = FACTORY->NewConsString(string, foo_string); | 875 Handle<String> flat_string = factory->NewConsString(string, foo_string); |
| 868 FlattenString(flat_string); | 876 FlattenString(flat_string); |
| 869 | 877 |
| 870 for (int i = 0; i < 500; i++) { | 878 for (int i = 0; i < 500; i++) { |
| 871 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); | 879 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); |
| 872 } | 880 } |
| 873 DeleteArray<char>(foo); | 881 DeleteArray<char>(foo); |
| 874 } | 882 } |
| 875 | 883 |
| 876 | 884 |
| 877 TEST(Utf8Conversion) { | 885 TEST(Utf8Conversion) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 CHECK_EQ(Smi::cast(results[i]->ToSmi()->ToObjectChecked())->value(), | 1060 CHECK_EQ(Smi::cast(results[i]->ToSmi()->ToObjectChecked())->value(), |
| 1053 result->ToInt32()->Value()); | 1061 result->ToInt32()->Value()); |
| 1054 } | 1062 } |
| 1055 } | 1063 } |
| 1056 } | 1064 } |
| 1057 | 1065 |
| 1058 | 1066 |
| 1059 TEST(SliceFromCons) { | 1067 TEST(SliceFromCons) { |
| 1060 FLAG_string_slices = true; | 1068 FLAG_string_slices = true; |
| 1061 CcTest::InitializeVM(); | 1069 CcTest::InitializeVM(); |
| 1070 Factory* factory = Isolate::Current()->factory(); |
| 1062 v8::HandleScope scope(CcTest::isolate()); | 1071 v8::HandleScope scope(CcTest::isolate()); |
| 1063 Handle<String> string = | 1072 Handle<String> string = |
| 1064 FACTORY->NewStringFromAscii(CStrVector("parentparentparent")); | 1073 factory->NewStringFromAscii(CStrVector("parentparentparent")); |
| 1065 Handle<String> parent = FACTORY->NewConsString(string, string); | 1074 Handle<String> parent = factory->NewConsString(string, string); |
| 1066 CHECK(parent->IsConsString()); | 1075 CHECK(parent->IsConsString()); |
| 1067 CHECK(!parent->IsFlat()); | 1076 CHECK(!parent->IsFlat()); |
| 1068 Handle<String> slice = FACTORY->NewSubString(parent, 1, 25); | 1077 Handle<String> slice = factory->NewSubString(parent, 1, 25); |
| 1069 // After slicing, the original string becomes a flat cons. | 1078 // After slicing, the original string becomes a flat cons. |
| 1070 CHECK(parent->IsFlat()); | 1079 CHECK(parent->IsFlat()); |
| 1071 CHECK(slice->IsSlicedString()); | 1080 CHECK(slice->IsSlicedString()); |
| 1072 CHECK_EQ(SlicedString::cast(*slice)->parent(), | 1081 CHECK_EQ(SlicedString::cast(*slice)->parent(), |
| 1073 // Parent could have been short-circuited. | 1082 // Parent could have been short-circuited. |
| 1074 parent->IsConsString() ? ConsString::cast(*parent)->first() | 1083 parent->IsConsString() ? ConsString::cast(*parent)->first() |
| 1075 : *parent); | 1084 : *parent); |
| 1076 CHECK(SlicedString::cast(*slice)->parent()->IsSeqString()); | 1085 CHECK(SlicedString::cast(*slice)->parent()->IsSeqString()); |
| 1077 CHECK(slice->IsFlat()); | 1086 CHECK(slice->IsFlat()); |
| 1078 } | 1087 } |
| 1079 | 1088 |
| 1080 | 1089 |
| 1081 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | 1090 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { |
| 1082 public: | 1091 public: |
| 1083 explicit AsciiVectorResource(i::Vector<const char> vector) | 1092 explicit AsciiVectorResource(i::Vector<const char> vector) |
| 1084 : data_(vector) {} | 1093 : data_(vector) {} |
| 1085 virtual ~AsciiVectorResource() {} | 1094 virtual ~AsciiVectorResource() {} |
| 1086 virtual size_t length() const { return data_.length(); } | 1095 virtual size_t length() const { return data_.length(); } |
| 1087 virtual const char* data() const { return data_.start(); } | 1096 virtual const char* data() const { return data_.start(); } |
| 1088 private: | 1097 private: |
| 1089 i::Vector<const char> data_; | 1098 i::Vector<const char> data_; |
| 1090 }; | 1099 }; |
| 1091 | 1100 |
| 1092 | 1101 |
| 1093 TEST(SliceFromExternal) { | 1102 TEST(SliceFromExternal) { |
| 1094 FLAG_string_slices = true; | 1103 FLAG_string_slices = true; |
| 1095 CcTest::InitializeVM(); | 1104 CcTest::InitializeVM(); |
| 1105 Factory* factory = Isolate::Current()->factory(); |
| 1096 v8::HandleScope scope(CcTest::isolate()); | 1106 v8::HandleScope scope(CcTest::isolate()); |
| 1097 AsciiVectorResource resource( | 1107 AsciiVectorResource resource( |
| 1098 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); | 1108 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); |
| 1099 Handle<String> string = FACTORY->NewExternalStringFromAscii(&resource); | 1109 Handle<String> string = factory->NewExternalStringFromAscii(&resource); |
| 1100 CHECK(string->IsExternalString()); | 1110 CHECK(string->IsExternalString()); |
| 1101 Handle<String> slice = FACTORY->NewSubString(string, 1, 25); | 1111 Handle<String> slice = factory->NewSubString(string, 1, 25); |
| 1102 CHECK(slice->IsSlicedString()); | 1112 CHECK(slice->IsSlicedString()); |
| 1103 CHECK(string->IsExternalString()); | 1113 CHECK(string->IsExternalString()); |
| 1104 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); | 1114 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); |
| 1105 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); | 1115 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); |
| 1106 CHECK(slice->IsFlat()); | 1116 CHECK(slice->IsFlat()); |
| 1107 } | 1117 } |
| 1108 | 1118 |
| 1109 | 1119 |
| 1110 TEST(TrivialSlice) { | 1120 TEST(TrivialSlice) { |
| 1111 // This tests whether a slice that contains the entire parent string | 1121 // This tests whether a slice that contains the entire parent string |
| 1112 // actually creates a new string (it should not). | 1122 // actually creates a new string (it should not). |
| 1113 FLAG_string_slices = true; | 1123 FLAG_string_slices = true; |
| 1114 CcTest::InitializeVM(); | 1124 CcTest::InitializeVM(); |
| 1125 Factory* factory = Isolate::Current()->factory(); |
| 1115 v8::HandleScope scope(CcTest::isolate()); | 1126 v8::HandleScope scope(CcTest::isolate()); |
| 1116 v8::Local<v8::Value> result; | 1127 v8::Local<v8::Value> result; |
| 1117 Handle<String> string; | 1128 Handle<String> string; |
| 1118 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; | 1129 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; |
| 1119 const char* check = "str.slice(0,26)"; | 1130 const char* check = "str.slice(0,26)"; |
| 1120 const char* crosscheck = "str.slice(1,25)"; | 1131 const char* crosscheck = "str.slice(1,25)"; |
| 1121 | 1132 |
| 1122 CompileRun(init); | 1133 CompileRun(init); |
| 1123 | 1134 |
| 1124 result = CompileRun(check); | 1135 result = CompileRun(check); |
| 1125 CHECK(result->IsString()); | 1136 CHECK(result->IsString()); |
| 1126 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1137 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| 1127 CHECK(!string->IsSlicedString()); | 1138 CHECK(!string->IsSlicedString()); |
| 1128 | 1139 |
| 1129 string = FACTORY->NewSubString(string, 0, 26); | 1140 string = factory->NewSubString(string, 0, 26); |
| 1130 CHECK(!string->IsSlicedString()); | 1141 CHECK(!string->IsSlicedString()); |
| 1131 result = CompileRun(crosscheck); | 1142 result = CompileRun(crosscheck); |
| 1132 CHECK(result->IsString()); | 1143 CHECK(result->IsString()); |
| 1133 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1144 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| 1134 CHECK(string->IsSlicedString()); | 1145 CHECK(string->IsSlicedString()); |
| 1135 CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); | 1146 CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); |
| 1136 } | 1147 } |
| 1137 | 1148 |
| 1138 | 1149 |
| 1139 TEST(SliceFromSlice) { | 1150 TEST(SliceFromSlice) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 CheckCanonicalEquivalence(c, test); | 1348 CheckCanonicalEquivalence(c, test); |
| 1338 continue; | 1349 continue; |
| 1339 } | 1350 } |
| 1340 if (upper != c && lower != c) { | 1351 if (upper != c && lower != c) { |
| 1341 CheckCanonicalEquivalence(c, test); | 1352 CheckCanonicalEquivalence(c, test); |
| 1342 continue; | 1353 continue; |
| 1343 } | 1354 } |
| 1344 CHECK_EQ(Min(upper, lower), test); | 1355 CHECK_EQ(Min(upper, lower), test); |
| 1345 } | 1356 } |
| 1346 } | 1357 } |
| OLD | NEW |