| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 126 |
| 127 private: | 127 private: |
| 128 const char* data_; | 128 const char* data_; |
| 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 Zone* zone) { |
| 137 // A list of pointers that we don't have any interest in cleaning up. | 138 // 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. | 139 // If they are reachable from a root then leak detection won't complain. |
| 139 Isolate* isolate = Isolate::Current(); | 140 Isolate* isolate = Isolate::Current(); |
| 140 Factory* factory = isolate->factory(); | 141 Factory* factory = isolate->factory(); |
| 141 Zone* zone = isolate->runtime_zone(); | |
| 142 for (int i = 0; i < bb_length; i++) { | 142 for (int i = 0; i < bb_length; i++) { |
| 143 int len = rng->next(16); | 143 int len = rng->next(16); |
| 144 int slice_head_chars = 0; | 144 int slice_head_chars = 0; |
| 145 int slice_tail_chars = 0; | 145 int slice_tail_chars = 0; |
| 146 int slice_depth = 0; | 146 int slice_depth = 0; |
| 147 for (int j = 0; j < 3; j++) { | 147 for (int j = 0; j < 3; j++) { |
| 148 if (rng->next(0.35)) slice_depth++; | 148 if (rng->next(0.35)) slice_depth++; |
| 149 } | 149 } |
| 150 // Must truncate something for a slice string. Loop until | 150 // Must truncate something for a slice string. Loop until |
| 151 // at least one end will be sliced. | 151 // at least one end will be sliced. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 CHECK(this->empty_leaves_ == that.empty_leaves_); | 256 CHECK(this->empty_leaves_ == that.empty_leaves_); |
| 257 CHECK(this->chars_ == that.chars_); | 257 CHECK(this->chars_ == that.chars_); |
| 258 CHECK(this->left_traversals_ == that.left_traversals_); | 258 CHECK(this->left_traversals_ == that.left_traversals_); |
| 259 CHECK(this->right_traversals_ == that.right_traversals_); | 259 CHECK(this->right_traversals_ == that.right_traversals_); |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 class ConsStringGenerationData { | 263 class ConsStringGenerationData { |
| 264 public: | 264 public: |
| 265 static const int kNumberOfBuildingBlocks = 256; | 265 static const int kNumberOfBuildingBlocks = 256; |
| 266 explicit ConsStringGenerationData(bool long_blocks); | 266 ConsStringGenerationData(bool long_blocks, Zone* zone); |
| 267 void Reset(); | 267 void Reset(); |
| 268 inline Handle<String> block(int offset); | 268 inline Handle<String> block(int offset); |
| 269 inline Handle<String> block(uint32_t offset); | 269 inline Handle<String> block(uint32_t offset); |
| 270 // Input variables. | 270 // Input variables. |
| 271 double early_termination_threshold_; | 271 double early_termination_threshold_; |
| 272 double leftness_; | 272 double leftness_; |
| 273 double rightness_; | 273 double rightness_; |
| 274 double empty_leaf_threshold_; | 274 double empty_leaf_threshold_; |
| 275 unsigned max_leaves_; | 275 unsigned max_leaves_; |
| 276 // Cached data. | 276 // Cached data. |
| 277 Handle<String> building_blocks_[kNumberOfBuildingBlocks]; | 277 Handle<String> building_blocks_[kNumberOfBuildingBlocks]; |
| 278 String* empty_string_; | 278 String* empty_string_; |
| 279 RandomNumberGenerator rng_; | 279 RandomNumberGenerator rng_; |
| 280 // Stats. | 280 // Stats. |
| 281 ConsStringStats stats_; | 281 ConsStringStats stats_; |
| 282 unsigned early_terminations_; | 282 unsigned early_terminations_; |
| 283 private: | 283 private: |
| 284 DISALLOW_COPY_AND_ASSIGN(ConsStringGenerationData); | 284 DISALLOW_COPY_AND_ASSIGN(ConsStringGenerationData); |
| 285 }; | 285 }; |
| 286 | 286 |
| 287 | 287 |
| 288 ConsStringGenerationData::ConsStringGenerationData(bool long_blocks) { | 288 ConsStringGenerationData::ConsStringGenerationData(bool long_blocks, |
| 289 Zone* zone) { |
| 289 rng_.init(); | 290 rng_.init(); |
| 290 InitializeBuildingBlocks( | 291 InitializeBuildingBlocks( |
| 291 building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_); | 292 building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_, zone); |
| 292 empty_string_ = Isolate::Current()->heap()->empty_string(); | 293 empty_string_ = Isolate::Current()->heap()->empty_string(); |
| 293 Reset(); | 294 Reset(); |
| 294 } | 295 } |
| 295 | 296 |
| 296 | 297 |
| 297 Handle<String> ConsStringGenerationData::block(uint32_t offset) { | 298 Handle<String> ConsStringGenerationData::block(uint32_t offset) { |
| 298 return building_blocks_[offset % kNumberOfBuildingBlocks ]; | 299 return building_blocks_[offset % kNumberOfBuildingBlocks ]; |
| 299 } | 300 } |
| 300 | 301 |
| 301 | 302 |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 } | 564 } |
| 564 s1->Get(s1->length() - 1); | 565 s1->Get(s1->length() - 1); |
| 565 s2->Get(s2->length() - 1); | 566 s2->Get(s2->length() - 1); |
| 566 } | 567 } |
| 567 | 568 |
| 568 | 569 |
| 569 TEST(Traverse) { | 570 TEST(Traverse) { |
| 570 printf("TestTraverse\n"); | 571 printf("TestTraverse\n"); |
| 571 CcTest::InitializeVM(); | 572 CcTest::InitializeVM(); |
| 572 v8::HandleScope scope(CcTest::isolate()); | 573 v8::HandleScope scope(CcTest::isolate()); |
| 573 ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); | 574 Zone zone(Isolate::Current()); |
| 574 ConsStringGenerationData data(false); | 575 ConsStringGenerationData data(false, &zone); |
| 575 Handle<String> flat = ConstructBalanced(&data); | 576 Handle<String> flat = ConstructBalanced(&data); |
| 576 FlattenString(flat); | 577 FlattenString(flat); |
| 577 Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); | 578 Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); |
| 578 Handle<String> right_asymmetric = ConstructRight(&data, DEEP_DEPTH); | 579 Handle<String> right_asymmetric = ConstructRight(&data, DEEP_DEPTH); |
| 579 Handle<String> symmetric = ConstructBalanced(&data); | 580 Handle<String> symmetric = ConstructBalanced(&data); |
| 580 printf("1\n"); | 581 printf("1\n"); |
| 581 Traverse(flat, symmetric); | 582 Traverse(flat, symmetric); |
| 582 printf("2\n"); | 583 printf("2\n"); |
| 583 Traverse(flat, left_asymmetric); | 584 Traverse(flat, left_asymmetric); |
| 584 printf("3\n"); | 585 printf("3\n"); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 "early_terminations", data.early_terminations_); | 654 "early_terminations", data.early_terminations_); |
| 654 #endif | 655 #endif |
| 655 } | 656 } |
| 656 | 657 |
| 657 | 658 |
| 658 template<typename BuildString> | 659 template<typename BuildString> |
| 659 void TestStringCharacterStream(BuildString build, int test_cases) { | 660 void TestStringCharacterStream(BuildString build, int test_cases) { |
| 660 CcTest::InitializeVM(); | 661 CcTest::InitializeVM(); |
| 661 Isolate* isolate = Isolate::Current(); | 662 Isolate* isolate = Isolate::Current(); |
| 662 HandleScope outer_scope(isolate); | 663 HandleScope outer_scope(isolate); |
| 663 ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); | 664 Zone zone(isolate); |
| 664 ConsStringGenerationData data(true); | 665 ConsStringGenerationData data(true, &zone); |
| 665 for (int i = 0; i < test_cases; i++) { | 666 for (int i = 0; i < test_cases; i++) { |
| 666 printf("%d\n", i); | 667 printf("%d\n", i); |
| 667 HandleScope inner_scope(isolate); | 668 HandleScope inner_scope(isolate); |
| 668 AlwaysAllocateScope always_allocate; | 669 AlwaysAllocateScope always_allocate; |
| 669 // Build flat version of cons string. | 670 // Build flat version of cons string. |
| 670 Handle<String> flat_string = build(i, &data); | 671 Handle<String> flat_string = build(i, &data); |
| 671 ConsStringStats flat_string_stats; | 672 ConsStringStats flat_string_stats; |
| 672 AccumulateStats(flat_string, &flat_string_stats); | 673 AccumulateStats(flat_string, &flat_string_stats); |
| 673 // Flatten string. | 674 // Flatten string. |
| 674 FlattenString(flat_string); | 675 FlattenString(flat_string); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 for (int j = 0; j < lengths[i]; j++) | 923 for (int j = 0; j < lengths[i]; j++) |
| 923 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); | 924 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); |
| 924 // Check that the rest of the buffer hasn't been touched | 925 // Check that the rest of the buffer hasn't been touched |
| 925 for (int j = lengths[i]; j < 11; j++) | 926 for (int j = lengths[i]; j < 11; j++) |
| 926 CHECK_EQ(kNoChar, buffer[j]); | 927 CHECK_EQ(kNoChar, buffer[j]); |
| 927 } | 928 } |
| 928 } | 929 } |
| 929 | 930 |
| 930 | 931 |
| 931 TEST(ExternalShortStringAdd) { | 932 TEST(ExternalShortStringAdd) { |
| 932 ZoneScope zonescope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); | 933 Isolate* isolate = Isolate::Current(); |
| 934 Zone zone(isolate); |
| 933 | 935 |
| 934 CcTest::InitializeVM(); | 936 CcTest::InitializeVM(); |
| 935 v8::HandleScope handle_scope(CcTest::isolate()); | 937 v8::HandleScope handle_scope(CcTest::isolate()); |
| 936 Zone* zone = Isolate::Current()->runtime_zone(); | |
| 937 | 938 |
| 938 // Make sure we cover all always-flat lengths and at least one above. | 939 // Make sure we cover all always-flat lengths and at least one above. |
| 939 static const int kMaxLength = 20; | 940 static const int kMaxLength = 20; |
| 940 CHECK_GT(kMaxLength, i::ConsString::kMinLength); | 941 CHECK_GT(kMaxLength, i::ConsString::kMinLength); |
| 941 | 942 |
| 942 // Allocate two JavaScript arrays for holding short strings. | 943 // Allocate two JavaScript arrays for holding short strings. |
| 943 v8::Handle<v8::Array> ascii_external_strings = | 944 v8::Handle<v8::Array> ascii_external_strings = |
| 944 v8::Array::New(kMaxLength + 1); | 945 v8::Array::New(kMaxLength + 1); |
| 945 v8::Handle<v8::Array> non_ascii_external_strings = | 946 v8::Handle<v8::Array> non_ascii_external_strings = |
| 946 v8::Array::New(kMaxLength + 1); | 947 v8::Array::New(kMaxLength + 1); |
| 947 | 948 |
| 948 // Generate short ascii and non-ascii external strings. | 949 // Generate short ascii and non-ascii external strings. |
| 949 for (int i = 0; i <= kMaxLength; i++) { | 950 for (int i = 0; i <= kMaxLength; i++) { |
| 950 char* ascii = zone->NewArray<char>(i + 1); | 951 char* ascii = zone.NewArray<char>(i + 1); |
| 951 for (int j = 0; j < i; j++) { | 952 for (int j = 0; j < i; j++) { |
| 952 ascii[j] = 'a'; | 953 ascii[j] = 'a'; |
| 953 } | 954 } |
| 954 // Terminating '\0' is left out on purpose. It is not required for external | 955 // Terminating '\0' is left out on purpose. It is not required for external |
| 955 // string data. | 956 // string data. |
| 956 AsciiResource* ascii_resource = | 957 AsciiResource* ascii_resource = |
| 957 new(zone) AsciiResource(Vector<const char>(ascii, i)); | 958 new(&zone) AsciiResource(Vector<const char>(ascii, i)); |
| 958 v8::Local<v8::String> ascii_external_string = | 959 v8::Local<v8::String> ascii_external_string = |
| 959 v8::String::NewExternal(ascii_resource); | 960 v8::String::NewExternal(ascii_resource); |
| 960 | 961 |
| 961 ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); | 962 ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); |
| 962 uc16* non_ascii = zone->NewArray<uc16>(i + 1); | 963 uc16* non_ascii = zone.NewArray<uc16>(i + 1); |
| 963 for (int j = 0; j < i; j++) { | 964 for (int j = 0; j < i; j++) { |
| 964 non_ascii[j] = 0x1234; | 965 non_ascii[j] = 0x1234; |
| 965 } | 966 } |
| 966 // Terminating '\0' is left out on purpose. It is not required for external | 967 // Terminating '\0' is left out on purpose. It is not required for external |
| 967 // string data. | 968 // string data. |
| 968 Resource* resource = new(zone) Resource(Vector<const uc16>(non_ascii, i)); | 969 Resource* resource = new(&zone) Resource(Vector<const uc16>(non_ascii, i)); |
| 969 v8::Local<v8::String> non_ascii_external_string = | 970 v8::Local<v8::String> non_ascii_external_string = |
| 970 v8::String::NewExternal(resource); | 971 v8::String::NewExternal(resource); |
| 971 non_ascii_external_strings->Set(v8::Integer::New(i), | 972 non_ascii_external_strings->Set(v8::Integer::New(i), |
| 972 non_ascii_external_string); | 973 non_ascii_external_string); |
| 973 } | 974 } |
| 974 | 975 |
| 975 // Add the arrays with the short external strings in the global object. | 976 // Add the arrays with the short external strings in the global object. |
| 976 v8::Handle<v8::Object> global = CcTest::env()->Global(); | 977 v8::Handle<v8::Object> global = CcTest::env()->Global(); |
| 977 global->Set(v8_str("external_ascii"), ascii_external_strings); | 978 global->Set(v8_str("external_ascii"), ascii_external_strings); |
| 978 global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); | 979 global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 "test()"; | 1015 "test()"; |
| 1015 CHECK_EQ(0, CompileRun(source)->Int32Value()); | 1016 CHECK_EQ(0, CompileRun(source)->Int32Value()); |
| 1016 } | 1017 } |
| 1017 | 1018 |
| 1018 | 1019 |
| 1019 TEST(CachedHashOverflow) { | 1020 TEST(CachedHashOverflow) { |
| 1020 // We incorrectly allowed strings to be tagged as array indices even if their | 1021 // We incorrectly allowed strings to be tagged as array indices even if their |
| 1021 // values didn't fit in the hash field. | 1022 // values didn't fit in the hash field. |
| 1022 // See http://code.google.com/p/v8/issues/detail?id=728 | 1023 // See http://code.google.com/p/v8/issues/detail?id=728 |
| 1023 Isolate* isolate = Isolate::Current(); | 1024 Isolate* isolate = Isolate::Current(); |
| 1024 ZoneScope zone(isolate->runtime_zone(), DELETE_ON_EXIT); | 1025 Zone zone(isolate); |
| 1025 | 1026 |
| 1026 CcTest::InitializeVM(); | 1027 CcTest::InitializeVM(); |
| 1027 v8::HandleScope handle_scope(CcTest::isolate()); | 1028 v8::HandleScope handle_scope(CcTest::isolate()); |
| 1028 // Lines must be executed sequentially. Combining them into one script | 1029 // Lines must be executed sequentially. Combining them into one script |
| 1029 // makes the bug go away. | 1030 // makes the bug go away. |
| 1030 const char* lines[] = { | 1031 const char* lines[] = { |
| 1031 "var x = [];", | 1032 "var x = [];", |
| 1032 "x[4] = 42;", | 1033 "x[4] = 42;", |
| 1033 "var s = \"1073741828\";", | 1034 "var s = \"1073741828\";", |
| 1034 "x[s];", | 1035 "x[s];", |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 CheckCanonicalEquivalence(c, test); | 1349 CheckCanonicalEquivalence(c, test); |
| 1349 continue; | 1350 continue; |
| 1350 } | 1351 } |
| 1351 if (upper != c && lower != c) { | 1352 if (upper != c && lower != c) { |
| 1352 CheckCanonicalEquivalence(c, test); | 1353 CheckCanonicalEquivalence(c, test); |
| 1353 continue; | 1354 continue; |
| 1354 } | 1355 } |
| 1355 CHECK_EQ(Min(upper, lower), test); | 1356 CHECK_EQ(Min(upper, lower), test); |
| 1356 } | 1357 } |
| 1357 } | 1358 } |
| OLD | NEW |