| // Copyright 2018 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/instruction-stream.h" |
| |
| #include "src/builtins/builtins.h" |
| #include "src/objects-inl.h" |
| #include "src/snapshot/snapshot.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| // static |
| bool InstructionStream::PcIsOffHeap(Isolate* isolate, Address pc) { |
| if (FLAG_embedded_builtins) { |
| const Address start = reinterpret_cast<Address>(isolate->embedded_blob()); |
| return start <= pc && pc < start + isolate->embedded_blob_size(); |
| } else { |
| return false; |
| } |
| } |
| |
| // static |
| Code* InstructionStream::TryLookupCode(Isolate* isolate, Address address) { |
| if (!PcIsOffHeap(isolate, address)) return nullptr; |
| |
| EmbeddedData d = EmbeddedData::FromBlob(); |
| |
| int l = 0, r = Builtins::builtin_count; |
| while (l < r) { |
| const int mid = (l + r) / 2; |
| Address start = d.InstructionStartOfBuiltin(mid); |
| Address end = start + d.InstructionSizeOfBuiltin(mid); |
| |
| if (address < start) { |
| r = mid; |
| } else if (address >= end) { |
| l = mid + 1; |
| } else { |
| return isolate->builtins()->builtin(mid); |
| } |
| } |
| |
| UNREACHABLE(); |
| } |
| |
| // static |
| void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate, |
| uint8_t** data, |
| uint32_t* size) { |
| EmbeddedData d = EmbeddedData::FromIsolate(isolate); |
| |
| const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize()); |
| const uint32_t allocated_size = RoundUp(d.size(), page_size); |
| |
| uint8_t* allocated_bytes = static_cast<uint8_t*>( |
| AllocatePages(GetRandomMmapAddr(), allocated_size, page_size, |
| PageAllocator::kReadWrite)); |
| CHECK_NOT_NULL(allocated_bytes); |
| |
| std::memcpy(allocated_bytes, d.data(), d.size()); |
| CHECK(SetPermissions(allocated_bytes, allocated_size, |
| PageAllocator::kReadExecute)); |
| |
| *data = allocated_bytes; |
| *size = d.size(); |
| |
| d.Dispose(); |
| } |
| |
| // static |
| void InstructionStream::FreeOffHeapInstructionStream(uint8_t* data, |
| uint32_t size) { |
| const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize()); |
| CHECK(FreePages(data, RoundUp(size, page_size))); |
| } |
| |
| } // namespace internal |
| } // namespace v8 |