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 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 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 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 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