[iOS] Add optimized version of StringImpl's equal(LChar*,LChar*) for Apple CPUs
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2013 20:44:08 +0000 (20:44 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2013 20:44:08 +0000 (20:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=112202

Patch by Benjamin Poulain <bpoulain@apple.com> on 2013-03-13
Reviewed by Gavin Barraclough.

* Source/WTF/wtf/Platform.h:
Make the macro WTF_ARM_ARCH_VERSION valid on any architecture.
* wtf/text/StringImpl.h:
(WTF::equal):
On ARMv7S, the new version is about 11% percent faster than the simple loop.
On ARMv7 classic, memcmp is a little faster than the simple loop on Apple A5.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@145748 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/WTF/wtf/text/StringImpl.h

index b50805e..35f7fcb 100644 (file)
@@ -1,3 +1,17 @@
+2013-03-13  Benjamin Poulain  <bpoulain@apple.com>
+
+        [iOS] Add optimized version of StringImpl's equal(LChar*,LChar*) for Apple CPUs
+        https://bugs.webkit.org/show_bug.cgi?id=112202
+
+        Reviewed by Gavin Barraclough.
+
+        * Source/WTF/wtf/Platform.h:
+        Make the macro WTF_ARM_ARCH_VERSION valid on any architecture.
+        * wtf/text/StringImpl.h:
+        (WTF::equal):
+        On ARMv7S, the new version is about 11% percent faster than the simple loop.
+        On ARMv7 classic, memcmp is a little faster than the simple loop on Apple A5.
+
 2013-03-13  James Robinson  <jamesr@chromium.org>
 
         SchedulePair.cpp is CF-specific
index 9301f10..bd3fcc9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
  * Copyright (C) 2007-2009 Torch Mobile, Inc.
  * Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
  *
 #endif
 
 /* CPU(ARM) - ARM, any version*/
+#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && defined(WTF_ARM_ARCH_VERSION) && WTF_ARM_ARCH_VERSION >= N)
+
 #if   defined(arm) \
     || defined(__arm__) \
     || defined(ARM) \
 
 #endif
 
-#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
-
 /* Set WTF_ARM_ARCH_VERSION */
 #if   defined(__ARM_ARCH_4__) \
     || defined(__ARM_ARCH_4T__) \
index f5db68e..cb3f0bf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -917,6 +917,61 @@ ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
     
     return true;
 }
+#elif CPU(APPLE_ARMV7S)
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
+{
+    bool isEqual = false;
+    asm("lsr    r3, %[length], #2\n"
+
+        "0:\n" // Tag 0 = Start of loop over 32 bits.
+        "cbz    r3, 2f\n"
+        "ldr    r9, [%[a]], #4\n"
+        "sub    r3, #1\n"
+        "ldr    r12, [%[b]], #4\n"
+        "cmp    r9, r12\n"
+        "beq    0b\n"
+        "b      66f\n"
+
+        "2:\n" // Tag 2 = End of loop over 32 bits, check for pair of characters.
+        "tst    %[length], #2\n"
+        "beq    1f\n"
+        "ldrh   r9, [%[a]], #2\n"
+        "ldrh   r12, [%[b]], #2\n"
+        "cmp    r9, r12\n"
+        "bne    66f\n"
+
+        "1:\n" // Tag 1 = Check for a single character left.
+        "tst    %[length], #1\n"
+        "beq    42f\n"
+        "ldrb   r9, [%[a]]\n"
+        "ldrb   r12, [%[b]]\n"
+        "cmp    r9, r12\n"
+        "bne    66f\n"
+
+        "42:\n" // Tag 42 = Success.
+        "mov    %[isEqual], #1\n"
+        "66:\n" // Tag 66 = End without changing isEqual to 1.
+        : [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b)
+        : [length]"r"(length)
+        : "r3", "r9", "r12"
+        );
+    return isEqual;
+}
+
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
+{
+    return !memcmp(a, b, length);
+}
+#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7)
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
+{
+    return !memcmp(a, b, length);
+}
+
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
+{
+    return !memcmp(a, b, length);
+}
 #else
 ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
 {