[js_runtime] Use Symbol for identityHashCode

Partial mitigation for #47595

Change-Id: I35bc2b80e5b85af5da0707577e4f67434e4b597f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219843
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index ff38ff8..a7f3ca8 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -262,15 +262,35 @@
 }
 
 class Primitives {
+  static Object? _identityHashCodeProperty;
+
   static int objectHashCode(object) {
-    int? hash = JS('int|Null', r'#.$identityHash', object);
+    Object property =
+        _identityHashCodeProperty ??= _computeIdentityHashCodeProperty();
+    int? hash = JS('int|Null', r'#[#]', object, property);
     if (hash == null) {
       hash = JS('int', '(Math.random() * 0x3fffffff) | 0');
-      JS('void', r'#.$identityHash = #', object, hash);
+      JS('void', r'#[#] = #', object, property, hash);
     }
     return JS('int', '#', hash);
   }
 
+  static Object _computeIdentityHashCodeProperty() =>
+      JS_GET_FLAG('LEGACY_JAVASCRIPT')
+          ? _computeIdentityHashCodePropertyLegacy()
+          : _computeIdentityHashCodePropertyModern();
+
+  static Object _computeIdentityHashCodePropertyLegacy() {
+    if (JS<bool>('bool', 'typeof Symbol == "function"') ||
+        JS<bool>('bool', 'typeof Symbol() == "symbol"')) {
+      return _computeIdentityHashCodePropertyModern();
+    }
+    return r'$identityHashCode';
+  }
+
+  static Object _computeIdentityHashCodePropertyModern() =>
+      JS('', 'Symbol("identityHashCode")');
+
   static int? parseInt(String source, int? radix) {
     checkString(source);
     var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');