OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 | 2 |
3 // Check that we can traverse very deep stacks of ConsStrings using | 3 // Check that we can traverse very deep stacks of ConsStrings using |
4 // StringInputBuffer. Check that Get(int) works on very deep stacks | 4 // StringInputBuffer. Check that Get(int) works on very deep stacks |
5 // of ConsStrings. These operations may not be very fast, but they | 5 // of ConsStrings. These operations may not be very fast, but they |
6 // should be possible without getting errors due to too deep recursion. | 6 // should be possible without getting errors due to too deep recursion. |
7 | 7 |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include "v8.h" | 10 #include "v8.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 } | 55 } |
56 switch (gen() % 4) { | 56 switch (gen() % 4) { |
57 case 0: { | 57 case 0: { |
58 uc16 buf[2000]; | 58 uc16 buf[2000]; |
59 for (int j = 0; j < len; j++) { | 59 for (int j = 0; j < len; j++) { |
60 buf[j] = gen() % 65536; | 60 buf[j] = gen() % 65536; |
61 } | 61 } |
62 building_blocks[i] = | 62 building_blocks[i] = |
63 Factory::NewStringFromTwoByte(Vector<const uc16>(buf, len)); | 63 Factory::NewStringFromTwoByte(Vector<const uc16>(buf, len)); |
64 for (int j = 0; j < len; j++) { | 64 for (int j = 0; j < len; j++) { |
65 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 65 StringShape shape(*building_blocks[i]); |
| 66 CHECK_EQ(buf[j], building_blocks[i]->Get(shape, j)); |
66 } | 67 } |
67 break; | 68 break; |
68 } | 69 } |
69 case 1: { | 70 case 1: { |
70 char buf[2000]; | 71 char buf[2000]; |
71 for (int j = 0; j < len; j++) { | 72 for (int j = 0; j < len; j++) { |
72 buf[j] = gen() % 128; | 73 buf[j] = gen() % 128; |
73 } | 74 } |
74 building_blocks[i] = | 75 building_blocks[i] = |
75 Factory::NewStringFromAscii(Vector<const char>(buf, len)); | 76 Factory::NewStringFromAscii(Vector<const char>(buf, len)); |
76 for (int j = 0; j < len; j++) { | 77 for (int j = 0; j < len; j++) { |
77 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 78 StringShape shape(*building_blocks[i]); |
| 79 CHECK_EQ(buf[j], building_blocks[i]->Get(shape, j)); |
78 } | 80 } |
79 break; | 81 break; |
80 } | 82 } |
81 case 2: { | 83 case 2: { |
82 class Resource: public v8::String::ExternalStringResource, | 84 class Resource: public v8::String::ExternalStringResource, |
83 public Malloced { | 85 public Malloced { |
84 public: | 86 public: |
85 explicit Resource(Vector<const uc16> string): data_(string.start()) { | 87 explicit Resource(Vector<const uc16> string): data_(string.start()) { |
86 length_ = string.length(); | 88 length_ = string.length(); |
87 } | 89 } |
88 virtual const uint16_t* data() const { return data_; } | 90 virtual const uint16_t* data() const { return data_; } |
89 virtual size_t length() const { return length_; } | 91 virtual size_t length() const { return length_; } |
90 | 92 |
91 private: | 93 private: |
92 const uc16* data_; | 94 const uc16* data_; |
93 size_t length_; | 95 size_t length_; |
94 }; | 96 }; |
95 uc16* buf = NewArray<uc16>(len); | 97 uc16* buf = NewArray<uc16>(len); |
96 for (int j = 0; j < len; j++) { | 98 for (int j = 0; j < len; j++) { |
97 buf[j] = gen() % 65536; | 99 buf[j] = gen() % 65536; |
98 } | 100 } |
99 Resource* resource = new Resource(Vector<const uc16>(buf, len)); | 101 Resource* resource = new Resource(Vector<const uc16>(buf, len)); |
100 building_blocks[i] = Factory::NewExternalStringFromTwoByte(resource); | 102 building_blocks[i] = Factory::NewExternalStringFromTwoByte(resource); |
101 for (int j = 0; j < len; j++) { | 103 for (int j = 0; j < len; j++) { |
102 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 104 StringShape shape(*building_blocks[i]); |
| 105 CHECK_EQ(buf[j], building_blocks[i]->Get(shape, j)); |
103 } | 106 } |
104 break; | 107 break; |
105 } | 108 } |
106 case 3: { | 109 case 3: { |
107 char* buf = NewArray<char>(len); | 110 char* buf = NewArray<char>(len); |
108 for (int j = 0; j < len; j++) { | 111 for (int j = 0; j < len; j++) { |
109 buf[j] = gen() % 128; | 112 buf[j] = gen() % 128; |
110 } | 113 } |
111 building_blocks[i] = | 114 building_blocks[i] = |
112 Factory::NewStringFromAscii(Vector<const char>(buf, len)); | 115 Factory::NewStringFromAscii(Vector<const char>(buf, len)); |
113 for (int j = 0; j < len; j++) { | 116 for (int j = 0; j < len; j++) { |
114 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 117 StringShape shape(*building_blocks[i]); |
| 118 CHECK_EQ(buf[j], building_blocks[i]->Get(shape, j)); |
115 } | 119 } |
116 break; | 120 break; |
117 } | 121 } |
118 } | 122 } |
119 } | 123 } |
120 } | 124 } |
121 | 125 |
122 | 126 |
123 static Handle<String> ConstructLeft( | 127 static Handle<String> ConstructLeft( |
124 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], | 128 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], |
125 int depth) { | 129 int depth) { |
126 Handle<String> answer = Factory::NewStringFromAscii(CStrVector("")); | 130 Handle<String> answer = Factory::NewStringFromAscii(CStrVector("")); |
127 for (int i = 0; i < depth; i++) { | 131 for (int i = 0; i < depth; i++) { |
128 answer = | 132 answer = |
129 Factory::NewConsString(answer, | 133 Factory::NewConsString(answer, |
130 building_blocks[i % NUMBER_OF_BUILDING_BLOCKS]); | 134 StringShape(*answer), |
| 135 building_blocks[i % NUMBER_OF_BUILDING_BLOCKS], |
| 136 StringShape(*building_blocks[i % NUMBER_OF_BUILDI
NG_BLOCKS])); |
131 } | 137 } |
132 return answer; | 138 return answer; |
133 } | 139 } |
134 | 140 |
135 | 141 |
136 static Handle<String> ConstructRight( | 142 static Handle<String> ConstructRight( |
137 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], | 143 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], |
138 int depth) { | 144 int depth) { |
139 Handle<String> answer = Factory::NewStringFromAscii(CStrVector("")); | 145 Handle<String> answer = Factory::NewStringFromAscii(CStrVector("")); |
140 for (int i = depth - 1; i >= 0; i--) { | 146 for (int i = depth - 1; i >= 0; i--) { |
141 answer = | 147 answer = |
142 Factory::NewConsString(building_blocks[i % NUMBER_OF_BUILDING_BLOCKS], | 148 Factory::NewConsString(building_blocks[i % NUMBER_OF_BUILDING_BLOCKS], |
143 answer); | 149 StringShape(*building_blocks[i % NUMBER_OF_BUILDI
NG_BLOCKS]), |
| 150 answer, |
| 151 StringShape(*answer)); |
144 } | 152 } |
145 return answer; | 153 return answer; |
146 } | 154 } |
147 | 155 |
148 | 156 |
149 static Handle<String> ConstructBalancedHelper( | 157 static Handle<String> ConstructBalancedHelper( |
150 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], | 158 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], |
151 int from, | 159 int from, |
152 int to) { | 160 int to) { |
153 ASSERT(to > from); | 161 ASSERT(to > from); |
154 if (to - from == 1) { | 162 if (to - from == 1) { |
155 return building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]; | 163 return building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]; |
156 } | 164 } |
157 if (to - from == 2) { | 165 if (to - from == 2) { |
158 return Factory::NewConsString( | 166 return Factory::NewConsString( |
159 building_blocks[from % NUMBER_OF_BUILDING_BLOCKS], | 167 building_blocks[from % NUMBER_OF_BUILDING_BLOCKS], |
160 building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS]); | 168 StringShape(*building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]), |
| 169 building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS], |
| 170 StringShape(*building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS])); |
161 } | 171 } |
| 172 Handle<String> part1 = |
| 173 ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2)); |
| 174 Handle<String> part2 = |
| 175 ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to); |
162 return Factory::NewConsString( | 176 return Factory::NewConsString( |
163 ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2)), | 177 part1, |
164 ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to)); | 178 StringShape(*part1), |
| 179 part2, |
| 180 StringShape(*part2)); |
165 } | 181 } |
166 | 182 |
167 | 183 |
168 static Handle<String> ConstructBalanced( | 184 static Handle<String> ConstructBalanced( |
169 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { | 185 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { |
170 return ConstructBalancedHelper(building_blocks, 0, DEEP_DEPTH); | 186 return ConstructBalancedHelper(building_blocks, 0, DEEP_DEPTH); |
171 } | 187 } |
172 | 188 |
173 | 189 |
174 static StringInputBuffer buffer; | 190 static StringInputBuffer buffer; |
(...skipping 17 matching lines...) Expand all Loading... |
192 static void TraverseFirst(Handle<String> s1, Handle<String> s2, int chars) { | 208 static void TraverseFirst(Handle<String> s1, Handle<String> s2, int chars) { |
193 int i = 0; | 209 int i = 0; |
194 buffer.Reset(*s1); | 210 buffer.Reset(*s1); |
195 StringInputBuffer buffer2(*s2); | 211 StringInputBuffer buffer2(*s2); |
196 while (buffer.has_more() && i < chars) { | 212 while (buffer.has_more() && i < chars) { |
197 CHECK(buffer2.has_more()); | 213 CHECK(buffer2.has_more()); |
198 uint16_t c = buffer.GetNext(); | 214 uint16_t c = buffer.GetNext(); |
199 CHECK_EQ(c, buffer2.GetNext()); | 215 CHECK_EQ(c, buffer2.GetNext()); |
200 i++; | 216 i++; |
201 } | 217 } |
202 s1->Get(s1->length() - 1); | 218 StringShape shape1(*s1); |
203 s2->Get(s2->length() - 1); | 219 StringShape shape2(*s2); |
| 220 s1->Get(shape1, s1->length(shape1) - 1); |
| 221 s2->Get(shape2, s2->length(shape2) - 1); |
204 } | 222 } |
205 | 223 |
206 | 224 |
207 TEST(Traverse) { | 225 TEST(Traverse) { |
208 printf("TestTraverse\n"); | 226 printf("TestTraverse\n"); |
209 InitializeVM(); | 227 InitializeVM(); |
210 v8::HandleScope scope; | 228 v8::HandleScope scope; |
211 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]; | 229 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]; |
212 InitializeBuildingBlocks(building_blocks); | 230 InitializeBuildingBlocks(building_blocks); |
213 Handle<String> flat = ConstructBalanced(building_blocks); | 231 Handle<String> flat = ConstructBalanced(building_blocks); |
(...skipping 12 matching lines...) Expand all Loading... |
226 ConstructLeft(building_blocks, SUPER_DEEP_DEPTH); | 244 ConstructLeft(building_blocks, SUPER_DEEP_DEPTH); |
227 Handle<String> right_deep_asymmetric = | 245 Handle<String> right_deep_asymmetric = |
228 ConstructRight(building_blocks, SUPER_DEEP_DEPTH); | 246 ConstructRight(building_blocks, SUPER_DEEP_DEPTH); |
229 printf("5\n"); | 247 printf("5\n"); |
230 TraverseFirst(left_asymmetric, left_deep_asymmetric, 1050); | 248 TraverseFirst(left_asymmetric, left_deep_asymmetric, 1050); |
231 printf("6\n"); | 249 printf("6\n"); |
232 TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536); | 250 TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536); |
233 printf("7\n"); | 251 printf("7\n"); |
234 Handle<String> right_deep_slice = | 252 Handle<String> right_deep_slice = |
235 Factory::NewStringSlice(left_deep_asymmetric, | 253 Factory::NewStringSlice(left_deep_asymmetric, |
| 254 StringShape(*left_deep_asymmetric), |
236 left_deep_asymmetric->length() - 1050, | 255 left_deep_asymmetric->length() - 1050, |
237 left_deep_asymmetric->length() - 50); | 256 left_deep_asymmetric->length() - 50); |
238 Handle<String> left_deep_slice = | 257 Handle<String> left_deep_slice = |
239 Factory::NewStringSlice(right_deep_asymmetric, | 258 Factory::NewStringSlice(right_deep_asymmetric, |
| 259 StringShape(*right_deep_asymmetric), |
240 right_deep_asymmetric->length() - 1050, | 260 right_deep_asymmetric->length() - 1050, |
241 right_deep_asymmetric->length() - 50); | 261 right_deep_asymmetric->length() - 50); |
242 printf("8\n"); | 262 printf("8\n"); |
243 Traverse(right_deep_slice, left_deep_slice); | 263 Traverse(right_deep_slice, left_deep_slice); |
244 printf("9\n"); | 264 printf("9\n"); |
245 FlattenString(left_asymmetric); | 265 FlattenString(left_asymmetric); |
246 printf("10\n"); | 266 printf("10\n"); |
247 Traverse(flat, left_asymmetric); | 267 Traverse(flat, left_asymmetric); |
248 printf("11\n"); | 268 printf("11\n"); |
249 FlattenString(right_asymmetric); | 269 FlattenString(right_asymmetric); |
250 printf("12\n"); | 270 printf("12\n"); |
251 Traverse(flat, right_asymmetric); | 271 Traverse(flat, right_asymmetric); |
252 printf("14\n"); | 272 printf("14\n"); |
253 FlattenString(symmetric); | 273 FlattenString(symmetric); |
254 printf("15\n"); | 274 printf("15\n"); |
255 Traverse(flat, symmetric); | 275 Traverse(flat, symmetric); |
256 printf("16\n"); | 276 printf("16\n"); |
257 FlattenString(left_deep_asymmetric); | 277 FlattenString(left_deep_asymmetric); |
258 printf("18\n"); | 278 printf("18\n"); |
259 } | 279 } |
260 | 280 |
261 | 281 |
262 static Handle<String> SliceOf(Handle<String> underlying) { | 282 static Handle<String> SliceOf(Handle<String> underlying) { |
263 int start = gen() % underlying->length(); | 283 int start = gen() % underlying->length(); |
264 int end = start + gen() % (underlying->length() - start); | 284 int end = start + gen() % (underlying->length() - start); |
265 return Factory::NewStringSlice(underlying, start, end); | 285 return Factory::NewStringSlice(underlying, StringShape(*underlying), start, en
d); |
266 } | 286 } |
267 | 287 |
268 | 288 |
269 static Handle<String> ConstructSliceTree( | 289 static Handle<String> ConstructSliceTree( |
270 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], | 290 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], |
271 int from, | 291 int from, |
272 int to) { | 292 int to) { |
273 ASSERT(to > from); | 293 ASSERT(to > from); |
274 if (to - from <= 1) | 294 if (to - from <= 1) |
275 return SliceOf(building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]); | 295 return SliceOf(building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]); |
276 if (to - from == 2) { | 296 if (to - from == 2) { |
277 Handle<String> lhs = building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]; | 297 Handle<String> lhs = building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]; |
278 if (gen() % 2 == 0) | 298 if (gen() % 2 == 0) |
279 lhs = SliceOf(lhs); | 299 lhs = SliceOf(lhs); |
280 Handle<String> rhs = building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS]; | 300 Handle<String> rhs = building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS]; |
281 if (gen() % 2 == 0) | 301 if (gen() % 2 == 0) |
282 rhs = SliceOf(rhs); | 302 rhs = SliceOf(rhs); |
283 return Factory::NewConsString(lhs, rhs); | 303 return Factory::NewConsString(lhs, StringShape(*lhs), rhs, StringShape(*rhs)
); |
284 } | 304 } |
285 Handle<String> branch = Factory::NewConsString( | 305 Handle<String> part1 = |
286 ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2)), | 306 ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2)); |
287 ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to)); | 307 Handle<String> part2 = |
| 308 ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to); |
| 309 Handle<String> branch = Factory::NewConsString(part1, StringShape(*part1), par
t2, StringShape(*part2)); |
288 if (gen() % 2 == 0) | 310 if (gen() % 2 == 0) |
289 return branch; | 311 return branch; |
290 return(SliceOf(branch)); | 312 return(SliceOf(branch)); |
291 } | 313 } |
292 | 314 |
293 | 315 |
294 TEST(Slice) { | 316 TEST(Slice) { |
295 printf("TestSlice\n"); | 317 printf("TestSlice\n"); |
296 InitializeVM(); | 318 InitializeVM(); |
297 v8::HandleScope scope; | 319 v8::HandleScope scope; |
(...skipping 19 matching lines...) Expand all Loading... |
317 v8::HandleScope scope; | 339 v8::HandleScope scope; |
318 | 340 |
319 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); | 341 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); |
320 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { | 342 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { |
321 foo[i] = "foo "[i % 4]; | 343 foo[i] = "foo "[i % 4]; |
322 } | 344 } |
323 Handle<String> string = | 345 Handle<String> string = |
324 Factory::NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); | 346 Factory::NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); |
325 Handle<String> foo_string = Factory::NewStringFromAscii(CStrVector("foo")); | 347 Handle<String> foo_string = Factory::NewStringFromAscii(CStrVector("foo")); |
326 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { | 348 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { |
327 string = Factory::NewConsString(string, foo_string); | 349 string = Factory::NewConsString(string, |
| 350 StringShape(*string), |
| 351 foo_string, |
| 352 StringShape(*foo_string)); |
328 } | 353 } |
329 Handle<String> flat_string = Factory::NewConsString(string, foo_string); | 354 Handle<String> flat_string = Factory::NewConsString(string, |
| 355 StringShape(*string), |
| 356 foo_string, |
| 357 StringShape(*foo_string)); |
330 FlattenString(flat_string); | 358 FlattenString(flat_string); |
331 | 359 |
332 for (int i = 0; i < 500; i++) { | 360 for (int i = 0; i < 500; i++) { |
333 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); | 361 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); |
334 } | 362 } |
335 } | 363 } |
336 | 364 |
337 | 365 |
338 TEST(Utf8Conversion) { | 366 TEST(Utf8Conversion) { |
339 // Smoke test for converting strings to utf-8. | 367 // Smoke test for converting strings to utf-8. |
(...skipping 27 matching lines...) Expand all Loading... |
367 int written = mixed->WriteUtf8(buffer, i); | 395 int written = mixed->WriteUtf8(buffer, i); |
368 CHECK_EQ(lengths[i], written); | 396 CHECK_EQ(lengths[i], written); |
369 // Check that the contents are correct | 397 // Check that the contents are correct |
370 for (int j = 0; j < lengths[i]; j++) | 398 for (int j = 0; j < lengths[i]; j++) |
371 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); | 399 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); |
372 // Check that the rest of the buffer hasn't been touched | 400 // Check that the rest of the buffer hasn't been touched |
373 for (int j = lengths[i]; j < 11; j++) | 401 for (int j = lengths[i]; j < 11; j++) |
374 CHECK_EQ(kNoChar, buffer[j]); | 402 CHECK_EQ(kNoChar, buffer[j]); |
375 } | 403 } |
376 } | 404 } |
OLD | NEW |