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