 Chromium Code Reviews
 Chromium Code Reviews Issue 7477045:
  Tentative implementation of string slices (hidden under the flag --string-slices).  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 7477045:
  Tentative implementation of string slices (hidden under the flag --string-slices).  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1281 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 1281 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 
| 1282 | 1282 | 
| 1283 table_.Register(kVisitGlobalContext, | 1283 table_.Register(kVisitGlobalContext, | 
| 1284 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1284 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 
| 1285 template VisitSpecialized<Context::kSize>); | 1285 template VisitSpecialized<Context::kSize>); | 
| 1286 | 1286 | 
| 1287 table_.Register(kVisitConsString, | 1287 table_.Register(kVisitConsString, | 
| 1288 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1288 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 
| 1289 template VisitSpecialized<ConsString::kSize>); | 1289 template VisitSpecialized<ConsString::kSize>); | 
| 1290 | 1290 | 
| 1291 table_.Register(kVisitSlicedString, | |
| 1292 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | |
| 1293 template VisitSpecialized<SlicedString::kSize>); | |
| 1294 | |
| 1291 table_.Register(kVisitSharedFunctionInfo, | 1295 table_.Register(kVisitSharedFunctionInfo, | 
| 1292 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1296 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 
| 1293 template VisitSpecialized<SharedFunctionInfo::kSize>); | 1297 template VisitSpecialized<SharedFunctionInfo::kSize>); | 
| 1294 | 1298 | 
| 1295 table_.Register(kVisitJSRegExp, | 1299 table_.Register(kVisitJSRegExp, | 
| 1296 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1300 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 
| 1297 Visit); | 1301 Visit); | 
| 1298 | 1302 | 
| 1299 table_.Register(kVisitJSFunction, | 1303 table_.Register(kVisitJSFunction, | 
| 1300 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1304 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 
| (...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2538 // we can try to save memory if all chars actually fit in ascii. | 2542 // we can try to save memory if all chars actually fit in ascii. | 
| 2539 is_ascii_data_in_two_byte_string = | 2543 is_ascii_data_in_two_byte_string = | 
| 2540 first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars(); | 2544 first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars(); | 
| 2541 if (is_ascii_data_in_two_byte_string) { | 2545 if (is_ascii_data_in_two_byte_string) { | 
| 2542 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 2546 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 
| 2543 } | 2547 } | 
| 2544 } | 2548 } | 
| 2545 | 2549 | 
| 2546 // If the resulting string is small make a flat string. | 2550 // If the resulting string is small make a flat string. | 
| 2547 if (length < String::kMinNonFlatLength) { | 2551 if (length < String::kMinNonFlatLength) { | 
| 2552 // Note that both parts cannot be string slices since: | |
| 
Vitaly Repeshko
2011/08/17 19:20:23
"Note that neither of the two inputs can be a slic
 | |
| 2553 STATIC_ASSERT(String::kMinNonFlatLength <= SlicedString::kMinLength); | |
| 2548 ASSERT(first->IsFlat()); | 2554 ASSERT(first->IsFlat()); | 
| 2549 ASSERT(second->IsFlat()); | 2555 ASSERT(second->IsFlat()); | 
| 2550 if (is_ascii) { | 2556 if (is_ascii) { | 
| 2551 Object* result; | 2557 Object* result; | 
| 2552 { MaybeObject* maybe_result = AllocateRawAsciiString(length); | 2558 { MaybeObject* maybe_result = AllocateRawAsciiString(length); | 
| 2553 if (!maybe_result->ToObject(&result)) return maybe_result; | 2559 if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2554 } | 2560 } | 
| 2555 // Copy the characters into the new object. | 2561 // Copy the characters into the new object. | 
| 2556 char* dest = SeqAsciiString::cast(result)->GetChars(); | 2562 char* dest = SeqAsciiString::cast(result)->GetChars(); | 
| 2557 // Copy first part. | 2563 // Copy first part. | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2629 // dictionary. Check whether we already have the string in the symbol | 2635 // dictionary. Check whether we already have the string in the symbol | 
| 2630 // table to prevent creation of many unneccesary strings. | 2636 // table to prevent creation of many unneccesary strings. | 
| 2631 unsigned c1 = buffer->Get(start); | 2637 unsigned c1 = buffer->Get(start); | 
| 2632 unsigned c2 = buffer->Get(start + 1); | 2638 unsigned c2 = buffer->Get(start + 1); | 
| 2633 return MakeOrFindTwoCharacterString(this, c1, c2); | 2639 return MakeOrFindTwoCharacterString(this, c1, c2); | 
| 2634 } | 2640 } | 
| 2635 | 2641 | 
| 2636 // Make an attempt to flatten the buffer to reduce access time. | 2642 // Make an attempt to flatten the buffer to reduce access time. | 
| 2637 buffer = buffer->TryFlattenGetString(); | 2643 buffer = buffer->TryFlattenGetString(); | 
| 2638 | 2644 | 
| 2645 if (!FLAG_string_slices || | |
| 2646 (buffer->IsConsString() && | |
| 2647 (!buffer->IsFlat() || | |
| 2648 !ConsString::cast(buffer)->first()->IsSeqString())) || | |
| 
Yang
2011/08/17 09:34:37
A little ugly for now, but this will be removed on
 
Vitaly Repeshko
2011/08/17 19:20:23
OK, but the indentation looks weird. Also please m
 | |
| 2649 buffer->IsExternalString() || | |
| 2650 length < SlicedString::kMinLength) { | |
| 2651 Object* result; | |
| 2652 { MaybeObject* maybe_result = buffer->IsAsciiRepresentation() | |
| 2653 ? AllocateRawAsciiString(length, pretenure ) | |
| 
Vitaly Repeshko
2011/08/17 19:20:23
nit: Extra space before ')'.
 | |
| 2654 : AllocateRawTwoByteString(length, pretenure); | |
| 2655 if (!maybe_result->ToObject(&result)) return maybe_result; | |
| 2656 } | |
| 2657 String* string_result = String::cast(result); | |
| 2658 // Copy the characters into the new object. | |
| 2659 if (buffer->IsAsciiRepresentation()) { | |
| 2660 ASSERT(string_result->IsAsciiRepresentation()); | |
| 2661 char* dest = SeqAsciiString::cast(string_result)->GetChars(); | |
| 2662 String::WriteToFlat(buffer, dest, start, end); | |
| 2663 } else { | |
| 2664 ASSERT(string_result->IsTwoByteRepresentation()); | |
| 2665 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); | |
| 2666 String::WriteToFlat(buffer, dest, start, end); | |
| 2667 } | |
| 2668 return result; | |
| 2669 } | |
| 2670 | |
| 2671 ASSERT(buffer->IsFlat()); | |
| 2672 ASSERT(!buffer->IsExternalString()); | |
| 2673 #if DEBUG | |
| 2674 buffer->StringVerify(); | |
| 2675 #endif | |
| 2676 | |
| 2639 Object* result; | 2677 Object* result; | 
| 2640 { MaybeObject* maybe_result = buffer->IsAsciiRepresentation() | 2678 { Map* map = buffer->IsAsciiRepresentation() | 
| 2641 ? AllocateRawAsciiString(length, pretenure ) | 2679 ? sliced_ascii_string_map() | 
| 2642 : AllocateRawTwoByteString(length, pretenure); | 2680 : sliced_string_map(); | 
| 2681 MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | |
| 
Vitaly Repeshko
2011/08/17 19:20:23
Consider adding Heap::Allocate{Ascii,TwoByte}Slice
 
Yang
2011/08/18 12:17:32
I decided not to, at least for now, since this is
 | |
| 2643 if (!maybe_result->ToObject(&result)) return maybe_result; | 2682 if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2644 } | 2683 } | 
| 2645 String* string_result = String::cast(result); | 2684 | 
| 2646 // Copy the characters into the new object. | 2685 AssertNoAllocation no_gc; | 
| 2647 if (buffer->IsAsciiRepresentation()) { | 2686 SlicedString* sliced_string = SlicedString::cast(result); | 
| 2648 ASSERT(string_result->IsAsciiRepresentation()); | 2687 sliced_string->set_length(length); | 
| 2649 char* dest = SeqAsciiString::cast(string_result)->GetChars(); | 2688 sliced_string->set_hash_field(String::kEmptyHashField); | 
| 2650 String::WriteToFlat(buffer, dest, start, end); | 2689 if (buffer->IsConsString()) { | 
| 2690 ConsString* cons = ConsString::cast(buffer); | |
| 2691 ASSERT(cons->second()->length() == 0); | |
| 2692 sliced_string->set_parent(cons->first()); | |
| 2693 sliced_string->set_offset(start); | |
| 2694 } else if (buffer->IsSlicedString()) { | |
| 2695 // Prevent nesting sliced strings. | |
| 2696 SlicedString* parent_slice = SlicedString::cast(buffer); | |
| 2697 sliced_string->set_parent(parent_slice->parent()); | |
| 2698 sliced_string->set_offset(start + parent_slice->offset()); | |
| 2651 } else { | 2699 } else { | 
| 2652 ASSERT(string_result->IsTwoByteRepresentation()); | 2700 sliced_string->set_parent(buffer); | 
| 2653 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); | 2701 sliced_string->set_offset(start); | 
| 2654 String::WriteToFlat(buffer, dest, start, end); | |
| 2655 } | 2702 } | 
| 2656 | 2703 ASSERT(sliced_string->parent()->IsSeqString()); | 
| 2657 return result; | 2704 return result; | 
| 2658 } | 2705 } | 
| 2659 | 2706 | 
| 2660 | 2707 | 
| 2661 MaybeObject* Heap::AllocateExternalStringFromAscii( | 2708 MaybeObject* Heap::AllocateExternalStringFromAscii( | 
| 2662 ExternalAsciiString::Resource* resource) { | 2709 ExternalAsciiString::Resource* resource) { | 
| 2663 size_t length = resource->length(); | 2710 size_t length = resource->length(); | 
| 2664 if (length > static_cast<size_t>(String::kMaxLength)) { | 2711 if (length > static_cast<size_t>(String::kMaxLength)) { | 
| 2665 isolate()->context()->mark_out_of_memory(); | 2712 isolate()->context()->mark_out_of_memory(); | 
| 2666 return Failure::OutOfMemoryException(); | 2713 return Failure::OutOfMemoryException(); | 
| (...skipping 3357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6024 } | 6071 } | 
| 6025 | 6072 | 
| 6026 | 6073 | 
| 6027 void ExternalStringTable::TearDown() { | 6074 void ExternalStringTable::TearDown() { | 
| 6028 new_space_strings_.Free(); | 6075 new_space_strings_.Free(); | 
| 6029 old_space_strings_.Free(); | 6076 old_space_strings_.Free(); | 
| 6030 } | 6077 } | 
| 6031 | 6078 | 
| 6032 | 6079 | 
| 6033 } } // namespace v8::internal | 6080 } } // namespace v8::internal | 
| OLD | NEW |