• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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