Commit graph

2307 commits

Author SHA1 Message Date
Fabian 1278672998 Split modrm stat into reg_with_offset and complex 2020-12-31 19:14:28 -06:00
Fabian 1de8fe1888 Fix unnecessary push to stack 2020-12-31 19:14:28 -06:00
Fabian f98f423d1b Comment 2020-12-31 19:14:28 -06:00
Fabian 78ef12be68 Custom implementations for several sse instructions
- mov dword/qword [mem], xmm
- mov xmm, dword/qword [mem]
- some arithmetic
2020-12-31 19:14:28 -06:00
Fabian 4619d4dd6d Add info to assertion 2020-12-31 19:14:28 -06:00
Fabian 63afa77167 Global pointers: Align general purpose registers, sse registers and flags 2020-12-31 19:14:28 -06:00
Fabian e99da40215 Make std/cld custom (FC/FD), remove unused unguarded_register and no_register properties from x86 table 2020-12-31 19:14:28 -06:00
Fabian 0263764a5c Remove unused unguarded_register property during analysis 2020-12-31 19:14:28 -06:00
Fabian 0e8c8a1dda More opstats 2020-12-31 19:14:28 -06:00
Fabian d98e1b2f70 Generate code (instead of call) for 32-bit arithmetic operations 2020-12-31 19:14:28 -06:00
Fabian 970739f60b Generate custom code for getzf/getcf/test_be 2020-12-31 19:14:28 -06:00
Fabian e0473dae18 profiler: Count generated simple/complex modrm address expressions 2020-12-31 19:14:28 -06:00
Fabian 5da6cde13f Custom codegen for cbw/cwde/cwd/cdq/pushf/sahf (98/99/9C/9E) 2020-12-31 19:14:28 -06:00
Fabian 701d59e0dd Custom codegen for absolute cli (FA) 2020-12-31 19:14:28 -06:00
Fabian ff64866e25 Custom codegen for absolute cmpxchg (0FB1) 2020-12-31 19:14:28 -06:00
Fabian b5a72061fb Custom codegen for absolute jmp/call (FF_2/FF_4) 2020-12-31 19:14:28 -06:00
Fabian fb7e4d376a Custom codegen for lfence (0FAE_5) 2020-12-31 19:14:28 -06:00
Fabian b240a8fde9 Custom codegen for push sreg (06/0E/16/1E/0FA0/0FA8) 2020-12-31 19:14:28 -06:00
Fabian a9dac09ceb Custom codegen for xchg (91-98) 2020-12-31 19:14:28 -06:00
Fabian 091b2324d9 Custom codegen for 8C 2020-12-31 19:14:28 -06:00
Fabian c04ca292b9 Run latest rustfmt 2020-12-31 19:14:28 -06:00
Fabian 93ffd50969 Custom codegen for more sse move aliases (660F29/660F6F/F30F7F) 2020-08-30 19:37:15 -05:00
Fabian 75e5c2a56f Codegen for 8-bit shifts (D0/D2) 2020-08-30 19:37:15 -05:00
Fabian 815e5d338e Codegen more fpu instructions and run their tests (D9_6, DA_5) 2020-08-30 19:37:15 -05:00
Fabian fdd1dc377d Custom codegen for xadd (0FC1) 2020-08-30 19:37:15 -05:00
Fabian 874818866a Codegen for mul32 + custom mul/imul (F7_[45]) 2020-08-30 19:37:15 -05:00
Fabian 2a3e4bfa86 Minor: Remove unused 2020-08-30 19:37:15 -05:00
Fabian 1f74ee534c Simplify cmpxchg using SAFE_READ_WRITE macro 2020-08-30 19:37:15 -05:00
Fabian c086c710ad Stat: Count duplicate entries 2020-08-30 19:37:15 -05:00
Fabian 0d938fb3da Minor: Flatten pattern match 2020-08-30 19:37:15 -05:00
Fabian f22325ecf4 Minor: Use hex constant 2020-08-30 19:37:15 -05:00
Fabian b774db3f81 Fix: Clear prefixes when leaving instruction early 2020-08-30 19:37:15 -05:00
Fabian ac9ef7d447 gen_pop/gen_push: Avoid some unnecessary locals after registers-in-locals 2020-08-30 19:37:15 -05:00
Fabian ce10336747 Minor: Remove unused functions 2020-08-30 19:37:15 -05:00
Fabian 447307c27f Minor: Remove unnecessary parens 2020-08-30 19:37:15 -05:00
Fabian 7c4ed66c20 Cleanup: Rename trigger_gp_non_raising to trigger_gp 2020-08-30 19:37:15 -05:00
Fabian 158bb75fec FPU: Implement zero divide fault 2020-08-30 19:37:15 -05:00
Fabian 0269e9cecf Fix fxtract 2020-08-30 19:37:15 -05:00
Fabian 724090b319 Reduce code size by removing register restoring around safe_{read,write}*_jit 2020-08-30 19:37:15 -05:00
Fabian 723f78c14f Reduce code size by creating a block to jump to that handles the page fault case 2020-08-30 19:37:15 -05:00
Fabian 799171ba03 Refactor do_page_translation into do_page_walk which does the page walk without calling in case of a fault 2020-08-30 19:37:15 -05:00
Fabian 7024207fa4 Codegen for inc/dec (group 40-4F) 2020-08-30 19:37:15 -05:00
Fabian a8308b988d Store registers in locals
This changes registers to be temporarily stored in wasm locals, across
each complete wasm module. Registers are moved from memory to locals
upon entering the wasm module and moved from locals to memory upon
leaving. Additionally, calls to functions that modify registers are
wrapped between moving registers to memory before and moving back to
locals after. This affects:

