Skip to content
Snippets Groups Projects
Commit c6b1da20 authored by David Goulet's avatar David Goulet :panda_face:
Browse files

Merge remote-tracking branch 'mbeth-private/ticket40833_mr'

parents 3487a0d6 a94ce252
No related branches found
No related tags found
No related merge requests found
......@@ -27,12 +27,51 @@ HASHX_PRIVATE bool hashx_compile_a64(const hashx_program* program, uint8_t* code
HASHX_PRIVATE void hashx_compiler_init(hashx_ctx* compiler);
HASHX_PRIVATE void hashx_compiler_destroy(hashx_ctx* compiler);
#define COMP_PAGE_SIZE 4096
#define COMP_RESERVE_SIZE 1024
#define COMP_AVG_INSTR_SIZE 5
#define COMP_CODE_SIZE \
ALIGN_SIZE( \
HASHX_PROGRAM_MAX_SIZE * COMP_AVG_INSTR_SIZE + COMP_RESERVE_SIZE, \
COMP_PAGE_SIZE)
/* Compiled code sizes in bytes:
*
* Prologue Epilogue MulH Reg-Reg Reg-Imm32 Branch+Tgt MaxInst
* X86 69 64 9 3..4 7 15 10 (br)
* A64 40 36 4 4 12 24 24 (br)
*
* Maximum code sizes, assuming an arbitrary instruction mix including unlimited
* branch instructions. (Branch size * 512 + prologue + epilogue)
*
* Max possible code size (any instructions)
* X86 5253
* A64 12364
*
* Actual code sizes tend to be much smaller due to the instruction mix chosen
* by the program generator. To get a quick overview of the statistics, we
* measure the sample mean and sample standard deviation for 1 million random
* hash programs:
*
* Mean Std Deviation 4096 bytes at
* X86 2786.4 26.259 49.9 standard deviations
* A64 3507.7 58.526 10.1 standard deviations
*
* If we search for PRNG sequences that maximize generated code size, it's easy
* to find aarch64 code that needs in the range of 4100-4300 bytes. On x86, this
* search still doesn't turn up programs anywhere close to a full page.
*
* Anyway, this is all to say that a one-page buffer is fine except for in
* extremely rare cases on aarch64, and a two-page buffer is enough for any
* behavior we can expect from the program generator under arbitrary input,
* but only a 4-page buffer is enough for fully arbitrary instruction streams
* on any architecture.
*
* Let's use a 2-page buffer on aarch64, or 1-page elsewhere.
*
* Note that the buffer allocation is done by platform-independent code,
* so COMP_CODE_SIZE must always have a valid size even on platforms where
* it is not actually supported or used.
*
* If this buffer fills up, compilation will fail with a runtime error.
*/
#ifdef HASHX_COMPILER_A64
#define COMP_CODE_SIZE (4096 * 2)
#else
#define COMP_CODE_SIZE (4096 * 1)
#endif
#endif
......@@ -23,6 +23,9 @@
#ifdef HASHX_COMPILER_A64
/* Largest compiled instruction (BRANCH) */
#define COMP_MAX_INSTR_SIZE 24
static const uint8_t a64_prologue[] = {
0x07, 0x1c, 0x40, 0xf9, /* ldr x7, [x0, #56] */
0x06, 0x18, 0x40, 0xf9, /* ldr x6, [x0, #48] */
......@@ -56,6 +59,8 @@ bool hashx_compile_a64(const hashx_program* program, uint8_t* code) {
int creg = -1;
EMIT(pos, a64_prologue);
for (size_t i = 0; i < program->code_size; ++i) {
if (pos + COMP_MAX_INSTR_SIZE > code + COMP_CODE_SIZE)
return false;
const instruction* instr = &program->code[i];
switch (instr->opcode)
{
......@@ -145,6 +150,8 @@ bool hashx_compile_a64(const hashx_program* program, uint8_t* code) {
UNREACHABLE;
}
}
if (pos + sizeof a64_epilogue > code + COMP_CODE_SIZE)
return false;
EMIT(pos, a64_epilogue);
if (!hashx_vm_rx(code, COMP_CODE_SIZE))
return false;
......
......@@ -25,6 +25,9 @@
#ifdef HASHX_COMPILER_X86
/* Largest compiled instruction (BRANCH) */
#define COMP_MAX_INSTR_SIZE 10
static const uint8_t x86_prologue[] = {
#ifndef WINABI
0x48, 0x89, 0xF9, /* mov rcx, rdi */
......@@ -88,6 +91,8 @@ bool hashx_compile_x86(const hashx_program* program, uint8_t* code) {
uint8_t* target = NULL;
EMIT(pos, x86_prologue);
for (size_t i = 0; i < program->code_size; ++i) {
if (pos + COMP_MAX_INSTR_SIZE > code + COMP_CODE_SIZE)
return false;
const instruction* instr = &program->code[i];
switch (instr->opcode)
{
......@@ -145,6 +150,8 @@ bool hashx_compile_x86(const hashx_program* program, uint8_t* code) {
UNREACHABLE;
}
}
if (pos + sizeof x86_epilogue > code + COMP_CODE_SIZE)
return false;
EMIT(pos, x86_epilogue);
return hashx_vm_rx(code, COMP_CODE_SIZE);
}
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment