| Index: src/runtime/runtime-typedarray.cc
|
| diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc
|
| index c820cf6f53e0c412ace6e42366e6ef3c1fe7b9ea..4ca7bbb009fb431e9d684e8d96d5d004dfbd10cf 100644
|
| --- a/src/runtime/runtime-typedarray.cc
|
| +++ b/src/runtime/runtime-typedarray.cc
|
| @@ -369,22 +369,24 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
|
|
|
| namespace {
|
|
|
| -#define TYPED_ARRAY_SORT_COMPAREFN(Type, type, TYPE, ctype, size) \
|
| - bool compare##Type(ctype x, ctype y) { \
|
| - if (x < y) { \
|
| - return true; \
|
| - } else if (x > y) { \
|
| - return false; \
|
| - } else if (x == 0 && x == y) { \
|
| - return std::signbit(static_cast<double>(x)) ? true : false; \
|
| - } else if (std::isnan(static_cast<double>(x))) { \
|
| - return false; \
|
| - } \
|
| - return true; \
|
| +template <typename T>
|
| +bool CompareNum(T x, T y) {
|
| + if (x < y) {
|
| + return true;
|
| + } else if (x > y) {
|
| + return false;
|
| + } else if (!std::is_integral<T>::value) {
|
| + double _x = x, _y = y;
|
| + if (x == 0 && x == y) {
|
| + /* -0.0 is less than +0.0 */
|
| + return std::signbit(_x) && !std::signbit(_y);
|
| + } else if (!std::isnan(_x) && std::isnan(_y)) {
|
| + /* number is less than NaN */
|
| + return true;
|
| + }
|
| }
|
| -
|
| -TYPED_ARRAYS(TYPED_ARRAY_SORT_COMPAREFN)
|
| -#undef TYPED_ARRAY_SORT_COMPAREFN
|
| + return false;
|
| +}
|
|
|
| } // namespace
|
|
|
| @@ -399,20 +401,25 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
|
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| isolate, array, JSTypedArray::Validate(isolate, target_obj, method));
|
|
|
| - // This line can be remove when JSTypedArray::Validate throws
|
| + // This line can be removed when JSTypedArray::Validate throws
|
| // if array.[[ViewedArrayBuffer]] is neutered(v8:4648)
|
| if (V8_UNLIKELY(array->WasNeutered())) return *array;
|
|
|
| size_t length = array->length_value();
|
| - if (length == 0) return *array;
|
| + if (length <= 1) return *array;
|
|
|
| + Handle<FixedTypedArrayBase> elements(
|
| + FixedTypedArrayBase::cast(array->elements()));
|
| switch (array->type()) {
|
| -#define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \
|
| - case kExternal##Type##Array: { \
|
| - ctype* backing_store = \
|
| - static_cast<ctype*>(array->GetBuffer()->backing_store()); \
|
| - std::sort(backing_store, backing_store + length, compare##Type); \
|
| - break; \
|
| +#define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \
|
| + case kExternal##Type##Array: { \
|
| + ctype* data = static_cast<ctype*>(elements->DataPtr()); \
|
| + if (kExternal##Type##Array == kExternalFloat64Array || \
|
| + kExternal##Type##Array == kExternalFloat32Array) \
|
| + std::sort(data, data + length, CompareNum<ctype>); \
|
| + else \
|
| + std::sort(data, data + length); \
|
| + break; \
|
| }
|
|
|
| TYPED_ARRAYS(TYPED_ARRAY_SORT)
|
|
|