1. All non-custom instructions
2. safe_{read,write}_slow, since it may page fault (the slow path of all memory accesses)
3. task_switch_test* and trigger_ud
4. All block boundaries
5. The fallback functions of gen_safe_read_write (read-modify-write memory accesses)

The performance benefits are currently mostly eaten up by 1. and 4. (if
one calculates the total number of read/writes to registers in memory,
they are higher after this patch, as each instructions of typ 1. or 4.
requires moving all 8 register twice). This can be improved later by the
relatively mechanical work of making instructions custom (not
necessarily full code generation, only the part of the instruction where
registers are accessed). Multi-page wasm module generation will
significantly reduce the number of type 4. instructions.

Due to 2., the overall code size has significantly increased. This case
(the slow path of memory access) is often generated but rarely executed.
These moves can be removed in a later patch by a different scheme for
safe_{read,write}_slow, which has been left out of this patch for
simplicity of reviewing.

This also simplifies our code generation for storing registers, as

    instructions_body.const_i32(register_offset);
    // some computations ...
    instruction_body.store_i32();

turns into:

    // some computations ...
    write_register(register_index);

I.e., a prefix is not necessary anymore as locals are indexed directly.

Further patches will allow getting rid of some temporary locals, as
registers now can be used directly.
2020-08-30 19:37:15 -05:00
Fabian 56dc1af7cc Split SAFE_WRITE stat into WRITE and READ_WRITE 2020-08-30 19:37:15 -05:00
Fabian 8838e263c3 Profiler: Track number of page faults and wasm bytes generated 2020-08-30 19:37:15 -05:00
Fabian ed5ecda0ae Custom implementation for pop [mem] (preparation for registers-in-locals) 2020-08-30 19:37:15 -05:00
Fabian 730919e317 Use gen_trigger_ud for invalid LEA encodings 2020-08-30 19:37:15 -05:00
Fabian f5540d9edf Use pop16_reg_jit for pop esp 2020-08-30 19:37:15 -05:00
Fabian 32f988a08d Pass JitContext to gen_get_reg* (preparation for registers-in-locals) 2020-08-30 19:37:15 -05:00
Fabian 4d35564761 Simplify get_seg: Generate code inline, avoid importing it in every module 2020-08-30 19:37:15 -05:00
Fabian 0c42ea0d1f Custom code generation for leave (C9) 2020-08-30 19:37:15 -05:00
Fabian 837e6ff362 Custom code generation for ret imm (C2) 2020-08-30 19:37:15 -05:00
Fabian c0f1d2a487 Custom code generation for arith al/ax/eax, imm (group [0123][45CD], A8/A9) 2020-08-30 19:37:15 -05:00
Fabian fc954cecea Update libwabt (fix failing decoding of large generated modules) 2020-08-30 19:37:15 -05:00
Fabian 04281702ed Track jit exits to same/different page 2020-08-30 19:37:15 -05:00
Fabian f14e9528d6 Custom code generation for cmovcc (0F40-0F4F) 2020-08-30 19:37:15 -05:00
Fabian aef22e38ad Add missing tracking of jit exit points 2020-08-30 19:37:15 -05:00
Fabian 69b834c8de Move condition function generation into codegen module and use it for cmovcc/setcc 2020-08-30 19:37:15 -05:00
Fabian c9163c2df5 Custom code generation for mov reg, imm (B0-BF) 2020-08-30 19:37:15 -05:00
Ernest Wong dbfa0edc3c Filestorage: Split read() logic into different cases for readability 2020-08-30 19:37:15 -05:00
Ernest Wong 607078f59d Filestorage: Optimise .read to single IndexedDB request for 4k block
Reusing the naming scheme of
sha256sum
sha256sum-0
sha256sum-1
sha256sum-2
etc
but the extra metadata such as total file size and block count are no
longer needed in the first block.
2020-08-30 19:37:15 -05:00
Fabian 2c23ffc2cf Use get_eflags_no_arith over flags[0] (minor performance) 2020-08-30 19:37:15 -05:00
Fabian 2837ccd06b Support for gen_safe_read128 and code generation for MOVDQU (F30F6F) 2020-08-30 19:37:15 -05:00
Fabian 70cc242eb1 Simplify call_interrupt_vector from js 2020-08-30 19:37:15 -05:00
Fabian dca6be2d94 Also generate nop for prefetch instruction 2020-08-30 19:37:15 -05:00
Fabian 440b67eda5 Support for gen_safe_write128 and code generation for MOVAPS/MOVDQA (0F29/660F7F) 2020-08-30 19:37:15 -05:00
Fabian e2ab5eabdd Code generation for missing memory operations (8-bit shifts, shrd, shld, xadd) 2020-08-30 19:37:15 -05:00
Fabian ec846b34d9 Codegen for fpu instructions (misc instructions) (D9_[14], DB_5, DD_5, DF_4) 2020-08-30 19:37:15 -05:00
Fabian 1eab44746b Codegen for fpu instructions (fldcw/fstcw) (D9_5, D9_7) 2020-08-30 19:37:15 -05:00
Fabian fdce557820 Codegen for fpu instructions (memory stores: fst/fstp/fist/fistp) (D9_[23], DB_[23], DD_[23], DF_[237]) 2020-08-30 19:37:15 -05:00
Fabian b11b2725bb Use i64 locals for gen_safe_write64 2020-08-30 19:37:15 -05:00
Fabian 7c99bdae74 Codegen for fpu instructions (memory loads: fld, fild) (D9_0, DB_0, DD_0, DF_5) 2020-08-30 19:37:15 -05:00
Fabian c452c357dd Codegen for fpu instructions (DE group) 2020-08-30 19:37:15 -05:00
Fabian 21caefbffd Codegen for fpu instructions (DC group) 2020-08-30 19:37:15 -05:00
Fabian f797ce10c9 64-bit operations for gen_safe_{read,write,read_write} 2020-08-30 19:37:15 -05:00
Fabian 4c3f8dcde8 Support for i64 locals 2020-08-30 19:37:15 -05:00
Fabian f6718c3ead Fix a few missing local frees 2020-08-30 19:37:15 -05:00
Fabian ec059a9f27 Codegen for fpu instructions (D8 group) 2020-08-30 19:37:15 -05:00
Fabian 66c96bd1b1 Clean up old C code 2020-08-30 19:37:15 -05:00
Fabian 05296b0586 Enable fpu instructions in nasm tests 2020-08-30 19:37:15 -05:00
Fabian bb0e58ace9 More precise emulation of fpu instructions 2020-08-30 19:37:15 -05:00
Fabian a179d2ec7e Reduce default logging in ne2k 2020-08-30 19:37:15 -05:00
Fabian 18cdd2107f Reset fpu state in cpu.reset 2020-08-30 19:37:15 -05:00
Fabian c46d12f921 Allow using libv86-debug.js with v86oxide.wasm 2020-08-30 19:37:15 -05:00
Fabian c20a54a9e4 Don't print full array in assertion (slow) 2020-08-30 19:37:15 -05:00
Ernest Wong e5e1f68244 Fix type error for logging filestorage error 2020-08-30 19:37:15 -05:00
Ernest Wong 4651e28177 Fix type annotations for async functions 2020-08-30 19:37:15 -05:00
Fabian 4827732a4c Make closure compiler happy 2020-08-30 19:37:15 -05:00
Fabian 7e04f313ba Remove unused as_text option 2020-08-30 19:37:15 -05:00
Ernest Wong 1155faae25 Filestorage: Simplify IndexedDBFileStorage#set - remove async 2020-08-30 19:37:15 -05:00
Ernest Wong 602cfe0e3c Filestorage: Fix IndexedDB error logging 2020-08-30 19:37:15 -05:00
Ernest Wong 75bee02ac7 Filestorage: Don't wait before issuing next store.put request 2020-08-30 19:37:15 -05:00
Ernest Wong aadae9242c Filestorage: Clone array views to avoid serializing full array buffer
IndexedDB uses the StructuredSerializeForStorage algorithm to store
records into the database.

