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 #include "src/instruction-stream.h"
6
7 #include "src/builtins/builtins.h"
8 #include "src/objects-inl.h"
9 #include "src/snapshot/snapshot.h"
10
11 namespace v8 {
12 namespace internal {
13
14 // static
PcIsOffHeap(Isolate * isolate,Address pc)15 bool InstructionStream::PcIsOffHeap(Isolate* isolate, Address pc) {
16 if (FLAG_embedded_builtins) {
17 const Address start = reinterpret_cast<Address>(isolate->embedded_blob());
18 return start <= pc && pc < start + isolate->embedded_blob_size();
19 } else {
20 return false;
21 }
22 }
23
24 // static
TryLookupCode(Isolate * isolate,Address address)25 Code* InstructionStream::TryLookupCode(Isolate* isolate, Address address) {
26 if (!PcIsOffHeap(isolate, address)) return nullptr;
27
28 EmbeddedData d = EmbeddedData::FromBlob();
29
30 int l = 0, r = Builtins::builtin_count;
31 while (l < r) {
32 const int mid = (l + r) / 2;
33 Address start = d.InstructionStartOfBuiltin(mid);
34 Address end = start + d.InstructionSizeOfBuiltin(mid);
35
36 if (address < start) {
37 r = mid;
38 } else if (address >= end) {
39 l = mid + 1;
40 } else {
41 return isolate->builtins()->builtin(mid);
42 }
43 }
44
45 UNREACHABLE();
46 }
47
48 // static
CreateOffHeapInstructionStream(Isolate * isolate,uint8_t ** data,uint32_t * size)49 void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
50 uint8_t** data,
51 uint32_t* size) {
52 EmbeddedData d = EmbeddedData::FromIsolate(isolate);
53
54 const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize());
55 const uint32_t allocated_size = RoundUp(d.size(), page_size);
56
57 uint8_t* allocated_bytes = static_cast<uint8_t*>(
58 AllocatePages(GetRandomMmapAddr(), allocated_size, page_size,
59 PageAllocator::kReadWrite));
60 CHECK_NOT_NULL(allocated_bytes);
61
62 std::memcpy(allocated_bytes, d.data(), d.size());
63 CHECK(SetPermissions(allocated_bytes, allocated_size,
64 PageAllocator::kReadExecute));
65
66 *data = allocated_bytes;
67 *size = d.size();
68
69 d.Dispose();
70 }
71
72 // static
FreeOffHeapInstructionStream(uint8_t * data,uint32_t size)73 void InstructionStream::FreeOffHeapInstructionStream(uint8_t* data,
74 uint32_t size) {
75 const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize());
76 CHECK(FreePages(data, RoundUp(size, page_size)));
77 }
78
79 } // namespace internal
80 } // namespace v8
81