Skip to content

Commit 17d6ba1

Browse files
alexmarkovCommit Queue
authored and
Commit Queue
committed
[vm] Remove external strings
This change removes support for external strings from the VM along with Dart_NewExternalLatin1String, Dart_NewExternalUTF16String and Dart_IsExternalString Dart C API functions. External strings are not used by the VM nor any known embedder, but Dart VM was paying the maintenance and performance price for the external string implementation classes. TEST=ci Change-Id: I094cd2d2b7ec0840e9f09e1ca9e5a7acd4e78c28 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358760 Reviewed-by: Ryan Macnak <[email protected]> Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 2d1c691 commit 17d6ba1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+513
-2128
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ advantage of these improvements, set your package's
124124
[#53785]: https://github.com/dart-lang/sdk/issues/53785
125125

126126
### Dart Runtime
127+
127128
- Dart VM flags and options can now be provided to any executable
128129
generated using `dart compile exe` via the `DART_VM_OPTIONS` environment
129130
variable. `DART_VM_OPTIONS` should be set to a list of comma-separated flags
@@ -137,6 +138,10 @@ advantage of these improvements, set your package's
137138
DART_VM_OPTIONS=--random_seed=42,--verbose_gc
138139
```
139140

141+
- Dart VM no longer supports external strings: `Dart_IsExternalString`,
142+
`Dart_NewExternalLatin1String` and `Dart_NewExternalUTF16String` functions are
143+
removed from Dart C API.
144+
140145
### Tools
141146

142147
#### DevTools

pkg/vm_service/test/regexp_function_test.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ final tests = <IsolateTest>[
6262
case {
6363
'_oneByteFunction': {'type': '@Function'},
6464
'_twoByteFunction': {'type': '@Function'},
65-
'_externalOneByteFunction': {'type': '@Function'},
66-
'_externalTwoByteFunction': {'type': '@Function'},
6765
}) {
6866
// Running with compiled regexp.
6967
} else {

runtime/include/dart_api.h

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,6 @@ DART_EXPORT bool Dart_IsDouble(Dart_Handle object);
19261926
DART_EXPORT bool Dart_IsBoolean(Dart_Handle object);
19271927
DART_EXPORT bool Dart_IsString(Dart_Handle object);
19281928
DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object); /* (ISO-8859-1) */
1929-
DART_EXPORT bool Dart_IsExternalString(Dart_Handle object);
19301929
DART_EXPORT bool Dart_IsList(Dart_Handle object);
19311930
DART_EXPORT bool Dart_IsMap(Dart_Handle object);
19321931
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object);
@@ -2293,48 +2292,6 @@ DART_EXPORT Dart_Handle Dart_NewStringFromUTF16(const uint16_t* utf16_array,
22932292
DART_EXPORT Dart_Handle Dart_NewStringFromUTF32(const int32_t* utf32_array,
22942293
intptr_t length);
22952294

2296-
/**
2297-
* Returns a String which references an external array of
2298-
* Latin-1 (ISO-8859-1) encoded characters.
2299-
*
2300-
* \param latin1_array Array of Latin-1 encoded characters. This must not move.
2301-
* \param length The length of the characters array.
2302-
* \param peer An external pointer to associate with this string.
2303-
* \param external_allocation_size The number of externally allocated
2304-
* bytes for peer. Used to inform the garbage collector.
2305-
* \param callback A callback to be called when this string is finalized.
2306-
*
2307-
* \return The String object if no error occurs. Otherwise returns
2308-
* an error handle.
2309-
*/
2310-
DART_EXPORT Dart_Handle
2311-
Dart_NewExternalLatin1String(const uint8_t* latin1_array,
2312-
intptr_t length,
2313-
void* peer,
2314-
intptr_t external_allocation_size,
2315-
Dart_HandleFinalizer callback);
2316-
2317-
/**
2318-
* Returns a String which references an external array of UTF-16 encoded
2319-
* characters.
2320-
*
2321-
* \param utf16_array An array of UTF-16 encoded characters. This must not move.
2322-
* \param length The length of the characters array.
2323-
* \param peer An external pointer to associate with this string.
2324-
* \param external_allocation_size The number of externally allocated
2325-
* bytes for peer. Used to inform the garbage collector.
2326-
* \param callback A callback to be called when this string is finalized.
2327-
*
2328-
* \return The String object if no error occurs. Otherwise returns
2329-
* an error handle.
2330-
*/
2331-
DART_EXPORT Dart_Handle
2332-
Dart_NewExternalUTF16String(const uint16_t* utf16_array,
2333-
intptr_t length,
2334-
void* peer,
2335-
intptr_t external_allocation_size,
2336-
Dart_HandleFinalizer callback);
2337-
23382295
/**
23392296
* Gets the C string representation of a String.
23402297
* (It is a sequence of UTF-8 encoded values with a '\0' termination.)

runtime/lib/string.cc

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,13 @@ DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 0, 3) {
104104
static uint16_t CharacterLimit(const String& string,
105105
intptr_t start,
106106
intptr_t end) {
107-
ASSERT(string.IsTwoByteString() || string.IsExternalTwoByteString());
107+
ASSERT(string.IsTwoByteString());
108108
// Maybe do loop unrolling, and handle two uint16_t in a single uint32_t
109109
// operation.
110110
NoSafepointScope no_safepoint;
111111
uint16_t result = 0;
112-
if (string.IsTwoByteString()) {
113-
for (intptr_t i = start; i < end; i++) {
114-
result |= TwoByteString::CharAt(string, i);
115-
}
116-
} else {
117-
for (intptr_t i = start; i < end; i++) {
118-
result |= ExternalTwoByteString::CharAt(string, i);
119-
}
112+
for (intptr_t i = start; i < end; i++) {
113+
result |= TwoByteString::CharAt(string, i);
120114
}
121115
return result;
122116
}
@@ -180,7 +174,7 @@ DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 0, 4) {
180174
if (is_onebyte) {
181175
// If any of the base string slices are not one-byte, the result will be
182176
// a two-byte string.
183-
if (!base.IsOneByteString() && !base.IsExternalOneByteString()) {
177+
if (!base.IsOneByteString()) {
184178
is_onebyte = CheckSlicesOneByte(base, matches, len);
185179
}
186180
}

runtime/lib/vmservice.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,6 @@ static void ContentsFinalizer(void* isolate_callback_data, void* peer) {
324324
delete[] data;
325325
}
326326

327-
static void FilenameFinalizer(void* isolate_callback_data, void* peer) {
328-
char* filename = reinterpret_cast<char*>(peer);
329-
delete[] filename;
330-
}
331-
332327
#endif
333328

334329
DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 0, 1) {
@@ -365,9 +360,8 @@ DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 0, 1) {
365360
uint8_t* contents = archive.NextContent();
366361
intptr_t contents_length = archive.NextContentLength();
367362

368-
Dart_Handle dart_filename = Dart_NewExternalLatin1String(
369-
reinterpret_cast<uint8_t*>(filename), filename_length, filename,
370-
filename_length, FilenameFinalizer);
363+
Dart_Handle dart_filename = Dart_NewStringFromUTF8(
364+
reinterpret_cast<uint8_t*>(filename), filename_length);
371365
ASSERT(!Dart_IsError(dart_filename));
372366

373367
Dart_Handle dart_contents = Dart_NewExternalTypedDataWithFinalizer(

runtime/observatory/lib/src/elements/instance_view.dart

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -442,14 +442,6 @@ class InstanceViewElement extends CustomElement implements Renderable {
442442
if (_instance.twoByteFunction != null) {
443443
members.add(member('twoByteFunction', _instance.twoByteFunction));
444444
}
445-
if (_instance.externalOneByteFunction != null) {
446-
members.add(member(
447-
'externalOneByteFunction', _instance.externalOneByteFunction));
448-
}
449-
if (_instance.externalTwoByteFunction != null) {
450-
members.add(member(
451-
'externalTwoByteFunction', _instance.externalTwoByteFunction));
452-
}
453445
if (_instance.oneByteBytecode != null) {
454446
members.add(member('oneByteBytecode', _instance.oneByteBytecode));
455447
}

runtime/observatory/lib/src/models/objects/instance.dart

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -449,18 +449,6 @@ abstract class Instance extends Object implements InstanceRef {
449449
/// RegExp
450450
FunctionRef? get twoByteFunction;
451451

452-
/// [optional]
453-
///
454-
/// Provided for instance kinds:
455-
/// RegExp
456-
FunctionRef? get externalOneByteFunction;
457-
458-
/// [optional]
459-
///
460-
/// Provided for instance kinds:
461-
/// RegExp
462-
FunctionRef? get externalTwoByteFunction;
463-
464452
/// [optional]
465453
///
466454
/// Provided for instance kinds:

runtime/observatory/lib/src/service/object.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2896,8 +2896,6 @@ class Instance extends HeapObject implements M.Instance {
28962896
Breakpoint? activationBreakpoint; // If a Closure.
28972897
ServiceFunction? oneByteFunction; // If a RegExp.
28982898
ServiceFunction? twoByteFunction; // If a RegExp.
2899-
ServiceFunction? externalOneByteFunction; // If a RegExp.
2900-
ServiceFunction? externalTwoByteFunction; // If a RegExp.
29012899
Instance? oneByteBytecode; // If a RegExp.
29022900
Instance? twoByteBytecode; // If a RegExp.
29032901
bool? isCaseSensitive; // If a RegExp.
@@ -2984,10 +2982,6 @@ class Instance extends HeapObject implements M.Instance {
29842982
bool isCompiled = map['_oneByteFunction'] is ServiceFunction;
29852983
oneByteFunction = isCompiled ? map['_oneByteFunction'] : null;
29862984
twoByteFunction = isCompiled ? map['_twoByteFunction'] : null;
2987-
externalOneByteFunction =
2988-
isCompiled ? map['_externalOneByteFunction'] : null;
2989-
externalTwoByteFunction =
2990-
isCompiled ? map['_externalTwoByteFunction'] : null;
29912985
oneByteBytecode = map['_oneByteBytecode'];
29922986
twoByteBytecode = map['_twoByteBytecode'];
29932987

runtime/observatory/tests/service/regexp_function_test.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ var tests = <IsolateTest>[
5151
expect(f1 is ServiceFunction, isTrue);
5252
var f2 = await regex.twoByteFunction!.load();
5353
expect(f2 is ServiceFunction, isTrue);
54-
var f3 = await regex.externalOneByteFunction!.load();
55-
expect(f3 is ServiceFunction, isTrue);
56-
var f4 = await regex.externalTwoByteFunction!.load();
57-
expect(f4 is ServiceFunction, isTrue);
5854
}
5955
}
6056
];

runtime/tests/vm/dart/exported_symbols_test.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ main() {
168168
"Dart_IsCompilationError",
169169
"Dart_IsDouble",
170170
"Dart_IsError",
171-
"Dart_IsExternalString",
172171
"Dart_IsFatalError",
173172
"Dart_IsFunction",
174173
"Dart_IsFuture",
@@ -238,10 +237,8 @@ main() {
238237
"Dart_NewByteBuffer",
239238
"Dart_NewCompilationError",
240239
"Dart_NewDouble",
241-
"Dart_NewExternalLatin1String",
242240
"Dart_NewExternalTypedData",
243241
"Dart_NewExternalTypedDataWithFinalizer",
244-
"Dart_NewExternalUTF16String",
245242
"Dart_NewFinalizableHandle",
246243
"Dart_NewInteger",
247244
"Dart_NewIntegerFromHexCString",

runtime/vm/benchmark_test.cc

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -205,47 +205,6 @@ void benchmark(int count) {
205205
benchmark->set_score(elapsed_time);
206206
}
207207

208-
static void NoopFinalizer(void* isolate_callback_data, void* peer) {}
209-
210-
//
211-
// Measure time accessing internal and external strings.
212-
//
213-
BENCHMARK(DartStringAccess) {
214-
const int kNumIterations = 10000000;
215-
Timer timer;
216-
timer.Start();
217-
Dart_EnterScope();
218-
219-
// Create strings.
220-
uint8_t data8[] = {'o', 'n', 'e', 0xFF};
221-
int external_peer_data = 123;
222-
intptr_t char_size;
223-
intptr_t str_len;
224-
Dart_Handle external_string = Dart_NewExternalLatin1String(
225-
data8, ARRAY_SIZE(data8), &external_peer_data, sizeof(data8),
226-
NoopFinalizer);
227-
Dart_Handle internal_string = NewString("two");
228-
229-
// Run benchmark.
230-
for (int64_t i = 0; i < kNumIterations; i++) {
231-
EXPECT(Dart_IsString(internal_string));
232-
EXPECT(!Dart_IsExternalString(internal_string));
233-
EXPECT_VALID(external_string);
234-
EXPECT(Dart_IsExternalString(external_string));
235-
void* external_peer = nullptr;
236-
EXPECT_VALID(Dart_StringGetProperties(external_string, &char_size, &str_len,
237-
&external_peer));
238-
EXPECT_EQ(1, char_size);
239-
EXPECT_EQ(4, str_len);
240-
EXPECT_EQ(&external_peer_data, external_peer);
241-
}
242-
243-
Dart_ExitScope();
244-
timer.Stop();
245-
int64_t elapsed_time = timer.TotalElapsedTime();
246-
benchmark->set_score(elapsed_time);
247-
}
248-
249208
static void vmservice_resolver(Dart_NativeArguments args) {}
250209

251210
static Dart_NativeFunction NativeResolver(Dart_Handle name,

runtime/vm/class_finalizer.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,6 @@ void ClassFinalizer::VerifyBootstrapClasses() {
255255
ASSERT_EQUAL(OneByteString::InstanceSize(), cls.host_instance_size());
256256
cls = object_store->two_byte_string_class();
257257
ASSERT_EQUAL(TwoByteString::InstanceSize(), cls.host_instance_size());
258-
cls = object_store->external_one_byte_string_class();
259-
ASSERT_EQUAL(ExternalOneByteString::InstanceSize(), cls.host_instance_size());
260-
cls = object_store->external_two_byte_string_class();
261-
ASSERT_EQUAL(ExternalTwoByteString::InstanceSize(), cls.host_instance_size());
262258
cls = object_store->double_class();
263259
ASSERT_EQUAL(Double::InstanceSize(), cls.host_instance_size());
264260
cls = object_store->bool_class();

runtime/vm/class_id.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,7 @@ static constexpr intptr_t kClassIdTagMax = (1 << 20) - 1;
132132
#define CLASS_LIST_STRINGS(V) \
133133
V(String) \
134134
V(OneByteString) \
135-
V(TwoByteString) \
136-
V(ExternalOneByteString) \
137-
V(ExternalTwoByteString)
135+
V(TwoByteString)
138136

139137
#define CLASS_LIST_TYPED_DATA(V) \
140138
V(Int8Array) \
@@ -274,7 +272,6 @@ bool IsNumberClassId(intptr_t index);
274272
bool IsIntegerClassId(intptr_t index);
275273
bool IsStringClassId(intptr_t index);
276274
bool IsOneByteStringClassId(intptr_t index);
277-
bool IsExternalStringClassId(intptr_t index);
278275
bool IsBuiltinListClassId(intptr_t index);
279276
bool IsTypeClassId(intptr_t index);
280277
bool IsTypedDataBaseClassId(intptr_t index);
@@ -348,21 +345,14 @@ inline bool IsIntegerClassId(intptr_t index) {
348345

349346
// Make sure this check is updated when new StringCid types are added.
350347
COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
351-
kTwoByteStringCid == kStringCid + 2 &&
352-
kExternalOneByteStringCid == kStringCid + 3 &&
353-
kExternalTwoByteStringCid == kStringCid + 4);
348+
kTwoByteStringCid == kStringCid + 2);
354349

355350
inline bool IsStringClassId(intptr_t index) {
356-
return (index >= kStringCid && index <= kExternalTwoByteStringCid);
351+
return (index >= kStringCid && index <= kTwoByteStringCid);
357352
}
358353

359354
inline bool IsOneByteStringClassId(intptr_t index) {
360-
return (index == kOneByteStringCid || index == kExternalOneByteStringCid);
361-
}
362-
363-
inline bool IsExternalStringClassId(intptr_t index) {
364-
return (index == kExternalOneByteStringCid ||
365-
index == kExternalTwoByteStringCid);
355+
return (index == kOneByteStringCid);
366356
}
367357

368358
inline bool IsArrayClassId(intptr_t index) {

runtime/vm/compiler/asm_intrinsifier_arm.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -975,15 +975,15 @@ static void JumpIfString(Assembler* assembler,
975975
Register cid,
976976
Register tmp,
977977
Label* target) {
978-
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
978+
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kTwoByteStringCid,
979979
Assembler::kIfInRange, target);
980980
}
981981

982982
static void JumpIfNotString(Assembler* assembler,
983983
Register cid,
984984
Register tmp,
985985
Label* target) {
986-
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
986+
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kTwoByteStringCid,
987987
Assembler::kIfNotInRange, target);
988988
}
989989

runtime/vm/compiler/asm_intrinsifier_arm64.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,15 +1131,15 @@ static void JumpIfString(Assembler* assembler,
11311131
Register cid,
11321132
Register tmp,
11331133
Label* target) {
1134-
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
1134+
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kTwoByteStringCid,
11351135
Assembler::kIfInRange, target);
11361136
}
11371137

11381138
static void JumpIfNotString(Assembler* assembler,
11391139
Register cid,
11401140
Register tmp,
11411141
Label* target) {
1142-
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
1142+
assembler->RangeCheck(cid, tmp, kOneByteStringCid, kTwoByteStringCid,
11431143
Assembler::kIfNotInRange, target);
11441144
}
11451145

runtime/vm/compiler/asm_intrinsifier_ia32.cc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,15 +1100,13 @@ static void JumpIfNotInteger(Assembler* assembler,
11001100
}
11011101

11021102
static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
1103-
assembler->RangeCheck(cid, kNoRegister, kOneByteStringCid,
1104-
kExternalTwoByteStringCid, Assembler::kIfInRange,
1105-
target);
1103+
assembler->RangeCheck(cid, kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1104+
Assembler::kIfInRange, target);
11061105
}
11071106

11081107
static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
1109-
assembler->RangeCheck(cid, kNoRegister, kOneByteStringCid,
1110-
kExternalTwoByteStringCid, Assembler::kIfNotInRange,
1111-
target);
1108+
assembler->RangeCheck(cid, kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1109+
Assembler::kIfNotInRange, target);
11121110
}
11131111

11141112
static void JumpIfNotList(Assembler* assembler, Register cid, Label* target) {

0 commit comments

Comments
 (0)