• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SNAPSHOT_SOURCE_SINK_H_
6 #define V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
7 
8 #include <utility>
9 
10 #include "src/base/atomicops.h"
11 #include "src/base/logging.h"
12 #include "src/common/globals.h"
13 #include "src/snapshot/snapshot-utils.h"
14 #include "src/utils/utils.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 
20 /**
21  * Source to read snapshot and builtins files from.
22  *
23  * Note: Memory ownership remains with callee.
24  */
25 class SnapshotByteSource final {
26  public:
SnapshotByteSource(const char * data,int length)27   SnapshotByteSource(const char* data, int length)
28       : data_(reinterpret_cast<const byte*>(data)),
29         length_(length),
30         position_(0) {}
31 
SnapshotByteSource(Vector<const byte> payload)32   explicit SnapshotByteSource(Vector<const byte> payload)
33       : data_(payload.begin()), length_(payload.length()), position_(0) {}
34 
35   ~SnapshotByteSource() = default;
36   SnapshotByteSource(const SnapshotByteSource&) = delete;
37   SnapshotByteSource& operator=(const SnapshotByteSource&) = delete;
38 
HasMore()39   bool HasMore() { return position_ < length_; }
40 
Get()41   byte Get() {
42     DCHECK(position_ < length_);
43     return data_[position_++];
44   }
45 
Peek()46   byte Peek() const {
47     DCHECK(position_ < length_);
48     return data_[position_];
49   }
50 
Advance(int by)51   void Advance(int by) { position_ += by; }
52 
CopyRaw(void * to,int number_of_bytes)53   void CopyRaw(void* to, int number_of_bytes) {
54     memcpy(to, data_ + position_, number_of_bytes);
55     position_ += number_of_bytes;
56   }
57 
CopySlots(Address * dest,int number_of_slots)58   void CopySlots(Address* dest, int number_of_slots) {
59     base::AtomicWord* start = reinterpret_cast<base::AtomicWord*>(dest);
60     base::AtomicWord* end = start + number_of_slots;
61     for (base::AtomicWord* p = start; p < end;
62          ++p, position_ += sizeof(base::AtomicWord)) {
63       base::AtomicWord val;
64       memcpy(&val, data_ + position_, sizeof(base::AtomicWord));
65       base::Relaxed_Store(p, val);
66     }
67   }
68 
69 #ifdef V8_COMPRESS_POINTERS
CopySlots(Tagged_t * dest,int number_of_slots)70   void CopySlots(Tagged_t* dest, int number_of_slots) {
71     AtomicTagged_t* start = reinterpret_cast<AtomicTagged_t*>(dest);
72     AtomicTagged_t* end = start + number_of_slots;
73     for (AtomicTagged_t* p = start; p < end;
74          ++p, position_ += sizeof(AtomicTagged_t)) {
75       AtomicTagged_t val;
76       memcpy(&val, data_ + position_, sizeof(AtomicTagged_t));
77       base::Relaxed_Store(p, val);
78     }
79   }
80 #endif
81 
GetInt()82   inline int GetInt() {
83     // This way of decoding variable-length encoded integers does not
84     // suffer from branch mispredictions.
85     DCHECK(position_ + 3 < length_);
86     uint32_t answer = data_[position_];
87     answer |= data_[position_ + 1] << 8;
88     answer |= data_[position_ + 2] << 16;
89     answer |= data_[position_ + 3] << 24;
90     int bytes = (answer & 3) + 1;
91     Advance(bytes);
92     uint32_t mask = 0xffffffffu;
93     mask >>= 32 - (bytes << 3);
94     answer &= mask;
95     answer >>= 2;
96     return answer;
97   }
98 
99   // Returns length.
100   int GetBlob(const byte** data);
101 
position()102   int position() { return position_; }
set_position(int position)103   void set_position(int position) { position_ = position; }
104 
GetChecksum()105   uint32_t GetChecksum() const {
106     return Checksum(Vector<const byte>(data_, length_));
107   }
108 
109  private:
110   const byte* data_;
111   int length_;
112   int position_;
113 };
114 
115 /**
116  * Sink to write snapshot files to.
117  *
118  * Users must implement actual storage or i/o.
119  */
120 class SnapshotByteSink {
121  public:
122   SnapshotByteSink() = default;
SnapshotByteSink(int initial_size)123   explicit SnapshotByteSink(int initial_size) : data_(initial_size) {}
124 
125   ~SnapshotByteSink() = default;
126 
Put(byte b,const char * description)127   void Put(byte b, const char* description) { data_.push_back(b); }
128 
129   void PutInt(uintptr_t integer, const char* description);
130   void PutRaw(const byte* data, int number_of_bytes, const char* description);
131 
132   void Append(const SnapshotByteSink& other);
Position()133   int Position() const { return static_cast<int>(data_.size()); }
134 
data()135   const std::vector<byte>* data() const { return &data_; }
136 
137  private:
138   std::vector<byte> data_;
139 };
140 
141 }  // namespace internal
142 }  // namespace v8
143 
144 #endif  // V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
145