Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: test/cctest/test-strings.cc

Issue 385004: Remove sliced string string type... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/string.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 printf("4\n"); 234 printf("4\n");
235 Handle<String> left_deep_asymmetric = 235 Handle<String> left_deep_asymmetric =
236 ConstructLeft(building_blocks, SUPER_DEEP_DEPTH); 236 ConstructLeft(building_blocks, SUPER_DEEP_DEPTH);
237 Handle<String> right_deep_asymmetric = 237 Handle<String> right_deep_asymmetric =
238 ConstructRight(building_blocks, SUPER_DEEP_DEPTH); 238 ConstructRight(building_blocks, SUPER_DEEP_DEPTH);
239 printf("5\n"); 239 printf("5\n");
240 TraverseFirst(left_asymmetric, left_deep_asymmetric, 1050); 240 TraverseFirst(left_asymmetric, left_deep_asymmetric, 1050);
241 printf("6\n"); 241 printf("6\n");
242 TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536); 242 TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536);
243 printf("7\n"); 243 printf("7\n");
244 Handle<String> right_deep_slice =
245 Factory::NewStringSlice(left_deep_asymmetric,
246 left_deep_asymmetric->length() - 1050,
247 left_deep_asymmetric->length() - 50);
248 Handle<String> left_deep_slice =
249 Factory::NewStringSlice(right_deep_asymmetric,
250 right_deep_asymmetric->length() - 1050,
251 right_deep_asymmetric->length() - 50);
252 printf("8\n");
253 Traverse(right_deep_slice, left_deep_slice);
254 printf("9\n");
255 FlattenString(left_asymmetric); 244 FlattenString(left_asymmetric);
256 printf("10\n"); 245 printf("10\n");
257 Traverse(flat, left_asymmetric); 246 Traverse(flat, left_asymmetric);
258 printf("11\n"); 247 printf("11\n");
259 FlattenString(right_asymmetric); 248 FlattenString(right_asymmetric);
260 printf("12\n"); 249 printf("12\n");
261 Traverse(flat, right_asymmetric); 250 Traverse(flat, right_asymmetric);
262 printf("14\n"); 251 printf("14\n");
263 FlattenString(symmetric); 252 FlattenString(symmetric);
264 printf("15\n"); 253 printf("15\n");
265 Traverse(flat, symmetric); 254 Traverse(flat, symmetric);
266 printf("16\n"); 255 printf("16\n");
267 FlattenString(left_deep_asymmetric); 256 FlattenString(left_deep_asymmetric);
268 printf("18\n"); 257 printf("18\n");
269 } 258 }
270 259
271 260
272 static Handle<String> SliceOf(Handle<String> underlying) {
273 int start = gen() % underlying->length();
274 int end = start + gen() % (underlying->length() - start);
275 return Factory::NewStringSlice(underlying,
276 start,
277 end);
278 }
279
280
281 static Handle<String> ConstructSliceTree(
282 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS],
283 int from,
284 int to) {
285 CHECK(to > from);
286 if (to - from <= 1)
287 return SliceOf(building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]);
288 if (to - from == 2) {
289 Handle<String> lhs = building_blocks[from % NUMBER_OF_BUILDING_BLOCKS];
290 if (gen() % 2 == 0)
291 lhs = SliceOf(lhs);
292 Handle<String> rhs = building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS];
293 if (gen() % 2 == 0)
294 rhs = SliceOf(rhs);
295 return Factory::NewConsString(lhs, rhs);
296 }
297 Handle<String> part1 =
298 ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2));
299 Handle<String> part2 =
300 ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to);
301 Handle<String> branch = Factory::NewConsString(part1, part2);
302 if (gen() % 2 == 0)
303 return branch;
304 return(SliceOf(branch));
305 }
306
307
308 TEST(Slice) {
309 printf("TestSlice\n");
310 InitializeVM();
311 v8::HandleScope scope;
312 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS];
313 ZoneScope zone(DELETE_ON_EXIT);
314 InitializeBuildingBlocks(building_blocks);
315
316 seed = 42;
317 Handle<String> slice_tree =
318 ConstructSliceTree(building_blocks, 0, DEEP_DEPTH);
319 seed = 42;
320 Handle<String> flat_slice_tree =
321 ConstructSliceTree(building_blocks, 0, DEEP_DEPTH);
322 FlattenString(flat_slice_tree);
323 Traverse(flat_slice_tree, slice_tree);
324 }
325
326 static const int DEEP_ASCII_DEPTH = 100000; 261 static const int DEEP_ASCII_DEPTH = 100000;
327 262
328 263
329 TEST(DeepAscii) { 264 TEST(DeepAscii) {
330 printf("TestDeepAscii\n"); 265 printf("TestDeepAscii\n");
331 InitializeVM(); 266 InitializeVM();
332 v8::HandleScope scope; 267 v8::HandleScope scope;
333 268
334 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); 269 char* foo = NewArray<char>(DEEP_ASCII_DEPTH);
335 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { 270 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 } 342 }
408 343
409 const uint16_t* data() const { return data_; } 344 const uint16_t* data() const { return data_; }
410 size_t length() const { return length_; } 345 size_t length() const { return length_; }
411 346
412 private: 347 private:
413 const uint16_t* data_; 348 const uint16_t* data_;
414 size_t length_; 349 size_t length_;
415 bool* destructed_; 350 bool* destructed_;
416 }; 351 };
417
418
419 // Regression test case for http://crbug.com/9746. The problem was
420 // that when we marked objects reachable only through weak pointers,
421 // we ended up keeping a sliced symbol alive, even though we already
422 // invoked the weak callback on the underlying external string thus
423 // deleting its resource.
424 TEST(Regress9746) {
425 InitializeVM();
426
427 // Setup lengths that guarantee we'll get slices instead of simple
428 // flat strings.
429 static const int kFullStringLength = String::kMinNonFlatLength * 2;
430 static const int kSliceStringLength = String::kMinNonFlatLength + 1;
431
432 uint16_t* source = new uint16_t[kFullStringLength];
433 for (int i = 0; i < kFullStringLength; i++) source[i] = '1';
434 char* key = new char[kSliceStringLength];
435 for (int i = 0; i < kSliceStringLength; i++) key[i] = '1';
436 Vector<const char> key_vector(key, kSliceStringLength);
437
438 // Allocate an external string resource that keeps track of when it
439 // is destructed.
440 bool resource_destructed = false;
441 TwoByteResource* resource =
442 new TwoByteResource(source, kFullStringLength, &resource_destructed);
443
444 {
445 v8::HandleScope scope;
446
447 // Allocate an external string resource and external string. We
448 // have to go through the API to get the weak handle and the
449 // automatic destruction going.
450 Handle<String> string =
451 v8::Utils::OpenHandle(*v8::String::NewExternal(resource));
452
453 // Create a slice of the external string.
454 Handle<String> slice =
455 Factory::NewStringSlice(string, 0, kSliceStringLength);
456 CHECK_EQ(kSliceStringLength, slice->length());
457 CHECK(StringShape(*slice).IsSliced());
458
459 // Make sure the slice ends up in old space so we can morph it
460 // into a symbol.
461 while (Heap::InNewSpace(*slice)) {
462 Heap::PerformScavenge();
463 }
464
465 // Force the slice into the symbol table.
466 slice = Factory::SymbolFromString(slice);
467 CHECK(slice->IsSymbol());
468 CHECK(StringShape(*slice).IsSliced());
469
470 Handle<String> buffer(Handle<SlicedString>::cast(slice)->buffer());
471 CHECK(StringShape(*buffer).IsExternal());
472 CHECK(buffer->IsTwoByteRepresentation());
473
474 // Finally, base a script on the slice of the external string and
475 // get its wrapper. This allocates yet another weak handle that
476 // indirectly refers to the external string.
477 Handle<Script> script = Factory::NewScript(slice);
478 Handle<JSObject> wrapper = GetScriptWrapper(script);
479 }
480
481 // When we collect all garbage, we cannot get rid of the sliced
482 // symbol entry in the symbol table because it is used by the script
483 // kept alive by the weak wrapper. Make sure we don't destruct the
484 // external string.
485 Heap::CollectAllGarbage(false);
486 CHECK(!resource_destructed);
487
488 {
489 v8::HandleScope scope;
490
491 // Make sure the sliced symbol is still in the table.
492 Handle<String> symbol = Factory::LookupSymbol(key_vector);
493 CHECK(StringShape(*symbol).IsSliced());
494
495 // Make sure the buffer is still a two-byte external string.
496 Handle<String> buffer(Handle<SlicedString>::cast(symbol)->buffer());
497 CHECK(StringShape(*buffer).IsExternal());
498 CHECK(buffer->IsTwoByteRepresentation());
499 }
500
501 // Forcing another garbage collection should let us get rid of the
502 // slice from the symbol table. The external string remains in the
503 // heap until the next GC.
504 Heap::CollectAllGarbage(false);
505 CHECK(!resource_destructed);
506 v8::HandleScope scope;
507 Handle<String> key_string = Factory::NewStringFromAscii(key_vector);
508 String* out;
509 CHECK(!Heap::LookupSymbolIfExists(*key_string, &out));
510
511 // Forcing yet another garbage collection must allow us to finally
512 // get rid of the external string.
513 Heap::CollectAllGarbage(false);
514 CHECK(resource_destructed);
515
516 delete[] source;
517 delete[] key;
518 }
OLDNEW
« no previous file with comments | « src/string.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698