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_H_ 6 #define V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_ 7 8 #include "src/interpreter/interpreter.h" 9 #include "src/snapshot/builtin-deserializer-allocator.h" 10 #include "src/snapshot/builtin-snapshot-utils.h" 11 #include "src/snapshot/deserializer.h" 12 13 namespace v8 { 14 namespace internal { 15 16 class BuiltinSnapshotData; 17 18 // Deserializes the builtins blob. 19 class BuiltinDeserializer final 20 : public Deserializer<BuiltinDeserializerAllocator> { 21 using BSU = BuiltinSnapshotUtils; 22 using Bytecode = interpreter::Bytecode; 23 using OperandScale = interpreter::OperandScale; 24 25 public: 26 BuiltinDeserializer(Isolate* isolate, const BuiltinSnapshotData* data); 27 28 // Builtins deserialization is tightly integrated with deserialization of the 29 // startup blob. In particular, we need to ensure that no GC can occur 30 // between startup- and builtins deserialization, as all builtins have been 31 // pre-allocated and their pointers may not be invalidated. 32 // 33 // After this, the instruction cache must be flushed by the caller (we don't 34 // do it ourselves since the startup serializer batch-flushes all code pages). 35 void DeserializeEagerBuiltinsAndHandlers(); 36 37 // Deserializes the single given builtin. This is used whenever a builtin is 38 // lazily deserialized at runtime. 39 Code* DeserializeBuiltin(int builtin_id); 40 41 // Deserializes the single given handler. This is used whenever a handler is 42 // lazily deserialized at runtime. 43 Code* DeserializeHandler(Bytecode bytecode, OperandScale operand_scale); 44 45 private: 46 // Deserializes the single given builtin. Assumes that reservations have 47 // already been allocated. 48 Code* DeserializeBuiltinRaw(int builtin_id); 49 50 // Deserializes the single given bytecode handler. Assumes that reservations 51 // have already been allocated. 52 Code* DeserializeHandlerRaw(Bytecode bytecode, OperandScale operand_scale); 53 54 // Extracts the size builtin Code objects (baked into the snapshot). 55 uint32_t ExtractCodeObjectSize(int builtin_id); 56 57 // BuiltinDeserializer implements its own builtin iteration logic. Make sure 58 // the RootVisitor API is not used accidentally. VisitRootPointers(Root root,const char * description,Object ** start,Object ** end)59 void VisitRootPointers(Root root, const char* description, Object** start, 60 Object** end) override { 61 UNREACHABLE(); 62 } 63 CurrentCodeObjectId()64 int CurrentCodeObjectId() const { return current_code_object_id_; } 65 66 // Convenience function to grab the handler off the heap's strong root list. 67 Code* GetDeserializeLazyHandler(OperandScale operand_scale) const; 68 69 private: 70 // Stores the code object currently being deserialized. The 71 // {current_code_object_id} stores the index of the currently-deserialized 72 // code object within the snapshot (and within {code_offsets_}). We need this 73 // to determine where to 'allocate' from during deserialization. 74 static const int kNoCodeObjectId = -1; 75 int current_code_object_id_ = kNoCodeObjectId; 76 77 // The offsets of each builtin within the serialized data. Equivalent to 78 // BuiltinSerializer::builtin_offsets_ but on the deserialization side. 79 Vector<const uint32_t> code_offsets_; 80 81 // For current_code_object_id_. 82 friend class DeserializingCodeObjectScope; 83 84 // For isolate(), IsLazyDeserializationEnabled(), CurrentCodeObjectId() and 85 // ExtractBuiltinSize(). 86 friend class BuiltinDeserializerAllocator; 87 }; 88 89 } // namespace internal 90 } // namespace v8 91 92 #endif // V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_ 93