It appears that the html5 spec defines the StructuredSerializeForStorage
algorithm in a way that, when we serialize a TypedArray, the associated
ArrayBuffer is also serialized. Meaning even if the TypedArray is a view
of a single byte in the ArrayBuffer, the potentially-megabytes of data
in the ArrayBuffer are also copied over.

This makes sense. After deserialization, you'd expect the TypedArray to
function the same way as before meaning it should have the same
`.byteOffset` and `.buffer` properties.

However, it is easy to overlook this and think that a TypedArray viewing
2 bytes will only have the 2 bytes stored in the database.

This commit fixes a source of crashes. When calling
IndexedDBFileStorage#set() with a 3Mb file, the file is to be stored as
approx 800 lots of 4k blocks. However, in reality, 800 lots of 3 Mb array
buffers are being stored into the database. As the transaction is not
committed until the last request has been placed, I suspect that Chrome was
trying to store those 2.4 Gb worth of data in memory and did not handle
this case properly, leading to out-of-memory.

This commit also fixes a source of poor performance. When calling
IndexedDBFileStorage#read() to read 4k of a 48 Mb file, the browser seems
to be deserializing the entire 48 Mb into memory and garbage collecting
it even though only 4k is needed.
2020-08-30 19:37:15 -05:00
Fabian 47e91de601 Remove has_rand_int, always require get_rand_int to be available 2020-08-30 19:37:15 -05:00
Fabian 0d70c87796 Implement rdrand on Node (for __x86_rdrand) 2020-08-30 19:37:15 -05:00
Fabian bea53fdfb2 Fix profiler build 2020-08-30 19:37:15 -05:00
Fabian 23c5ebdf61 Reduce value of WASM_TABLE_SIZE and incraese JIT_THRESHOLD
Now that WASM_TABLE_SIZE may be capped, we set it slightly below the
limit under which chromium crashes: https://bugs.chromium.org/p/v8/issues/detail?id=8427

