Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Unified Diff: runtime/lib/string_buffer_patch.dart

Issue 12421002: Change VM's string-buffer patch to use a Uin16Array as backing buffer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments, PTAL. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/lib/string_buffer_patch.dart
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 8fadafaa1259f867a224224f38a8a58969df5692..8c5b525d2a9940f4fb70adfd61fdf094a673d247 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -3,13 +3,22 @@
// BSD-style license that can be found in the LICENSE file.
patch class StringBuffer {
- List<String> _buffer;
- int _length;
+ /** Backing store for collected UTF-16 code units. */
+ Uint16List _buffer;
+ /** Number of code units collected. */
+ int _length = 0;
+ /**
+ * Collects the approximate maximal magnitude of the added code units.
+ *
+ * The value of each added code unit is or'ed with this variable, so the
+ * most significant bit set in any code unit is also set in this value.
+ * If below 256, the string is a Latin-1 string.
+ */
+ int _code_magnitude = 0;
srdjan 2013/03/07 17:58:34 s/_code_magnitude/_codeMagnitude/
Lasse Reichstein Nielsen 2013/03/08 07:18:44 On 2013/03/07 17:58:34, srdjan wrote: > s/_code_ma
Lasse Reichstein Nielsen 2013/03/08 07:18:44 _codeUnitMagnitude even.
/// Creates the string buffer with an initial content.
- /* patch */ StringBuffer([Object content = ""]) {
- _buffer = new List<String>();
- _length = 0;
+ /* patch */ StringBuffer([Object content = ""])
+ : _buffer = new Uint16List(16) {
write(content);
}
@@ -17,37 +26,75 @@ patch class StringBuffer {
/// Adds [obj] to the buffer.
/* patch */ void write(Object obj) {
- // TODO(srdjan): The following four lines could be replaced by
- // '$obj', but apparently this is too slow on the Dart VM.
String str;
if (obj is String) {
str = obj;
} else {
+ // TODO(srdjan): The following four lines could be replaced by
+ // '$obj', but apparently this is too slow on the Dart VM.
str = obj.toString();
if (str is! String) {
throw new ArgumentError('toString() did not return a string');
}
}
if (str.isEmpty) return;
- _buffer.add(str);
+ _ensureCapacity(str.length);
+ for (int i = 0; i < str.length; i++) {
+ int unit = str.codeUnitAt(i);
+ _buffer[_length + i] = unit;
+ _code_magnitude |= unit;
+ }
_length += str.length;
}
- /// Clears the string buffer.
+ /* patch */ writeCharCode(int charCode) {
+ if (charCode <= 0xFFFF) {
+ if (charCode < 0) {
+ throw new RangeError.range(charCode, 0, 0x10FFFF);
+ }
+ _ensureCapacity(1);
+ _buffer[_length++] = charCode;
+ _code_magnitude |= charCode;
+ } else {
+ if (charCode > 0x10FFFF) {
+ throw new RangeError.range(charCode, 0, 0x10FFFF);
+ }
+ _ensureCapacity(2);
+ int bits = charCode - 0x10000;
+ _buffer[_length++] = 0xD800 | (bits >> 10);
+ _buffer[_length++] = 0xDC00 | (bits & 0x3FF);
+ _code_magnitude |= 0xFFFF;
+ }
+ }
+
+ /** Makes the buffer empty. */
/* patch */ void clear() {
- _buffer = new List<String>();
_length = 0;
+ _code_magnitude = 0;
}
- /// Returns the contents of buffer as a concatenated string.
+ /** Returns the contents of buffer as a string. */
/* patch */ String toString() {
- if (_buffer.length == 0) return "";
- if (_buffer.length == 1) return _buffer[0];
- String result = _StringBase.concatAll(_buffer);
- _buffer.clear();
- _buffer.add(result);
- // Since we track the length at each add operation, there is no
- // need to update it in this function.
- return result;
+ if (_length == 0) return "";
+ return _create(_buffer, _length, _code_magnitude <= 0xFF);
Vyacheslav Egorov (Google) 2013/03/07 13:50:52 consider: final isLatin1 = _code_magnitude <= 0x
Lasse Reichstein Nielsen 2013/03/08 07:18:44 Done.
}
+
+ /** Ensures that the buffer has enough capacity to contain n code units. */
srdjan 2013/03/07 17:58:34 s/contain/add/
Lasse Reichstein Nielsen 2013/03/08 07:18:44 Done.
+ void _ensureCapacity(int n) {
+ int requiredCapacity = _length + n;
+ if (requiredCapacity <= _buffer.length) return;
Vyacheslav Egorov (Google) 2013/03/07 13:50:52 consider { return; } and more vertical white s
srdjan 2013/03/07 17:58:34 I would split the rare case out: if (requiredCapac
Lasse Reichstein Nielsen 2013/03/08 07:18:44 Done.
+ int newCapacity = _buffer.length;
+ do {
+ newCapacity *= 2;
srdjan 2013/03/07 17:58:34 Optional: This growth may be too aggressive. Opini
Lasse Reichstein Nielsen 2013/03/08 07:18:44 I was wondering if it was too small, and consideri
+ } while (newCapacity < requiredCapacity);
+ List<int> newBuffer = new Uint16List(newCapacity);
+ newBuffer.setRange(0, _length, _buffer);
+ _buffer = newBuffer;
+ }
+
+ /**
+ * Create a [String] from the UFT-16 code units in buffer.
+ */
+ static String _create(List<int> buffer, int length, bool isLatin1)
srdjan 2013/03/07 17:58:34 s/List<int>/Uint16List/
Lasse Reichstein Nielsen 2013/03/08 07:18:44 Done.
+ native "StringBuffer_createStringFromUint16Array";
}

Powered by Google App Engine
This is Rietveld 408576698