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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 DCHECK(target->GetBuffer()->backing_store() == | 329 DCHECK(target->GetBuffer()->backing_store() == |
330 source->GetBuffer()->backing_store()); | 330 source->GetBuffer()->backing_store()); |
331 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); | 331 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); |
332 } else { // Non-overlapping typed arrays | 332 } else { // Non-overlapping typed arrays |
333 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); | 333 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); |
334 } | 334 } |
335 } | 335 } |
336 | 336 |
337 namespace { | 337 namespace { |
338 | 338 |
339 #define TYPED_ARRAY_SORT_COMPAREFN(Type, type, TYPE, ctype, size) \ | 339 template <typename T> |
340 bool compare##Type(ctype x, ctype y) { \ | 340 bool CompareNum(T x, T y) { |
341 if (x < y) { \ | 341 if (x < y) { |
342 return true; \ | 342 return true; |
343 } else if (x > y) { \ | 343 } else if (x > y) { |
344 return false; \ | 344 return false; |
345 } else { \ | 345 } else if (!std::is_integral<T>::value) { |
346 double _x = x, _y = y; \ | 346 double _x = x, _y = y; |
347 if (x == 0 && x == y) { \ | 347 if (x == 0 && x == y) { |
348 /* -0.0 is less than +0.0 */ \ | 348 /* -0.0 is less than +0.0 */ |
349 return std::signbit(_x) && !std::signbit(_y); \ | 349 return std::signbit(_x) && !std::signbit(_y); |
350 } else if (!std::isnan(_x) && std::isnan(_y)) { \ | 350 } else if (!std::isnan(_x) && std::isnan(_y)) { |
351 /* number is less than NaN */ \ | 351 /* number is less than NaN */ |
352 return true; \ | 352 return true; |
353 } \ | 353 } |
354 } \ | |
355 return false; \ | |
356 } | 354 } |
357 | 355 return false; |
358 TYPED_ARRAYS(TYPED_ARRAY_SORT_COMPAREFN) | 356 } |
359 #undef TYPED_ARRAY_SORT_COMPAREFN | |
360 | 357 |
361 } // namespace | 358 } // namespace |
362 | 359 |
363 RUNTIME_FUNCTION(Runtime_TypedArraySortFast) { | 360 RUNTIME_FUNCTION(Runtime_TypedArraySortFast) { |
364 HandleScope scope(isolate); | 361 HandleScope scope(isolate); |
365 DCHECK_EQ(1, args.length()); | 362 DCHECK_EQ(1, args.length()); |
366 | 363 |
367 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); | 364 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); |
368 | 365 |
369 Handle<JSTypedArray> array; | 366 Handle<JSTypedArray> array; |
370 const char* method = "%TypedArray%.prototype.sort"; | 367 const char* method = "%TypedArray%.prototype.sort"; |
371 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 368 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
372 isolate, array, JSTypedArray::Validate(isolate, target_obj, method)); | 369 isolate, array, JSTypedArray::Validate(isolate, target_obj, method)); |
373 | 370 |
374 // This line can be removed when JSTypedArray::Validate throws | 371 // This line can be removed when JSTypedArray::Validate throws |
375 // if array.[[ViewedArrayBuffer]] is neutered(v8:4648) | 372 // if array.[[ViewedArrayBuffer]] is neutered(v8:4648) |
376 if (V8_UNLIKELY(array->WasNeutered())) return *array; | 373 if (V8_UNLIKELY(array->WasNeutered())) return *array; |
377 | 374 |
378 size_t length = array->length_value(); | 375 size_t length = array->length_value(); |
379 if (length == 0) return *array; | 376 if (length <= 1) return *array; |
380 | 377 |
381 switch (array->type()) { | 378 switch (array->type()) { |
382 #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \ | 379 #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \ |
383 case kExternal##Type##Array: { \ | 380 case kExternal##Type##Array: { \ |
384 ctype* backing_store = \ | 381 ctype* backing_store = \ |
385 static_cast<ctype*>(array->GetBuffer()->backing_store()); \ | 382 static_cast<ctype*>(array->GetBuffer()->backing_store()); \ |
386 std::sort(backing_store, backing_store + length, compare##Type); \ | 383 if (kExternal##Type##Array == kExternalFloat64Array || \ |
387 break; \ | 384 kExternal##Type##Array == kExternalFloat32Array) \ |
| 385 std::sort(backing_store, backing_store + length, CompareNum<ctype>); \ |
| 386 else \ |
| 387 std::sort(backing_store, backing_store + length); \ |
| 388 break; \ |
388 } | 389 } |
389 | 390 |
390 TYPED_ARRAYS(TYPED_ARRAY_SORT) | 391 TYPED_ARRAYS(TYPED_ARRAY_SORT) |
391 #undef TYPED_ARRAY_SORT | 392 #undef TYPED_ARRAY_SORT |
392 } | 393 } |
393 | 394 |
394 return *array; | 395 return *array; |
395 } | 396 } |
396 | 397 |
397 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { | 398 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 return isolate->heap()->false_value(); | 441 return isolate->heap()->false_value(); |
441 } | 442 } |
442 | 443 |
443 Handle<JSTypedArray> obj(JSTypedArray::cast(args[0])); | 444 Handle<JSTypedArray> obj(JSTypedArray::cast(args[0])); |
444 return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() && | 445 return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() && |
445 obj->type() == kExternalInt32Array); | 446 obj->type() == kExternalInt32Array); |
446 } | 447 } |
447 | 448 |
448 } // namespace internal | 449 } // namespace internal |
449 } // namespace v8 | 450 } // namespace v8 |
OLD | NEW |