blob: f0686af3c0e9f71a2e3477bad9282adea043b008 [file] [log] [blame]
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
#define V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
#include <utility>
#include "src/base/atomicops.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/snapshot/snapshot-utils.h"
#include "src/utils/utils.h"
namespace v8 {
namespace internal {
/**
* Source to read snapshot and builtins files from.
*
* Note: Memory ownership remains with callee.
*/
class SnapshotByteSource final {
public:
SnapshotByteSource(const char* data, int length)
: data_(reinterpret_cast<const byte*>(data)),
length_(length),
position_(0) {}
explicit SnapshotByteSource(Vector<const byte> payload)
: data_(payload.begin()), length_(payload.length()), position_(0) {}
~SnapshotByteSource() = default;
SnapshotByteSource(const SnapshotByteSource&) = delete;
SnapshotByteSource& operator=(const SnapshotByteSource&) = delete;
bool HasMore() { return position_ < length_; }
byte Get() {
DCHECK(position_ < length_);
return data_[position_++];
}
byte Peek() const {
DCHECK(position_ < length_);
return data_[position_];
}
void Advance(int by) { position_ += by; }
void CopyRaw(void* to, int number_of_bytes) {
memcpy(to, data_ + position_, number_of_bytes);
position_ += number_of_bytes;
}
void CopySlots(Address* dest, int number_of_slots) {
base::AtomicWord* start = reinterpret_cast<base::AtomicWord*>(dest);
base::AtomicWord* end = start + number_of_slots;
for (base::AtomicWord* p = start; p < end;
++p, position_ += sizeof(base::AtomicWord)) {
base::AtomicWord val;
memcpy(&val, data_ + position_, sizeof(base::AtomicWord));
base::Relaxed_Store(p, val);
}
}
#ifdef V8_COMPRESS_POINTERS
void CopySlots(Tagged_t* dest, int number_of_slots) {
AtomicTagged_t* start = reinterpret_cast<AtomicTagged_t*>(dest);
AtomicTagged_t* end = start + number_of_slots;
for (AtomicTagged_t* p = start; p < end;
++p, position_ += sizeof(AtomicTagged_t)) {
AtomicTagged_t val;
memcpy(&val, data_ + position_, sizeof(AtomicTagged_t));
base::Relaxed_Store(p, val);
}
}
#endif
inline int GetInt() {
// This way of decoding variable-length encoded integers does not
// suffer from branch mispredictions.
DCHECK(position_ + 3 < length_);
uint32_t answer = data_[position_];
answer |= data_[position_ + 1] << 8;
answer |= data_[position_ + 2] << 16;
answer |= data_[position_ + 3] << 24;
int bytes = (answer & 3) + 1;
Advance(bytes);
uint32_t mask = 0xffffffffu;
mask >>= 32 - (bytes << 3);
answer &= mask;
answer >>= 2;
return answer;
}
// Returns length.
int GetBlob(const byte** data);
int position() { return position_; }
void set_position(int position) { position_ = position; }
uint32_t GetChecksum() const {
return Checksum(Vector<const byte>(data_, length_));
}
private:
const byte* data_;
int length_;
int position_;
};
/**
* Sink to write snapshot files to.
*
* Users must implement actual storage or i/o.
*/
class SnapshotByteSink {
public:
SnapshotByteSink() = default;
explicit SnapshotByteSink(int initial_size) : data_(initial_size) {}
~SnapshotByteSink() = default;
void Put(byte b, const char* description) { data_.push_back(b); }
void PutInt(uintptr_t integer, const char* description);
void PutRaw(const byte* data, int number_of_bytes, const char* description);
void Append(const SnapshotByteSink& other);
int Position() const { return static_cast<int>(data_.size()); }
const std::vector<byte>* data() const { return &data_; }
private:
std::vector<byte> data_;
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_