diff options
| author | 2016-05-24 19:30:45 +0100 | |
|---|---|---|
| committer | 2016-05-25 11:48:53 +0100 | |
| commit | 53b52005ddae649e6f1cf475de7c259bc6885e6d (patch) | |
| tree | 6d0a2618fda946fa26e3cdb27825f03834e3529b /compiler/optimizing | |
| parent | db9fcb30402a2726564905c206fa23ee86e146c3 (diff) | |
Apply String.equals() optimizations on arm, arm64 and x86-64.
This is a follow-up to
https://android-review.googlesource.com/174192
Change-Id: Ie71197df22548d6eb0ca773de6f19fcbb975f065
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/intrinsics_arm.cc | 27 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 25 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 8 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 27 |
4 files changed, 51 insertions, 36 deletions
diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc index de04175e38..5e5e9732a5 100644 --- a/compiler/optimizing/intrinsics_arm.cc +++ b/compiler/optimizing/intrinsics_arm.cc @@ -1055,17 +1055,22 @@ void IntrinsicCodeGeneratorARM::VisitStringEquals(HInvoke* invoke) { // 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. - __ CompareAndBranchIfZero(arg, &return_false); - - // 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, Address(str, class_offset)); - __ ldr(temp1, Address(arg, class_offset)); - __ cmp(temp, ShifterOperand(temp1)); - __ b(&return_false, NE); + StringEqualsOptimizations optimizations(invoke); + if (!optimizations.GetArgumentNotNull()) { + // Check if input is null, return false if it is. + __ CompareAndBranchIfZero(arg, &return_false); + } + + if (!optimizations.GetArgumentIsString()) { + // 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, Address(str, class_offset)); + __ ldr(temp1, Address(arg, class_offset)); + __ cmp(temp, ShifterOperand(temp1)); + __ b(&return_false, NE); + } // Load lengths of this and argument strings. __ ldr(temp, Address(str, count_offset)); diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 6cd1726eb3..30ab111ffd 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -1327,21 +1327,26 @@ void IntrinsicCodeGeneratorARM64::VisitStringEquals(HInvoke* invoke) { // 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); + StringEqualsOptimizations optimizations(invoke); + if (!optimizations.GetArgumentNotNull()) { + // 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); + if (!optimizations.GetArgumentIsString()) { + // 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)); diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 99bc40e71e..e530b90066 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -1319,11 +1319,11 @@ void IntrinsicCodeGeneratorX86::VisitStringEquals(HInvoke* invoke) { __ j(kEqual, &return_false); } - // 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. if (!optimizations.GetArgumentIsString()) { + // 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. __ movl(ecx, Address(str, class_offset)); __ cmpl(ecx, Address(arg, class_offset)); __ j(kNotEqual, &return_false); diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 06e9cc2b28..2b626be040 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -1416,17 +1416,22 @@ void IntrinsicCodeGeneratorX86_64::VisitStringEquals(HInvoke* invoke) { // 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. - __ testl(arg, arg); - __ j(kEqual, &return_false); - - // 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. - __ movl(rcx, Address(str, class_offset)); - __ cmpl(rcx, Address(arg, class_offset)); - __ j(kNotEqual, &return_false); + StringEqualsOptimizations optimizations(invoke); + if (!optimizations.GetArgumentNotNull()) { + // Check if input is null, return false if it is. + __ testl(arg, arg); + __ j(kEqual, &return_false); + } + + if (!optimizations.GetArgumentIsString()) { + // 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. + __ movl(rcx, Address(str, class_offset)); + __ cmpl(rcx, Address(arg, class_offset)); + __ j(kNotEqual, &return_false); + } // Reference equality check, return true if same reference. __ cmpl(str, arg); |