diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index 24ac2a2830d4..49b7899d0de4 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc @@ -962,6 +962,7 @@ bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph( case MethodRecognizer::kTypedData_Float32x4Array_factory: case MethodRecognizer::kTypedData_Int32x4Array_factory: case MethodRecognizer::kTypedData_Float64x2Array_factory: + case MethodRecognizer::kMemCopy: case MethodRecognizer::kFfiLoadInt8: case MethodRecognizer::kFfiLoadInt16: case MethodRecognizer::kFfiLoadInt32: @@ -1232,6 +1233,25 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod( body += Utf8Scan(); body += Box(kUnboxedIntPtr); break; + case MethodRecognizer::kMemCopy: { + ASSERT_EQUAL(function.NumParameters(), 5); + LocalVariable* arg_target = parsed_function_->RawParameterVariable(0); + LocalVariable* arg_target_offset_in_bytes = + parsed_function_->RawParameterVariable(1); + LocalVariable* arg_source = parsed_function_->RawParameterVariable(2); + LocalVariable* arg_source_offset_in_bytes = + parsed_function_->RawParameterVariable(3); + LocalVariable* arg_length_in_bytes = + parsed_function_->RawParameterVariable(4); + body += LoadLocal(arg_source); + body += LoadLocal(arg_target); + body += LoadLocal(arg_source_offset_in_bytes); + body += LoadLocal(arg_target_offset_in_bytes); + body += LoadLocal(arg_length_in_bytes); + // Pointers and TypedData have the same layout. + body += MemoryCopy(kTypedDataUint8ArrayCid, kTypedDataUint8ArrayCid); + body += NullConstant(); + } break; case MethodRecognizer::kFfiAbi: ASSERT_EQUAL(function.NumParameters(), 0); body += IntConstant(static_cast(compiler::ffi::TargetAbi())); diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index 39ffd20862c2..651bbfef3004 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h @@ -325,6 +325,7 @@ namespace dart { V(_Smi, get:hashCode, Smi_hashCode, 0x75e0ccd2) \ V(_Mint, get:hashCode, Mint_hashCode, 0x75e0ccd2) \ V(_Double, get:hashCode, Double_hashCode, 0x75e0ccd2) \ + V(::, _memCopy, MemCopy, 0x274f4816) \ // List of intrinsics: // (class-name, function-name, intrinsification method, fingerprint). diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart index ad5b23d9e61b..7ab4f389f067 100644 --- a/sdk/lib/_internal/vm/lib/ffi_patch.dart +++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart @@ -246,44 +246,10 @@ class _FfiAbiSpecificMapping { /// Copies data byte-wise from [source] to [target]. /// /// [source] and [target] should either be [Pointer] or [TypedData]. -/// -/// TODO(dartbug.com/37271): Make recognized method and use MemoryCopyInstr. -void _memCopy(Object target, int targetOffsetInBytes, Object source, - int sourceOffsetInBytes, int lengthInBytes) { - assert(source is Pointer || source is TypedData); - assert(target is Pointer || target is TypedData); - if (source is Pointer) { - final sourcePointer = source.cast(); - if (target is Pointer) { - final targetPointer = target.cast(); - for (int i = 0; i < lengthInBytes; i++) { - targetPointer[i + targetOffsetInBytes] = - sourcePointer[i + sourceOffsetInBytes]; - } - } else if (target is TypedData) { - final targetTypedData = target.buffer.asUint8List(target.offsetInBytes); - for (int i = 0; i < lengthInBytes; i++) { - targetTypedData[i + targetOffsetInBytes] = - sourcePointer[i + sourceOffsetInBytes]; - } - } - } else if (source is TypedData) { - final sourceTypedData = source.buffer.asUint8List(source.offsetInBytes); - if (target is Pointer) { - final targetPointer = target.cast(); - for (int i = 0; i < lengthInBytes; i++) { - targetPointer[i + targetOffsetInBytes] = - sourceTypedData[i + sourceOffsetInBytes]; - } - } else if (target is TypedData) { - final targetTypedData = target.buffer.asUint8List(target.offsetInBytes); - targetTypedData.setRange( - targetOffsetInBytes, - targetOffsetInBytes + lengthInBytes, - sourceTypedData.sublist(sourceOffsetInBytes)); - } - } -} +@pragma("vm:entry-point") +@pragma("vm:recognized", "other") +external void _memCopy(Object target, int targetOffsetInBytes, Object source, + int sourceOffsetInBytes, int lengthInBytes); // The following functions are implemented in the method recognizer. //