Skip to content

Commit 1025d34

Browse files
otherdanielCommit bot
authored andcommitted
Avoid excessive data copying for ExternalStreamingStream::SetBookmark.
BUG=v8:4422 [email protected] LOG=Y Review URL: https://codereview.chromium.org/1346613002 Cr-Commit-Position: refs/heads/master@{#30763}
1 parent 04087a7 commit 1025d34

2 files changed

Lines changed: 35 additions & 7 deletions

File tree

src/scanner-character-streams.cc

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ size_t ExternalStreamingStream::FillBuffer(size_t position) {
347347
current_data_length_ = source_stream_->GetMoreData(&current_data_);
348348
current_data_offset_ = 0;
349349
bool data_ends = current_data_length_ == 0;
350+
bookmark_data_is_from_current_data_ = false;
350351

351352
// A caveat: a data chunk might end with bytes from an incomplete UTF-8
352353
// character (the rest of the bytes will be in the next chunk).
@@ -406,6 +407,15 @@ bool ExternalStreamingStream::SetBookmark() {
406407
// - buffer_[buffer_cursor_ .. buffer_end_] => bookmark_buffer_
407408
// - current_data_[.._offset_ .. .._length_] => bookmark_data_
408409
// - utf8_split_char_buffer_* => bookmark_utf8_split...
410+
//
411+
// To make sure we don't unnecessarily copy data, we also maintain
412+
// whether bookmark_data_ contains a copy of the current current_data_
413+
// block. This is done with:
414+
// - bookmark_data_is_from_current_data_
415+
// - bookmark_data_offset_: offset into bookmark_data_
416+
//
417+
// Note that bookmark_data_is_from_current_data_ must be maintained
418+
// whenever current_data_ is updated.
409419

410420
bookmark_ = pos_;
411421

@@ -415,10 +425,21 @@ bool ExternalStreamingStream::SetBookmark() {
415425
CopyCharsUnsigned(bookmark_buffer_.start(), buffer_cursor_, buffer_length);
416426

417427
size_t data_length = current_data_length_ - current_data_offset_;
418-
bookmark_data_.Dispose();
419-
bookmark_data_ = Vector<uint8_t>::New(static_cast<int>(data_length));
420-
CopyBytes(bookmark_data_.start(), current_data_ + current_data_offset_,
421-
data_length);
428+
size_t bookmark_data_length = static_cast<size_t>(bookmark_data_.length());
429+
if (bookmark_data_is_from_current_data_ &&
430+
data_length < bookmark_data_length) {
431+
// Fast case: bookmark_data_ was previously copied from the current
432+
// data block, and we have enough data for this bookmark.
433+
bookmark_data_offset_ = bookmark_data_length - data_length;
434+
} else {
435+
// Slow case: We need to copy current_data_.
436+
bookmark_data_.Dispose();
437+
bookmark_data_ = Vector<uint8_t>::New(static_cast<int>(data_length));
438+
CopyBytes(bookmark_data_.start(), current_data_ + current_data_offset_,
439+
data_length);
440+
bookmark_data_is_from_current_data_ = true;
441+
bookmark_data_offset_ = 0;
442+
}
422443

423444
bookmark_utf8_split_char_buffer_length_ = utf8_split_char_buffer_length_;
424445
for (size_t i = 0; i < utf8_split_char_buffer_length_; i++) {
@@ -437,12 +458,14 @@ void ExternalStreamingStream::ResetToBookmark() {
437458

438459
// bookmark_data_* => current_data_*
439460
// (current_data_ assumes ownership of its memory.)
440-
uint8_t* data = new uint8_t[bookmark_data_.length()];
461+
uint8_t* data = new uint8_t[bookmark_data_.length() - bookmark_data_offset_];
441462
current_data_offset_ = 0;
442-
current_data_length_ = bookmark_data_.length();
443-
CopyCharsUnsigned(data, bookmark_data_.begin(), bookmark_data_.length());
463+
current_data_length_ = bookmark_data_.length() - bookmark_data_offset_;
464+
CopyCharsUnsigned(data, bookmark_data_.begin() + bookmark_data_offset_,
465+
bookmark_data_.length());
444466
delete[] current_data_;
445467
current_data_ = data;
468+
bookmark_data_is_from_current_data_ = true;
446469

447470
// bookmark_buffer_ needs to be copied to buffer_.
448471
CopyCharsUnsigned(buffer_, bookmark_buffer_.begin(),
@@ -463,6 +486,7 @@ void ExternalStreamingStream::FlushCurrent() {
463486
current_data_ = NULL;
464487
current_data_length_ = 0;
465488
current_data_offset_ = 0;
489+
bookmark_data_is_from_current_data_ = false;
466490
}
467491

468492

src/scanner-character-streams.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ class ExternalStreamingStream : public BufferedUtf16CharacterStream {
9999
current_data_length_(0),
100100
utf8_split_char_buffer_length_(0),
101101
bookmark_(0),
102+
bookmark_data_is_from_current_data_(false),
103+
bookmark_data_offset_(0),
102104
bookmark_utf8_split_char_buffer_length_(0) {}
103105

104106
virtual ~ExternalStreamingStream() {
@@ -139,6 +141,8 @@ class ExternalStreamingStream : public BufferedUtf16CharacterStream {
139141
size_t bookmark_;
140142
Vector<uint16_t> bookmark_buffer_;
141143
Vector<uint8_t> bookmark_data_;
144+
bool bookmark_data_is_from_current_data_;
145+
size_t bookmark_data_offset_;
142146
uint8_t bookmark_utf8_split_char_buffer_[4];
143147
size_t bookmark_utf8_split_char_buffer_length_;
144148
};

0 commit comments

Comments
 (0)