JIT_THRESHOLD is also reduced due to two reasons:

- With the lower WASM_TABLE_SIZE, we want to avoid compiling too many
  modules
- It has occasionally been observed that under node, the engine's wasm
  compiler can't catch up with the number of modules we produce, thus
  resulting in 100s of pending compiled modules. This most likely
  happens only under node as we don't render the screen and
  the main loop (based on setImmediate) is faster.
  The new value doesn't seem to exhibit this problem, but we may want to
  increase the threshold further if the problem appears again
2020-08-30 19:37:15 -05:00
Fabian 71093270cd Add stat to track running out of wasm indices 2020-08-30 19:37:15 -05:00
Fabian 0e16983dd3 Handle case when wasm table is full (fixes #35)
Also fix jit_empty_cache when callbacks are pending (fixes #53)

This is also a preparation for setting WASM_TABLE_SIZE to a low value to
work around memory limitations in browsers.
2020-08-30 19:37:15 -05:00
Fabian 3f3446b5dd Update linux-boot benchmark script 2020-08-30 19:37:15 -05:00
Fabian b96e36ddd4 Allow dev tools on electron 2020-08-30 19:37:15 -05:00
Ernest Wong ad3bf2afe0 Filestorage: Export classes properly to all platforms 2020-08-30 19:37:15 -05:00
Ernest Wong c928964562 Minor: Tidy quotes and spacing 2020-08-30 19:37:15 -05:00
Ernest Wong c273741405 Add tests for file storage chunking 2020-08-30 19:37:15 -05:00
Ernest Wong a841194d28 Filestorage: Reuse IDBObjectStore throughout transaction
- More like passing the same reference to it when calling db_get/set.
- In reality, it was still the same store object being accessed, but
this commit improves the coherence of the db_get/set helper methods.
2020-08-30 19:37:15 -05:00
Ernest Wong bf35f0ab0b Filestorage: Avoid additional allocation for small files 2020-08-30 19:37:15 -05:00
Ernest Wong 840415a052 Filestorage: (minor) Improve naming can_uncache() -> uncache() 2020-08-30 19:37:15 -05:00
Ernest Wong d6bfa143ed Filestorage: Don't rely on errors to select type of storage 2020-08-30 19:37:15 -05:00
Ernest Wong 738edf7b6c Filestorage: Initialise IndexedDB before constructor
Simplifies several checks
2020-08-30 19:37:15 -05:00
Ernest Wong 9db722f71f Filestorage: Improve usefulness of IndexedDB error messages 2020-08-30 19:37:15 -05:00
Ernest Wong c625bba498 Filestorage: Implement cache cleanup - avoid memory growth 2020-08-30 19:37:15 -05:00
Ernest Wong 3a74e66b72 Filestorage: Expose load_from_server 2020-08-30 19:37:15 -05:00
Ernest Wong 62c880b415 Filestorage: Integrate chunking and revert unnecessary chunking
- Integrate new FileStorage interface with lib/filesystem.js
- Simplify the FileStorage interface with the intention that it only
serves read-only files.
2020-08-30 19:37:15 -05:00
Ernest Wong afd27597d7 Filestorage: Draft chunking behind new FileStorage interface 2020-08-30 19:37:15 -05:00
Ernest Wong efa45a3d11 Filestorage: Make filestorage .get .set atomic
...by sticking to the same transaction throughout an operation.
2020-08-30 19:37:15 -05:00
Ernest Wong 7cfe865556 Filestorage: Draft chunking behind existing FileStorage interface 2020-08-30 19:37:15 -05:00
Ernest Wong 8b64844d27 Filestorage: Give project-related name for IndexedDB Storage 2020-08-30 19:37:15 -05:00
Ernest Wong 83b283ebbe Filestorage: Replace the two server classes with a wrapper class
Simplifies both the filestorage.js code as well as the starter.js code
that uses these FileStorage classes.

Now, the ServerFileStorageWrapper decorates the other FileStorage
classes by loading from the server when the file is not available.

Moreover, the previous starter.js was incorrectly passing the `baseurl`
parameter (it was passing it when baseurl was not defined nor needed).
2020-08-30 19:37:15 -05:00
Ernest Wong 93d9f6923e Filestorage: Prevent overlapped reinitialization of IndexedDB
Catches cases when IndexDBFileStorage#init is accidentally called in
multiple places.
2020-08-30 19:37:15 -05:00
Ernest Wong a85dd50169 Filestorage: Improve assert coverage and robustness
Checks that sha256sum is also not undefrined nor null.
Avoids ReferenceError when window is not defined e.g. on NodeJS.
2020-08-30 19:37:15 -05:00
Ernest Wong c2dcb440dd Filestorage: Refactor fallback and load-from-server
Fallback logic is moved to the caller's responsibility.

Empty FileStorages and FileStorages that load from the server are
separated into different classes. This is to avoid faults where the
caller of the constructor forgets to pass in a `baseurl` parameter and
leads to some confusing bug.
2020-08-30 19:37:15 -05:00
Ernest Wong 6a06a7108a Tidy: file_storage snake case and interface naming convention 2020-08-30 19:37:15 -05:00
Fabian 88f482fae0 Commit temporary workaround 2020-08-30 19:37:15 -05:00
Fabian 608559fa94 Call hlt_loop immediately on an hlt instruction 2020-08-30 19:37:15 -05:00
Fabian 01697a7ebb Delete some dead code 2020-08-30 19:37:15 -05:00
Fabian 2233b069b3 Mark Bitmap as constructor 2020-08-30 19:37:15 -05:00
Fabian 7720f9a8e6 Print opcode on unimplemented sse instructions 2020-08-30 19:37:15 -05:00
Fabian 400673646f Remove unused constants 2020-08-30 19:37:15 -05:00
Fabian 58b8c49fb0 Pack memory in state image, reduces memory use during state loading 2020-08-30 19:37:15 -05:00
Fabian 32606a26ac rtc: Implement alarm interrupt 2020-08-30 19:37:15 -05:00
Amaan Cheval 3eb15d328d cpu: Update iret for minor fixes from manual
Citations for these changes:

  https://imgur.com/a/QgNekKL
2020-08-30 19:37:15 -05:00
Amaan Cheval 1d5e0052b4 cpu: Port iret, iret16, iret32 to Rust 2020-08-30 19:37:15 -05:00
Amaan Cheval 8aa06b54e0 cpu: Port switch_cs_real_mode to Rust 2020-08-30 19:37:15 -05:00
Fabian e5fbbd0f2d Implement json loading for nodejs 2020-08-30 19:37:15 -05:00
Fabian d2f86799e9 Simplify load_from_json: Accept json object directly, don't run asynchronously 2020-08-30 19:37:14 -05:00
Fabian f7c22266c9 initrd/bzimage detection: Ignore case 2020-08-30 19:37:14 -05:00
Fabian 028e131ddb Rename OnJSONLoaded & small refactor 2020-08-30 19:37:14 -05:00
Fabian aea2409b1d Ignore filesystem base when state image is provided 2020-08-30 19:37:14 -05:00
Fabian af0f153640 Refactor using new filesystem function 2020-08-30 19:37:14 -05:00
Fabian 3f79814e05 Detect initrd/bzimage in 9p filesystem and load before boot 2020-08-30 19:37:14 -05:00
Fabian e94c30ef6f Don't wrap text in SyncBuffer 2020-08-30 19:37:14 -05:00
Fabian 9ffbba7bcd Use bzimage loader for debian-full, remove ugly build script for the 9p boot hard drive image 2020-08-30 19:37:14 -05:00
Fabian e1c6116a0f Implement Linux kernel boot protocol, accept bzimage/initrd as boot configuration 2020-08-30 19:37:14 -05:00
Fabian 04d282c298 Firmware port: Pretend to be qemu, implement all indexes used by seabios 2020-08-30 19:37:14 -05:00
Fabian 753fcb25c7 Simplify multiboot buffer during init 2020-08-30 19:37:14 -05:00
Fabian 8d6baff91c Fix rustfmt 2020-08-30 19:29:54 -05:00
Fabian cb0ca91f58 Resolve some internal imports directly 2020-08-30 19:29:54 -05:00
Fabian 57b51d440d nodejs: Prefer perf_hooks module over custom shim for performance.now 2020-08-30 19:29:54 -05:00
Fabian 53bd41614f Fix minor problem with Rust port of call_interrupt_vector 2020-08-30 19:29:54 -05:00
Fabian 7796d9dcb4 Clean up wasm loading, remove unused code for emscripten 2020-08-30 19:29:54 -05:00