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

Side by Side Diff: src/runtime.cc

Issue 11688003: Revert r13275 and 13276 (Remove most uses of StringInputBuffer). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 11 months 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/runtime.h ('k') | src/string-stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3471 matching lines...) Expand 10 before | Expand all | Expand 10 after
3482 3482
3483 // No need to flatten if we are going to find the answer on the first 3483 // No need to flatten if we are going to find the answer on the first
3484 // character. At this point we know there is at least one character 3484 // character. At this point we know there is at least one character
3485 // in each string, due to the trivial case handling above. 3485 // in each string, due to the trivial case handling above.
3486 int d = str1->Get(0) - str2->Get(0); 3486 int d = str1->Get(0) - str2->Get(0);
3487 if (d != 0) return Smi::FromInt(d); 3487 if (d != 0) return Smi::FromInt(d);
3488 3488
3489 str1->TryFlatten(); 3489 str1->TryFlatten();
3490 str2->TryFlatten(); 3490 str2->TryFlatten();
3491 3491
3492 ConsStringIteratorOp* op1 = 3492 StringInputBuffer& buf1 =
3493 isolate->runtime_state()->string_locale_compare_it1(); 3493 *isolate->runtime_state()->string_locale_compare_buf1();
3494 ConsStringIteratorOp* op2 = 3494 StringInputBuffer& buf2 =
3495 isolate->runtime_state()->string_locale_compare_it2(); 3495 *isolate->runtime_state()->string_locale_compare_buf2();
3496 // TODO(dcarney) Can do array compares here more efficiently. 3496
3497 StringCharacterStream stream1(str1, op1); 3497 buf1.Reset(str1);
3498 StringCharacterStream stream2(str2, op2); 3498 buf2.Reset(str2);
3499 3499
3500 for (int i = 0; i < end; i++) { 3500 for (int i = 0; i < end; i++) {
3501 uint16_t char1 = stream1.GetNext(); 3501 uint16_t char1 = buf1.GetNext();
3502 uint16_t char2 = stream2.GetNext(); 3502 uint16_t char2 = buf2.GetNext();
3503 if (char1 != char2) return Smi::FromInt(char1 - char2); 3503 if (char1 != char2) return Smi::FromInt(char1 - char2);
3504 } 3504 }
3505 3505
3506 return Smi::FromInt(str1_length - str2_length); 3506 return Smi::FromInt(str1_length - str2_length);
3507 } 3507 }
3508 3508
3509 3509
3510 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) { 3510 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
3511 NoHandleAllocation ha; 3511 NoHandleAllocation ha;
3512 ASSERT(args.length() == 3); 3512 ASSERT(args.length() == 3);
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after
5136 const char hex_chars[] = "0123456789ABCDEF"; 5136 const char hex_chars[] = "0123456789ABCDEF";
5137 NoHandleAllocation ha; 5137 NoHandleAllocation ha;
5138 ASSERT(args.length() == 1); 5138 ASSERT(args.length() == 1);
5139 CONVERT_ARG_CHECKED(String, source, 0); 5139 CONVERT_ARG_CHECKED(String, source, 0);
5140 5140
5141 source->TryFlatten(); 5141 source->TryFlatten();
5142 5142
5143 int escaped_length = 0; 5143 int escaped_length = 0;
5144 int length = source->length(); 5144 int length = source->length();
5145 { 5145 {
5146 Access<ConsStringIteratorOp> op( 5146 Access<StringInputBuffer> buffer(
5147 isolate->runtime_state()->string_iterator()); 5147 isolate->runtime_state()->string_input_buffer());
5148 StringCharacterStream stream(source, op.value()); 5148 buffer->Reset(source);
5149 while (stream.HasMore()) { 5149 while (buffer->has_more()) {
5150 uint16_t character = stream.GetNext(); 5150 uint16_t character = buffer->GetNext();
5151 if (character >= 256) { 5151 if (character >= 256) {
5152 escaped_length += 6; 5152 escaped_length += 6;
5153 } else if (IsNotEscaped(character)) { 5153 } else if (IsNotEscaped(character)) {
5154 escaped_length++; 5154 escaped_length++;
5155 } else { 5155 } else {
5156 escaped_length += 3; 5156 escaped_length += 3;
5157 } 5157 }
5158 // We don't allow strings that are longer than a maximal length. 5158 // We don't allow strings that are longer than a maximal length.
5159 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. 5159 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow.
5160 if (escaped_length > String::kMaxLength) { 5160 if (escaped_length > String::kMaxLength) {
5161 isolate->context()->mark_out_of_memory(); 5161 isolate->context()->mark_out_of_memory();
5162 return Failure::OutOfMemoryException(); 5162 return Failure::OutOfMemoryException();
5163 } 5163 }
5164 } 5164 }
5165 } 5165 }
5166 // No length change implies no change. Return original string if no change. 5166 // No length change implies no change. Return original string if no change.
5167 if (escaped_length == length) { 5167 if (escaped_length == length) {
5168 return source; 5168 return source;
5169 } 5169 }
5170 Object* o; 5170 Object* o;
5171 { MaybeObject* maybe_o = 5171 { MaybeObject* maybe_o =
5172 isolate->heap()->AllocateRawOneByteString(escaped_length); 5172 isolate->heap()->AllocateRawOneByteString(escaped_length);
5173 if (!maybe_o->ToObject(&o)) return maybe_o; 5173 if (!maybe_o->ToObject(&o)) return maybe_o;
5174 } 5174 }
5175 String* destination = String::cast(o); 5175 String* destination = String::cast(o);
5176 int dest_position = 0; 5176 int dest_position = 0;
5177 5177
5178 Access<ConsStringIteratorOp> op( 5178 Access<StringInputBuffer> buffer(
5179 isolate->runtime_state()->string_iterator()); 5179 isolate->runtime_state()->string_input_buffer());
5180 StringCharacterStream stream(source, op.value()); 5180 buffer->Rewind();
5181 while (stream.HasMore()) { 5181 while (buffer->has_more()) {
5182 uint16_t chr = stream.GetNext(); 5182 uint16_t chr = buffer->GetNext();
5183 if (chr >= 256) { 5183 if (chr >= 256) {
5184 destination->Set(dest_position, '%'); 5184 destination->Set(dest_position, '%');
5185 destination->Set(dest_position+1, 'u'); 5185 destination->Set(dest_position+1, 'u');
5186 destination->Set(dest_position+2, hex_chars[chr >> 12]); 5186 destination->Set(dest_position+2, hex_chars[chr >> 12]);
5187 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]); 5187 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]);
5188 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]); 5188 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]);
5189 destination->Set(dest_position+5, hex_chars[chr & 0xf]); 5189 destination->Set(dest_position+5, hex_chars[chr & 0xf]);
5190 dest_position += 6; 5190 dest_position += 6;
5191 } else if (IsNotEscaped(chr)) { 5191 } else if (IsNotEscaped(chr)) {
5192 destination->Set(dest_position, chr); 5192 destination->Set(dest_position, chr);
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
5710 { MaybeObject* maybe_o = s->IsOneByteRepresentation() 5710 { MaybeObject* maybe_o = s->IsOneByteRepresentation()
5711 ? isolate->heap()->AllocateRawOneByteString(length) 5711 ? isolate->heap()->AllocateRawOneByteString(length)
5712 : isolate->heap()->AllocateRawTwoByteString(length); 5712 : isolate->heap()->AllocateRawTwoByteString(length);
5713 if (!maybe_o->ToObject(&o)) return maybe_o; 5713 if (!maybe_o->ToObject(&o)) return maybe_o;
5714 } 5714 }
5715 String* result = String::cast(o); 5715 String* result = String::cast(o);
5716 bool has_changed_character = false; 5716 bool has_changed_character = false;
5717 5717
5718 // Convert all characters to upper case, assuming that they will fit 5718 // Convert all characters to upper case, assuming that they will fit
5719 // in the buffer 5719 // in the buffer
5720 Access<ConsStringIteratorOp> op( 5720 Access<StringInputBuffer> buffer(
5721 isolate->runtime_state()->string_iterator()); 5721 isolate->runtime_state()->string_input_buffer());
5722 StringCharacterStream stream(s, op.value()); 5722 buffer->Reset(s);
5723 unibrow::uchar chars[Converter::kMaxWidth]; 5723 unibrow::uchar chars[Converter::kMaxWidth];
5724 // We can assume that the string is not empty 5724 // We can assume that the string is not empty
5725 uc32 current = stream.GetNext(); 5725 uc32 current = buffer->GetNext();
5726 for (int i = 0; i < length;) { 5726 for (int i = 0; i < length;) {
5727 bool has_next = stream.HasMore(); 5727 bool has_next = buffer->has_more();
5728 uc32 next = has_next ? stream.GetNext() : 0; 5728 uc32 next = has_next ? buffer->GetNext() : 0;
5729 int char_length = mapping->get(current, next, chars); 5729 int char_length = mapping->get(current, next, chars);
5730 if (char_length == 0) { 5730 if (char_length == 0) {
5731 // The case conversion of this character is the character itself. 5731 // The case conversion of this character is the character itself.
5732 result->Set(i, current); 5732 result->Set(i, current);
5733 i++; 5733 i++;
5734 } else if (char_length == 1) { 5734 } else if (char_length == 1) {
5735 // Common case: converting the letter resulted in one character. 5735 // Common case: converting the letter resulted in one character.
5736 ASSERT(static_cast<uc32>(chars[0]) != current); 5736 ASSERT(static_cast<uc32>(chars[0]) != current);
5737 result->Set(i, chars[0]); 5737 result->Set(i, chars[0]);
5738 has_changed_character = true; 5738 has_changed_character = true;
5739 i++; 5739 i++;
5740 } else if (length == input_string_length) { 5740 } else if (length == input_string_length) {
5741 // We've assumed that the result would be as long as the 5741 // We've assumed that the result would be as long as the
5742 // input but here is a character that converts to several 5742 // input but here is a character that converts to several
5743 // characters. No matter, we calculate the exact length 5743 // characters. No matter, we calculate the exact length
5744 // of the result and try the whole thing again. 5744 // of the result and try the whole thing again.
5745 // 5745 //
5746 // Note that this leaves room for optimization. We could just 5746 // Note that this leaves room for optimization. We could just
5747 // memcpy what we already have to the result string. Also, 5747 // memcpy what we already have to the result string. Also,
5748 // the result string is the last object allocated we could 5748 // the result string is the last object allocated we could
5749 // "realloc" it and probably, in the vast majority of cases, 5749 // "realloc" it and probably, in the vast majority of cases,
5750 // extend the existing string to be able to hold the full 5750 // extend the existing string to be able to hold the full
5751 // result. 5751 // result.
5752 int next_length = 0; 5752 int next_length = 0;
5753 if (has_next) { 5753 if (has_next) {
5754 next_length = mapping->get(next, 0, chars); 5754 next_length = mapping->get(next, 0, chars);
5755 if (next_length == 0) next_length = 1; 5755 if (next_length == 0) next_length = 1;
5756 } 5756 }
5757 int current_length = i + char_length + next_length; 5757 int current_length = i + char_length + next_length;
5758 while (stream.HasMore()) { 5758 while (buffer->has_more()) {
5759 current = stream.GetNext(); 5759 current = buffer->GetNext();
5760 // NOTE: we use 0 as the next character here because, while 5760 // NOTE: we use 0 as the next character here because, while
5761 // the next character may affect what a character converts to, 5761 // the next character may affect what a character converts to,
5762 // it does not in any case affect the length of what it convert 5762 // it does not in any case affect the length of what it convert
5763 // to. 5763 // to.
5764 int char_length = mapping->get(current, 0, chars); 5764 int char_length = mapping->get(current, 0, chars);
5765 if (char_length == 0) char_length = 1; 5765 if (char_length == 0) char_length = 1;
5766 current_length += char_length; 5766 current_length += char_length;
5767 if (current_length > Smi::kMaxValue) { 5767 if (current_length > Smi::kMaxValue) {
5768 isolate->context()->mark_out_of_memory(); 5768 isolate->context()->mark_out_of_memory();
5769 return Failure::OutOfMemoryException(); 5769 return Failure::OutOfMemoryException();
(...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after
6953 x_scaled /= 10; 6953 x_scaled /= 10;
6954 tie = GREATER; 6954 tie = GREATER;
6955 } 6955 }
6956 6956
6957 if (x_scaled < y_scaled) return Smi::FromInt(LESS); 6957 if (x_scaled < y_scaled) return Smi::FromInt(LESS);
6958 if (x_scaled > y_scaled) return Smi::FromInt(GREATER); 6958 if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
6959 return Smi::FromInt(tie); 6959 return Smi::FromInt(tie);
6960 } 6960 }
6961 6961
6962 6962
6963 static Object* StringCharacterStreamCompare(RuntimeState* state, 6963 static Object* StringInputBufferCompare(RuntimeState* state,
6964 String* x, 6964 String* x,
6965 String* y) { 6965 String* y) {
6966 StringCharacterStream stream_x(x, state->string_iterator_compare_x()); 6966 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx();
6967 StringCharacterStream stream_y(y, state->string_iterator_compare_y()); 6967 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy();
6968 while (stream_x.HasMore() && stream_y.HasMore()) { 6968 bufx.Reset(x);
6969 int d = stream_x.GetNext() - stream_y.GetNext(); 6969 bufy.Reset(y);
6970 while (bufx.has_more() && bufy.has_more()) {
6971 int d = bufx.GetNext() - bufy.GetNext();
6970 if (d < 0) return Smi::FromInt(LESS); 6972 if (d < 0) return Smi::FromInt(LESS);
6971 else if (d > 0) return Smi::FromInt(GREATER); 6973 else if (d > 0) return Smi::FromInt(GREATER);
6972 } 6974 }
6973 6975
6974 // x is (non-trivial) prefix of y: 6976 // x is (non-trivial) prefix of y:
6975 if (stream_y.HasMore()) return Smi::FromInt(LESS); 6977 if (bufy.has_more()) return Smi::FromInt(LESS);
6976 // y is prefix of x: 6978 // y is prefix of x:
6977 return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL); 6979 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
6978 } 6980 }
6979 6981
6980 6982
6981 static Object* FlatStringCompare(String* x, String* y) { 6983 static Object* FlatStringCompare(String* x, String* y) {
6982 ASSERT(x->IsFlat()); 6984 ASSERT(x->IsFlat());
6983 ASSERT(y->IsFlat()); 6985 ASSERT(y->IsFlat());
6984 Object* equal_prefix_result = Smi::FromInt(EQUAL); 6986 Object* equal_prefix_result = Smi::FromInt(EQUAL);
6985 int prefix_length = x->length(); 6987 int prefix_length = x->length();
6986 if (y->length() < prefix_length) { 6988 if (y->length() < prefix_length) {
6987 prefix_length = y->length(); 6989 prefix_length = y->length();
(...skipping 23 matching lines...) Expand all
7011 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); 7013 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7012 } 7014 }
7013 } 7015 }
7014 Object* result; 7016 Object* result;
7015 if (r == 0) { 7017 if (r == 0) {
7016 result = equal_prefix_result; 7018 result = equal_prefix_result;
7017 } else { 7019 } else {
7018 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); 7020 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7019 } 7021 }
7020 ASSERT(result == 7022 ASSERT(result ==
7021 StringCharacterStreamCompare(Isolate::Current()->runtime_state(), x, y)); 7023 StringInputBufferCompare(Isolate::Current()->runtime_state(), x, y));
7022 return result; 7024 return result;
7023 } 7025 }
7024 7026
7025 7027
7026 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) { 7028 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
7027 NoHandleAllocation ha; 7029 NoHandleAllocation ha;
7028 ASSERT(args.length() == 2); 7030 ASSERT(args.length() == 2);
7029 7031
7030 CONVERT_ARG_CHECKED(String, x, 0); 7032 CONVERT_ARG_CHECKED(String, x, 0);
7031 CONVERT_ARG_CHECKED(String, y, 1); 7033 CONVERT_ARG_CHECKED(String, y, 1);
(...skipping 15 matching lines...) Expand all
7047 7049
7048 Object* obj; 7050 Object* obj;
7049 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x); 7051 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
7050 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7052 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7051 } 7053 }
7052 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y); 7054 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
7053 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7055 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7054 } 7056 }
7055 7057
7056 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) 7058 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
7057 : StringCharacterStreamCompare(isolate->runtime_state(), x, y); 7059 : StringInputBufferCompare(isolate->runtime_state(), x, y);
7058 } 7060 }
7059 7061
7060 7062
7061 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) { 7063 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
7062 NoHandleAllocation ha; 7064 NoHandleAllocation ha;
7063 ASSERT(args.length() == 1); 7065 ASSERT(args.length() == 1);
7064 isolate->counters()->math_acos()->Increment(); 7066 isolate->counters()->math_acos()->Increment();
7065 7067
7066 CONVERT_DOUBLE_ARG_CHECKED(x, 0); 7068 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7067 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x); 7069 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
(...skipping 2808 matching lines...) Expand 10 before | Expand all | Expand 10 after
9876 } 9878 }
9877 9879
9878 9880
9879 // This will not allocate (flatten the string), but it may run 9881 // This will not allocate (flatten the string), but it may run
9880 // very slowly for very deeply nested ConsStrings. For debugging use only. 9882 // very slowly for very deeply nested ConsStrings. For debugging use only.
9881 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) { 9883 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
9882 NoHandleAllocation ha; 9884 NoHandleAllocation ha;
9883 ASSERT(args.length() == 1); 9885 ASSERT(args.length() == 1);
9884 9886
9885 CONVERT_ARG_CHECKED(String, string, 0); 9887 CONVERT_ARG_CHECKED(String, string, 0);
9886 ConsStringIteratorOp op; 9888 StringInputBuffer buffer(string);
9887 StringCharacterStream stream(string, &op); 9889 while (buffer.has_more()) {
9888 while (stream.HasMore()) { 9890 uint16_t character = buffer.GetNext();
9889 uint16_t character = stream.GetNext();
9890 PrintF("%c", character); 9891 PrintF("%c", character);
9891 } 9892 }
9892 return string; 9893 return string;
9893 } 9894 }
9894 9895
9895 // Moves all own elements of an object, that are below a limit, to positions 9896 // Moves all own elements of an object, that are below a limit, to positions
9896 // starting at zero. All undefined values are placed after non-undefined values, 9897 // starting at zero. All undefined values are placed after non-undefined values,
9897 // and are followed by non-existing element. Does not change the length 9898 // and are followed by non-existing element. Does not change the length
9898 // property. 9899 // property.
9899 // Returns the number of non-undefined elements collected. 9900 // Returns the number of non-undefined elements collected.
(...skipping 3750 matching lines...) Expand 10 before | Expand all | Expand 10 after
13650 // Handle last resort GC and make sure to allow future allocations 13651 // Handle last resort GC and make sure to allow future allocations
13651 // to grow the heap without causing GCs (if possible). 13652 // to grow the heap without causing GCs (if possible).
13652 isolate->counters()->gc_last_resort_from_js()->Increment(); 13653 isolate->counters()->gc_last_resort_from_js()->Increment();
13653 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13654 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13654 "Runtime::PerformGC"); 13655 "Runtime::PerformGC");
13655 } 13656 }
13656 } 13657 }
13657 13658
13658 13659
13659 } } // namespace v8::internal 13660 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698