Skip to content

Commit e210ee3

Browse files
rmacnak-googleCommit Queue
authored and
Commit Queue
committed
[vm] Internal-only String.intern.
TEST=ci Bug: #50648 Change-Id: I02e89c0def9913f12bf7fdd2ef8f3ff6cba231e3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278808 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent f9524f8 commit e210ee3

File tree

5 files changed

+51
-0
lines changed

5 files changed

+51
-0
lines changed

runtime/lib/string.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 0, 4) {
245245
return result.ptr();
246246
}
247247

248+
DEFINE_NATIVE_ENTRY(StringBase_intern, 0, 1) {
249+
const String& receiver =
250+
String::CheckedHandle(zone, arguments->NativeArgAt(0));
251+
return Symbols::New(thread, receiver);
252+
}
253+
248254
DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 0, 3) {
249255
const String& receiver =
250256
String::CheckedHandle(zone, arguments->NativeArgAt(0));
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "dart:_internal" show intern;
6+
import "package:expect/expect.dart";
7+
8+
@pragma("vm:never-inline")
9+
String genString(int i) => "abc-${i}-xyz";
10+
11+
main() {
12+
int random = Object().hashCode;
13+
var a = genString(random);
14+
var b = genString(random);
15+
Expect.notIdentical(a, b);
16+
17+
var internedA = intern(a);
18+
Expect.equals(a, internedA);
19+
// Likely, but not guarenteed: Expect.identical(a, internedA);
20+
var internedB = intern(b);
21+
Expect.equals(b, internedB);
22+
// Likely, but not guarenteed: Expect.identical(a, internedB);
23+
Expect.identical(internedA, internedB);
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// VMOptions=--old_gen_heap_size=20
6+
7+
import "dart:_internal" show intern;
8+
9+
@pragma("vm:never-inline")
10+
use(x) => x;
11+
12+
main() {
13+
const MB = 1 << 20;
14+
for (var i = 0; i < 20 * MB; i++) {
15+
use(intern((i.toString()))); // Should not hit OutOfMemory
16+
}
17+
}

runtime/vm/bootstrap_natives.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ namespace dart {
125125
V(StringBase_createFromCodePoints, 3) \
126126
V(StringBase_substringUnchecked, 3) \
127127
V(StringBase_joinReplaceAllResult, 4) \
128+
V(StringBase_intern, 1) \
128129
V(StringBuffer_createStringFromUint16Array, 3) \
129130
V(OneByteString_substringUnchecked, 3) \
130131
V(OneByteString_allocateFromOneByteList, 3) \

sdk/lib/_internal/vm/lib/internal_patch.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,6 @@ class FinalizerEntry {
431431
@FfiNative<Void Function(Handle, IntPtr)>('FinalizerEntry_SetExternalSize')
432432
external void setExternalSize(int externalSize);
433433
}
434+
435+
@pragma("vm:external-name", "StringBase_intern")
436+
external String intern(String str);

0 commit comments

Comments
 (0)