Improve speed of state restoring by loading ram directly
This commit is contained in:
parent
3e80be32a9
commit
9d1dc4de96
|
@ -595,7 +595,7 @@ CPU.prototype.debug_init = function()
|
|||
start = 0;
|
||||
}
|
||||
|
||||
return cpu.memory.buffer.slice(start, start + count);
|
||||
return cpu.memory.mem8.slice(start, start + count).buffer;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ DMA.prototype.do_write = function(buffer, start, len, channel, fn)
|
|||
this.channel_addr[channel] += read_count;
|
||||
|
||||
buffer.set(start,
|
||||
new Uint8Array(this.memory.buffer, addr, read_count + 1),
|
||||
this.memory.mem8.subarray(addr, read_count + 1),
|
||||
function() {
|
||||
fn(false);
|
||||
}
|
||||
|
|
|
@ -24,29 +24,28 @@ function Memory(memory_size)
|
|||
|
||||
dbg_assert((memory_size & MMAP_BLOCK_SIZE - 1) === 0);
|
||||
|
||||
this.buffer = new ArrayBuffer(memory_size);
|
||||
var buffer = new ArrayBuffer(memory_size);
|
||||
|
||||
this.mem8 = new Uint8Array(this.buffer);
|
||||
this.mem16 = new Uint16Array(this.buffer);
|
||||
this.mem32s = new Int32Array(this.buffer);
|
||||
this.mem8 = new Uint8Array(buffer);
|
||||
this.mem16 = new Uint16Array(buffer);
|
||||
this.mem32s = new Int32Array(buffer);
|
||||
};
|
||||
|
||||
Memory.prototype.get_state = function()
|
||||
{
|
||||
return [
|
||||
this.size,
|
||||
this.buffer,
|
||||
this.mem8,
|
||||
];
|
||||
}
|
||||
|
||||
Memory.prototype.set_state = function(state)
|
||||
{
|
||||
this.size = state[0];
|
||||
this.buffer = state[1];
|
||||
|
||||
this.mem8 = new Uint8Array(this.buffer);
|
||||
this.mem16 = new Uint16Array(this.buffer);
|
||||
this.mem32s = new Int32Array(this.buffer);
|
||||
this.mem8 = state[1];
|
||||
this.mem16 = new Uint16Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 1);
|
||||
this.mem32s = new Int32Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 2);
|
||||
};
|
||||
|
||||
// called by all memory reads and writes
|
||||
|
|
61
src/state.js
61
src/state.js
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
/** @const */
|
||||
var STATE_VERSION = 1;
|
||||
var STATE_VERSION = 2;
|
||||
|
||||
/** @const */
|
||||
var STATE_MAGIC = 0x86768676|0;
|
||||
|
@ -30,7 +30,7 @@ function StateLoadError(msg)
|
|||
StateLoadError.prototype = new Error;
|
||||
|
||||
|
||||
function save_object(obj, arraybuffers)
|
||||
function save_object(obj, saved_buffers)
|
||||
{
|
||||
if(typeof obj !== "object" || obj === null || obj instanceof Array)
|
||||
{
|
||||
|
@ -42,17 +42,11 @@ function save_object(obj, arraybuffers)
|
|||
if(obj.BYTES_PER_ELEMENT)
|
||||
{
|
||||
// Uint8Array, etc.
|
||||
var buffer = new Uint8Array(obj.buffer, obj.byteOffset, obj.length * obj.BYTES_PER_ELEMENT);
|
||||
|
||||
return {
|
||||
"__state_type__": obj.constructor.name,
|
||||
"buffer_id": arraybuffers.push(obj.buffer) - 1,
|
||||
};
|
||||
}
|
||||
|
||||
if(obj instanceof ArrayBuffer)
|
||||
{
|
||||
return {
|
||||
"__state_type__": "ArrayBuffer",
|
||||
"buffer_id": arraybuffers.push(obj) - 1,
|
||||
"buffer_id": saved_buffers.push(buffer) - 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -70,7 +64,7 @@ function save_object(obj, arraybuffers)
|
|||
|
||||
dbg_assert(typeof value !== "function");
|
||||
|
||||
result[i] = save_object(value, arraybuffers);
|
||||
result[i] = save_object(value, saved_buffers);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -118,22 +112,6 @@ function restore_object(base, obj, buffers)
|
|||
|
||||
return base;
|
||||
}
|
||||
else if(type === "ArrayBuffer")
|
||||
{
|
||||
var info = buffers.infos[obj["buffer_id"]];
|
||||
|
||||
if(base && base.byteLength === info.length)
|
||||
{
|
||||
new Uint8Array(base).set(new Uint8Array(buffers.full, info.offset, info.length));
|
||||
}
|
||||
else
|
||||
{
|
||||
//base = buffers.full.slice(info.offset, info.offset + info.length);
|
||||
dbg_assert(false, base ? "buffer of different size" : "no buffer");
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
else
|
||||
{
|
||||
var table = {
|
||||
|
@ -152,11 +130,16 @@ function restore_object(base, obj, buffers)
|
|||
|
||||
var info = buffers.infos[obj["buffer_id"]];
|
||||
|
||||
// restore large buffers by just returning a view on the state blob
|
||||
if(info.length >= 1024 * 1024 && constructor === Uint8Array)
|
||||
{
|
||||
return new Uint8Array(buffers.full, info.offset, info.length);
|
||||
}
|
||||
// avoid a new allocation if possible
|
||||
if(base &&
|
||||
base.constructor === constructor &&
|
||||
base.byteOffset === 0 &&
|
||||
base.byteLength === info.length)
|
||||
else if(base &&
|
||||
base.constructor === constructor &&
|
||||
base.byteOffset === 0 &&
|
||||
base.byteLength === info.length)
|
||||
{
|
||||
new Uint8Array(base.buffer).set(
|
||||
new Uint8Array(buffers.full, info.offset, info.length),
|
||||
|
@ -174,15 +157,15 @@ function restore_object(base, obj, buffers)
|
|||
|
||||
CPU.prototype.save_state = function()
|
||||
{
|
||||
var arraybuffers = [];
|
||||
var state = save_object(this, arraybuffers);
|
||||
var saved_buffers = [];
|
||||
var state = save_object(this, saved_buffers);
|
||||
|
||||
var buffer_infos = [];
|
||||
var total_buffer_size = 0;
|
||||
|
||||
for(var i = 0; i < arraybuffers.length; i++)
|
||||
for(var i = 0; i < saved_buffers.length; i++)
|
||||
{
|
||||
var len = arraybuffers[i].byteLength;
|
||||
var len = saved_buffers[i].byteLength;
|
||||
|
||||
buffer_infos[i] = {
|
||||
offset: total_buffer_size,
|
||||
|
@ -201,6 +184,7 @@ CPU.prototype.save_state = function()
|
|||
});
|
||||
|
||||
var buffer_block_start = STATE_INFO_BLOCK_START + 2 * info_object.length;
|
||||
buffer_block_start = buffer_block_start + 3 & ~3;
|
||||
var total_size = buffer_block_start + total_buffer_size;
|
||||
|
||||
//console.log("State: json_size=" + Math.ceil(buffer_block_start / 1024 / 1024) + "MB " +
|
||||
|
@ -233,9 +217,9 @@ CPU.prototype.save_state = function()
|
|||
info_block[i] = info_object.charCodeAt(i);
|
||||
}
|
||||
|
||||
for(var i = 0; i < arraybuffers.length; i++)
|
||||
for(var i = 0; i < saved_buffers.length; i++)
|
||||
{
|
||||
var buffer = arraybuffers[i];
|
||||
var buffer = saved_buffers[i];
|
||||
buffer_block.set(new Uint8Array(buffer), buffer_infos[i].offset);
|
||||
}
|
||||
|
||||
|
@ -304,6 +288,7 @@ CPU.prototype.restore_state = function(state)
|
|||
var state_object = info_block_obj["state"];
|
||||
var buffer_infos = info_block_obj["buffer_infos"];
|
||||
var buffer_block_start = STATE_INFO_BLOCK_START + info_block_len;
|
||||
buffer_block_start = buffer_block_start + 3 & ~3;
|
||||
|
||||
for(var i = 0; i < buffer_infos.length; i++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue