// This enumeration list the different kind of instructions which can be // decoded. These kind correspond to the set of visitor defined by the default // Decoder. enumclass InstDecodedKind : uint8_t {
NotDecodedYet, #define DECLARE(E) E,
VISITOR_LIST(DECLARE) #undef DECLARE
};
// A SinglePageDecodeCache is used to store the decoded kind of all instructions // in an executable page of code. Each time an instruction is decoded, its // decoded kind is recorded in this structure. The previous instruction value is // also recorded in this structure when using a debug build. // // The next time the same offset is visited, the instruction would be decoded // using the previously recorded decode kind. It is also compared against the // previously recorded bits of the instruction to check for potential missing // cache invalidations, in debug builds. // // This structure stores the equivalent of a single page of code to have better // memory locality when using the simulator. As opposed to having a hash-table // for all instructions. However a hash-table is used by the CachingDecoder to // map the prefixes of page addresses to these SinglePageDecodeCaches. class SinglePageDecodeCache { public: staticconst uintptr_t PageSize = 1 << 12; staticconst uintptr_t PageMask = PageSize - 1; staticconst uintptr_t InstSize = vixl::kInstructionSize; staticconst uintptr_t InstMask = InstSize - 1; staticconst uintptr_t InstPerPage = PageSize / InstSize;
private: // Record the address at which the corresponding code page starts. const uintptr_t pageStart_;
// Cache what instruction got decoded previously, in order to assert if we see // any stale instructions after.
uint32_t instCache_[InstPerPage];
// Cache the decoding of the instruction such that we can skip the decoding // part.
InstDecodedKind decodeCache_[InstPerPage];
};
// A DecoderVisitor which will record which visitor function should be called // the next time we want to decode the same instruction. class CachingDecoderVisitor : public DecoderVisitor { public:
CachingDecoderVisitor() = default; virtual ~CachingDecoderVisitor() {}
// The Caching decoder works by extending the default vixl Decoder class. It // extends it by overloading the Decode function. // // The overloaded Decode function checks whether the instruction given as // argument got decoded before or since it got invalidated. If it was not // previously decoded, the value of the instruction is recorded as well as the // kind of instruction. Otherwise, the value of the instruction is checked // against the previously recorded value and the instruction kind is used to // skip the decoding visitor and resume the execution of instruction. // // The caching decoder stores the equivalent of a page of executable code in a // hash-table. Each SinglePageDecodeCache stores an array of decoded kind as // well as the value of the previously decoded instruction. // // When testing if an instruction was decoded before, we check if the address of // the instruction is contained in the last SinglePageDecodeCache. If it is not, // then the hash-table entry is queried and created if necessary, and the last // SinglePageDecodeCache is updated. Then, the last SinglePageDecodeCache // necessary contains the decoded kind of the instruction given as argument. // // The caching decoder add an extra function for flushing the cache, which is in // charge of clearing the decoded kind of instruction in the range of addresses // given as argument. This is indirectly called by // CPU::EnsureIAndDCacheCoherency. class CachingDecoder : public Decoder { using ICacheMap = mozilla::HashMap<uintptr_t, SinglePageDecodeCache*>; public:
CachingDecoder()
: lastPage_(nullptr)
{
PrependVisitor(&cachingDecoder_);
}
~CachingDecoder() {
RemoveVisitor(&cachingDecoder_);
}
private: // Record the type of the decoded instruction, to avoid decoding it a second // time the next time we execute it.
CachingDecoderVisitor cachingDecoder_;
// Store the mapping of Instruction pointer to the corresponding // SinglePageDecodeCache.
ICacheMap iCache_;
// Record the last SinglePageDecodeCache seen, such that we can quickly access // it for the next instruction.
SinglePageDecodeCache* lastPage_;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.