mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 01:25:41 +00:00
[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:
parent
d24e9a0940
commit
974d289181
1
AUTHORS
1
AUTHORS
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue