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

Side by Side Diff: src/runtime.cc

Issue 11727003: Reland 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 StringInputBuffer& buf1 = 3492 ConsStringIteratorOp* op1 =
3493 *isolate->runtime_state()->string_locale_compare_buf1(); 3493 isolate->runtime_state()->string_locale_compare_it1();
3494 StringInputBuffer& buf2 = 3494 ConsStringIteratorOp* op2 =
3495 *isolate->runtime_state()->string_locale_compare_buf2(); 3495 isolate->runtime_state()->string_locale_compare_it2();
3496 3496 // TODO(dcarney) Can do array compares here more efficiently.
3497 buf1.Reset(str1); 3497 StringCharacterStream stream1(str1, op1);
3498 buf2.Reset(str2); 3498 StringCharacterStream stream2(str2, op2);
3499 3499
3500 for (int i = 0; i < end; i++) { 3500 for (int i = 0; i < end; i++) {
3501 uint16_t char1 = buf1.GetNext(); 3501 uint16_t char1 = stream1.GetNext();
3502 uint16_t char2 = buf2.GetNext(); 3502 uint16_t char2 = stream2.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<StringInputBuffer> buffer( 5146 Access<ConsStringIteratorOp> op(
5147 isolate->runtime_state()->string_input_buffer()); 5147 isolate->runtime_state()->string_iterator());
5148 buffer->Reset(source); 5148 StringCharacterStream stream(source, op.value());
5149 while (buffer->has_more()) { 5149 while (stream.HasMore()) {
5150 uint16_t character = buffer->GetNext(); 5150 uint16_t character = stream.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<StringInputBuffer> buffer( 5178 Access<ConsStringIteratorOp> op(
5179 isolate->runtime_state()->string_input_buffer()); 5179 isolate->runtime_state()->string_iterator());
5180 buffer->Rewind(); 5180 StringCharacterStream stream(source, op.value());
5181 while (buffer->has_more()) { 5181 while (stream.HasMore()) {
5182 uint16_t chr = buffer->GetNext(); 5182 uint16_t chr = stream.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<StringInputBuffer> buffer( 5720 Access<ConsStringIteratorOp> op(
5721 isolate->runtime_state()->string_input_buffer()); 5721 isolate->runtime_state()->string_iterator());
5722 buffer->Reset(s); 5722 StringCharacterStream stream(s, op.value());
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 = buffer->GetNext(); 5725 uc32 current = stream.GetNext();
5726 for (int i = 0; i < length;) { 5726 for (int i = 0; i < length;) {
5727 bool has_next = buffer->has_more(); 5727 bool has_next = stream.HasMore();
5728 uc32 next = has_next ? buffer->GetNext() : 0; 5728 uc32 next = has_next ? stream.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 (buffer->has_more()) { 5758 while (stream.HasMore()) {
5759 current = buffer->GetNext(); 5759 current = stream.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* StringInputBufferCompare(RuntimeState* state, 6963 static Object* StringCharacterStreamCompare(RuntimeState* state,
6964 String* x, 6964 String* x,
6965 String* y) { 6965 String* y) {
6966 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); 6966 StringCharacterStream stream_x(x, state->string_iterator_compare_x());
6967 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); 6967 StringCharacterStream stream_y(y, state->string_iterator_compare_y());
6968 bufx.Reset(x); 6968 while (stream_x.HasMore() && stream_y.HasMore()) {
6969 bufy.Reset(y); 6969 int d = stream_x.GetNext() - stream_y.GetNext();
6970 while (bufx.has_more() && bufy.has_more()) {
6971 int d = bufx.GetNext() - bufy.GetNext();
6972 if (d < 0) return Smi::FromInt(LESS); 6970 if (d < 0) return Smi::FromInt(LESS);
6973 else if (d > 0) return Smi::FromInt(GREATER); 6971 else if (d > 0) return Smi::FromInt(GREATER);
6974 } 6972 }
6975 6973
6976 // x is (non-trivial) prefix of y: 6974 // x is (non-trivial) prefix of y:
6977 if (bufy.has_more()) return Smi::FromInt(LESS); 6975 if (stream_y.HasMore()) return Smi::FromInt(LESS);
6978 // y is prefix of x: 6976 // y is prefix of x:
6979 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); 6977 return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
6980 } 6978 }
6981 6979
6982 6980
6983 static Object* FlatStringCompare(String* x, String* y) { 6981 static Object* FlatStringCompare(String* x, String* y) {
6984 ASSERT(x->IsFlat()); 6982 ASSERT(x->IsFlat());
6985 ASSERT(y->IsFlat()); 6983 ASSERT(y->IsFlat());
6986 Object* equal_prefix_result = Smi::FromInt(EQUAL); 6984 Object* equal_prefix_result = Smi::FromInt(EQUAL);
6987 int prefix_length = x->length(); 6985 int prefix_length = x->length();
6988 if (y->length() < prefix_length) { 6986 if (y->length() < prefix_length) {
6989 prefix_length = y->length(); 6987 prefix_length = y->length();
(...skipping 23 matching lines...) Expand all
7013 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); 7011 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7014 } 7012 }
7015 } 7013 }
7016 Object* result; 7014 Object* result;
7017 if (r == 0) { 7015 if (r == 0) {
7018 result = equal_prefix_result; 7016 result = equal_prefix_result;
7019 } else { 7017 } else {
7020 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); 7018 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7021 } 7019 }
7022 ASSERT(result == 7020 ASSERT(result ==
7023 StringInputBufferCompare(Isolate::Current()->runtime_state(), x, y)); 7021 StringCharacterStreamCompare(Isolate::Current()->runtime_state(), x, y));
7024 return result; 7022 return result;
7025 } 7023 }
7026 7024
7027 7025
7028 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) { 7026 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
7029 NoHandleAllocation ha; 7027 NoHandleAllocation ha;
7030 ASSERT(args.length() == 2); 7028 ASSERT(args.length() == 2);
7031 7029
7032 CONVERT_ARG_CHECKED(String, x, 0); 7030 CONVERT_ARG_CHECKED(String, x, 0);
7033 CONVERT_ARG_CHECKED(String, y, 1); 7031 CONVERT_ARG_CHECKED(String, y, 1);
(...skipping 15 matching lines...) Expand all
7049 7047
7050 Object* obj; 7048 Object* obj;
7051 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x); 7049 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
7052 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7050 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7053 } 7051 }
7054 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y); 7052 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
7055 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7053 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7056 } 7054 }
7057 7055
7058 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) 7056 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
7059 : StringInputBufferCompare(isolate->runtime_state(), x, y); 7057 : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
7060 } 7058 }
7061 7059
7062 7060
7063 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) { 7061 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
7064 NoHandleAllocation ha; 7062 NoHandleAllocation ha;
7065 ASSERT(args.length() == 1); 7063 ASSERT(args.length() == 1);
7066 isolate->counters()->math_acos()->Increment(); 7064 isolate->counters()->math_acos()->Increment();
7067 7065
7068 CONVERT_DOUBLE_ARG_CHECKED(x, 0); 7066 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7069 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x); 7067 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
(...skipping 2808 matching lines...) Expand 10 before | Expand all | Expand 10 after
9878 } 9876 }
9879 9877
9880 9878
9881 // This will not allocate (flatten the string), but it may run 9879 // This will not allocate (flatten the string), but it may run
9882 // very slowly for very deeply nested ConsStrings. For debugging use only. 9880 // very slowly for very deeply nested ConsStrings. For debugging use only.
9883 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) { 9881 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
9884 NoHandleAllocation ha; 9882 NoHandleAllocation ha;
9885 ASSERT(args.length() == 1); 9883 ASSERT(args.length() == 1);
9886 9884
9887 CONVERT_ARG_CHECKED(String, string, 0); 9885 CONVERT_ARG_CHECKED(String, string, 0);
9888 StringInputBuffer buffer(string); 9886 ConsStringIteratorOp op;
9889 while (buffer.has_more()) { 9887 StringCharacterStream stream(string, &op);
9890 uint16_t character = buffer.GetNext(); 9888 while (stream.HasMore()) {
9889 uint16_t character = stream.GetNext();
9891 PrintF("%c", character); 9890 PrintF("%c", character);
9892 } 9891 }
9893 return string; 9892 return string;
9894 } 9893 }
9895 9894
9896 // Moves all own elements of an object, that are below a limit, to positions 9895 // Moves all own elements of an object, that are below a limit, to positions
9897 // starting at zero. All undefined values are placed after non-undefined values, 9896 // starting at zero. All undefined values are placed after non-undefined values,
9898 // and are followed by non-existing element. Does not change the length 9897 // and are followed by non-existing element. Does not change the length
9899 // property. 9898 // property.
9900 // Returns the number of non-undefined elements collected. 9899 // Returns the number of non-undefined elements collected.
(...skipping 3720 matching lines...) Expand 10 before | Expand all | Expand 10 after
13621 // Handle last resort GC and make sure to allow future allocations 13620 // Handle last resort GC and make sure to allow future allocations
13622 // to grow the heap without causing GCs (if possible). 13621 // to grow the heap without causing GCs (if possible).
13623 isolate->counters()->gc_last_resort_from_js()->Increment(); 13622 isolate->counters()->gc_last_resort_from_js()->Increment();
13624 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13623 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13625 "Runtime::PerformGC"); 13624 "Runtime::PerformGC");
13626 } 13625 }
13627 } 13626 }
13628 13627
13629 13628
13630 } } // namespace v8::internal 13629 } } // 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