Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache very common instructions #113

Open
athre0z opened this issue Mar 24, 2019 · 2 comments
Open

Cache very common instructions #113

athre0z opened this issue Mar 24, 2019 · 2 comments
Assignees
Labels
A-decoder Area: Decoder C-feature Category: Addition of a new feature

Comments

@athre0z
Copy link
Member

athre0z commented Mar 24, 2019

It might be worth a try to cache the ~10 most common instructions in the decoder for improved performance. I did a very hacky quick test and determined that caching CC and 00 00 alone results in a ~10% performance boost.

@athre0z athre0z added C-feature Category: Addition of a new feature A-decoder Area: Decoder labels Mar 24, 2019
@athre0z athre0z added this to the someday milestone Mar 24, 2019
@flobernd
Copy link
Member

flobernd commented Mar 25, 2019

Concept idea:

Add an extra layer above the ZydisDecoderDecodeBuffer function (care for the double pointer):

ZydisDecoderDecodeBufferCached(ZydisDecoder decoder, ..., 
    const ZydisCacheTable* cache, ZydisDecodedInstruction** instruction)

// The `instruction` parameter could be used as in- and output: A pointer to the cached
// instruction is returned, if it was found in the cache ...
// ... or directly fill the passed struct, if the instruction was not found in the cache.
ZydisDecodedInstruction instruction_data;
ZydisDecodedInstruction* instruction = &instruction_data;
ZydisDecoderDecodeBufferCached(..., &instruction);

// E.g.:
ZyanStatus ZydisDecoderDecodeBufferCached(..., ZydisDecodedInstruction** instruction)
{
    // ...
    if (found_in_cache)
    {
        *instruction = &cache[index];
        return ZYAN_STATUS_TRUE; // indicate, that the instruction was cached
    } else
    {
        const ZyanStatus status = ZydisDecoderDecodeBuffer(..., *instruction);
        ZYAN_CHECK(status);
        return ZYAN_STATUS_FALSE; // indicate, that the instruction was not cached
    }
}

Make sure to add good documentation about the in/out parameter and warn the user to not override data in a cached instruction (could be indicated by the return code).

Add an initializer function:

ZydisDecoderInitializeCache(ZydisDecoder decoder, ZydisCacheTable* cache)

Define the ZydisCacheTable struct:

typedef struct ZydisCacheTable_
{
    ZyanI8 index[2][256]; // <- up to 2-byte opcodes for now; easy to extend
    ZydisDecodedInstruction instructions[n];
} ZydisCacheTable;

@athre0z
Copy link
Member Author

athre0z commented Mar 27, 2019

Make sure to add good documentation about the in/out parameter and warn the user to not override data in a cached instruction (could be indicated by the return code).

With a detached caching layer, we can just make the instruction argument const, thus clearly communicating the immutability.

@athre0z athre0z self-assigned this Mar 27, 2019
@athre0z athre0z removed this from the someday milestone Nov 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-decoder Area: Decoder C-feature Category: Addition of a new feature
Projects
None yet
Development

No branches or pull requests

2 participants