Bug 1252019: Don't patch profiling entries for the BadIndirectCall exit; r=luke

This commit is contained in:
Benjamin Bouvier 2016-02-29 15:09:53 +01:00
parent 9cb8ed1049
commit b4c662fefb
3 changed files with 38 additions and 17 deletions

View File

@ -800,10 +800,13 @@ Module::setProfilingEnabled(JSContext* cx, bool enabled)
}
// Update the function-pointer tables to point to profiling prologues.
for (FuncPtrTable& funcPtrTable : funcPtrTables_) {
auto array = reinterpret_cast<void**>(globalData() + funcPtrTable.globalDataOffset);
for (size_t i = 0; i < funcPtrTable.numElems; i++) {
for (FuncPtrTable& table : funcPtrTables_) {
auto array = reinterpret_cast<void**>(globalData() + table.globalDataOffset);
for (size_t i = 0; i < table.numElems; i++) {
const CodeRange* codeRange = lookupCodeRange(array[i]);
// Don't update entries for the BadIndirectCall exit.
if (codeRange->isErrorExit())
continue;
void* from = code() + codeRange->funcNonProfilingEntry();
void* to = code() + codeRange->funcProfilingEntry();
if (!enabled)
@ -1057,8 +1060,9 @@ Module::staticallyLink(ExclusiveContext* cx, const StaticLinkData& linkData)
auto array = reinterpret_cast<void**>(globalData() + table.globalDataOffset);
for (size_t i = 0; i < table.elemOffsets.length(); i++) {
uint8_t* elem = code() + table.elemOffsets[i];
if (profilingEnabled_)
elem = code() + lookupCodeRange(elem)->funcProfilingEntry();
const CodeRange* codeRange = lookupCodeRange(elem);
if (profilingEnabled_ && !codeRange->isErrorExit())
elem = code() + codeRange->funcProfilingEntry();
array[i] = elem;
}
}

View File

@ -249,6 +249,9 @@ class CodeRange
bool isImportExit() const {
return kind() == ImportJitExit || kind() == ImportInterpExit;
}
bool isErrorExit() const {
return kind() == ErrorExit;
}
uint32_t funcProfilingEntry() const {
MOZ_ASSERT(isFunction());
return begin();

View File

@ -325,26 +325,40 @@ var {v2i, i2i, i2v} = wasmEvalText(`(module
(export "i2v" 8)
)`);
const badIndirectCall = /wasm indirect call signature mismatch/;
assertEq(v2i(0), 13);
assertEq(v2i(1), 42);
assertErrorMessage(() => v2i(2), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => v2i(3), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => v2i(4), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => v2i(5), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => v2i(2), Error, badIndirectCall);
assertErrorMessage(() => v2i(3), Error, badIndirectCall);
assertErrorMessage(() => v2i(4), Error, badIndirectCall);
assertErrorMessage(() => v2i(5), Error, badIndirectCall);
assertErrorMessage(() => i2i(0), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2i(1), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2i(0), Error, badIndirectCall);
assertErrorMessage(() => i2i(1), Error, badIndirectCall);
assertEq(i2i(2, 100), 101);
assertEq(i2i(3, 100), 102);
assertEq(i2i(4, 100), 103);
assertEq(i2i(5, 100), 104);
assertErrorMessage(() => i2v(0), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(1), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(2), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(3), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(4), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(5), Error, /wasm indirect call signature mismatch/);
assertErrorMessage(() => i2v(0), Error, badIndirectCall);
assertErrorMessage(() => i2v(1), Error, badIndirectCall);
assertErrorMessage(() => i2v(2), Error, badIndirectCall);
assertErrorMessage(() => i2v(3), Error, badIndirectCall);
assertErrorMessage(() => i2v(4), Error, badIndirectCall);
assertErrorMessage(() => i2v(5), Error, badIndirectCall);
{
enableSPSProfiling();
wasmEvalText(`(
module
(func (result i32) (i32.const 0))
(func)
(table 1 0)
(export "" 0)
)`)();
disableSPSProfiling();
}
for (bad of [6, 7, 100, Math.pow(2,31)-1, Math.pow(2,31), Math.pow(2,31)+1, Math.pow(2,32)-2, Math.pow(2,32)-1]) {
assertThrowsInstanceOf(() => v2i(bad), RangeError);