// 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. #ifndef V8_CODEGEN_RELOC_INFO_H_ #define V8_CODEGEN_RELOC_INFO_H_ #include "src/base/export-template.h" #include "src/common/code-memory-access.h" #include "src/common/globals.h" #include "src/objects/code.h" #include "src/objects/instruction-stream.h" namespace v8 { namespace internal { class CodeReference; class EmbeddedData; // Specifies whether to perform icache flush operations on RelocInfo updates. // If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an // instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be // skipped (only use this if you will flush the icache manually before it is // executed). enum ICacheFlushMode { … }; namespace detail { // ----------------------------------------------------------------------------- // Implementation of RelocInfoWriter and RelocIterator // // Relocation information is written backwards in memory, from high addresses // towards low addresses, byte by byte. Therefore, in the encodings listed // below, the first byte listed it at the highest address, and successive // bytes in the record are at progressively lower addresses. // // Encoding // // The most common modes are given single-byte encodings. Also, it is // easy to identify the type of reloc info and skip unwanted modes in // an iteration. // // The encoding relies on the fact that there are fewer than 14 // different relocation modes using standard non-compact encoding. // // The first byte of a relocation record has a tag in its low 2 bits: // Here are the record schemes, depending on the low tag and optional higher // tags. // // Low tag: // 00: embedded_object: [6-bit pc delta] 00 // // 01: code_target: [6-bit pc delta] 01 // // 10: wasm_stub_call: [6-bit pc delta] 10 // // 11: long_record [6 bit reloc mode] 11 // followed by pc delta // followed by optional data depending on type. // // If a pc delta exceeds 6 bits, it is split into a remainder that fits into // 6 bits and a part that does not. The latter is encoded as a long record // with PC_JUMP as pseudo reloc info mode. The former is encoded as part of // the following record in the usual way. The long pc jump record has variable // length: // pc-jump: [PC_JUMP] 11 // 1 [7 bits data] // ... // 0 [7 bits data] // (Bits 6..31 of pc delta, encoded with VLQ.) constexpr int kTagBits = …; constexpr int kTagMask = …; constexpr int kLongTagBits = …; constexpr int kEmbeddedObjectTag = …; constexpr int kCodeTargetTag = …; constexpr int kWasmStubCallTag = …; constexpr int kDefaultTag = …; constexpr int kSmallPCDeltaBits = …; constexpr int kSmallPCDeltaMask = …; } // namespace detail // ----------------------------------------------------------------------------- // Relocation information // Relocation information consists of the address (pc) of the datum // to which the relocation information applies, the relocation mode // (rmode), and an optional data field. The relocation mode may be // "descriptive" and not indicate a need for relocation, but simply // describe a property of the datum. Such rmodes are useful for GC // and nice disassembly output. class RelocInfo { … }; class WritableRelocInfo : public RelocInfo { … }; // RelocInfoWriter serializes a stream of relocation info. It writes towards // lower addresses. class RelocInfoWriter { … }; // A RelocIterator iterates over relocation information. // Typical use: // // for (RelocIterator it(code); !it.done(); it.next()) { // // do something with it.rinfo() here // } // // A mask can be specified to skip unwanted modes. template <typename RelocInfoT> class RelocIteratorBase { … }; extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) RelocIteratorBase<RelocInfo>; extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) RelocIteratorBase<WritableRelocInfo>; class V8_EXPORT_PRIVATE RelocIterator : public RelocIteratorBase<RelocInfo> { … }; class V8_EXPORT_PRIVATE WritableRelocIterator : public RelocIteratorBase<WritableRelocInfo> { … }; } // namespace internal } // namespace v8 #endif // V8_CODEGEN_RELOC_INFO_H_