Commit 32ec5335 authored by cwhan.tunz's avatar cwhan.tunz Committed by Commit bot

[typedarrays] sort in C++ for no comparison function

- If no comparison function is given for %TypedArray%.prototype.sort,
sort the typedarray using std::sort in C++. This gets 20 times more
benchmark score in Float64Array.
- Move ValidateTypedArray in builtin-typedarray.cc to static inline
method of JSTypedArray class.

BUG=v8:5953

Review-Url: https://codereview.chromium.org/2693043009
Cr-Commit-Position: refs/heads/master@{#43427}
parent 64a563c9
......@@ -148,18 +148,6 @@ TF_BUILTIN(TypedArrayPrototypeKeys, TypedArrayBuiltinsAssembler) {
namespace {
MaybeHandle<JSTypedArray> ValidateTypedArray(Isolate* isolate,
Handle<Object> receiver,
const char* method_name) {
if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
const MessageTemplate::Template message = MessageTemplate::kNotTypedArray;
THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
}
// TODO(caitp): throw if array.[[ViewedArrayBuffer]] is neutered (per v8:4648)
return Handle<JSTypedArray>::cast(receiver);
}
int64_t CapRelativeIndex(Handle<Object> num, int64_t minimum, int64_t maximum) {
int64_t relative;
if (V8_LIKELY(num->IsSmi())) {
......@@ -186,7 +174,7 @@ BUILTIN(TypedArrayPrototypeCopyWithin) {
Handle<JSTypedArray> array;
const char* method = "%TypedArray%.prototype.copyWithin";
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, array, ValidateTypedArray(isolate, args.receiver(), method));
isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
if (V8_UNLIKELY(array->WasNeutered())) return *array;
......
......@@ -517,25 +517,6 @@ function TypedArrayReverse() {
return PackedArrayReverse(this, length);
}
function TypedArrayComparefn(x, y) {
if (x === 0 && x === y) {
x = 1 / x;
y = 1 / y;
}
if (x < y) {
return -1;
} else if (x > y) {
return 1;
} else if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) {
return NUMBER_IS_NAN(y) ? 0 : 1;
} else if (NUMBER_IS_NAN(x)) {
return 1;
}
return 0;
}
// ES6 draft 05-18-15, section 22.2.3.25
function TypedArraySort(comparefn) {
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
......@@ -543,7 +524,7 @@ function TypedArraySort(comparefn) {
var length = %_TypedArrayGetLength(this);
if (IS_UNDEFINED(comparefn)) {
comparefn = TypedArrayComparefn;
return %TypedArraySortFast(this);
}
return InnerArraySort(this, length, comparefn);
......
......@@ -6927,6 +6927,18 @@ void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kLengthOffset, value, mode);
}
// static
MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name) {
if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
const MessageTemplate::Template message = MessageTemplate::kNotTypedArray;
THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
}
// TODO(caitp): throw if array.[[ViewedArrayBuffer]] is neutered (per v8:4648)
return Handle<JSTypedArray>::cast(receiver);
}
#ifdef VERIFY_HEAP
ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
......
......@@ -10793,6 +10793,10 @@ class JSTypedArray: public JSArrayBufferView {
Handle<JSArrayBuffer> GetBuffer();
static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name);
// Dispatched behavior.
DECLARE_PRINTER(JSTypedArray)
DECLARE_VERIFIER(JSTypedArray)
......
......@@ -367,6 +367,60 @@ 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; \
}
TYPED_ARRAYS(TYPED_ARRAY_SORT_COMPAREFN)
#undef TYPED_ARRAY_SORT_COMPAREFN
} // namespace
RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
Handle<JSTypedArray> array;
const char* method = "%TypedArray%.prototype.sort";
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, array, JSTypedArray::Validate(isolate, target_obj, method));
// This line can be remove 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;
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; \
}
TYPED_ARRAYS(TYPED_ARRAY_SORT)
#undef TYPED_ARRAY_SORT
}
return *array;
}
RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
DCHECK_EQ(0, args.length());
......
......@@ -614,6 +614,7 @@ namespace internal {
F(TypedArrayGetLength, 1, 1) \
F(TypedArrayGetBuffer, 1, 1) \
F(TypedArraySetFastCases, 3, 1) \
F(TypedArraySortFast, 1, 1) \
F(TypedArrayMaxSizeInHeap, 0, 1) \
F(IsTypedArray, 1, 1) \
F(IsSharedTypedArray, 1, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment