Replaces String cast with unsafe cast where it is safe
Unfortunately, GWT compiler doesn't optimize cast that are guarded
with instanceOf checks which results in double checking for casting.
This patch fixes such double checks in critical emul code for String.
Change-Id: I2d3176bf2d41d3b0cc22747422d6d4c032ee3761
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index d023b3e..2ed5862 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -660,7 +660,7 @@
@DoNotInline
@Override
public boolean equals(Object other) {
- return (other instanceof String) && equals((String) other);
+ return (other instanceof String) && equals(unsafeCast(other));
}
// This a non-standard overload for faster code path when the target type is string. Note that
@@ -671,6 +671,11 @@
return String(this) == other;
}-*/;
+ // TODO(goktug): replace unsafeCast with a real cast when the compiler can optimize it.
+ static native String unsafeCast(Object string) /*-{
+ return string;
+ }-*/;
+
public native boolean equalsIgnoreCase(String other) /*-{
if (other == null) {
return false;
diff --git a/user/super/com/google/gwt/emul/java/lang/System.java b/user/super/com/google/gwt/emul/java/lang/System.java
index e8a0631..c516276 100644
--- a/user/super/com/google/gwt/emul/java/lang/System.java
+++ b/user/super/com/google/gwt/emul/java/lang/System.java
@@ -112,7 +112,7 @@
public static int identityHashCode(Object o) {
return (o == null) ? 0 : (!(o instanceof String)) ? Impl.getHashCode(o)
- : String.HashCache.getHashCode((String) o);
+ : String.HashCache.getHashCode(String.unsafeCast(o));
}
public static native void setErr(PrintStream err) /*-{
diff --git a/user/super/com/google/gwt/emul/java/util/AbstractHashMap.java b/user/super/com/google/gwt/emul/java/util/AbstractHashMap.java
index 140472b..3e86ee2 100644
--- a/user/super/com/google/gwt/emul/java/util/AbstractHashMap.java
+++ b/user/super/com/google/gwt/emul/java/util/AbstractHashMap.java
@@ -172,7 +172,7 @@
@SpecializeMethod(params = {String.class}, target = "hasStringValue")
@Override
public boolean containsKey(Object key) {
- return key instanceof String ? hasStringValue((String) key) : hasHashValue(key);
+ return key instanceof String ? hasStringValue(unsafeCast(key)) : hasHashValue(key);
}
@Override
@@ -188,19 +188,19 @@
@SpecializeMethod(params = {String.class}, target = "getStringValue")
@Override
public V get(Object key) {
- return key instanceof String ? getStringValue((String) key) : getHashValue(key);
+ return key instanceof String ? getStringValue(unsafeCast(key)) : getHashValue(key);
}
@SpecializeMethod(params = {String.class, Object.class}, target = "putStringValue")
@Override
public V put(K key, V value) {
- return key instanceof String ? putStringValue((String) key, value) : putHashValue(key, value);
+ return key instanceof String ? putStringValue(unsafeCast(key), value) : putHashValue(key, value);
}
@SpecializeMethod(params = {String.class}, target = "removeStringValue")
@Override
public V remove(Object key) {
- return key instanceof String ? removeStringValue((String) key) : removeHashValue(key);
+ return key instanceof String ? removeStringValue(unsafeCast(key)) : removeHashValue(key);
}
@Override
@@ -301,4 +301,9 @@
protected V removeStringValue(String key) {
return key == null ? removeHashValue(null) : stringMap.remove(key);
}
+
+ // TODO(goktug): replace unsafeCast with a real cast when the compiler can optimize it.
+ static native String unsafeCast(Object string) /*-{
+ return string;
+ }-*/;
}