From a0aed63bbb479ae933d7098336e0d7ef09f58e3f Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Wed, 24 Apr 2013 11:20:16 +0000 Subject: [PATCH] Replace qsort with std::sort. std::sort is a template, so it can be inlined more aggressively. Also, it's O(n log n), while libc's qsort is O(n^2) BUG=2639 Review URL: https://codereview.chromium.org/14315005 Patch from Jochen Eisinger . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14406 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/d8.cc | 14 ++++++++++---- src/hydrogen.cc | 23 ++++++++++------------- src/list-inl.h | 2 +- src/store-buffer.cc | 38 +++++--------------------------------- src/store-buffer.h | 2 ++ src/utils.h | 20 ++++++++++++++------ 6 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/d8.cc b/src/d8.cc index fe9fdca550..22ace174d2 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -42,6 +42,13 @@ #ifdef V8_SHARED #include +#endif // V8_SHARED + +#ifndef V8_SHARED +#include +#endif // !V8_SHARED + +#ifdef V8_SHARED #include "../include/v8-testing.h" #endif // V8_SHARED @@ -1573,9 +1580,8 @@ struct CounterAndKey { }; -int CompareKeys(const void* a, const void* b) { - return strcmp(static_cast(a)->key, - static_cast(b)->key); +inline bool operator<(const CounterAndKey& lhs, const CounterAndKey& rhs) { + return strcmp(lhs.key, rhs.key) < 0; } #endif // V8_SHARED @@ -1595,7 +1601,7 @@ void Shell::OnExit() { counters[j].counter = i.CurrentValue(); counters[j].key = i.CurrentKey(); } - qsort(counters, number_of_counters, sizeof(counters[0]), CompareKeys); + std::sort(counters, counters + number_of_counters); printf("+----------------------------------------------------------------+" "-------------+\n"); printf("| Name |" diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 20e1d0d341..610266f3ec 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -25,9 +25,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "v8.h" #include "hydrogen.h" +#include + +#include "v8.h" #include "codegen.h" #include "full-codegen.h" #include "hashmap.h" @@ -8006,14 +8008,12 @@ class FunctionSorter { }; -static int CompareHotness(void const* a, void const* b) { - FunctionSorter const* function1 = reinterpret_cast(a); - FunctionSorter const* function2 = reinterpret_cast(b); - int diff = function1->ticks() - function2->ticks(); - if (diff != 0) return -diff; - diff = function1->ast_length() - function2->ast_length(); - if (diff != 0) return diff; - return function1->src_length() - function2->src_length(); +inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { + int diff = lhs.ticks() - rhs.ticks(); + if (diff != 0) return diff > 0; + diff = lhs.ast_length() - rhs.ast_length(); + if (diff != 0) return diff < 0; + return lhs.src_length() < rhs.src_length(); } @@ -8056,10 +8056,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( } } - qsort(reinterpret_cast(&order[0]), - ordered_functions, - sizeof(order[0]), - &CompareHotness); + std::sort(order, order + ordered_functions); HBasicBlock* number_block = NULL; diff --git a/src/list-inl.h b/src/list-inl.h index 408859e456..d815a7e227 100644 --- a/src/list-inl.h +++ b/src/list-inl.h @@ -216,7 +216,7 @@ void List::Sort(int (*cmp)(const T* x, const T* y)) { template void List::Sort() { - Sort(PointerValueCompare); + ToVector().Sort(); } diff --git a/src/store-buffer.cc b/src/store-buffer.cc index 8a69164039..7d73dd5ed1 100644 --- a/src/store-buffer.cc +++ b/src/store-buffer.cc @@ -25,9 +25,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "v8.h" - #include "store-buffer.h" + +#include + +#include "v8.h" #include "store-buffer-inl.h" #include "v8-counters.h" @@ -122,33 +124,6 @@ void StoreBuffer::StoreBufferOverflow(Isolate* isolate) { } -#if V8_TARGET_ARCH_X64 -static int CompareAddresses(const void* void_a, const void* void_b) { - intptr_t a = - reinterpret_cast(*reinterpret_cast(void_a)); - intptr_t b = - reinterpret_cast(*reinterpret_cast(void_b)); - // Unfortunately if int is smaller than intptr_t there is no branch-free - // way to return a number with the same sign as the difference between the - // pointers. - if (a == b) return 0; - if (a < b) return -1; - ASSERT(a > b); - return 1; -} -#else -static int CompareAddresses(const void* void_a, const void* void_b) { - intptr_t a = - reinterpret_cast(*reinterpret_cast(void_a)); - intptr_t b = - reinterpret_cast(*reinterpret_cast(void_b)); - ASSERT(sizeof(1) == sizeof(a)); - // Shift down to avoid wraparound. - return (a >> kPointerSizeLog2) - (b >> kPointerSizeLog2); -} -#endif - - void StoreBuffer::Uniq() { // Remove adjacent duplicates and cells that do not point at new space. Address previous = NULL; @@ -283,10 +258,7 @@ void StoreBuffer::Filter(int flag) { void StoreBuffer::SortUniq() { Compact(); if (old_buffer_is_sorted_) return; - qsort(reinterpret_cast(old_start_), - old_top_ - old_start_, - sizeof(*old_top_), - &CompareAddresses); + std::sort(old_start_, old_top_); Uniq(); old_buffer_is_sorted_ = true; diff --git a/src/store-buffer.h b/src/store-buffer.h index 79046d1540..514534a1ed 100644 --- a/src/store-buffer.h +++ b/src/store-buffer.h @@ -37,6 +37,8 @@ namespace v8 { namespace internal { +class Page; +class PagedSpace; class StoreBuffer; typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to); diff --git a/src/utils.h b/src/utils.h index b84d592386..b2c2ff1098 100644 --- a/src/utils.h +++ b/src/utils.h @@ -30,6 +30,7 @@ #include #include +#include #include #include "allocation.h" @@ -410,15 +411,11 @@ class Vector { } void Sort(int (*cmp)(const T*, const T*)) { - typedef int (*RawComparer)(const void*, const void*); - qsort(start(), - length(), - sizeof(T), - reinterpret_cast(cmp)); + std::sort(start(), start() + length(), RawComparer(cmp)); } void Sort() { - Sort(PointerValueCompare); + std::sort(start(), start() + length()); } void Truncate(int length) { @@ -454,6 +451,17 @@ class Vector { private: T* start_; int length_; + + class RawComparer { + public: + explicit RawComparer(int (*cmp)(const T*, const T*)) : cmp_(cmp) {} + bool operator()(const T& a, const T& b) { + return cmp_(&a, &b) < 0; + } + + private: + int (*cmp_)(const T*, const T*); + }; };