Removed SAMPLER and RegFrame code (DEBUG-only code that's easy to resurrect if needed later)
This commit is contained in:
parent
d1d733e38b
commit
b944cff3b5
6 changed files with 2 additions and 139 deletions
|
|
@ -18,7 +18,6 @@
|
||||||
"FATARRAYS": true,
|
"FATARRAYS": true,
|
||||||
"TYPEDARRAYS": true,
|
"TYPEDARRAYS": true,
|
||||||
"BACKTRACK": true,
|
"BACKTRACK": true,
|
||||||
"SAMPLER": true,
|
|
||||||
"BUGS_8086": true,
|
"BUGS_8086": true,
|
||||||
"I386": true,
|
"I386": true,
|
||||||
"COMPAQ386": true,
|
"COMPAQ386": true,
|
||||||
|
|
|
||||||
|
|
@ -3174,7 +3174,7 @@ ChipSet.prototype.outPICLo = function(iPIC, bOut, addrFrom)
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {
|
if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {
|
||||||
this.printMessage("outPIC" + iPIC + '(' + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service", true, true);
|
this.printMessage("outPIC" + iPIC + '(' + str.toHexByte(pic.port) + "): unexpected EOI command, IRQ " + nIRQ + " not in service", true, true);
|
||||||
if (!SAMPLER && MAXDEBUG) this.dbg.stopCPU();
|
if (MAXDEBUG) this.dbg.stopCPU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -3416,7 +3416,7 @@ if (DEBUGGER) {
|
||||||
|
|
||||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||||
|
|
||||||
if (!SAMPLER) this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)"
|
this.println(sMessage); // + " (" + this.cpu.getCycles() + " cycles)"
|
||||||
|
|
||||||
this.sMessagePrev = sMessage;
|
this.sMessagePrev = sMessage;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,17 +103,6 @@ var BACKTRACK = false;
|
||||||
*/
|
*/
|
||||||
var SYMBOLS = DEBUGGER;
|
var SYMBOLS = DEBUGGER;
|
||||||
|
|
||||||
/**
|
|
||||||
* @define {boolean}
|
|
||||||
*
|
|
||||||
* SAMPLER enables instruction sampling (a work-in-progress). This was used briefly as an internal debugging aid,
|
|
||||||
* to periodically record LIP values in a fixed-length sampling buffer, halting execution once the sampling buffer
|
|
||||||
* was full, and then compare those sampled LIP values to corresponding LIP values on subsequent runs, to look
|
|
||||||
* for deviations. In theory, every run is supposed to be absolutely identical, even if you interrupt execution
|
|
||||||
* with the Debugger or enable/disable different sets of messages, but in practice, that's hard to guarantee.
|
|
||||||
*/
|
|
||||||
var SAMPLER = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @define {boolean}
|
* @define {boolean}
|
||||||
*
|
*
|
||||||
|
|
@ -162,7 +151,6 @@ if (NODE) {
|
||||||
global.TYPEDARRAYS = TYPEDARRAYS;
|
global.TYPEDARRAYS = TYPEDARRAYS;
|
||||||
global.BACKTRACK = BACKTRACK;
|
global.BACKTRACK = BACKTRACK;
|
||||||
global.SYMBOLS = SYMBOLS;
|
global.SYMBOLS = SYMBOLS;
|
||||||
global.SAMPLER = SAMPLER;
|
|
||||||
global.BUGS_8086 = BUGS_8086;
|
global.BUGS_8086 = BUGS_8086;
|
||||||
global.I386 = I386;
|
global.I386 = I386;
|
||||||
global.COMPAQ386 = COMPAQ386;
|
global.COMPAQ386 = COMPAQ386;
|
||||||
|
|
|
||||||
|
|
@ -181,36 +181,11 @@ function X86CPU(parmsCPU)
|
||||||
this.nBusMask = this.nMemMask = 0;
|
this.nBusMask = this.nMemMask = 0;
|
||||||
this.nBlockShift = this.nBlockSize = this.nBlockLimit = this.nBlockTotal = this.nBlockMask = 0;
|
this.nBlockShift = this.nBlockSize = this.nBlockLimit = this.nBlockTotal = this.nBlockMask = 0;
|
||||||
|
|
||||||
if (SAMPLER) {
|
|
||||||
/*
|
|
||||||
* For now, we're just going to sample LIP values (well, LIP + cycle count)
|
|
||||||
*/
|
|
||||||
this.nSamples = 50000;
|
|
||||||
this.nSampleFreq = 1000;
|
|
||||||
this.nSampleSkip = 0;
|
|
||||||
this.aSamples = new Array(this.nSamples);
|
|
||||||
for (var i = 0; i < this.nSamples; i++) this.aSamples[i] = -1;
|
|
||||||
this.iSampleNext = 0;
|
|
||||||
this.iSampleFreq = 0;
|
|
||||||
this.iSampleSkip = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This initial resetRegs() call is important to create all the registers (eg, the X86Seg registers),
|
* This initial resetRegs() call is important to create all the registers (eg, the X86Seg registers),
|
||||||
* so that if/when we call restore(), it will have something to fill in.
|
* so that if/when we call restore(), it will have something to fill in.
|
||||||
*/
|
*/
|
||||||
this.resetRegs();
|
this.resetRegs();
|
||||||
|
|
||||||
/*
|
|
||||||
* Register frames have proven to be a useful tool for catching register corruption bugs (eg, LOOP instructions
|
|
||||||
* improperly zeroing the high bits of ECX), but they shouldn't be enabled by default, because the associated
|
|
||||||
* functions (pushRegFrame() and popRegFrame()) can produce false positives, and weeding those out is a nuisance.
|
|
||||||
*
|
|
||||||
* In a perfect world, every time we IRET'ed to the CS:EIP where a hardware interrupt was injected, we could
|
|
||||||
* assume that the current register values will ALWAYS match the original register values (ie, at the time
|
|
||||||
* of injection). But we can't assume that; there's too much clever code out there.
|
|
||||||
*/
|
|
||||||
// if (DEBUG) this.aRegFrames = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.subclass(X86CPU, CPU);
|
Component.subclass(X86CPU, CPU);
|
||||||
|
|
@ -1214,7 +1189,6 @@ X86CPU.prototype.reset = function()
|
||||||
this.resetRegs();
|
this.resetRegs();
|
||||||
this.resetCycles();
|
this.resetCycles();
|
||||||
this.clearError(); // clear any fatal error/exception that setError() may have flagged
|
this.clearError(); // clear any fatal error/exception that setError() may have flagged
|
||||||
if (SAMPLER) this.iSampleNext = this.iSampleFreq = this.iSampleSkip = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -4161,71 +4135,6 @@ X86CPU.prototype.pushWord = function(w)
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* newRegFrame()
|
|
||||||
*
|
|
||||||
* @this {X86CPU}
|
|
||||||
* @return {Array}
|
|
||||||
*
|
|
||||||
X86CPU.prototype.newRegFrame = function()
|
|
||||||
{
|
|
||||||
return [this.getIP(), this.segCS.sel, this.segDS.sel, this.segES.sel, this.segSS.sel,
|
|
||||||
this.regEAX, this.regEBX, this.regECX, this.regEDX, this.regESI, this.regEDI, this.regEBP, this.getSP(),
|
|
||||||
this.dbg? this.dbg.cOpcodes : 0];
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pushRegFrame()
|
|
||||||
*
|
|
||||||
* Call this immediately before injecting a hardware interrupt. Subsequent IRET instructions will check the most
|
|
||||||
* recent frame to verify that all registers have been restored to their original values.
|
|
||||||
*
|
|
||||||
* @this {X86CPU}
|
|
||||||
*
|
|
||||||
X86CPU.prototype.pushRegFrame = function()
|
|
||||||
{
|
|
||||||
this.aRegFrames.push(this.newRegFrame());
|
|
||||||
if (this.aRegFrames.length > 10) {
|
|
||||||
this.println("frame overflow");
|
|
||||||
this.stopCPU();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* popRegFrame()
|
|
||||||
*
|
|
||||||
* Call this immediately after an IRET. If EIP and CS match the most recent frame, check the rest of the registers.
|
|
||||||
*
|
|
||||||
* @this {X86CPU}
|
|
||||||
*
|
|
||||||
X86CPU.prototype.popRegFrame = function()
|
|
||||||
{
|
|
||||||
if (this.aRegFrames.length) {
|
|
||||||
var a = this.aRegFrames[this.aRegFrames.length-1];
|
|
||||||
if (a[1] !== this.segCS.sel || a[0] !== this.getIP()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var fMatch = true;
|
|
||||||
var b = this.newRegFrame(), i;
|
|
||||||
for (i = 2; i < a.length-2; i++) {
|
|
||||||
if (a[i] !== b[i]) {
|
|
||||||
this.println("frame mismatch at " + i + ": original=" + str.toHex(a[i]) + ", current=" + str.toHex(b[i]));
|
|
||||||
fMatch = false;
|
|
||||||
this.stopCPU();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!fMatch) {
|
|
||||||
i++;
|
|
||||||
this.println("opcode delta: " + (b[i] - a[i]));
|
|
||||||
}
|
|
||||||
this.aRegFrames.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checkINTR()
|
* checkINTR()
|
||||||
*
|
*
|
||||||
|
|
@ -4295,7 +4204,6 @@ X86CPU.prototype.checkINTR = function()
|
||||||
this.intFlags &= ~X86.INTFLAG.INTR;
|
this.intFlags &= ~X86.INTFLAG.INTR;
|
||||||
if (nIDT >= 0) {
|
if (nIDT >= 0) {
|
||||||
this.intFlags &= ~X86.INTFLAG.HALT;
|
this.intFlags &= ~X86.INTFLAG.HALT;
|
||||||
// if (DEBUG) this.pushRegFrame(); // the corresponding popRegFrame() is in opIRET()
|
|
||||||
X86.fnINT.call(this, this.nFault = nIDT, null, 11);
|
X86.fnINT.call(this, this.nFault = nIDT, null, 11);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -4603,37 +4511,6 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
||||||
nDebugState = 1;
|
nDebugState = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* SAMPLER:
|
|
||||||
*
|
|
||||||
if (SAMPLER) {
|
|
||||||
if (++this.iSampleFreq >= this.nSampleFreq) {
|
|
||||||
this.iSampleFreq = 0;
|
|
||||||
if (this.iSampleSkip < this.nSampleSkip) {
|
|
||||||
this.iSampleSkip++;
|
|
||||||
} else {
|
|
||||||
if (this.iSampleNext == this.nSamples) {
|
|
||||||
this.println("sample buffer full");
|
|
||||||
this.stopCPU();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var t = this.regLIP + this.getCycles();
|
|
||||||
var n = this.aSamples[this.iSampleNext];
|
|
||||||
if (n !== -1) {
|
|
||||||
if (n !== t) {
|
|
||||||
this.println("sample deviation at index " + this.iSampleNext + ": current LIP=" + str.toHex(this.regLIP));
|
|
||||||
this.stopCPU();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.aSamples[this.iSampleNext] = t;
|
|
||||||
}
|
|
||||||
this.iSampleNext++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
this.opFlags = 0;
|
this.opFlags = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -3686,7 +3686,6 @@ X86.opIRET = function IRET()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
X86.fnIRET.call(this);
|
X86.fnIRET.call(this);
|
||||||
// if (DEBUG) this.popRegFrame();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue