1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_SNAPSHOT_SOURCE_SINK_H_
6 #define V8_SNAPSHOT_SOURCE_SINK_H_
7 
8 #include "src/base/logging.h"
9 #include "src/utils.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 
15 /**
16  * Source to read snapshot and builtins files from.
17  *
18  * Note: Memory ownership remains with callee.
19  */
20 class SnapshotByteSource FINAL {
21  public:
22   SnapshotByteSource(const byte* array, int length);
23   ~SnapshotByteSource();
24 
HasMore()25   bool HasMore() { return position_ < length_; }
26 
Get()27   int Get() {
28     DCHECK(position_ < length_);
29     return data_[position_++];
30   }
31 
32   int32_t GetUnalignedInt();
33 
Advance(int by)34   void Advance(int by) { position_ += by; }
35 
36   void CopyRaw(byte* to, int number_of_bytes);
37 
GetInt()38   inline int GetInt() {
39     // This way of variable-length encoding integers does not suffer from branch
40     // mispredictions.
41     uint32_t answer = GetUnalignedInt();
42     int bytes = answer & 3;
43     Advance(bytes);
44     uint32_t mask = 0xffffffffu;
45     mask >>= 32 - (bytes << 3);
46     answer &= mask;
47     answer >>= 2;
48     return answer;
49   }
50 
51   bool GetBlob(const byte** data, int* number_of_bytes);
52 
53   bool AtEOF();
54 
position()55   int position() { return position_; }
56 
57  private:
58   const byte* data_;
59   int length_;
60   int position_;
61 
62   DISALLOW_COPY_AND_ASSIGN(SnapshotByteSource);
63 };
64 
65 
66 /**
67  * Sink to write snapshot files to.
68  *
69  * Subclasses must implement actual storage or i/o.
70  */
71 class SnapshotByteSink {
72  public:
~SnapshotByteSink()73   virtual ~SnapshotByteSink() { }
74   virtual void Put(byte b, const char* description) = 0;
PutSection(int b,const char * description)75   virtual void PutSection(int b, const char* description) {
76     DCHECK_LE(b, kMaxUInt8);
77     Put(static_cast<byte>(b), description);
78   }
79   void PutInt(uintptr_t integer, const char* description);
80   void PutRaw(byte* data, int number_of_bytes, const char* description);
81   void PutBlob(byte* data, int number_of_bytes, const char* description);
82   virtual int Position() = 0;
83 };
84 
85 
86 class DummySnapshotSink : public SnapshotByteSink {
87  public:
DummySnapshotSink()88   DummySnapshotSink() : length_(0) {}
~DummySnapshotSink()89   virtual ~DummySnapshotSink() {}
Put(byte b,const char * description)90   virtual void Put(byte b, const char* description) { length_++; }
Position()91   virtual int Position() { return length_; }
92 
93  private:
94   int length_;
95 };
96 
97 
98 // Wrap a SnapshotByteSink into a DebugSnapshotSink to get debugging output.
99 class DebugSnapshotSink : public SnapshotByteSink {
100  public:
DebugSnapshotSink(SnapshotByteSink * chained)101   explicit DebugSnapshotSink(SnapshotByteSink* chained) : sink_(chained) {}
102   virtual void Put(byte b, const char* description) OVERRIDE;
Position()103   virtual int Position() OVERRIDE { return sink_->Position(); }
104 
105  private:
106   SnapshotByteSink* sink_;
107 };
108 
109 
110 class ListSnapshotSink : public i::SnapshotByteSink {
111  public:
ListSnapshotSink(i::List<byte> * data)112   explicit ListSnapshotSink(i::List<byte>* data) : data_(data) {}
Put(byte b,const char * description)113   virtual void Put(byte b, const char* description) OVERRIDE {
114     data_->Add(b);
115   }
Position()116   virtual int Position() OVERRIDE { return data_->length(); }
117 
118  private:
119   i::List<byte>* data_;
120 };
121 
122 }  // namespace v8::internal
123 }  // namespace v8
124 
125 #endif  // V8_SNAPSHOT_SOURCE_SINK_H_
126