Bug 1046688 - Fix assertion in AsmJSModule::restoreToInitialState (r=dougc)

--HG--
extra : rebase_source : 0e3774d978412ea2f688c593bb9cb2282cf695f2
This commit is contained in:
Luke Wagner 2014-08-04 13:02:02 -05:00
parent aaaf4dcfb2
commit 7d1a9fa933
4 changed files with 40 additions and 6 deletions

View File

@ -790,18 +790,31 @@ AsmJSModule::initHeap(Handle<ArrayBufferObject*> heap, JSContext *cx)
}
void
AsmJSModule::restoreToInitialState(ArrayBufferObject *maybePrevBuffer, ExclusiveContext *cx)
AsmJSModule::restoreToInitialState(uint8_t *prevCode, ArrayBufferObject *maybePrevBuffer,
ExclusiveContext *cx)
{
#ifdef DEBUG
// Put the absolute links back to -1 so PatchDataWithValueCheck assertions
// in staticallyLink are valid.
for (size_t imm = 0; imm < AsmJSImm_Limit; imm++) {
void *callee = AddressOf(AsmJSImmKind(imm), cx);
// If we are in profiling mode, calls to builtins will have been patched
// by setProfilingEnabled to be calls to thunks.
AsmJSExit::BuiltinKind builtin;
void *profilingCallee = profilingEnabled_ && ImmKindIsBuiltin(AsmJSImmKind(imm), &builtin)
? prevCode + builtinThunkOffsets_[builtin]
: nullptr;
const AsmJSModule::OffsetVector &offsets = staticLinkData_.absoluteLinks[imm];
void *target = AddressOf(AsmJSImmKind(imm), cx);
for (size_t i = 0; i < offsets.length(); i++) {
Assembler::PatchDataWithValueCheck(CodeLocationLabel(code_ + offsets[i]),
uint8_t *caller = code_ + offsets[i];
void *originalValue = profilingCallee && !lookupCodeRange(caller)->isThunk()
? profilingCallee
: callee;
Assembler::PatchDataWithValueCheck(CodeLocationLabel(caller),
PatchedImmPtr((void*)-1),
PatchedImmPtr(target));
PatchedImmPtr(originalValue));
}
}
#endif
@ -1538,7 +1551,7 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
// flush all of them at once.
out.setAutoFlushICacheRange();
out.restoreToInitialState(maybeHeap_, cx);
out.restoreToInitialState(code_, maybeHeap_, cx);
return true;
}

View File

@ -1148,7 +1148,8 @@ class AsmJSModule
}
void initHeap(Handle<ArrayBufferObject*> heap, JSContext *cx);
bool clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const;
void restoreToInitialState(ArrayBufferObject *maybePrevBuffer, ExclusiveContext *cx);
void restoreToInitialState(uint8_t *prevCode, ArrayBufferObject *maybePrevBuffer,
ExclusiveContext *cx);
/*************************************************************************/
// Functions that can be called after dynamic linking succeeds:

View File

@ -0,0 +1,11 @@
enableSPSProfiling();
for (var j = 0; j < 1000; ++j) {
(function(stdlib) {
"use asm";
var pow = stdlib.Math.pow;
function f() {
return +pow(.0, .0)
}
return f;
})(this)()
}

View File

@ -774,6 +774,15 @@ BuiltinToImmKind(AsmJSExit::BuiltinKind builtin)
return AsmJSImmKind(builtin);
}
static inline bool
ImmKindIsBuiltin(AsmJSImmKind imm, AsmJSExit::BuiltinKind *builtin)
{
if (unsigned(imm) >= unsigned(AsmJSExit::Builtin_Limit))
return false;
*builtin = AsmJSExit::BuiltinKind(imm);
return true;
}
// Pointer to be embedded as an immediate in asm.js code.
class AsmJSImmPtr
{