Commit 59de35b2 authored by Franziska Hinkelmann's avatar Franziska Hinkelmann Committed by Commit Bot

[runtime] Port TypedArraySetFromOverlappingTypedArray to C++

Bug: v8:6704
Change-Id: I153a8d3501de19f4e5d9c580060f987f169b5edd
Reviewed-on: https://chromium-review.googlesource.com/617000Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Franziska Hinkelmann <franzih@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47426}
parent aee29a9f
......@@ -250,60 +250,6 @@ TYPED_ARRAYS(TYPED_ARRAY_SUBARRAY_CASE)
%SetForceInlineFlag(GlobalTypedArray.prototype.subarray);
function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
var sourceElementSize = source.BYTES_PER_ELEMENT;
var targetElementSize = target.BYTES_PER_ELEMENT;
var sourceLength = %_TypedArrayGetLength(source);
// Copy left part.
function CopyLeftPart() {
// First un-mutated byte after the next write
var targetPtr = %_ArrayBufferViewGetByteOffset(target) +
(offset + 1) * targetElementSize;
// Next read at sourcePtr. We do not care for memory changing before
// sourcePtr - we have already copied it.
var sourcePtr = %_ArrayBufferViewGetByteOffset(source);
for (var leftIndex = 0;
leftIndex < sourceLength && targetPtr <= sourcePtr;
leftIndex++) {
target[offset + leftIndex] = source[leftIndex];
targetPtr += targetElementSize;
sourcePtr += sourceElementSize;
}
return leftIndex;
}
var leftIndex = CopyLeftPart();
// Copy right part;
function CopyRightPart() {
// First unmutated byte before the next write
var targetPtr = %_ArrayBufferViewGetByteOffset(target) +
(offset + sourceLength - 1) * targetElementSize;
// Next read before sourcePtr. We do not care for memory changing after
// sourcePtr - we have already copied it.
var sourcePtr = %_ArrayBufferViewGetByteOffset(source) +
sourceLength * sourceElementSize;
for(var rightIndex = sourceLength - 1;
rightIndex >= leftIndex && targetPtr >= sourcePtr;
rightIndex--) {
target[offset + rightIndex] = source[rightIndex];
targetPtr -= targetElementSize;
sourcePtr -= sourceElementSize;
}
return rightIndex;
}
var rightIndex = CopyRightPart();
var temp = new GlobalArray(rightIndex + 1 - leftIndex);
for (var i = leftIndex; i <= rightIndex; i++) {
temp[i - leftIndex] = source[i];
}
for (i = leftIndex; i <= rightIndex; i++) {
target[offset + i] = temp[i - leftIndex];
}
}
// 22.2.3.23%TypedArray%.prototype.set ( overloaded [ , offset ] )
DEFINE_METHOD_LEN(
GlobalTypedArray.prototype,
set(obj, offset) {
......@@ -319,7 +265,7 @@ DEFINE_METHOD_LEN(
case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
return;
case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
%_TypedArraySetFromOverlapping(this, obj, intOffset);
return;
case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
if (intOffset === 0) {
......
......@@ -137,6 +137,95 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFromArrayLike) {
return *target;
}
// TypedArraySetFromOverlappingTypedArray(target, source, offset);
RUNTIME_FUNCTION(Runtime_TypedArraySetFromOverlapping) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target, 0);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source, 1);
CONVERT_INT32_ARG_CHECKED(offset, 2);
DCHECK_GE(offset, 0);
size_t sourceElementSize = source->element_size();
size_t targetElementSize = target->element_size();
uint32_t source_length = source->length_value();
// Copy left part.
// First un-mutated byte after the next write
uint32_t target_ptr = 0;
CHECK(target->byte_offset()->ToUint32(&target_ptr));
target_ptr += (offset + 1) * targetElementSize;
// Next read at sourcePtr. We do not care for memory changing before
// sourcePtr - we have already copied it.
uint32_t source_ptr = 0;
CHECK(source->byte_offset()->ToUint32(&source_ptr));
uint32_t left_index;
for (left_index = 0; left_index < source_length && target_ptr <= source_ptr;
left_index++) {
Handle<Object> value;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value, Object::GetElement(isolate, source, left_index));
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value,
Object::SetElement(isolate, target, offset + left_index, value,
LanguageMode::STRICT));
target_ptr += targetElementSize;
source_ptr += sourceElementSize;
}
// Copy right part;
// First unmutated byte before the next write
CHECK(target->byte_offset()->ToUint32(&target_ptr));
target_ptr += (offset + source_length - 1) * targetElementSize;
// Next read before sourcePtr. We do not care for memory changing after
// sourcePtr - we have already copied it.
CHECK(target->byte_offset()->ToUint32(&source_ptr));
source_ptr += source_length * sourceElementSize;
uint32_t right_index;
for (right_index = source_length - 1;
right_index > left_index && target_ptr >= source_ptr; right_index--) {
Handle<Object> value;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value, Object::GetElement(isolate, source, right_index));
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value,
Object::SetElement(isolate, target, offset + right_index, value,
LanguageMode::STRICT));
target_ptr -= targetElementSize;
source_ptr -= sourceElementSize;
}
std::vector<Handle<Object>> temp(right_index + 1 - left_index);
for (uint32_t i = left_index; i <= right_index; i++) {
Handle<Object> value;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
Object::GetElement(isolate, source, i));
temp[i - left_index] = value;
}
for (uint32_t i = left_index; i <= right_index; i++) {
Handle<Object> value;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value,
Object::SetElement(isolate, target, offset + i, temp[i - left_index],
LanguageMode::STRICT));
}
return *target;
}
RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
......
......@@ -621,6 +621,7 @@ namespace internal {
F(TypedArrayGetLength, 1, 1) \
F(TypedArrayGetBuffer, 1, 1) \
F(TypedArraySetFromArrayLike, 4, 1) \
F(TypedArraySetFromOverlapping, 3, 1) \
F(TypedArraySetFastCases, 3, 1) \
F(TypedArraySortFast, 1, 1) \
F(TypedArrayMaxSizeInHeap, 0, 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