[vm, compiler] Also don't go out-of-bounds for PointerToMemory.
TEST=windows-x64 Bug: https://github.com/dart-lang/sdk/issues/53829 Change-Id: Ic7a3cd6e1e8d49a138a74a67c9d30680e91a86a6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/336620 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
committed by
Commit Queue
parent
07c77f59a2
commit
dd03188661
@@ -80,6 +80,42 @@ void AssemblerBase::StoreToSlotNoBarrier(Register src,
|
||||
return StoreIntoObjectNoBarrier(base, address, src);
|
||||
}
|
||||
|
||||
void AssemblerBase::UnrolledMemCopy(Register dst_base,
|
||||
intptr_t dst_offset,
|
||||
Register src_base,
|
||||
intptr_t src_offset,
|
||||
intptr_t size,
|
||||
Register temp) {
|
||||
intptr_t offset = 0;
|
||||
if (target::kWordSize >= 8) {
|
||||
while (offset + 8 <= size) {
|
||||
LoadFromOffset(temp, Address(src_base, src_offset + offset), kEightBytes);
|
||||
StoreToOffset(temp, Address(dst_base, dst_offset + offset), kEightBytes);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
while (offset + 4 <= size) {
|
||||
LoadFromOffset(temp, Address(src_base, src_offset + offset),
|
||||
kUnsignedFourBytes);
|
||||
StoreToOffset(temp, Address(dst_base, dst_offset + offset),
|
||||
kUnsignedFourBytes);
|
||||
offset += 4;
|
||||
}
|
||||
while (offset + 2 <= size) {
|
||||
LoadFromOffset(temp, Address(src_base, src_offset + offset),
|
||||
kUnsignedTwoBytes);
|
||||
StoreToOffset(temp, Address(dst_base, dst_offset + offset),
|
||||
kUnsignedTwoBytes);
|
||||
offset += 2;
|
||||
}
|
||||
while (offset + 1 <= size) {
|
||||
LoadFromOffset(temp, Address(src_base, src_offset + offset), kUnsignedByte);
|
||||
StoreToOffset(temp, Address(dst_base, dst_offset + offset), kUnsignedByte);
|
||||
offset += 1;
|
||||
}
|
||||
ASSERT(offset == size);
|
||||
}
|
||||
|
||||
void AssemblerBase::LoadTypeClassId(Register dst, Register src) {
|
||||
if (dst != src) {
|
||||
EnsureHasClassIdInDEBUG(kTypeCid, src, dst);
|
||||
|
||||
@@ -724,6 +724,12 @@ class AssemblerBase : public StackResource {
|
||||
Register temp,
|
||||
Label* equals) = 0;
|
||||
|
||||
void UnrolledMemCopy(Register dst_base,
|
||||
intptr_t dst_offset,
|
||||
Register src_base,
|
||||
intptr_t src_offset,
|
||||
intptr_t size,
|
||||
Register temp);
|
||||
enum CanBeSmi {
|
||||
kValueCanBeSmi,
|
||||
kValueIsNotSmi,
|
||||
|
||||
@@ -7473,17 +7473,14 @@ void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||
compiler->EmitNativeMove(dst, pointer_loc, &temp_alloc);
|
||||
__ LoadFromSlot(temp0, temp0, Slot::PointerBase_data());
|
||||
|
||||
// Copy chunks.
|
||||
// Copy chunks. The destination may be rounded up to a multiple of the
|
||||
// word size, because we do the same rounding when we allocate the space
|
||||
// on the stack. But source may not be allocated by the VM and end at a
|
||||
// page boundary.
|
||||
const intptr_t sp_offset =
|
||||
marshaller_.PassByPointerStackOffset(arg_index);
|
||||
// Struct size is rounded up to a multiple of target::kWordSize.
|
||||
// This is safe because we do the same rounding when we allocate the
|
||||
// space on the stack.
|
||||
for (intptr_t i = 0; i < arg_target.payload_type().SizeInBytes();
|
||||
i += compiler::target::kWordSize) {
|
||||
__ LoadMemoryValue(temp1, temp0, i);
|
||||
__ StoreMemoryValue(temp1, SPREG, i + sp_offset);
|
||||
}
|
||||
__ UnrolledMemCopy(SPREG, sp_offset, temp0, 0,
|
||||
arg_target.payload_type().SizeInBytes(), temp1);
|
||||
|
||||
// Store the stack address in the argument location.
|
||||
__ MoveRegister(temp0, SPREG);
|
||||
|
||||
Reference in New Issue
Block a user