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

Unified Diff: src/preparser-api.cc

Issue 5545006: Optimized scanner to avoid virtual calls for every character read. (Closed)
Patch Set: Addressed review comments. Created 10 years 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
« no previous file with comments | « src/preparser.cc ('k') | src/scanner.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser-api.cc
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
index f096e941b704ab29f3516176ea1aa000ed766bd7..df2cf2b4ebe8be31d369dd4a21ee7eccc0045d73 100644
--- a/src/preparser-api.cc
+++ b/src/preparser-api.cc
@@ -39,39 +39,82 @@ namespace v8 {
namespace internal {
// UTF16Buffer based on a v8::UnicodeInputStream.
-class InputStreamUTF16Buffer : public UTF16Buffer {
+class InputStreamUTF16Buffer : public UC16CharacterStream {
public:
- explicit InputStreamUTF16Buffer(UnicodeInputStream* stream)
- : UTF16Buffer(),
- stream_(stream) { }
+ explicit InputStreamUTF16Buffer(v8::UnicodeInputStream* stream)
+ : UC16CharacterStream(),
+ stream_(stream),
+ pushback_active_(false) {
+ buffer_cursor_ = buffer_end_ = buffer_ + kPushBackSize;
+ }
virtual ~InputStreamUTF16Buffer() { }
- virtual void PushBack(uc32 ch) {
+ virtual void PushBack(uc16 ch) {
+ ASSERT(pos_ > 0);
+ if (buffer_cursor_ > buffer_) {
+ // While we can stay within the buffer, just do so.
+ *--buffer_cursor_ = ch;
+ pos_--;
+ return;
+ }
+ if (!pushback_active_) {
+ // Push back the entire buffer to the stream and let the
+ // stream handle pushbacks from now.
+ // We leave buffer_cursor_ == buffer_end_, so the next read
+ // will fill the buffer from the current position.
+ // This should happen exceedingly rarely.
+ while (buffer_end_ > buffer_) {
+ stream_->PushBack(*--buffer_end_);
+ }
+ buffer_cursor_ = buffer_end_;
+ pushback_active_ = true;
+ }
stream_->PushBack(ch);
pos_--;
}
- virtual uc32 Advance() {
- uc32 result = stream_->Next();
- if (result >= 0) pos_++;
- return result;
+ protected:
+ virtual bool ReadBlock() {
+ // Copy the top of the buffer into the pushback area.
+ pushback_active_ = false;
+ int32_t value;
+ uc16* buffer_start = buffer_ + kPushBackSize;
+ buffer_cursor_ = buffer_end_ = buffer_start;
+ while ((value = stream_->Next()) >= 0) {
+ if (value > static_cast<int32_t>(unibrow::Utf8::kMaxThreeByteChar)) {
+ value = unibrow::Utf8::kBadChar;
+ }
+ // buffer_end_ is a const pointer, but buffer_ is writable.
+ buffer_start[buffer_end_++ - buffer_start] = static_cast<uc16>(value);
+ if (buffer_end_ == buffer_ + kPushBackSize + kBufferSize) break;
+ }
+ return buffer_end_ > buffer_start;
}
- virtual void SeekForward(int pos) {
+ virtual unsigned SlowSeekForward(unsigned pos) {
// Seeking in the input is not used by preparsing.
// It's only used by the real parser based on preparser data.
UNIMPLEMENTED();
+ return 0;
}
private:
+ static const unsigned kBufferSize = 512;
+ static const unsigned kPushBackSize = 16;
v8::UnicodeInputStream* const stream_;
+ // Buffer holding first kPushBackSize characters of pushback buffer,
+ // then kBufferSize chars of read-ahead.
+ // The pushback buffer is only used if pushing back characters past
+ // the start of a block.
+ uc16 buffer_[kBufferSize + kPushBackSize];
+ bool pushback_active_;
};
class StandAloneJavaScriptScanner : public JavaScriptScanner {
public:
- void Initialize(UTF16Buffer* source) {
+ void Initialize(UC16CharacterStream* source) {
source_ = source;
literal_flags_ = kLiteralString | kLiteralIdentifier;
Init();
« no previous file with comments | « src/preparser.cc ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698