1355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// Redistribution and use in source and binary forms, with or without 3750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// modification, are permitted provided that the following conditions are 4750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// met: 5750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// 6750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// * Redistributions of source code must retain the above copyright 7750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// notice, this list of conditions and the following disclaimer. 8750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// * Redistributions in binary form must reproduce the above 9750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// copyright notice, this list of conditions and the following 10750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// disclaimer in the documentation and/or other materials provided 11750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// with the distribution. 12750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// * Neither the name of Google Inc. nor the names of its 13750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// contributors may be used to endorse or promote products derived 14750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// from this software without specific prior written permission. 15750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// 16750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Check that we can traverse very deep stacks of ConsStrings using 294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// StringCharacterStram. Check that Get(int) works on very deep stacks 309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// of ConsStrings. These operations may not be very fast, but they 319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// should be possible without getting errors due to too deep recursion. 329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include <stdlib.h> 349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h" 38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/factory.h" 39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/objects.h" 40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 42c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org// Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry 43c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgclass MyRandomNumberGenerator { 44c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org public: 45c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MyRandomNumberGenerator() { 46c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org init(); 47c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 48c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 49c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org void init(uint32_t seed = 0x5688c73e) { 50c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org static const uint32_t phi = 0x9e3779b9; 51c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org c = 362436; 52c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org i = kQSize-1; 53c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Q[0] = seed; 54c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Q[1] = seed + phi; 55c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Q[2] = seed + phi + phi; 56c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org for (unsigned j = 3; j < kQSize; j++) { 57c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Q[j] = Q[j - 3] ^ Q[j - 2] ^ phi ^ j; 58c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 59c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 60c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 61c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t next() { 62c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint64_t a = 18782; 63c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t r = 0xfffffffe; 64c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org i = (i + 1) & (kQSize-1); 65c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint64_t t = a * Q[i] + c; 66c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org c = (t >> 32); 67c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t x = static_cast<uint32_t>(t + c); 68c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (x < c) { 69c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org x++; 70c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org c++; 71c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 72c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org return (Q[i] = r - x); 73c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 74c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 75c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t next(int max) { 76c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org return next() % max; 77c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 78c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 79c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org bool next(double threshold) { 80e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(threshold >= 0.0 && threshold <= 1.0); 81c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (threshold == 1.0) return true; 82c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (threshold == 0.0) return false; 83c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t value = next() % 100000; 84c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org return threshold > static_cast<double>(value)/100000.0; 85c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 86c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 87c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org private: 88c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org static const uint32_t kQSize = 4096; 89c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t Q[kQSize]; 90c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t c; 91c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org uint32_t i; 92c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org}; 93c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comusing namespace v8::internal; 969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic const int DEEP_DEPTH = 8 * 1024; 999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic const int SUPER_DEEP_DEPTH = 80 * 1024; 1009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 1019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 1026f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.orgclass Resource: public v8::String::ExternalStringResource { 1034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org public: 1046f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Resource(const uc16* data, size_t length): data_(data), length_(length) {} 1056f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ~Resource() { i::DeleteArray(data_); } 1064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org virtual const uint16_t* data() const { return data_; } 1074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org virtual size_t length() const { return length_; } 1084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org private: 1104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org const uc16* data_; 1114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org size_t length_; 1124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}; 1134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1152c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgclass OneByteResource : public v8::String::ExternalOneByteStringResource { 116ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org public: 1172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org OneByteResource(const char* data, size_t length) 1186f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org : data_(data), length_(length) {} 1192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org ~OneByteResource() { i::DeleteArray(data_); } 120ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org virtual const char* data() const { return data_; } 121ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org virtual size_t length() const { return length_; } 122ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 123ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org private: 124ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org const char* data_; 125ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org size_t length_; 126ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org}; 127ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 128ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 129a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic void InitializeBuildingBlocks(Handle<String>* building_blocks, 130a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int bb_length, 131a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool long_blocks, 1326f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org MyRandomNumberGenerator* rng) { 13341826e77311db718135ef6517b846933dfd275f3ager@chromium.org // A list of pointers that we don't have any interest in cleaning up. 13441826e77311db718135ef6517b846933dfd275f3ager@chromium.org // If they are reachable from a root then leak detection won't complain. 135528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 136d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Factory* factory = isolate->factory(); 137a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < bb_length; i++) { 138a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int len = rng->next(16); 139a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int slice_head_chars = 0; 140a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int slice_tail_chars = 0; 141a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int slice_depth = 0; 142a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int j = 0; j < 3; j++) { 143a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (rng->next(0.35)) slice_depth++; 144a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 145a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Must truncate something for a slice string. Loop until 146a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // at least one end will be sliced. 147a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org while (slice_head_chars == 0 && slice_tail_chars == 0) { 148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org slice_head_chars = rng->next(15); 149a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org slice_tail_chars = rng->next(12); 150a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (long_blocks) { 152a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Generate building blocks which will never be merged 153a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org len += ConsString::kMinLength + 1; 154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else if (len > 14) { 1559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com len += 1234; 1569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 157a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Don't slice 0 length strings. 158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (len == 0) slice_depth = 0; 159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int slice_length = slice_depth*(slice_head_chars + slice_tail_chars); 160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org len += slice_length; 161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org switch (rng->next(4)) { 1629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com case 0: { 1639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com uc16 buf[2000]; 1649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 165a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org buf[j] = rng->next(0x10000); 1669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org building_blocks[i] = factory->NewStringFromTwoByte( 1688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Vector<const uc16>(buf, len)).ToHandleChecked(); 1699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 170bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CHECK_EQ(buf[j], building_blocks[i]->Get(j)); 1719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com break; 1739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com case 1: { 1759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com char buf[2000]; 1769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 177a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org buf[j] = rng->next(0x80); 1789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org building_blocks[i] = factory->NewStringFromAscii( 1808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Vector<const char>(buf, len)).ToHandleChecked(); 1819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 182bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CHECK_EQ(buf[j], building_blocks[i]->Get(j)); 1839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com break; 1859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com case 2: { 1876f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org uc16* buf = NewArray<uc16>(len); 1889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org buf[j] = rng->next(0x10000); 1909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1916f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Resource* resource = new Resource(buf, len); 1926f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org building_blocks[i] = 1936f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org v8::Utils::OpenHandle( 1946f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org *v8::String::NewExternal(CcTest::isolate(), resource)); 1959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 196bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CHECK_EQ(buf[j], building_blocks[i]->Get(j)); 1979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com break; 1999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com case 3: { 2016f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org char* buf = NewArray<char>(len); 2029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 203a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org buf[j] = rng->next(0x80); 2049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org OneByteResource* resource = new OneByteResource(buf, len); 2066f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org building_blocks[i] = 2076f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org v8::Utils::OpenHandle( 2086f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org *v8::String::NewExternal(CcTest::isolate(), resource)); 2099a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int j = 0; j < len; j++) { 210bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CHECK_EQ(buf[j], building_blocks[i]->Get(j)); 2119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com break; 2139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int j = slice_depth; j > 0; j--) { 216d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org building_blocks[i] = factory->NewSubString( 217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org building_blocks[i], 218a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org slice_head_chars, 219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org building_blocks[i]->length() - slice_tail_chars); 220a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 221a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(len == building_blocks[i]->length() + slice_length); 222a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 223a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 224a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 225a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 226a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass ConsStringStats { 227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public: 228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringStats() { 229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Reset(); 230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 231a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void Reset(); 232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void VerifyEqual(const ConsStringStats& that) const; 2333484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int leaves_; 2343484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int empty_leaves_; 2353484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int chars_; 2363484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int left_traversals_; 2373484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int right_traversals_; 238a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private: 239a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org DISALLOW_COPY_AND_ASSIGN(ConsStringStats); 240a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}; 241a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 242a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid ConsStringStats::Reset() { 244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org leaves_ = 0; 245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org empty_leaves_ = 0; 246a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org chars_ = 0; 247a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org left_traversals_ = 0; 248a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org right_traversals_ = 0; 249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 250a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 251a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid ConsStringStats::VerifyEqual(const ConsStringStats& that) const { 2533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(this->leaves_, that.leaves_); 2543484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(this->empty_leaves_, that.empty_leaves_); 2553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(this->chars_, that.chars_); 2563484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(this->left_traversals_, that.left_traversals_); 2573484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(this->right_traversals_, that.right_traversals_); 258a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 259a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 260a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 261a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass ConsStringGenerationData { 262a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public: 263a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static const int kNumberOfBuildingBlocks = 256; 2646f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org explicit ConsStringGenerationData(bool long_blocks); 265a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void Reset(); 266a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org inline Handle<String> block(int offset); 267a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org inline Handle<String> block(uint32_t offset); 268a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Input variables. 269a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org double early_termination_threshold_; 270a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org double leftness_; 271a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org double rightness_; 272a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org double empty_leaf_threshold_; 2733484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int max_leaves_; 274a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Cached data. 275a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> building_blocks_[kNumberOfBuildingBlocks]; 276a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org String* empty_string_; 277c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MyRandomNumberGenerator rng_; 278a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Stats. 279a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringStats stats_; 2803484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int early_terminations_; 281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private: 282a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org DISALLOW_COPY_AND_ASSIGN(ConsStringGenerationData); 283a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}; 284a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 285a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 2866f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.orgConsStringGenerationData::ConsStringGenerationData(bool long_blocks) { 287a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org rng_.init(); 288a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org InitializeBuildingBlocks( 2896f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_); 290528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org empty_string_ = CcTest::heap()->empty_string(); 291a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Reset(); 292a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 293a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 294a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 295a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHandle<String> ConsStringGenerationData::block(uint32_t offset) { 296a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return building_blocks_[offset % kNumberOfBuildingBlocks ]; 297a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 298a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 299a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 300a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHandle<String> ConsStringGenerationData::block(int offset) { 301a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_GE(offset, 0); 302a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return building_blocks_[offset % kNumberOfBuildingBlocks]; 303a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 304a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 306a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid ConsStringGenerationData::Reset() { 307a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org early_termination_threshold_ = 0.01; 308a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org leftness_ = 0.75; 309a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org rightness_ = 0.75; 310a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org empty_leaf_threshold_ = 0.02; 311a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org max_leaves_ = 1000; 312a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats_.Reset(); 313a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org early_terminations_ = 0; 314a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org rng_.init(); 315a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 316a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 317a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 318a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid AccumulateStats(ConsString* cons_string, ConsStringStats* stats) { 319a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int left_length = cons_string->first()->length(); 320a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int right_length = cons_string->second()->length(); 321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(cons_string->length() == left_length + right_length); 322a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Check left side. 323a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool left_is_cons = cons_string->first()->IsConsString(); 324a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (left_is_cons) { 325a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->left_traversals_++; 326a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStats(ConsString::cast(cons_string->first()), stats); 327a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 328a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_NE(left_length, 0); 329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->leaves_++; 330a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->chars_ += left_length; 331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Check right side. 333a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (cons_string->second()->IsConsString()) { 334a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->right_traversals_++; 335a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStats(ConsString::cast(cons_string->second()), stats); 336a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 337a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (right_length == 0) { 338a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->empty_leaves_++; 339a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(!left_is_cons); 340a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 341a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->leaves_++; 342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->chars_ += right_length; 3439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 3449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 3459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 3469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 347a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid AccumulateStats(Handle<String> cons_string, ConsStringStats* stats) { 34879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 349a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (cons_string->IsConsString()) { 350a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return AccumulateStats(ConsString::cast(*cons_string), stats); 351a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 352a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // This string got flattened by gc. 353a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->chars_ += cons_string->length(); 354a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 355a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 357a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid AccumulateStatsWithOperator( 358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsString* cons_string, ConsStringStats* stats) { 3593484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org ConsStringIteratorOp op(cons_string); 3603484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org String* string; 3613484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int offset; 3623484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org while (NULL != (string = op.Next(&offset))) { 363a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Accumulate stats. 3643484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(0, offset); 365a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->leaves_++; 366a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats->chars_ += string->length(); 367a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 368a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 369a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 370a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 371a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid VerifyConsString(Handle<String> root, ConsStringGenerationData* data) { 372a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Verify basic data. 373a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(root->IsConsString()); 3743484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(root->length(), data->stats_.chars_); 375a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Recursive verify. 376a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringStats stats; 377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStats(ConsString::cast(*root), &stats); 378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.VerifyEqual(data->stats_); 379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Iteratively verify. 380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.Reset(); 381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStatsWithOperator(ConsString::cast(*root), &stats); 382a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Don't see these. Must copy over. 383a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.empty_leaves_ = data->stats_.empty_leaves_; 384a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.left_traversals_ = data->stats_.left_traversals_; 385a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.right_traversals_ = data->stats_.right_traversals_; 386a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Adjust total leaves to compensate. 387a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.leaves_ += stats.empty_leaves_; 388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org stats.VerifyEqual(data->stats_); 389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 390a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 391a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 392a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic Handle<String> ConstructRandomString(ConsStringGenerationData* data, 393a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org unsigned max_recursion) { 394528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 395a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Compute termination characteristics. 396a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool terminate = false; 397a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool flat = data->rng_.next(data->empty_leaf_threshold_); 398a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool terminate_early = data->rng_.next(data->early_termination_threshold_); 399a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (terminate_early) data->early_terminations_++; 400a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // The obvious condition. 401a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org terminate |= max_recursion == 0; 402a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Flat cons string terminate by definition. 403a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org terminate |= flat; 404a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Cap for max leaves. 405a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org terminate |= data->stats_.leaves_ >= data->max_leaves_; 406a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Roll the dice. 407a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org terminate |= terminate_early; 408a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Compute termination characteristics for each side. 409a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool terminate_left = terminate || !data->rng_.next(data->leftness_); 410a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool terminate_right = terminate || !data->rng_.next(data->rightness_); 411a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Generate left string. 412a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> left; 413a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (terminate_left) { 414a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org left = data->block(data->rng_.next()); 415a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_++; 416a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += left->length(); 417a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 418a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.left_traversals_++; 419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Generate right string. 421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> right; 422a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (terminate_right) { 423a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org right = data->block(data->rng_.next()); 424a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_++; 425a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += right->length(); 426a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 427a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.right_traversals_++; 428a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 429a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Generate the necessary sub-nodes recursively. 430a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!terminate_right) { 431a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Need to balance generation fairly. 432a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!terminate_left && data->rng_.next(0.5)) { 433a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org left = ConstructRandomString(data, max_recursion - 1); 434a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 435a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org right = ConstructRandomString(data, max_recursion - 1); 436a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 437a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!terminate_left && left.is_null()) { 438a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org left = ConstructRandomString(data, max_recursion - 1); 439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 440a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build the cons string. 441255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> root = factory->NewConsString(left, right).ToHandleChecked(); 442a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(root->IsConsString() && !root->IsFlat()); 443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Special work needed for flat string. 444a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (flat) { 445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.empty_leaves_++; 4469e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(root); 447a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(root->IsConsString() && root->IsFlat()); 448a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 449a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return root; 450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 451a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 452a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 4539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<String> ConstructLeft( 454a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringGenerationData* data, 4559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int depth) { 456528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 4572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Handle<String> answer = factory->NewStringFromStaticChars(""); 458a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_++; 4599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int i = 0; i < depth; i++) { 460a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> block = data->block(i); 461255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> next = 462255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(answer, block).ToHandleChecked(); 463a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (next->IsConsString()) data->stats_.leaves_++; 464a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += block->length(); 465a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org answer = next; 4669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 467a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.left_traversals_ = data->stats_.leaves_ - 2; 4689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return answer; 4699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 4709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 4719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 4729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<String> ConstructRight( 473a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringGenerationData* data, 4749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int depth) { 475528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 4762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Handle<String> answer = factory->NewStringFromStaticChars(""); 477a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_++; 4789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int i = depth - 1; i >= 0; i--) { 479a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> block = data->block(i); 480255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> next = 481255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(block, answer).ToHandleChecked(); 482a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (next->IsConsString()) data->stats_.leaves_++; 483a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += block->length(); 484a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org answer = next; 4859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 486a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.right_traversals_ = data->stats_.leaves_ - 2; 4879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return answer; 4889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 4899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 4909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 4919a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<String> ConstructBalancedHelper( 492a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringGenerationData* data, 4939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int from, 4949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int to) { 495528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 4963a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CHECK(to > from); 4979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (to - from == 1) { 498a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(from)->length(); 499a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return data->block(from); 5009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 5019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (to - from == 2) { 502a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(from)->length(); 503a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(from+1)->length(); 504255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return factory->NewConsString(data->block(from), data->block(from+1)) 505255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 5069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 507870a0b67c822d289024711912e2512af01b66c3bager@chromium.org Handle<String> part1 = 508a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConstructBalancedHelper(data, from, from + ((to - from) / 2)); 509870a0b67c822d289024711912e2512af01b66c3bager@chromium.org Handle<String> part2 = 510a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConstructBalancedHelper(data, from + ((to - from) / 2), to); 511a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (part1->IsConsString()) data->stats_.left_traversals_++; 512a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (part2->IsConsString()) data->stats_.right_traversals_++; 513255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return factory->NewConsString(part1, part2).ToHandleChecked(); 5149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 5159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<String> ConstructBalanced( 518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringGenerationData* data, int depth = DEEP_DEPTH) { 519a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> string = ConstructBalancedHelper(data, 0, depth); 520a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_ = 521a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.left_traversals_ + data->stats_.right_traversals_ + 2; 522a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return string; 5239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 5249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 526a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic ConsStringIteratorOp cons_string_iterator_op_1; 527a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic ConsStringIteratorOp cons_string_iterator_op_2; 5289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic void Traverse(Handle<String> s1, Handle<String> s2) { 5309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int i = 0; 5314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org StringCharacterStream character_stream_1(*s1, &cons_string_iterator_op_1); 5324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org StringCharacterStream character_stream_2(*s2, &cons_string_iterator_op_2); 5334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org while (character_stream_1.HasMore()) { 534a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(character_stream_2.HasMore()); 5354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org uint16_t c = character_stream_1.GetNext(); 536a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_EQ(c, character_stream_2.GetNext()); 5379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com i++; 5389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 539a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(!character_stream_1.HasMore()); 540a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(!character_stream_2.HasMore()); 5419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com CHECK_EQ(s1->length(), i); 5429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com CHECK_EQ(s2->length(), i); 5439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 5449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic void TraverseFirst(Handle<String> s1, Handle<String> s2, int chars) { 5479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int i = 0; 5484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org StringCharacterStream character_stream_1(*s1, &cons_string_iterator_op_1); 5494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org StringCharacterStream character_stream_2(*s2, &cons_string_iterator_op_2); 5504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org while (character_stream_1.HasMore() && i < chars) { 551a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(character_stream_2.HasMore()); 5524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org uint16_t c = character_stream_1.GetNext(); 553a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_EQ(c, character_stream_2.GetNext()); 5549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com i++; 5559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 556bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org s1->Get(s1->length() - 1); 557bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org s2->Get(s2->length() - 1); 5589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 5599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 5619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(Traverse) { 5629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("TestTraverse\n"); 563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 5656f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ConsStringGenerationData data(false); 566a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> flat = ConstructBalanced(&data); 5679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(flat); 568a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); 569a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> right_asymmetric = ConstructRight(&data, DEEP_DEPTH); 570a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> symmetric = ConstructBalanced(&data); 5719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("1\n"); 5729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, symmetric); 5739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("2\n"); 5749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, left_asymmetric); 5759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("3\n"); 5769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, right_asymmetric); 5779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("4\n"); 5789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Handle<String> left_deep_asymmetric = 579a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConstructLeft(&data, SUPER_DEEP_DEPTH); 5809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Handle<String> right_deep_asymmetric = 581a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConstructRight(&data, SUPER_DEEP_DEPTH); 5829a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("5\n"); 5839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com TraverseFirst(left_asymmetric, left_deep_asymmetric, 1050); 5849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("6\n"); 5859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536); 5869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("7\n"); 5879e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(left_asymmetric); 5889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("10\n"); 5899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, left_asymmetric); 5909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("11\n"); 5919e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(right_asymmetric); 5929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("12\n"); 5939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, right_asymmetric); 5949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("14\n"); 5959e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(symmetric); 5969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("15\n"); 5979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Traverse(flat, symmetric); 5989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("16\n"); 5999e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(left_deep_asymmetric); 6009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com printf("18\n"); 6019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 6029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 6039a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 604a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic void VerifyCharacterStream( 605a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org String* flat_string, String* cons_string) { 606a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Do not want to test ConString traversal on flat string. 607a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(flat_string->IsFlat() && !flat_string->IsConsString()); 608a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(cons_string->IsConsString()); 609a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // TODO(dcarney) Test stream reset as well. 610a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int length = flat_string->length(); 611a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Iterate start search in multiple places in the string. 612a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int outer_iterations = length > 20 ? 20 : length; 613a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int j = 0; j <= outer_iterations; j++) { 614a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int offset = length * j / outer_iterations; 615a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (offset < 0) offset = 0; 616a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Want to test the offset == length case. 617a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (offset > length) offset = length; 618a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org StringCharacterStream flat_stream( 6193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org flat_string, &cons_string_iterator_op_1, offset); 620a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org StringCharacterStream cons_stream( 6213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org cons_string, &cons_string_iterator_op_2, offset); 622a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = offset; i < length; i++) { 623a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org uint16_t c = flat_string->Get(i); 624a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(flat_stream.HasMore()); 625a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(cons_stream.HasMore()); 626a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_EQ(c, flat_stream.GetNext()); 627a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK_EQ(c, cons_stream.GetNext()); 628a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 629a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(!flat_stream.HasMore()); 630a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CHECK(!cons_stream.HasMore()); 631a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 632a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 633a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 634a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 635a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic inline void PrintStats(const ConsStringGenerationData& data) { 636a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#ifdef DEBUG 637a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgprintf( 638a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "%s: [%d], %s: [%d], %s: [%d], %s: [%d], %s: [%d], %s: [%d]\n", 639a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "leaves", data.stats_.leaves_, 640a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "empty", data.stats_.empty_leaves_, 641a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "chars", data.stats_.chars_, 642a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "lefts", data.stats_.left_traversals_, 643a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "rights", data.stats_.right_traversals_, 644a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org "early_terminations", data.early_terminations_); 645a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#endif 646a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 647a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 648a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 649a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate<typename BuildString> 650a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid TestStringCharacterStream(BuildString build, int test_cases) { 651e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 652528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 653a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HandleScope outer_scope(isolate); 6546f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ConsStringGenerationData data(true); 655a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < test_cases; i++) { 656a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org printf("%d\n", i); 657a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HandleScope inner_scope(isolate); 6585697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org AlwaysAllocateScope always_allocate(isolate); 659a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build flat version of cons string. 660a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> flat_string = build(i, &data); 661a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringStats flat_string_stats; 662a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStats(flat_string, &flat_string_stats); 663a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Flatten string. 6649e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(flat_string); 665a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build unflattened version of cons string to test. 666a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> cons_string = build(i, &data); 667a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsStringStats cons_string_stats; 668a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org AccumulateStats(cons_string, &cons_string_stats); 66979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 670a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org PrintStats(data); 671a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Full verify of cons string. 672a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org cons_string_stats.VerifyEqual(flat_string_stats); 673a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org cons_string_stats.VerifyEqual(data.stats_); 674a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org VerifyConsString(cons_string, &data); 675a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org String* flat_string_ptr = 676a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org flat_string->IsConsString() ? 677a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ConsString::cast(*flat_string)->first() : 678a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org *flat_string; 679a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org VerifyCharacterStream(flat_string_ptr, *cons_string); 680a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 681a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 683a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 684a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic const int kCharacterStreamNonRandomCases = 8; 685a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 686a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 687a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic Handle<String> BuildEdgeCaseConsString( 688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int test_case, ConsStringGenerationData* data) { 689528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->Reset(); 691a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org switch (test_case) { 692a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 0: 693a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructBalanced(data, 71); 694a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 1: 695a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructLeft(data, 71); 696a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 2: 697a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructRight(data, 71); 698a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 3: 699a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructLeft(data, 10); 700a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 4: 701a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructRight(data, 10); 702a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 5: 703a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // 2 element balanced tree. 704a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(0)->length(); 705a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(1)->length(); 706a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_ += 2; 707255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return factory->NewConsString(data->block(0), data->block(1)) 708255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 709a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 6: 710a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Simple flattened tree. 711a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(0)->length(); 712a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(1)->length(); 713a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_ += 2; 714a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.empty_leaves_ += 1; 715a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org { 716a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> string = 717255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(data->block(0), data->block(1)) 718255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 7199e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(string); 720a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return string; 721a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 722a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 7: 723a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Left node flattened. 724a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(0)->length(); 725a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(1)->length(); 726a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(2)->length(); 727a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_ += 3; 728a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.empty_leaves_ += 1; 729a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.left_traversals_ += 1; 730a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org { 731a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> left = 732255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(data->block(0), data->block(1)) 733255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 7349e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(left); 735255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return factory->NewConsString(left, data->block(2)).ToHandleChecked(); 736a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 737a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 8: 738a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Left node and right node flattened. 739a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(0)->length(); 740a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(1)->length(); 741a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(2)->length(); 742a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.chars_ += data->block(3)->length(); 743a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.leaves_ += 4; 744a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.empty_leaves_ += 2; 745a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.left_traversals_ += 1; 746a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->stats_.right_traversals_ += 1; 747a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org { 748a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> left = 749255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(data->block(0), data->block(1)) 750255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 7519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(left); 752a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> right = 753255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(data->block(2), data->block(2)) 754255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org .ToHandleChecked(); 7559e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(right); 756255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return factory->NewConsString(left, right).ToHandleChecked(); 757a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 758a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 759a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 760a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return Handle<String>(); 761a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 762a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 763a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 764a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgTEST(StringCharacterStreamEdgeCases) { 765a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org printf("TestStringCharacterStreamEdgeCases\n"); 766a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org TestStringCharacterStream( 767a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BuildEdgeCaseConsString, kCharacterStreamNonRandomCases); 768a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 769a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 770a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 771a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic const int kBalances = 3; 772a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic const int kTreeLengths = 4; 773a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic const int kEmptyLeaves = 4; 774a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic const int kUniqueRandomParameters = 775a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org kBalances*kTreeLengths*kEmptyLeaves; 776a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 777a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 778a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic void InitializeGenerationData( 779a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int test_case, ConsStringGenerationData* data) { 780a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Clear the settings and reinit the rng. 781a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->Reset(); 782a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Spin up the rng to a known location that is unique per test. 783a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static const int kPerTestJump = 501; 784a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int j = 0; j < test_case*kPerTestJump; j++) { 785a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->rng_.next(); 786a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 787a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Choose balanced, left or right heavy trees. 788a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org switch (test_case % kBalances) { 789a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 0: 790a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Nothing to do. Already balanced. 791a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 792a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 1: 793a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Left balanced. 794a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->leftness_ = 0.90; 795a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->rightness_ = 0.15; 796a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 797a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 2: 798a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Right balanced. 799a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->leftness_ = 0.15; 800a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->rightness_ = 0.90; 801a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 802a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org default: 803a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 804a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 805a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 806a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Must remove the influence of the above decision. 807a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org test_case /= kBalances; 808a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Choose tree length. 809a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org switch (test_case % kTreeLengths) { 810a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 0: 811a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->max_leaves_ = 16; 812a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->early_termination_threshold_ = 0.2; 813a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 814a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 1: 815a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->max_leaves_ = 50; 816a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->early_termination_threshold_ = 0.05; 817a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 818a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 2: 819a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->max_leaves_ = 500; 820a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->early_termination_threshold_ = 0.03; 821a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 822a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case 3: 823a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->max_leaves_ = 5000; 824a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->early_termination_threshold_ = 0.001; 825a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 826a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org default: 827a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 828a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 829a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 830a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Must remove the influence of the above decision. 831a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org test_case /= kTreeLengths; 832a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Choose how much we allow empty nodes, including not at all. 833a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org data->empty_leaf_threshold_ = 834a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 0.03 * static_cast<double>(test_case % kEmptyLeaves); 835a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 836a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 837a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 838a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic Handle<String> BuildRandomConsString( 839a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int test_case, ConsStringGenerationData* data) { 840a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org InitializeGenerationData(test_case, data); 841a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return ConstructRandomString(data, 200); 842a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 843a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 845a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgTEST(StringCharacterStreamRandom) { 846a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org printf("StringCharacterStreamRandom\n"); 847a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); 848a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 849a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 850a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 8512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgstatic const int kDeepOneByteDepth = 100000; 8529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 8539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 8542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgTEST(DeepOneByte) { 855e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 856528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 857e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 8589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 8592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org char* foo = NewArray<char>(kDeepOneByteDepth); 8602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for (int i = 0; i < kDeepOneByteDepth; i++) { 8619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com foo[i] = "foo "[i % 4]; 8629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 8632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Handle<String> string = 8642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org factory->NewStringFromOneByte(OneByteVector(foo, kDeepOneByteDepth)) 8652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org .ToHandleChecked(); 8662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Handle<String> foo_string = factory->NewStringFromStaticChars("foo"); 8672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for (int i = 0; i < kDeepOneByteDepth; i += 10) { 868255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org string = factory->NewConsString(string, foo_string).ToHandleChecked(); 8699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 870255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> flat_string = 871255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(string, foo_string).ToHandleChecked(); 8729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(flat_string); 8739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 8749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int i = 0; i < 500; i++) { 8752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org TraverseFirst(flat_string, string, kDeepOneByteDepth); 8769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 877bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org DeleteArray<char>(foo); 8789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com} 8799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 8809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 8819258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgTEST(Utf8Conversion) { 8829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Smoke test for converting strings to utf-8. 883e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 884e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope handle_scope(CcTest::isolate()); 8852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // A simple one-byte string 8862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const char* one_byte_string = "abcdef12345"; 8872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org int len = v8::String::NewFromUtf8(CcTest::isolate(), one_byte_string, 888f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::String::kNormalString, 8892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org StrLength(one_byte_string))->Utf8Length(); 8902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org CHECK_EQ(StrLength(one_byte_string), len); 8912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // A mixed one-byte and two-byte string 8929258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // U+02E4 -> CB A4 8939258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // U+0064 -> 64 8949258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // U+12E4 -> E1 8B A4 8959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // U+0030 -> 30 8969258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // U+3045 -> E3 81 85 8979258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org const uint16_t mixed_string[] = {0x02E4, 0x0064, 0x12E4, 0x0030, 0x3045}; 8989258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // The characters we expect to be output 8999258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org const unsigned char as_utf8[11] = {0xCB, 0xA4, 0x64, 0xE1, 0x8B, 0xA4, 0x30, 9009258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 0xE3, 0x81, 0x85, 0x00}; 9019258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // The number of bytes expected to be written for each length 9029258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org const int lengths[12] = {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11}; 903357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org const int char_lengths[12] = {0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5}; 904f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> mixed = v8::String::NewFromTwoByte( 905f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CcTest::isolate(), mixed_string, v8::String::kNormalString, 5); 9069258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org CHECK_EQ(10, mixed->Utf8Length()); 9079258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Try encoding the string with all capacities 9089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org char buffer[11]; 9099258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org const char kNoChar = static_cast<char>(-1); 9109258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org for (int i = 0; i <= 11; i++) { 9119258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Clear the buffer before reusing it 9129258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org for (int j = 0; j < 11; j++) 9139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org buffer[j] = kNoChar; 914357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org int chars_written; 915357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org int written = mixed->WriteUtf8(buffer, i, &chars_written); 9169258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org CHECK_EQ(lengths[i], written); 917357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org CHECK_EQ(char_lengths[i], chars_written); 9189258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Check that the contents are correct 9199258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org for (int j = 0; j < lengths[i]; j++) 9209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); 9219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Check that the rest of the buffer hasn't been touched 9229258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org for (int j = lengths[i]; j < 11; j++) 9239258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org CHECK_EQ(kNoChar, buffer[j]); 9249258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 9259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 926acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org 927acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org 928ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgTEST(ExternalShortStringAdd) { 929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LocalContext context; 930e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope handle_scope(CcTest::isolate()); 931acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org 932ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Make sure we cover all always-flat lengths and at least one above. 933ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org static const int kMaxLength = 20; 9342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org CHECK_GT(kMaxLength, i::ConsString::kMinLength); 935ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 936ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate two JavaScript arrays for holding short strings. 9372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::Handle<v8::Array> one_byte_external_strings = 9389f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org v8::Array::New(CcTest::isolate(), kMaxLength + 1); 9392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::Handle<v8::Array> non_one_byte_external_strings = 9409f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org v8::Array::New(CcTest::isolate(), kMaxLength + 1); 941ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 9422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Generate short one-byte and two-byte external strings. 943ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 0; i <= kMaxLength; i++) { 9442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org char* one_byte = NewArray<char>(i + 1); 945ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int j = 0; j < i; j++) { 9462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org one_byte[j] = 'a'; 947ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 948ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Terminating '\0' is left out on purpose. It is not required for external 949ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // string data. 9502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org OneByteResource* one_byte_resource = new OneByteResource(one_byte, i); 9512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::Local<v8::String> one_byte_external_string = 9522c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::String::NewExternal(CcTest::isolate(), one_byte_resource); 953ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 9542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), 9552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org one_byte_external_string); 9562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org uc16* non_one_byte = NewArray<uc16>(i + 1); 957ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int j = 0; j < i; j++) { 9582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org non_one_byte[j] = 0x1234; 959ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 960ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Terminating '\0' is left out on purpose. It is not required for external 961ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // string data. 9622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Resource* resource = new Resource(non_one_byte, i); 9632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::Local<v8::String> non_one_byte_external_string = 9642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::String::NewExternal(CcTest::isolate(), resource); 9652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org non_one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), 9662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org non_one_byte_external_string); 967ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 968acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org 969ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Add the arrays with the short external strings in the global object. 970528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Handle<v8::Object> global = context->Global(); 9712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org global->Set(v8_str("external_one_byte"), one_byte_external_strings); 9722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org global->Set(v8_str("external_non_one_byte"), non_one_byte_external_strings); 9730f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org global->Set(v8_str("max_length"), 9740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org v8::Integer::New(CcTest::isolate(), kMaxLength)); 975ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 9762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Add short external one-byte and two-byte strings checking the result. 977ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org static const char* source = 9782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "function test() {" 9792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " var one_byte_chars = 'aaaaaaaaaaaaaaaaaaaa';" 9802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " var non_one_byte_chars = " 9812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "'\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1" 9822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\" 9832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "u1234';" // NOLINT 9842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (one_byte_chars.length != max_length) return 1;" 9852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (non_one_byte_chars.length != max_length) return 2;" 9862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " var one_byte = Array(max_length + 1);" 9872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " var non_one_byte = Array(max_length + 1);" 9882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " for (var i = 0; i <= max_length; i++) {" 9892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " one_byte[i] = one_byte_chars.substring(0, i);" 9902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " non_one_byte[i] = non_one_byte_chars.substring(0, i);" 9912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " };" 9922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " for (var i = 0; i <= max_length; i++) {" 9932c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (one_byte[i] != external_one_byte[i]) return 3;" 9942c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (non_one_byte[i] != external_non_one_byte[i]) return 4;" 9952c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " for (var j = 0; j < i; j++) {" 9962c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (external_one_byte[i] !=" 9972c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " (external_one_byte[j] + external_one_byte[i - j])) return " 9982c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "5;" 9992c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (external_non_one_byte[i] !=" 10002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " (external_non_one_byte[j] + external_non_one_byte[i - " 10012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "j])) return 6;" 10022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (non_one_byte[i] != (non_one_byte[j] + non_one_byte[i - " 10032c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "j])) return 7;" 10042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (one_byte[i] != (one_byte[j] + one_byte[i - j])) return 8;" 10052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (one_byte[i] != (external_one_byte[j] + one_byte[i - j])) " 10062c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "return 9;" 10072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (one_byte[i] != (one_byte[j] + external_one_byte[i - j])) " 10082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "return 10;" 10092c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (non_one_byte[i] !=" 10102c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " (external_non_one_byte[j] + non_one_byte[i - j])) return " 10112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "11;" 10122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " if (non_one_byte[i] !=" 10132c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " (non_one_byte[j] + external_non_one_byte[i - j])) return " 10142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "12;" 10152c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " }" 10162c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " }" 10172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org " return 0;" 10182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "};" 10192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "test()"; 10204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK_EQ(0, CompileRun(source)->Int32Value()); 1021ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 10221af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 10231af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 1024c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgTEST(JSONStringifySliceMadeExternal) { 1025c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CcTest::InitializeVM(); 1026c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Create a sliced string from a one-byte string. The latter is turned 1027c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // into a two-byte external string. Check that JSON.stringify works. 1028c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org v8::HandleScope handle_scope(CcTest::isolate()); 1029c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org v8::Handle<v8::String> underlying = 1030c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CompileRun("var underlying = 'abcdefghijklmnopqrstuvwxyz';" 1031c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org "underlying")->ToString(); 1032c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org v8::Handle<v8::String> slice = 1033c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CompileRun("var slice = underlying.slice(1);" 1034c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org "slice")->ToString(); 1035c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString()); 1036c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString()); 1037c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1038c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int length = underlying->Length(); 10396f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org uc16* two_byte = NewArray<uc16>(length + 1); 1040c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org underlying->Write(two_byte); 10416f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Resource* resource = new Resource(two_byte, length); 1042c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK(underlying->MakeExternal(resource)); 1043c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString()); 1044c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalTwoByteString()); 1045c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1046c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CHECK_EQ("\"bcdefghijklmnopqrstuvwxyz\"", 1047c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org *v8::String::Utf8Value(CompileRun("JSON.stringify(slice)"))); 1048c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 1049c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1050c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 10511af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgTEST(CachedHashOverflow) { 1052528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CcTest::InitializeVM(); 10531af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // We incorrectly allowed strings to be tagged as array indices even if their 10541af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // values didn't fit in the hash field. 10551af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // See http://code.google.com/p/v8/issues/detail?id=728 1056528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 10571af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 1058e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope handle_scope(CcTest::isolate()); 10591af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // Lines must be executed sequentially. Combining them into one script 10601af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // makes the bug go away. 10611af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const char* lines[] = { 10621af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "var x = [];", 10631af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "x[4] = 42;", 10641af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "var s = \"1073741828\";", 10651af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "x[s];", 10661af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "x[s] = 37;", 10671af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "x[4];", 10681af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org "x[s];", 10691af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org NULL 10701af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org }; 10711af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 107209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Smi> fortytwo(Smi::FromInt(42), isolate); 107309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Smi> thirtyseven(Smi::FromInt(37), isolate); 107409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> results[] = { isolate->factory()->undefined_value(), 107509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org fortytwo, 107609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate->factory()->undefined_value(), 107709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate->factory()->undefined_value(), 107809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org thirtyseven, 107909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org fortytwo, 108009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org thirtyseven // Bug yielded 42 here. 10811af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org }; 10821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 10831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const char* line; 10841af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org for (int i = 0; (line = lines[i]); i++) { 10851af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org printf("%s\n", line); 1086f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Local<v8::Value> result = v8::Script::Compile( 1087f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::String::NewFromUtf8(CcTest::isolate(), line))->Run(); 10881af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org CHECK_EQ(results[i]->IsUndefined(), result->IsUndefined()); 10891af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org CHECK_EQ(results[i]->IsNumber(), result->IsNumber()); 10901af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (result->IsNumber()) { 10913484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org CHECK_EQ(Object::ToSmi(isolate, results[i]).ToHandleChecked()->value(), 10921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org result->ToInt32()->Value()); 10931af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 10941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 10951af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 10964668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 10974668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 10984668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.orgTEST(SliceFromCons) { 10994668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org FLAG_string_slices = true; 1100e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1101528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 1102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 11034668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> string = 11042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org factory->NewStringFromStaticChars("parentparentparent"); 1105255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> parent = 1106255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org factory->NewConsString(string, string).ToHandleChecked(); 11074668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(parent->IsConsString()); 11084668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(!parent->IsFlat()); 1109d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<String> slice = factory->NewSubString(parent, 1, 25); 11104668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // After slicing, the original string becomes a flat cons. 11114668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(parent->IsFlat()); 11124668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(slice->IsSlicedString()); 11134668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK_EQ(SlicedString::cast(*slice)->parent(), 11147bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org // Parent could have been short-circuited. 11157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org parent->IsConsString() ? ConsString::cast(*parent)->first() 11167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org : *parent); 11174668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(SlicedString::cast(*slice)->parent()->IsSeqString()); 11184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(slice->IsFlat()); 11194668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org} 11204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11214668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgclass OneByteVectorResource : public v8::String::ExternalOneByteStringResource { 1123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 11242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org explicit OneByteVectorResource(i::Vector<const char> vector) 1125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : data_(vector) {} 11262c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org virtual ~OneByteVectorResource() {} 1127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual size_t length() const { return data_.length(); } 1128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual const char* data() const { return data_.start(); } 1129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 1130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com i::Vector<const char> data_; 1131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 1132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comTEST(SliceFromExternal) { 1135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FLAG_string_slices = true; 1136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 1138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 11392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org OneByteVectorResource resource( 1140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); 1141255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<String> string = 11422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org factory->NewExternalStringFromOneByte(&resource).ToHandleChecked(); 1143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(string->IsExternalString()); 1144d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<String> slice = factory->NewSubString(string, 1, 25); 1145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(slice->IsSlicedString()); 1146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(string->IsExternalString()); 1147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); 1148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); 1149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(slice->IsFlat()); 1150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 11534668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.orgTEST(TrivialSlice) { 11544668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // This tests whether a slice that contains the entire parent string 11554668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // actually creates a new string (it should not). 11564668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org FLAG_string_slices = true; 1157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1158528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Factory* factory = CcTest::i_isolate()->factory(); 1159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 11604668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org v8::Local<v8::Value> result; 11614668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> string; 11624668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; 11634668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const char* check = "str.slice(0,26)"; 11644668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const char* crosscheck = "str.slice(1,25)"; 11654668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11664668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CompileRun(init); 11674668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11684668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org result = CompileRun(check); 11694668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(result->IsString()); 11704668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 11714668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(!string->IsSlicedString()); 11724668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1173d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org string = factory->NewSubString(string, 0, 26); 11744668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(!string->IsSlicedString()); 11754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org result = CompileRun(crosscheck); 11764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(result->IsString()); 11774668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 11784668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK(string->IsSlicedString()); 1179afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org CHECK_EQ("bcdefghijklmnopqrstuvwxy", string->ToCString().get()); 11804668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org} 11811805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 11821805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 11831805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgTEST(SliceFromSlice) { 11841805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // This tests whether a slice that contains the entire parent string 11851805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // actually creates a new string (it should not). 11861805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org FLAG_string_slices = true; 1187e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1188e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 11891805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org v8::Local<v8::Value> result; 11901805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Handle<String> string; 11911805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; 11921805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const char* slice = "var slice = str.slice(1,-1); slice"; 11931805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const char* slice_from_slice = "slice.slice(1,-1);"; 11941805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 11951805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CompileRun(init); 11961805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org result = CompileRun(slice); 11971805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(result->IsString()); 11981805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 11991805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(string->IsSlicedString()); 12001805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); 1201afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org CHECK_EQ("bcdefghijklmnopqrstuvwxy", string->ToCString().get()); 12021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 12031805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org result = CompileRun(slice_from_slice); 12041805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(result->IsString()); 12051805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 12061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(string->IsSlicedString()); 12071805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); 1208afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org CHECK_EQ("cdefghijklmnopqrstuvwx", string->ToCString().get()); 12091805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 12107d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 12117d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 1212d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.orgUNINITIALIZED_TEST(OneByteArrayJoin) { 1213d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org v8::Isolate::CreateParams create_params; 12147d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Set heap limits. 1215d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org create_params.constraints.set_max_semi_space_size(1); 1216d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org create_params.constraints.set_max_old_space_size(4); 1217d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org v8::Isolate* isolate = v8::Isolate::New(create_params); 1218d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org isolate->Enter(); 1219d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org 1220d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org { 1221d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org // String s is made of 2^17 = 131072 'c' characters and a is an array 1222d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org // starting with 'bad', followed by 2^14 times the string s. That means the 1223d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org // total length of the concatenated strings is 2^31 + 3. So on 32bit systems 1224d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org // summing the lengths of the strings (as Smis) overflows and wraps. 1225d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org LocalContext context(isolate); 1226d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org v8::HandleScope scope(isolate); 1227d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org v8::TryCatch try_catch; 1228d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CHECK(CompileRun( 1229d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "var two_14 = Math.pow(2, 14);" 1230d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "var two_17 = Math.pow(2, 17);" 1231d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "var s = Array(two_17 + 1).join('c');" 1232d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "var a = ['bad'];" 1233d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "for (var i = 1; i <= two_14; i++) a.push(s);" 1234d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org "a.join(" 1235d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org ");").IsEmpty()); 1236d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CHECK(try_catch.HasCaught()); 1237d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org } 1238d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org isolate->Exit(); 1239d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org isolate->Dispose(); 12407d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org} 1241ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1242ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1243ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comstatic void CheckException(const char* source) { 1244ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // An empty handle is returned upon exception. 1245ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CHECK(CompileRun(source).IsEmpty()); 1246ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 1247ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1248ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1249ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comTEST(RobustSubStringStub) { 1250ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // This tests whether the SubStringStub can handle unsafe arguments. 1251ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // If not recognized, those unsafe arguments lead to out-of-bounds reads. 1252ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com FLAG_allow_natives_syntax = true; 1253e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1254e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 1255ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com v8::Local<v8::Value> result; 1256ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Handle<String> string; 1257ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CompileRun("var short = 'abcdef';"); 1258ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1259ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Invalid indices. 1260ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, 0, 10000);"); 1261ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, -1234, 5);"); 1262ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, 5, 2);"); 1263ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Special HeapNumbers. 1264ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, 1, Infinity);"); 1265ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, NaN, 5);"); 1266ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // String arguments. 1267ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(short, '2', '5');"); 1268ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Ordinary HeapNumbers can be handled (in runtime). 1269ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com result = CompileRun("%_SubString(short, Math.sqrt(4), 5.1);"); 1270ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 1271afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org CHECK_EQ("cde", string->ToCString().get()); 1272ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1273ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CompileRun("var long = 'abcdefghijklmnopqrstuvwxyz';"); 1274ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Invalid indices. 1275ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, 0, 10000);"); 1276ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, -1234, 17);"); 1277ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, 17, 2);"); 1278ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Special HeapNumbers. 1279ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, 1, Infinity);"); 1280ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, NaN, 17);"); 1281ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // String arguments. 1282ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(long, '2', '17');"); 1283ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Ordinary HeapNumbers within bounds can be handled (in runtime). 1284ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com result = CompileRun("%_SubString(long, Math.sqrt(4), 17.1);"); 1285ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 1286afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org CHECK_EQ("cdefghijklmnopq", string->ToCString().get()); 1287ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1288ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Test that out-of-bounds substring of a slice fails when the indices 1289ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // would have been valid for the underlying string. 1290ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CompileRun("var slice = long.slice(1, 15);"); 1291ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CheckException("%_SubString(slice, 0, 17);"); 1292ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 1293400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 1294400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 1295355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgTEST(StringReplaceAtomTwoByteResult) { 1296e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 1297e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 1298355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org LocalContext context; 1299355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org v8::Local<v8::Value> result = CompileRun( 13002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "var subject = 'one_byte~only~string~'; " 1301355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org "var replace = '\x80'; " 1302355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org "subject.replace(/~/g, replace); "); 1303355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org CHECK(result->IsString()); 1304355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result)); 1305355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org CHECK(string->IsSeqTwoByteString()); 1306355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 13072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::Local<v8::String> expected = v8_str("one_byte\x80only\x80string\x80"); 1308355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org CHECK(expected->Equals(result)); 1309355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 1310412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org 1311412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org 1312412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.orgTEST(IsAscii) { 1313412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org CHECK(String::IsAscii(static_cast<char*>(NULL), 0)); 131459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org CHECK(String::IsOneByte(static_cast<uc16*>(NULL), 0)); 1315412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org} 131646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 131746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 13186bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 13196bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.orgtemplate<typename Op, bool return_first> 13206bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.orgstatic uint16_t ConvertLatin1(uint16_t c) { 13216bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org uint32_t result[Op::kMaxWidth]; 132246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org int chars; 13236bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org chars = Op::Convert(c, 0, result, NULL); 13246bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (chars == 0) return 0; 13256bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CHECK_LE(chars, static_cast<int>(sizeof(result))); 13266bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (!return_first && chars > 1) { 13276bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return 0; 132846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 13296bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return result[0]; 133046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 133146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 133246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 13336bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.orgstatic void CheckCanonicalEquivalence(uint16_t c, uint16_t test) { 13346bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org uint16_t expect = ConvertLatin1<unibrow::Ecma262UnCanonicalize, true>(c); 13356bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (expect > unibrow::Latin1::kMaxChar) expect = 0; 13366bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CHECK_EQ(expect, test); 13376bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org} 13386bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 13396bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 13406bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.orgTEST(Latin1IgnoreCase) { 13416bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org using namespace unibrow; 13426bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org for (uint16_t c = Latin1::kMaxChar + 1; c != 0; c++) { 13436bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org uint16_t lower = ConvertLatin1<ToLowercase, false>(c); 13446bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org uint16_t upper = ConvertLatin1<ToUppercase, false>(c); 13456bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org uint16_t test = Latin1::ConvertNonLatin1ToLatin1(c); 13466bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // Filter out all character whose upper is not their lower or vice versa. 13476bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (lower == 0 && upper == 0) { 13486bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CheckCanonicalEquivalence(c, test); 13496bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org continue; 13506bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13516bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (lower > Latin1::kMaxChar && upper > Latin1::kMaxChar) { 13526bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CheckCanonicalEquivalence(c, test); 13536bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org continue; 13546bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13556bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (lower == 0 && upper != 0) { 13566bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org lower = ConvertLatin1<ToLowercase, false>(upper); 13576bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13586bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (upper == 0 && lower != c) { 13596bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org upper = ConvertLatin1<ToUppercase, false>(lower); 13606bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13616bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (lower > Latin1::kMaxChar && upper > Latin1::kMaxChar) { 13626bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CheckCanonicalEquivalence(c, test); 13636bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org continue; 13646bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13656bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (upper != c && lower != c) { 13666bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CheckCanonicalEquivalence(c, test); 13676bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org continue; 13686bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 13696bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org CHECK_EQ(Min(upper, lower), test); 137046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 137146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 1372b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1373b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1374b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgclass DummyResource: public v8::String::ExternalStringResource { 1375b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org public: 1376b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org virtual const uint16_t* data() const { return NULL; } 1377b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org virtual size_t length() const { return 1 << 30; } 1378b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org}; 1379b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1380b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1381b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgclass DummyOneByteResource: public v8::String::ExternalOneByteStringResource { 1382b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org public: 1383b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org virtual const char* data() const { return NULL; } 1384b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org virtual size_t length() const { return 1 << 30; } 1385b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org}; 1386b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1387b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1388b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgTEST(InvalidExternalString) { 1389b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CcTest::InitializeVM(); 1390b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org LocalContext context; 1391b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 1392b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org { HandleScope scope(isolate); 1393b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org DummyOneByteResource r; 13942c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org CHECK(isolate->factory()->NewExternalStringFromOneByte(&r).is_null()); 1395b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CHECK(isolate->has_pending_exception()); 1396b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org isolate->clear_pending_exception(); 1397b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } 1398b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1399b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org { HandleScope scope(isolate); 1400b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org DummyResource r; 1401b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CHECK(isolate->factory()->NewExternalStringFromTwoByte(&r).is_null()); 1402b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CHECK(isolate->has_pending_exception()); 1403b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org isolate->clear_pending_exception(); 1404b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } 1405b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org} 1406b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1407b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1408b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org#define INVALID_STRING_TEST(FUN, TYPE) \ 1409b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org TEST(StringOOM##FUN) { \ 1410b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CcTest::InitializeVM(); \ 1411b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org LocalContext context; \ 1412b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); \ 1413b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org STATIC_ASSERT(String::kMaxLength < kMaxInt); \ 1414b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org static const int invalid = String::kMaxLength + 1; \ 1415b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org HandleScope scope(isolate); \ 1416b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Vector<TYPE> dummy = Vector<TYPE>::New(invalid); \ 1417b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CHECK(isolate->factory()->FUN(Vector<const TYPE>::cast(dummy)).is_null()); \ 1418b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org memset(dummy.start(), 0x20, dummy.length() * sizeof(TYPE)); \ 1419b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org CHECK(isolate->has_pending_exception()); \ 1420b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org isolate->clear_pending_exception(); \ 1421b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org dummy.Dispose(); \ 1422b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } 1423b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1424b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgINVALID_STRING_TEST(NewStringFromAscii, char) 1425b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgINVALID_STRING_TEST(NewStringFromUtf8, char) 1426b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgINVALID_STRING_TEST(NewStringFromOneByte, uint8_t) 1427b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 1428b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org#undef INVALID_STRING_TEST 1429