| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 DCHECK(target->GetBuffer()->backing_store() == | 362 DCHECK(target->GetBuffer()->backing_store() == |
| 363 source->GetBuffer()->backing_store()); | 363 source->GetBuffer()->backing_store()); |
| 364 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); | 364 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); |
| 365 } else { // Non-overlapping typed arrays | 365 } else { // Non-overlapping typed arrays |
| 366 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); | 366 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); |
| 367 } | 367 } |
| 368 } | 368 } |
| 369 | 369 |
| 370 namespace { | 370 namespace { |
| 371 | 371 |
| 372 #define TYPED_ARRAY_SORT_COMPAREFN(Type, type, TYPE, ctype, size) \ | 372 template <typename T> |
| 373 bool compare##Type(ctype x, ctype y) { \ | 373 bool CompareNum(T x, T y) { |
| 374 if (x < y) { \ | 374 if (x < y) { |
| 375 return true; \ | 375 return true; |
| 376 } else if (x > y) { \ | 376 } else if (x > y) { |
| 377 return false; \ | 377 return false; |
| 378 } else if (x == 0 && x == y) { \ | 378 } else if (!std::is_integral<T>::value) { |
| 379 return std::signbit(static_cast<double>(x)) ? true : false; \ | 379 double _x = x, _y = y; |
| 380 } else if (std::isnan(static_cast<double>(x))) { \ | 380 if (x == 0 && x == y) { |
| 381 return false; \ | 381 /* -0.0 is less than +0.0 */ |
| 382 } \ | 382 return std::signbit(_x) && !std::signbit(_y); |
| 383 return true; \ | 383 } else if (!std::isnan(_x) && std::isnan(_y)) { |
| 384 /* number is less than NaN */ |
| 385 return true; |
| 386 } |
| 384 } | 387 } |
| 385 | 388 return false; |
| 386 TYPED_ARRAYS(TYPED_ARRAY_SORT_COMPAREFN) | 389 } |
| 387 #undef TYPED_ARRAY_SORT_COMPAREFN | |
| 388 | 390 |
| 389 } // namespace | 391 } // namespace |
| 390 | 392 |
| 391 RUNTIME_FUNCTION(Runtime_TypedArraySortFast) { | 393 RUNTIME_FUNCTION(Runtime_TypedArraySortFast) { |
| 392 HandleScope scope(isolate); | 394 HandleScope scope(isolate); |
| 393 DCHECK_EQ(1, args.length()); | 395 DCHECK_EQ(1, args.length()); |
| 394 | 396 |
| 395 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); | 397 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); |
| 396 | 398 |
| 397 Handle<JSTypedArray> array; | 399 Handle<JSTypedArray> array; |
| 398 const char* method = "%TypedArray%.prototype.sort"; | 400 const char* method = "%TypedArray%.prototype.sort"; |
| 399 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 401 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 400 isolate, array, JSTypedArray::Validate(isolate, target_obj, method)); | 402 isolate, array, JSTypedArray::Validate(isolate, target_obj, method)); |
| 401 | 403 |
| 402 // This line can be remove when JSTypedArray::Validate throws | 404 // This line can be removed when JSTypedArray::Validate throws |
| 403 // if array.[[ViewedArrayBuffer]] is neutered(v8:4648) | 405 // if array.[[ViewedArrayBuffer]] is neutered(v8:4648) |
| 404 if (V8_UNLIKELY(array->WasNeutered())) return *array; | 406 if (V8_UNLIKELY(array->WasNeutered())) return *array; |
| 405 | 407 |
| 406 size_t length = array->length_value(); | 408 size_t length = array->length_value(); |
| 407 if (length == 0) return *array; | 409 if (length <= 1) return *array; |
| 408 | 410 |
| 411 Handle<FixedTypedArrayBase> elements( |
| 412 FixedTypedArrayBase::cast(array->elements())); |
| 409 switch (array->type()) { | 413 switch (array->type()) { |
| 410 #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \ | 414 #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \ |
| 411 case kExternal##Type##Array: { \ | 415 case kExternal##Type##Array: { \ |
| 412 ctype* backing_store = \ | 416 ctype* data = static_cast<ctype*>(elements->DataPtr()); \ |
| 413 static_cast<ctype*>(array->GetBuffer()->backing_store()); \ | 417 if (kExternal##Type##Array == kExternalFloat64Array || \ |
| 414 std::sort(backing_store, backing_store + length, compare##Type); \ | 418 kExternal##Type##Array == kExternalFloat32Array) \ |
| 415 break; \ | 419 std::sort(data, data + length, CompareNum<ctype>); \ |
| 420 else \ |
| 421 std::sort(data, data + length); \ |
| 422 break; \ |
| 416 } | 423 } |
| 417 | 424 |
| 418 TYPED_ARRAYS(TYPED_ARRAY_SORT) | 425 TYPED_ARRAYS(TYPED_ARRAY_SORT) |
| 419 #undef TYPED_ARRAY_SORT | 426 #undef TYPED_ARRAY_SORT |
| 420 } | 427 } |
| 421 | 428 |
| 422 return *array; | 429 return *array; |
| 423 } | 430 } |
| 424 | 431 |
| 425 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { | 432 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 return isolate->heap()->false_value(); | 475 return isolate->heap()->false_value(); |
| 469 } | 476 } |
| 470 | 477 |
| 471 Handle<JSTypedArray> obj(JSTypedArray::cast(args[0])); | 478 Handle<JSTypedArray> obj(JSTypedArray::cast(args[0])); |
| 472 return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() && | 479 return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() && |
| 473 obj->type() == kExternalInt32Array); | 480 obj->type() == kExternalInt32Array); |
| 474 } | 481 } |
| 475 | 482 |
| 476 } // namespace internal | 483 } // namespace internal |
| 477 } // namespace v8 | 484 } // namespace v8 |
| OLD | NEW |