Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index ed3527fa9202cb9977101725598cec30b3af1bba..2cbaad10fc8566914961340cbb9a9889c47cede1 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -907,6 +907,21 @@ TYPED_ARRAY_GETTER(Length, length) |
#undef TYPED_ARRAY_GETTER |
+// Return codes for Runtime_TypedArraySetFastCases. |
+// Should be synchronized with typedarray.js natives. |
+enum TypedArraySetResultCodes { |
+ // Set from typed array of the same type. |
+ // This is processed by TypedArraySetFastCases |
+ TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0, |
+ // Set from typed array of the different type, overlapping in memory. |
+ TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1, |
+ // Set from typed array of the different type, non-overlapping. |
+ TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2, |
+ // Set from non-typed array. |
+ TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3 |
+}; |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
HandleScope scope(isolate); |
CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); |
@@ -918,7 +933,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
"not_typed_array", HandleVector<Object>(NULL, 0))); |
if (!source_obj->IsJSTypedArray()) |
- return isolate->heap()->false_value(); |
+ return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY); |
Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj)); |
Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj)); |
@@ -933,20 +948,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
return isolate->Throw(*isolate->factory()->NewRangeError( |
"typed_array_set_source_too_large", HandleVector<Object>(NULL, 0))); |
- Handle<JSArrayBuffer> target_buffer(JSArrayBuffer::cast(target->buffer())); |
- Handle<JSArrayBuffer> source_buffer(JSArrayBuffer::cast(source->buffer())); |
size_t target_offset = NumberToSize(isolate, target->byte_offset()); |
size_t source_offset = NumberToSize(isolate, source->byte_offset()); |
uint8_t* target_base = |
- static_cast<uint8_t*>(target_buffer->backing_store()) + target_offset; |
+ static_cast<uint8_t*>( |
+ JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset; |
uint8_t* source_base = |
- static_cast<uint8_t*>(source_buffer->backing_store()) + source_offset; |
+ static_cast<uint8_t*>( |
+ JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset; |
// Typed arrays of the same type: use memmove. |
if (target->type() == source->type()) { |
memmove(target_base + offset * target->element_size(), |
source_base, source_byte_length); |
- return isolate->heap()->true_value(); |
+ return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE); |
} |
// Typed arrays of different types over the same backing store |
@@ -954,78 +969,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
source_base + source_byte_length > target_base) || |
(target_base <= source_base && |
target_base + target_byte_length > source_base)) { |
- size_t target_element_size = target->element_size(); |
- size_t source_element_size = source->element_size(); |
- |
- size_t source_length = NumberToSize(isolate, source->length()); |
- |
- // Copy left part |
- size_t left_index; |
- { |
- // First un-mutated byte after the next write |
- uint8_t* target_ptr = target_base + (offset + 1) * target_element_size; |
- // Next read at source_ptr. We do not care for memory changing before |
- // source_ptr - we have already copied it. |
- uint8_t* source_ptr = source_base; |
- for (left_index = 0; |
- left_index < source_length && target_ptr <= source_ptr; |
- left_index++) { |
- Handle<Object> v = Object::GetElement( |
- source, static_cast<uint32_t>(left_index)); |
- JSObject::SetElement( |
- target, static_cast<uint32_t>(offset + left_index), v, |
- NONE, kNonStrictMode); |
- target_ptr += target_element_size; |
- source_ptr += source_element_size; |
- } |
- } |
- // Copy right part |
- size_t right_index; |
- { |
- // First unmutated byte before the next write |
- uint8_t* target_ptr = |
- target_base + (offset + source_length - 1) * target_element_size; |
- // Next read before source_ptr. We do not care for memory changing after |
- // source_ptr - we have already copied it. |
- uint8_t* source_ptr = |
- source_base + source_length * source_element_size; |
- for (right_index = source_length - 1; |
- right_index >= left_index && target_ptr >= source_ptr; |
- right_index--) { |
- Handle<Object> v = Object::GetElement( |
- source, static_cast<uint32_t>(right_index)); |
- JSObject::SetElement( |
- target, static_cast<uint32_t>(offset + right_index), v, |
- NONE, kNonStrictMode); |
- target_ptr -= target_element_size; |
- source_ptr -= source_element_size; |
- } |
- } |
- // There can be at most 8 entries left in the middle that need buffering |
- // (because the largest element_size is 8 times the smallest). |
- ASSERT((right_index + 1) - left_index <= 8); |
- Handle<Object> temp[8]; |
- size_t idx; |
- for (idx = left_index; idx <= right_index; idx++) { |
- temp[idx - left_index] = Object::GetElement( |
- source, static_cast<uint32_t>(idx)); |
- } |
- for (idx = left_index; idx <= right_index; idx++) { |
- JSObject::SetElement( |
- target, static_cast<uint32_t>(offset + idx), temp[idx-left_index], |
- NONE, kNonStrictMode); |
- } |
+ // We do not support overlapping ArrayBuffers |
+ ASSERT( |
+ JSArrayBuffer::cast(target->buffer())->backing_store() == |
+ JSArrayBuffer::cast(source->buffer())->backing_store()); |
+ return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); |
} else { // Non-overlapping typed arrays |
- for (size_t idx = 0; idx < source_length; idx++) { |
- Handle<Object> value = Object::GetElement( |
- source, static_cast<uint32_t>(idx)); |
- JSObject::SetElement( |
- target, static_cast<uint32_t>(offset + idx), value, |
- NONE, kNonStrictMode); |
- } |
+ return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); |
} |
- |
- return isolate->heap()->true_value(); |
} |