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

Put jit_frame directly in cpu_state, saving a copy #780

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "misc.h"
#include "emu/float80.h"
#include "emu/memory.h"
#include "jit/frame.h"

struct cpu_state;
struct tlb;
Expand All @@ -26,8 +27,13 @@ static_assert(sizeof(union xmm_reg) == 16, "xmm_reg size");
static_assert(sizeof(union mm_reg) == 8, "mm_reg size");

struct cpu_state {
// DO NOT MOVE THIS!
// ...or do, i'm a comment, not a cop
struct jit_frame frame;

struct mem *mem;
struct jit *jit;

long cycle;

// general registers
Expand Down
6 changes: 4 additions & 2 deletions jit/frame.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#include "emu/cpu.h"
#ifndef JIT_FRAME_H
#define JIT_FRAME_H

// keep in sync with asm
#define JIT_RETURN_CACHE_SIZE 4096
#define JIT_RETURN_CACHE_HASH(x) ((x) & 0xFFF0) >> 4)

struct jit_frame {
struct cpu_state cpu;
void *bp;
addr_t value_addr;
uint64_t value[2]; // buffer for crosspage crap
struct jit_block *last_block;
long ret_cache[JIT_RETURN_CACHE_SIZE]; // a map of ip to pointer-to-call-gadget-arguments
};

#endif
18 changes: 8 additions & 10 deletions jit/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static void jit_free_jetsam(struct jit *jit) {
}
}

int jit_enter(struct jit_block *block, struct jit_frame *frame, struct tlb *tlb);
int jit_enter(struct jit_block *block, struct cpu_state *cpu, struct tlb *tlb);

static inline size_t jit_cache_hash(addr_t ip) {
return (ip ^ (ip >> 12)) % JIT_CACHE_SIZE;
Expand All @@ -167,11 +167,11 @@ static inline size_t jit_cache_hash(addr_t ip) {
static int cpu_step_to_interrupt(struct cpu_state *cpu, struct tlb *tlb) {
struct jit *jit = cpu->mem->jit;
struct jit_block *cache[JIT_CACHE_SIZE] = {};
struct jit_frame frame = {.cpu = *cpu, .ret_cache = {}};
cpu->frame = (struct jit_frame){};

int interrupt = INT_NONE;
while (interrupt == INT_NONE) {
addr_t ip = frame.cpu.eip;
addr_t ip = cpu->eip;
size_t cache_index = jit_cache_hash(ip);
struct jit_block *block = cache[cache_index];
if (block == NULL || block->addr != ip) {
Expand All @@ -186,7 +186,7 @@ static int cpu_step_to_interrupt(struct cpu_state *cpu, struct tlb *tlb) {
cache[cache_index] = block;
unlock(&jit->lock);
}
struct jit_block *last_block = frame.last_block;
struct jit_block *last_block = cpu->frame.last_block;
if (last_block != NULL &&
(last_block->jump_ip[0] != NULL ||
last_block->jump_ip[1] != NULL)) {
Expand All @@ -205,15 +205,14 @@ static int cpu_step_to_interrupt(struct cpu_state *cpu, struct tlb *tlb) {

unlock(&jit->lock);
}
frame.last_block = block;
cpu->frame.last_block = block;

// block may be jetsam, but that's ok, because it can't be freed until
// every thread on this jit is not executing anything

TRACE("%d %08x --- cycle %ld\n", current->pid, ip, cpu->cycle);

interrupt = jit_enter(block, &frame, tlb);
*cpu = frame.cpu;
interrupt = jit_enter(block, cpu, tlb);
if (interrupt == INT_NONE && ++cpu->cycle % (1 << 10) == 0)
interrupt = INT_TIMER;
}
Expand All @@ -229,9 +228,8 @@ static int cpu_single_step(struct cpu_state *cpu, struct tlb *tlb) {
gen_end(&state);

struct jit_block *block = state.block;
struct jit_frame frame = {.cpu = *cpu};
int interrupt = jit_enter(block, &frame, tlb);
*cpu = frame.cpu;
cpu->frame = (struct jit_frame){};
int interrupt = jit_enter(block, cpu, tlb);
jit_block_free(NULL, block);
if (interrupt == INT_NONE)
interrupt = INT_DEBUG;
Expand Down