Home | History | Annotate | Download | only in src
      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