• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 #ifndef V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
6 #define V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
7 
8 #include <unordered_set>
9 
10 #include "src/globals.h"
11 #include "src/heap/heap.h"
12 #include "src/interpreter/interpreter.h"
13 #include "src/snapshot/serializer-common.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 template <class AllocatorT>
19 class Deserializer;
20 
21 class BuiltinDeserializer;
22 class BuiltinSnapshotUtils;
23 
24 class BuiltinDeserializerAllocator final {
25   using BSU = BuiltinSnapshotUtils;
26   using Bytecode = interpreter::Bytecode;
27   using OperandScale = interpreter::OperandScale;
28 
29  public:
30   BuiltinDeserializerAllocator(
31       Deserializer<BuiltinDeserializerAllocator>* deserializer);
32 
33   ~BuiltinDeserializerAllocator();
34 
35   // ------- Allocation Methods -------
36   // Methods related to memory allocation during deserialization.
37 
38   // Allocation works differently here than in other deserializers. Instead of
39   // a statically-known memory area determined at serialization-time, our
40   // memory requirements here are determined at runtime. Another major
41   // difference is that we create builtin Code objects up-front (before
42   // deserialization) in order to avoid having to patch builtin references
43   // later on. See also the kBuiltin case in deserializer.cc.
44   //
45   // There are three ways that we use to reserve / allocate space. In all
46   // cases, required objects are requested from the GC prior to
47   // deserialization. 1. pre-allocated builtin code objects are written into
48   // the builtins table (this is to make deserialization of builtin references
49   // easier). Pre-allocated handler code objects are 2. stored in the
50   // {handler_allocations_} vector (at eager-deserialization time) and 3.
51   // stored in {handler_allocation_} (at lazy-deserialization time).
52   //
53   // Allocate simply returns the pre-allocated object prepared by
54   // InitializeFromReservations.
55   Address Allocate(AllocationSpace space, int size);
56 
MoveToNextChunk(AllocationSpace space)57   void MoveToNextChunk(AllocationSpace space) { UNREACHABLE(); }
SetAlignment(AllocationAlignment alignment)58   void SetAlignment(AllocationAlignment alignment) { UNREACHABLE(); }
59 
set_next_reference_is_weak(bool next_reference_is_weak)60   void set_next_reference_is_weak(bool next_reference_is_weak) {
61     next_reference_is_weak_ = next_reference_is_weak;
62   }
63 
GetAndClearNextReferenceIsWeak()64   bool GetAndClearNextReferenceIsWeak() {
65     bool saved = next_reference_is_weak_;
66     next_reference_is_weak_ = false;
67     return saved;
68   }
69 
70 #ifdef DEBUG
next_reference_is_weak()71   bool next_reference_is_weak() const { return next_reference_is_weak_; }
72 #endif
73 
GetMap(uint32_t index)74   HeapObject* GetMap(uint32_t index) { UNREACHABLE(); }
GetLargeObject(uint32_t index)75   HeapObject* GetLargeObject(uint32_t index) { UNREACHABLE(); }
GetObject(AllocationSpace space,uint32_t chunk_index,uint32_t chunk_offset)76   HeapObject* GetObject(AllocationSpace space, uint32_t chunk_index,
77                         uint32_t chunk_offset) {
78     UNREACHABLE();
79   }
80 
81   // ------- Reservation Methods -------
82   // Methods related to memory reservations (prior to deserialization).
83 
84   // Builtin deserialization does not bake reservations into the snapshot, hence
85   // this is a nop.
DecodeReservation(std::vector<SerializedData::Reservation> res)86   void DecodeReservation(std::vector<SerializedData::Reservation> res) {}
87 
88   // These methods are used to pre-allocate builtin objects prior to
89   // deserialization.
90   // TODO(jgruber): Refactor reservation/allocation logic in deserializers to
91   // make this less messy.
92   Heap::Reservation CreateReservationsForEagerBuiltinsAndHandlers();
93   void InitializeFromReservations(const Heap::Reservation& reservation);
94 
95   // Creates reservations and initializes the builtins table in preparation for
96   // lazily deserializing a single builtin.
97   void ReserveAndInitializeBuiltinsTableForBuiltin(int builtin_id);
98 
99   // Pre-allocates a code object preparation for lazily deserializing a single
100   // handler.
101   void ReserveForHandler(Bytecode bytecode, OperandScale operand_scale);
102 
103 #ifdef DEBUG
104   bool ReservationsAreFullyUsed() const;
105 #endif
106 
107  private:
108   Isolate* isolate() const;
109   BuiltinDeserializer* deserializer() const;
110 
111   // Used after memory allocation prior to isolate initialization, to register
112   // the newly created object in code space and add it to the builtins table.
113   void InitializeBuiltinFromReservation(const Heap::Chunk& chunk,
114                                         int builtin_id);
115 
116   // As above, but for interpreter bytecode handlers.
117   void InitializeHandlerFromReservation(
118       const Heap::Chunk& chunk, interpreter::Bytecode bytecode,
119       interpreter::OperandScale operand_scale);
120 
121 #ifdef DEBUG
122   void RegisterCodeObjectReservation(int code_object_id);
123   void RegisterCodeObjectAllocation(int code_object_id);
124   std::unordered_set<int> unused_reservations_;
125 #endif
126 
127  private:
128   // The current deserializer. Note that this always points to a
129   // BuiltinDeserializer instance, but we can't perform the cast during
130   // construction since that makes vtable-based checks fail.
131   Deserializer<BuiltinDeserializerAllocator>* const deserializer_;
132 
133   // Stores allocated space for bytecode handlers during eager deserialization.
134   std::vector<Address>* handler_allocations_ = nullptr;
135 
136   // Stores the allocated space for a single handler during lazy
137   // deserialization.
138   Address handler_allocation_ = kNullAddress;
139 
140   bool next_reference_is_weak_ = false;
141 
142   DISALLOW_COPY_AND_ASSIGN(BuiltinDeserializerAllocator)
143 };
144 
145 }  // namespace internal
146 }  // namespace v8
147 
148 #endif  // V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
149