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

Side by Side Diff: src/runtime.cc

Issue 650058: Improve string runtime compare performance for flat strings. (Closed)
Patch Set: Created 10 years, 10 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
« no previous file with comments | « src/objects.h ('k') | src/utils.h » ('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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 4575 matching lines...) Expand 10 before | Expand all | Expand 10 after
4586 if (diff != 0) return Smi::FromInt(diff); 4586 if (diff != 0) return Smi::FromInt(diff);
4587 } 4587 }
4588 4588
4589 // If one array is a suffix of the other array, the longest array is 4589 // If one array is a suffix of the other array, the longest array is
4590 // the representation of the largest of the Smis in the 4590 // the representation of the largest of the Smis in the
4591 // lexicographic ordering. 4591 // lexicographic ordering.
4592 return Smi::FromInt(x_index - y_index); 4592 return Smi::FromInt(x_index - y_index);
4593 } 4593 }
4594 4594
4595 4595
4596 static Object* StringInputBufferCompare(String* x, String* y) {
4597 static StringInputBuffer bufx;
4598 static StringInputBuffer bufy;
4599 bufx.Reset(x);
4600 bufy.Reset(y);
4601 while (bufx.has_more() && bufy.has_more()) {
4602 int d = bufx.GetNext() - bufy.GetNext();
4603 if (d < 0) return Smi::FromInt(LESS);
4604 else if (d > 0) return Smi::FromInt(GREATER);
4605 }
4606
4607 // x is (non-trivial) prefix of y:
4608 if (bufy.has_more()) return Smi::FromInt(LESS);
4609 // y is prefix of x:
4610 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
4611 }
4612
4613
4596 static Object* Runtime_StringCompare(Arguments args) { 4614 static Object* Runtime_StringCompare(Arguments args) {
4597 NoHandleAllocation ha; 4615 NoHandleAllocation ha;
4598 ASSERT(args.length() == 2); 4616 ASSERT(args.length() == 2);
4599 4617
4600 CONVERT_CHECKED(String, x, args[0]); 4618 CONVERT_CHECKED(String, x, args[0]);
4601 CONVERT_CHECKED(String, y, args[1]); 4619 CONVERT_CHECKED(String, y, args[1]);
4602 4620
4603 Counters::string_compare_runtime.Increment(); 4621 Counters::string_compare_runtime.Increment();
4604 4622
4605 // A few fast case tests before we flatten. 4623 // A few fast case tests before we flatten.
4606 if (x == y) return Smi::FromInt(EQUAL); 4624 if (x == y) return Smi::FromInt(EQUAL);
4607 if (y->length() == 0) { 4625 if (y->length() == 0) {
4608 if (x->length() == 0) return Smi::FromInt(EQUAL); 4626 if (x->length() == 0) return Smi::FromInt(EQUAL);
4609 return Smi::FromInt(GREATER); 4627 return Smi::FromInt(GREATER);
4610 } else if (x->length() == 0) { 4628 } else if (x->length() == 0) {
4611 return Smi::FromInt(LESS); 4629 return Smi::FromInt(LESS);
4612 } 4630 }
4613 4631
4614 int d = x->Get(0) - y->Get(0); 4632 int d = x->Get(0) - y->Get(0);
4615 if (d < 0) return Smi::FromInt(LESS); 4633 if (d < 0) return Smi::FromInt(LESS);
4616 else if (d > 0) return Smi::FromInt(GREATER); 4634 else if (d > 0) return Smi::FromInt(GREATER);
4617 4635
4618 x->TryFlattenIfNotFlat(); 4636 x->TryFlattenIfNotFlat();
4619 y->TryFlattenIfNotFlat(); 4637 y->TryFlattenIfNotFlat();
4620 4638
4621 static StringInputBuffer bufx; 4639 if (x->IsFlat() && y->IsFlat()) {
Søren Thygesen Gjesse 2010/02/22 10:14:00 How about moving the body of this if into a functi
Vitaly Repeshko 2010/02/25 12:50:10 Done.
4622 static StringInputBuffer bufy; 4640 Object* equal_prefix_result = Smi::FromInt(EQUAL);
4623 bufx.Reset(x); 4641 int prefix_length = x->length();
4624 bufy.Reset(y); 4642 if (y->length() < prefix_length) {
4625 while (bufx.has_more() && bufy.has_more()) { 4643 prefix_length = y->length();
4626 int d = bufx.GetNext() - bufy.GetNext(); 4644 equal_prefix_result = Smi::FromInt(GREATER);
4627 if (d < 0) return Smi::FromInt(LESS); 4645 } else if (y->length() > prefix_length) {
4628 else if (d > 0) return Smi::FromInt(GREATER); 4646 equal_prefix_result = Smi::FromInt(LESS);
4647 }
4648 int r;
4649 if (x->IsAsciiRepresentation()) {
4650 Vector<const char> x_chars = x->ToAsciiVector();
4651 if (y->IsAsciiRepresentation()) {
4652 Vector<const char> y_chars = y->ToAsciiVector();
4653 r = memcmp(x_chars.start(), y_chars.start(), prefix_length);
4654 } else {
4655 Vector<const uc16> y_chars = y->ToUC16Vector();
4656 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
4657 }
4658 } else {
4659 Vector<const uc16> x_chars = x->ToUC16Vector();
4660 if (y->IsAsciiRepresentation()) {
4661 Vector<const char> y_chars = y->ToAsciiVector();
4662 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
4663 } else {
4664 Vector<const uc16> y_chars = y->ToUC16Vector();
4665 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
Søren Thygesen Gjesse 2010/02/22 10:14:00 There is a wmemcmp in wchar.h - don't know if it m
Vitaly Repeshko 2010/02/25 12:50:10 I'm worried about variations in wchar_t definition
4666 }
4667 }
4668 Object* result;
4669 if (r == 0) {
4670 result = equal_prefix_result;
4671 } else {
4672 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
4673 }
4674 ASSERT(result == StringInputBufferCompare(x, y));
4675 return result;
4629 } 4676 }
4630 4677
4631 // x is (non-trivial) prefix of y: 4678 return StringInputBufferCompare(x, y);
4632 if (bufy.has_more()) return Smi::FromInt(LESS);
4633 // y is prefix of x:
4634 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
4635 } 4679 }
4636 4680
4637 4681
4638 static Object* Runtime_Math_abs(Arguments args) { 4682 static Object* Runtime_Math_abs(Arguments args) {
4639 NoHandleAllocation ha; 4683 NoHandleAllocation ha;
4640 ASSERT(args.length() == 1); 4684 ASSERT(args.length() == 1);
4641 4685
4642 CONVERT_DOUBLE_CHECKED(x, args[0]); 4686 CONVERT_DOUBLE_CHECKED(x, args[0]);
4643 return Heap::AllocateHeapNumber(fabs(x)); 4687 return Heap::AllocateHeapNumber(fabs(x));
4644 } 4688 }
(...skipping 3619 matching lines...) Expand 10 before | Expand all | Expand 10 after
8264 } else { 8308 } else {
8265 // Handle last resort GC and make sure to allow future allocations 8309 // Handle last resort GC and make sure to allow future allocations
8266 // to grow the heap without causing GCs (if possible). 8310 // to grow the heap without causing GCs (if possible).
8267 Counters::gc_last_resort_from_js.Increment(); 8311 Counters::gc_last_resort_from_js.Increment();
8268 Heap::CollectAllGarbage(false); 8312 Heap::CollectAllGarbage(false);
8269 } 8313 }
8270 } 8314 }
8271 8315
8272 8316
8273 } } // namespace v8::internal 8317 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698