Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
art
Commits
1def08ee
Commit
1def08ee
authored
9 years ago
by
Andreas Gampe
Committed by
Gerrit Code Review
9 years ago
Browse files
Options
Download
Plain Diff
Merge "Optimizing String.Equals as an intrinsic (ARM64)"
parents
0e780e48
ea34b407
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
1 deletion
+96
-1
compiler/optimizing/intrinsics_arm64.cc
compiler/optimizing/intrinsics_arm64.cc
+96
-1
No files found.
compiler/optimizing/intrinsics_arm64.cc
View file @
1def08ee
...
...
@@ -1055,6 +1055,102 @@ void IntrinsicCodeGeneratorARM64::VisitStringCompareTo(HInvoke* invoke) {
__
Bind
(
slow_path
->
GetExitLabel
());
}
void
IntrinsicLocationsBuilderARM64
::
VisitStringEquals
(
HInvoke
*
invoke
)
{
LocationSummary
*
locations
=
new
(
arena_
)
LocationSummary
(
invoke
,
LocationSummary
::
kNoCall
,
kIntrinsified
);
locations
->
SetInAt
(
0
,
Location
::
RequiresRegister
());
locations
->
SetInAt
(
1
,
Location
::
RequiresRegister
());
// Temporary registers to store lengths of strings and for calculations.
locations
->
AddTemp
(
Location
::
RequiresRegister
());
locations
->
AddTemp
(
Location
::
RequiresRegister
());
locations
->
SetOut
(
Location
::
RequiresRegister
(),
Location
::
kOutputOverlap
);
}
void
IntrinsicCodeGeneratorARM64
::
VisitStringEquals
(
HInvoke
*
invoke
)
{
vixl
::
MacroAssembler
*
masm
=
GetVIXLAssembler
();
LocationSummary
*
locations
=
invoke
->
GetLocations
();
Register
str
=
WRegisterFrom
(
locations
->
InAt
(
0
));
Register
arg
=
WRegisterFrom
(
locations
->
InAt
(
1
));
Register
out
=
XRegisterFrom
(
locations
->
Out
());
UseScratchRegisterScope
scratch_scope
(
masm
);
Register
temp
=
scratch_scope
.
AcquireW
();
Register
temp1
=
WRegisterFrom
(
locations
->
GetTemp
(
0
));
Register
temp2
=
WRegisterFrom
(
locations
->
GetTemp
(
1
));
vixl
::
Label
loop
;
vixl
::
Label
end
;
vixl
::
Label
return_true
;
vixl
::
Label
return_false
;
// Get offsets of count, value, and class fields within a string object.
const
int32_t
count_offset
=
mirror
::
String
::
CountOffset
().
Int32Value
();
const
int32_t
value_offset
=
mirror
::
String
::
ValueOffset
().
Int32Value
();
const
int32_t
class_offset
=
mirror
::
Object
::
ClassOffset
().
Int32Value
();
// Note that the null check must have been done earlier.
DCHECK
(
!
invoke
->
CanDoImplicitNullCheckOn
(
invoke
->
InputAt
(
0
)));
// Check if input is null, return false if it is.
__
Cbz
(
arg
,
&
return_false
);
// Reference equality check, return true if same reference.
__
Cmp
(
str
,
arg
);
__
B
(
&
return_true
,
eq
);
// Instanceof check for the argument by comparing class fields.
// All string objects must have the same type since String cannot be subclassed.
// Receiver must be a string object, so its class field is equal to all strings' class fields.
// If the argument is a string object, its class field must be equal to receiver's class field.
__
Ldr
(
temp
,
MemOperand
(
str
.
X
(),
class_offset
));
__
Ldr
(
temp1
,
MemOperand
(
arg
.
X
(),
class_offset
));
__
Cmp
(
temp
,
temp1
);
__
B
(
&
return_false
,
ne
);
// Load lengths of this and argument strings.
__
Ldr
(
temp
,
MemOperand
(
str
.
X
(),
count_offset
));
__
Ldr
(
temp1
,
MemOperand
(
arg
.
X
(),
count_offset
));
// Check if lengths are equal, return false if they're not.
__
Cmp
(
temp
,
temp1
);
__
B
(
&
return_false
,
ne
);
// Store offset of string value in preparation for comparison loop
__
Mov
(
temp1
,
value_offset
);
// Return true if both strings are empty.
__
Cbz
(
temp
,
&
return_true
);
// Assertions that must hold in order to compare strings 4 characters at a time.
DCHECK_ALIGNED
(
value_offset
,
8
);
static_assert
(
IsAligned
<
8
>
(
kObjectAlignment
),
"String of odd length is not zero padded"
);
temp1
=
temp1
.
X
();
temp2
=
temp2
.
X
();
// Loop to compare strings 4 characters at a time starting at the beginning of the string.
// Ok to do this because strings are zero-padded to be 8-byte aligned.
__
Bind
(
&
loop
);
__
Ldr
(
out
,
MemOperand
(
str
.
X
(),
temp1
));
__
Ldr
(
temp2
,
MemOperand
(
arg
.
X
(),
temp1
));
__
Add
(
temp1
,
temp1
,
Operand
(
sizeof
(
uint64_t
)));
__
Cmp
(
out
,
temp2
);
__
B
(
&
return_false
,
ne
);
__
Sub
(
temp
,
temp
,
Operand
(
4
),
SetFlags
);
__
B
(
&
loop
,
gt
);
// Return true and exit the function.
// If loop does not result in returning false, we return true.
__
Bind
(
&
return_true
);
__
Mov
(
out
,
1
);
__
B
(
&
end
);
// Return false and exit the function.
__
Bind
(
&
return_false
);
__
Mov
(
out
,
0
);
__
Bind
(
&
end
);
}
static
void
GenerateVisitStringIndexOf
(
HInvoke
*
invoke
,
vixl
::
MacroAssembler
*
masm
,
CodeGeneratorARM64
*
codegen
,
...
...
@@ -1229,7 +1325,6 @@ void IntrinsicCodeGeneratorARM64::Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED
UNIMPLEMENTED_INTRINSIC
(
SystemArrayCopyChar
)
UNIMPLEMENTED_INTRINSIC
(
ReferenceGetReferent
)
UNIMPLEMENTED_INTRINSIC
(
StringGetCharsNoCheck
)
UNIMPLEMENTED_INTRINSIC
(
StringEquals
)
#undef UNIMPLEMENTED_INTRINSIC
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment