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