[dart2wasm] Cache hash codes in JSStringImpl
Change-Id: I41980461f9e6a4818458aa17471bd868b70ad354
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362781
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart
index 41a79fa..0035b434 100644
--- a/pkg/dart2wasm/lib/intrinsics.dart
+++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -732,14 +732,14 @@
// dart:_object_helper static functions.
if (node.target.enclosingLibrary.name == 'dart._object_helper') {
switch (name) {
- case "getHash":
+ case "getIdentityHashField":
Expression arg = node.arguments.positional[0];
w.ValueType objectType = translator.objectInfo.nonNullableType;
codeGen.wrap(arg, objectType);
b.struct_get(translator.objectInfo.struct, FieldIndex.identityHash);
b.i64_extend_i32_u();
return w.NumType.i64;
- case "setHash":
+ case "setIdentityHashField":
Expression arg = node.arguments.positional[0];
Expression hash = node.arguments.positional[1];
w.ValueType objectType = translator.objectInfo.nonNullableType;
diff --git a/sdk/lib/_internal/wasm/lib/js_string.dart b/sdk/lib/_internal/wasm/lib/js_string.dart
index dcb2eeb..b8f2571 100644
--- a/sdk/lib/_internal/wasm/lib/js_string.dart
+++ b/sdk/lib/_internal/wasm/lib/js_string.dart
@@ -606,10 +606,17 @@
}
}
- /// This must be kept in sync with `StringBase.hashCode` in string_patch.dart.
- /// TODO(joshualitt): Find some way to cache the hash code.
@override
int get hashCode {
+ int hash = getIdentityHashField(this);
+ if (hash != 0) return hash;
+ hash = _computeHashCode();
+ setIdentityHashField(this, hash);
+ return hash;
+ }
+
+ /// This must be kept in sync with `StringBase.hashCode` in string_patch.dart.
+ int _computeHashCode() {
int hash = 0;
final length = this.length;
for (int i = 0; i < length; i++) {
diff --git a/sdk/lib/_internal/wasm/lib/js_types.dart b/sdk/lib/_internal/wasm/lib/js_types.dart
index be66655..1730dbc 100644
--- a/sdk/lib/_internal/wasm/lib/js_types.dart
+++ b/sdk/lib/_internal/wasm/lib/js_types.dart
@@ -16,6 +16,7 @@
import 'dart:_error_utils';
import 'dart:_internal';
import 'dart:_js_helper' as js;
+import 'dart:_object_helper';
import 'dart:_string_helper';
import 'dart:_wasm';
import 'dart:collection';
diff --git a/sdk/lib/_internal/wasm/lib/object_helper.dart b/sdk/lib/_internal/wasm/lib/object_helper.dart
index 13410eb..0378acc 100644
--- a/sdk/lib/_internal/wasm/lib/object_helper.dart
+++ b/sdk/lib/_internal/wasm/lib/object_helper.dart
@@ -5,5 +5,5 @@
library dart._object_helper;
// Access hidden identity hash code field.
-external int getHash(Object obj);
-external void setHash(Object obj, int hash);
+external int getIdentityHashField(Object obj);
+external void setIdentityHashField(Object obj, int hash);
diff --git a/sdk/lib/_internal/wasm/lib/object_patch.dart b/sdk/lib/_internal/wasm/lib/object_patch.dart
index 1deb40d..afce211 100644
--- a/sdk/lib/_internal/wasm/lib/object_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/object_patch.dart
@@ -13,14 +13,14 @@
static final _hashCodeRnd = new Random();
static int _objectHashCode(Object obj) {
- var result = getHash(obj);
+ var result = getIdentityHashField(obj);
if (result == 0) {
// We want the hash to be a Smi value greater than 0.
do {
result = _hashCodeRnd.nextInt(0x40000000);
} while (result == 0);
- setHash(obj, result);
+ setIdentityHashField(obj, result);
return result;
}
return result;
diff --git a/sdk/lib/_internal/wasm/lib/string.dart b/sdk/lib/_internal/wasm/lib/string.dart
index 8f69f78..a5b61afb 100644
--- a/sdk/lib/_internal/wasm/lib/string.dart
+++ b/sdk/lib/_internal/wasm/lib/string.dart
@@ -96,10 +96,10 @@
static const int _maxUnsignedSmiBits = 63;
int get hashCode {
- int hash = getHash(this);
+ int hash = getIdentityHashField(this);
if (hash != 0) return hash;
hash = _computeHashCode();
- setHash(this, hash);
+ setIdentityHashField(this, hash);
return hash;
}