Skip to content

Commit

Permalink
[vm] Internal-only String.intern.
Browse files Browse the repository at this point in the history
TEST=ci
Bug: #50648
Change-Id: I02e89c0def9913f12bf7fdd2ef8f3ff6cba231e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278808
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
  • Loading branch information
rmacnak-google authored and Commit Queue committed Jan 19, 2023
1 parent f9524f8 commit e210ee3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
6 changes: 6 additions & 0 deletions runtime/lib/string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,12 @@ DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 0, 4) {
return result.ptr();
}

DEFINE_NATIVE_ENTRY(StringBase_intern, 0, 1) {
const String& receiver =
String::CheckedHandle(zone, arguments->NativeArgAt(0));
return Symbols::New(thread, receiver);
}

DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 0, 3) {
const String& receiver =
String::CheckedHandle(zone, arguments->NativeArgAt(0));
Expand Down
24 changes: 24 additions & 0 deletions runtime/tests/vm/dart/string_intern_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:_internal" show intern;
import "package:expect/expect.dart";

@pragma("vm:never-inline")
String genString(int i) => "abc-${i}-xyz";

main() {
int random = Object().hashCode;
var a = genString(random);
var b = genString(random);
Expect.notIdentical(a, b);

var internedA = intern(a);
Expect.equals(a, internedA);
// Likely, but not guarenteed: Expect.identical(a, internedA);
var internedB = intern(b);
Expect.equals(b, internedB);
// Likely, but not guarenteed: Expect.identical(a, internedB);
Expect.identical(internedA, internedB);
}
17 changes: 17 additions & 0 deletions runtime/tests/vm/dart/weak_canonical_string_table_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// VMOptions=--old_gen_heap_size=20

import "dart:_internal" show intern;

@pragma("vm:never-inline")
use(x) => x;

main() {
const MB = 1 << 20;
for (var i = 0; i < 20 * MB; i++) {
use(intern((i.toString()))); // Should not hit OutOfMemory
}
}
1 change: 1 addition & 0 deletions runtime/vm/bootstrap_natives.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ namespace dart {
V(StringBase_createFromCodePoints, 3) \
V(StringBase_substringUnchecked, 3) \
V(StringBase_joinReplaceAllResult, 4) \
V(StringBase_intern, 1) \
V(StringBuffer_createStringFromUint16Array, 3) \
V(OneByteString_substringUnchecked, 3) \
V(OneByteString_allocateFromOneByteList, 3) \
Expand Down
3 changes: 3 additions & 0 deletions sdk/lib/_internal/vm/lib/internal_patch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,6 @@ class FinalizerEntry {
@FfiNative<Void Function(Handle, IntPtr)>('FinalizerEntry_SetExternalSize')
external void setExternalSize(int externalSize);
}

@pragma("vm:external-name", "StringBase_intern")
external String intern(String str);

0 comments on commit e210ee3

Please sign in to comment.