Bug 728086 - Poison the stack when not in use (r=luke)

This commit is contained in:
Bill McCloskey 2012-02-22 10:36:12 -08:00
Родитель d85e772fe4
Коммит db42dc186d
4 изменённых файлов: 94 добавлений и 6 удалений

Просмотреть файл

@ -0,0 +1,65 @@
var expected = '';
function TestCase(n, d, e, a) {}
function reportFailure (msg) {}
function toPrinted(value) {
value = value.replace(/\\\n/g, 'NL')
.replace(/[^\x20-\x7E]+/g, escapeString);
}
function escapeString (str) {}
function reportCompare (expected, actual, description) {
var expected_t = typeof expected;
var actual_t = typeof actual;
var output = "";
var testcase = new TestCase("unknown-test-name", description, expected, actual);
reportFailure (description + " : " + output);
}
function enterFunc (funcName)
callStack.push(funcName);
try {
reportCompare(expectCompile, actualCompile,
summary + ': compile actual');
} catch(ex) { }
var lfcode = new Array();
lfcode.push("gczeal(2);\
enterFunc ('test');\
");
lfcode.push("{}");
lfcode.push("noexist.js");
lfcode.push("var BUGNUMBER = 305064;\
var summary = 'Tests the trim, trimRight and trimLeft methods';\
var trimMethods = ['trim', 'trimLeft', 'trimRight'];\
var whitespace = [\
{s : '\\u0009', t : 'HORIZONTAL TAB'},\
{s : '\\u200A', t : 'HAIR SPACE'},\
];\
for (var j = 0; j < trimMethods.length; ++j)\
var method = trimMethods[j];\
reportCompare(true, true, 'Test skipped. String.prototype.' + method + ' is not supported');\
str = '';\
for (var i = 0; i < whitespace.length; ++i) {\
var v = whitespace[i].s;\
var t = (summary)[i].t;\
v = v + v + v;\
print('Test ' + method + ' with with leading whitespace. : ' + t);\
actual = str[method]();\
reportCompare(expected, actual, t + ':' + '\"' + toPrinted(str) + '\".' + method + '()');\
str = v + 'a' + v;\
}\
");
while (true) {
var file = lfcode.shift(); if (file == undefined) { break; }
if (file == "evaluate") {
} else {
loadFile(file);
}
}
function loadFile(lfVarx) {
try {
if (lfVarx.substr(-3) == ".js") {
switch (lfRunTypeId) {
}
} else {
eval(lfVarx);
}
} catch (lfVare) { }
}

Просмотреть файл

@ -792,9 +792,9 @@ CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *cla
if (!Wrapper::nativeCall(cx, wrapper, clasp, native, dstArgs)) if (!Wrapper::nativeCall(cx, wrapper, clasp, native, dstArgs))
return false; return false;
srcArgs.rval() = dstArgs.rval();
dstArgs.pop(); dstArgs.pop();
call.leave(); call.leave();
srcArgs.rval() = dstArgs.rval();
return call.origin->wrap(cx, &srcArgs.rval()); return call.origin->wrap(cx, &srcArgs.rval());
} }

Просмотреть файл

@ -413,6 +413,7 @@ StackSpace::init()
trustedEnd_ = base_ + CAPACITY_VALS; trustedEnd_ = base_ + CAPACITY_VALS;
conservativeEnd_ = defaultEnd_ = trustedEnd_ - BUFFER_VALS; conservativeEnd_ = defaultEnd_ = trustedEnd_ - BUFFER_VALS;
#endif #endif
Debug_SetValueRangeToCrashOnTouch(base_, trustedEnd_);
assertInvariants(); assertInvariants();
return true; return true;
} }
@ -736,6 +737,8 @@ ContextStack::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *iag)
if (!firstUnused) if (!firstUnused)
return false; return false;
MakeRangeGCSafe(firstUnused, argc);
ImplicitCast<CallArgs>(*iag) = CallArgsFromVp(argc, firstUnused); ImplicitCast<CallArgs>(*iag) = CallArgsFromVp(argc, firstUnused);
seg_->pushCall(*iag); seg_->pushCall(*iag);
@ -751,9 +754,19 @@ ContextStack::popInvokeArgs(const InvokeArgsGuard &iag)
JS_ASSERT(onTop()); JS_ASSERT(onTop());
JS_ASSERT(space().firstUnused() == seg_->calls().end()); JS_ASSERT(space().firstUnused() == seg_->calls().end());
Value *oldend = seg_->end();
Value *oldbeg;
seg_->popCall(); seg_->popCall();
if (iag.pushedSeg_) if (iag.pushedSeg_) {
oldbeg = reinterpret_cast<Value *>(seg_);
popSegment(); popSegment();
} else {
oldbeg = seg_->end();
}
if (seg_)
Debug_SetValueRangeToCrashOnTouch(oldbeg, oldend);
} }
bool bool
@ -866,9 +879,19 @@ ContextStack::popFrame(const FrameGuard &fg)
if (fg.regs_.fp()->isNonEvalFunctionFrame()) if (fg.regs_.fp()->isNonEvalFunctionFrame())
fg.regs_.fp()->functionEpilogue(); fg.regs_.fp()->functionEpilogue();
Value *oldend = seg_->end();
Value *oldbeg;
seg_->popRegs(fg.prevRegs_); seg_->popRegs(fg.prevRegs_);
if (fg.pushedSeg_) if (fg.pushedSeg_) {
oldbeg = reinterpret_cast<Value *>(seg_);
popSegment(); popSegment();
} else {
oldbeg = seg_->end();
}
if (seg_)
Debug_SetValueRangeToCrashOnTouch(oldbeg, oldend);
/* /*
* NB: this code can call out and observe the stack (e.g., through GC), so * NB: this code can call out and observe the stack (e.g., through GC), so

Просмотреть файл

@ -95,10 +95,10 @@ namespace detail {
* *
* SpiderMonkey uses a per-thread stack to store the activation records, * SpiderMonkey uses a per-thread stack to store the activation records,
* parameters, locals, and expression temporaries for the stack of actively * parameters, locals, and expression temporaries for the stack of actively
* executing scripts, functions and generators. The per-thread stack is owned * executing scripts, functions and generators. The stack is owned by the
* by the StackSpace object stored in the thread's ThreadData. * StackSpace object stored in the runtime.
* *
* The per-thread stack is subdivided into contiguous segments of memory which * The stack is subdivided into contiguous segments of memory which
* have a memory layout invariant that allows fixed offsets to be used for stack * have a memory layout invariant that allows fixed offsets to be used for stack
* access (by jit code) as well as fast call/return. This memory layout is * access (by jit code) as well as fast call/return. This memory layout is
* encapsulated by a set of types that describe different regions of memory. * encapsulated by a set of types that describe different regions of memory.