Line data Source code
1 : // Copyright 2018 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_EMBEDDED_DATA_H_
6 : #define V8_SNAPSHOT_EMBEDDED_DATA_H_
7 :
8 : #include "src/base/macros.h"
9 : #include "src/builtins/builtins.h"
10 : #include "src/globals.h"
11 : #include "src/isolate.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : class Code;
17 : class Isolate;
18 :
19 : // Wraps an off-heap instruction stream.
20 : // TODO(jgruber,v8:6666): Remove this class.
21 : class InstructionStream final : public AllStatic {
22 : public:
23 : // Returns true, iff the given pc points into an off-heap instruction stream.
24 : static bool PcIsOffHeap(Isolate* isolate, Address pc);
25 :
26 : // Returns the corresponding Code object if it exists, and nullptr otherwise.
27 : static Code TryLookupCode(Isolate* isolate, Address address);
28 :
29 : // During snapshot creation, we first create an executable off-heap area
30 : // containing all off-heap code. The area is guaranteed to be contiguous.
31 : // Note that this only applies when building the snapshot, e.g. for
32 : // mksnapshot. Otherwise, off-heap code is embedded directly into the binary.
33 : static void CreateOffHeapInstructionStream(Isolate* isolate, uint8_t** data,
34 : uint32_t* size);
35 : static void FreeOffHeapInstructionStream(uint8_t* data, uint32_t size);
36 : };
37 :
38 : class EmbeddedData final {
39 : public:
40 : static EmbeddedData FromIsolate(Isolate* isolate);
41 :
42 56 : static EmbeddedData FromBlob() {
43 : return EmbeddedData(Isolate::CurrentEmbeddedBlob(),
44 283462978 : Isolate::CurrentEmbeddedBlobSize());
45 : }
46 :
47 47641495 : static EmbeddedData FromBlob(Isolate* isolate) {
48 : return EmbeddedData(isolate->embedded_blob(),
49 47641495 : isolate->embedded_blob_size());
50 : }
51 :
52 : const uint8_t* data() const { return data_; }
53 : uint32_t size() const { return size_; }
54 :
55 56 : void Dispose() { delete[] data_; }
56 :
57 : Address InstructionStartOfBuiltin(int i) const;
58 : uint32_t InstructionSizeOfBuiltin(int i) const;
59 :
60 1505 : bool ContainsBuiltin(int i) const { return InstructionSizeOfBuiltin(i) > 0; }
61 :
62 : uint32_t AddressForHashing(Address addr) {
63 47641486 : Address start = reinterpret_cast<Address>(data_);
64 : DCHECK(IsInRange(addr, start, start + size_));
65 47641486 : return static_cast<uint32_t>(addr - start);
66 : }
67 :
68 : // Padded with kCodeAlignment.
69 : uint32_t PaddedInstructionSizeOfBuiltin(int i) const {
70 1505 : uint32_t size = InstructionSizeOfBuiltin(i);
71 22551972 : return (size == 0) ? 0 : PadAndAlign(size);
72 : }
73 :
74 : size_t CreateEmbeddedBlobHash() const;
75 : size_t EmbeddedBlobHash() const {
76 : return *reinterpret_cast<const size_t*>(data_ + EmbeddedBlobHashOffset());
77 : }
78 :
79 : size_t IsolateHash() const {
80 : return *reinterpret_cast<const size_t*>(data_ + IsolateHashOffset());
81 : }
82 :
83 : struct Metadata {
84 : // Blob layout information.
85 : uint32_t instructions_offset;
86 : uint32_t instructions_length;
87 : };
88 : STATIC_ASSERT(offsetof(Metadata, instructions_offset) == 0);
89 : STATIC_ASSERT(offsetof(Metadata, instructions_length) == kUInt32Size);
90 : STATIC_ASSERT(sizeof(Metadata) == kUInt32Size + kUInt32Size);
91 :
92 : // The layout of the blob is as follows:
93 : //
94 : // [0] hash of the remaining blob
95 : // [1] hash of embedded-blob-relevant heap objects
96 : // [2] metadata of instruction stream 0
97 : // ... metadata
98 : // ... instruction streams
99 :
100 : static constexpr uint32_t kTableSize = Builtins::builtin_count;
101 : static constexpr uint32_t EmbeddedBlobHashOffset() { return 0; }
102 : static constexpr uint32_t EmbeddedBlobHashSize() { return kSizetSize; }
103 : static constexpr uint32_t IsolateHashOffset() {
104 : return EmbeddedBlobHashOffset() + EmbeddedBlobHashSize();
105 : }
106 : static constexpr uint32_t IsolateHashSize() { return kSizetSize; }
107 : static constexpr uint32_t MetadataOffset() {
108 : return IsolateHashOffset() + IsolateHashSize();
109 : }
110 : static constexpr uint32_t MetadataSize() {
111 : return sizeof(struct Metadata) * kTableSize;
112 : }
113 : static constexpr uint32_t RawDataOffset() {
114 : return PadAndAlign(MetadataOffset() + MetadataSize());
115 : }
116 :
117 : private:
118 56 : EmbeddedData(const uint8_t* data, uint32_t size) : data_(data), size_(size) {
119 : DCHECK_NOT_NULL(data);
120 : DCHECK_LT(0, size);
121 : }
122 :
123 : const Metadata* Metadata() const {
124 : return reinterpret_cast<const struct Metadata*>(data_ + MetadataOffset());
125 : }
126 : const uint8_t* RawData() const { return data_ + RawDataOffset(); }
127 :
128 : static constexpr int PadAndAlign(int size) {
129 : // Ensure we have at least one byte trailing the actual builtin
130 : // instructions which we can later fill with int3.
131 11360284 : return RoundUp<kCodeAlignment>(size + 1);
132 : }
133 :
134 : void PrintStatistics() const;
135 :
136 : const uint8_t* data_;
137 : uint32_t size_;
138 : };
139 :
140 : } // namespace internal
141 : } // namespace v8
142 :
143 : #endif // V8_SNAPSHOT_EMBEDDED_DATA_H_
|