[runtime/vm] ARM64: Support unaligned memory accesses for regex.

Support unaligned memory accesses for regex compiler for arm64
target. Also fix a bug in LoadCodeUnitsInstr IL visitor where
Address::OperandSizeFor was used to get access size (which
returned size of one element independently of actual element
count).

Change-Id: I77c449c8597f8cfd500b8d701f72c39c46a443b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121424
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
Artem Serov 2019-10-15 20:11:40 +00:00 committed by commit-bot@chromium.org
parent d24e9a0940
commit 974d289181
5 changed files with 42 additions and 13 deletions

View file

@ -5,6 +5,7 @@
Google Inc.
The V8 project authors
Arm Ltd. <*@arm.com>
Ola Martin Bini <ola.bini@gmail.com>
Michael Haubenwallner <michael.haubenwallner@gmail.com>

View file

@ -1770,6 +1770,22 @@ Address Assembler::ElementAddressForRegIndex(bool is_load,
intptr_t index_scale,
Register array,
Register index) {
return ElementAddressForRegIndexWithSize(is_load,
is_external,
cid,
Address::OperandSizeFor(cid),
index_scale,
array,
index);
}
Address Assembler::ElementAddressForRegIndexWithSize(bool is_load,
bool is_external,
intptr_t cid,
OperandSize size,
intptr_t index_scale,
Register array,
Register index) {
// Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
const int32_t offset =
@ -1785,7 +1801,6 @@ Address Assembler::ElementAddressForRegIndex(bool is_load,
} else {
add(base, array, Operand(index, LSL, shift));
}
const OperandSize size = Address::OperandSizeFor(cid);
ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
return Address(base, offset, Address::Offset, size);
}

View file

@ -1641,6 +1641,18 @@ class Assembler : public AssemblerBase {
intptr_t index_scale,
Register array,
Register index);
// Special version of ElementAddressForRegIndex for the case when cid and
// operand size for the target load don't match (e.g. when loading a few
// elements of the array with one load).
Address ElementAddressForRegIndexWithSize(bool is_load,
bool is_external,
intptr_t cid,
OperandSize size,
intptr_t index_scale,
Register array,
Register index);
void LoadElementAddressForRegIndex(Register address,
bool is_load,
bool is_external,

View file

@ -1458,10 +1458,7 @@ void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// The string register points to the backing store for external strings.
const Register str = locs()->in(0).reg();
const Location index = locs()->in(1);
compiler::Address element_address = __ ElementAddressForRegIndex(
true, IsExternal(), class_id(), index_scale(), str, index.reg());
// Warning: element_address may use register TMP as base.
OperandSize sz = OperandSize::kByte;
Register result = locs()->out(0).reg();
switch (class_id()) {
@ -1469,37 +1466,41 @@ void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
case kExternalOneByteStringCid:
switch (element_count()) {
case 1:
__ ldr(result, element_address, kUnsignedByte);
sz = kUnsignedByte;
break;
case 2:
__ ldr(result, element_address, kUnsignedHalfword);
sz = kUnsignedHalfword;
break;
case 4:
__ ldr(result, element_address, kUnsignedWord);
sz = kUnsignedWord;
break;
default:
UNREACHABLE();
}
__ SmiTag(result);
break;
case kTwoByteStringCid:
case kExternalTwoByteStringCid:
switch (element_count()) {
case 1:
__ ldr(result, element_address, kUnsignedHalfword);
sz = kUnsignedHalfword;
break;
case 2:
__ ldr(result, element_address, kUnsignedWord);
sz = kUnsignedWord;
break;
default:
UNREACHABLE();
}
__ SmiTag(result);
break;
default:
UNREACHABLE();
break;
}
// Warning: element_address may use register TMP as base.
compiler::Address element_address = __ ElementAddressForRegIndexWithSize(
true, IsExternal(), class_id(), sz, index_scale(), str, index.reg());
__ ldr(result, element_address, sz);
__ SmiTag(result);
}
Representation StoreIndexedInstr::RequiredInputRepresentation(

View file

@ -289,7 +289,7 @@ void IRRegExpMacroAssembler::FinalizeRegistersArray() {
TypedData::New(kTypedDataInt32ArrayCid, registers_count_, Heap::kOld);
}
#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_ARM)
#if defined(TARGET_ARCH_ARM)
// Disabling unaligned accesses forces the regexp engine to load characters one
// by one instead of up to 4 at once, along with the associated performance hit.
// TODO(zerny): Be less conservative about disabling unaligned accesses.