| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef RUNTIME_VM_SNAPSHOT_H_ |
| #define RUNTIME_VM_SNAPSHOT_H_ |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "platform/assert.h" |
| #include "platform/unaligned.h" |
| #include "vm/allocation.h" |
| #include "vm/globals.h" |
| #include "vm/message.h" |
| #include "vm/thread.h" |
| |
| namespace dart { |
| |
| // Structure capturing the raw snapshot. |
| // |
| class Snapshot { |
| public: |
| enum Kind { |
| kFull, // Full snapshot of an application. |
| kFullCore, // Full snapshot of core libraries. |
| kFullJIT, // Full + JIT code |
| kFullAOT, // Full + AOT code |
| kNone, // gen_snapshot |
| kInvalid |
| }; |
| static const char* KindToCString(Kind kind); |
| |
| static const Snapshot* SetupFromBuffer(const void* raw_memory); |
| |
| static constexpr int32_t kMagicValue = 0xdcdcf5f5; |
| static constexpr intptr_t kMagicOffset = 0; |
| static constexpr intptr_t kMagicSize = sizeof(int32_t); |
| static constexpr intptr_t kLengthOffset = kMagicOffset + kMagicSize; |
| static constexpr intptr_t kLengthSize = sizeof(int64_t); |
| static constexpr intptr_t kKindOffset = kLengthOffset + kLengthSize; |
| static constexpr intptr_t kKindSize = sizeof(int64_t); |
| static constexpr intptr_t kHeaderSize = kKindOffset + kKindSize; |
| |
| // Accessors. |
| bool check_magic() const { |
| return Read<int32_t>(kMagicOffset) == kMagicValue; |
| } |
| void set_magic() { return Write<int32_t>(kMagicOffset, kMagicValue); } |
| // Excluding the magic value from the size written in the buffer is needed |
| // so we give a proper version mismatch error for snapshots create before |
| // magic value was written by the VM instead of the embedder. |
| int64_t large_length() const { |
| return Read<int64_t>(kLengthOffset) + kMagicSize; |
| } |
| intptr_t length() const { return static_cast<intptr_t>(large_length()); } |
| void set_length(intptr_t value) { |
| return Write<int64_t>(kLengthOffset, value - kMagicSize); |
| } |
| Kind kind() const { return static_cast<Kind>(Read<int64_t>(kKindOffset)); } |
| void set_kind(Kind value) { return Write<int64_t>(kKindOffset, value); } |
| |
| static bool IsFull(Kind kind) { |
| return (kind == kFull) || (kind == kFullCore) || (kind == kFullJIT) || |
| (kind == kFullAOT); |
| } |
| static bool IncludesCode(Kind kind) { |
| return (kind == kFullJIT) || (kind == kFullAOT); |
| } |
| |
| static bool IncludesStringsInROData(Kind kind) { |
| #if !defined(DART_COMPRESSED_POINTERS) |
| return IncludesCode(kind); |
| #else |
| return false; |
| #endif |
| } |
| |
| const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); } |
| |
| const uint8_t* DataImage() const { |
| if (!IncludesCode(kind())) { |
| return nullptr; |
| } |
| uword offset = Utils::RoundUp(length(), kObjectStartAlignment); |
| return Addr() + offset; |
| } |
| |
| private: |
| // Prevent Snapshot from ever being allocated directly. |
| Snapshot(); |
| |
| template <typename T> |
| T Read(intptr_t offset) const { |
| return LoadUnaligned( |
| reinterpret_cast<const T*>(reinterpret_cast<uword>(this) + offset)); |
| } |
| |
| template <typename T> |
| void Write(intptr_t offset, T value) { |
| return StoreUnaligned( |
| reinterpret_cast<T*>(reinterpret_cast<uword>(this) + offset), value); |
| } |
| |
| DISALLOW_COPY_AND_ASSIGN(Snapshot); |
| }; |
| |
| inline static bool IsSnapshotCompatible(Snapshot::Kind vm_kind, |
| Snapshot::Kind isolate_kind) { |
| if (vm_kind == isolate_kind) return true; |
| if (((vm_kind == Snapshot::kFull) || (vm_kind == Snapshot::kFullCore)) && |
| isolate_kind == Snapshot::kFullJIT) |
| return true; |
| return Snapshot::IsFull(isolate_kind); |
| } |
| |
| class SerializedObjectBuffer : public StackResource { |
| public: |
| SerializedObjectBuffer() |
| : StackResource(Thread::Current()), message_(nullptr) {} |
| |
| void set_message(std::unique_ptr<Message> message) { |
| ASSERT(message_ == nullptr); |
| message_ = std::move(message); |
| } |
| std::unique_ptr<Message> StealMessage() { return std::move(message_); } |
| |
| private: |
| std::unique_ptr<Message> message_; |
| }; |
| |
| } // namespace dart |
| |
| #endif // RUNTIME_VM_SNAPSHOT_H_ |