mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 857838 - Fix script-pc calculatins when iterating on baseline frames. r=jandem
This commit is contained in:
parent
6837e0d82f
commit
d549443ef1
@ -1184,6 +1184,13 @@ ion::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo)
|
||||
|
||||
IonSpew(IonSpew_BaselineBailouts, " Done restoring frames");
|
||||
|
||||
// Check that we can get the current script's PC.
|
||||
#ifdef DEBUG
|
||||
jsbytecode *pc;
|
||||
cx->stack.currentScript(&pc);
|
||||
IonSpew(IonSpew_BaselineBailouts, " Got pc=%p", pc);
|
||||
#endif
|
||||
|
||||
uint32_t numFrames = bailoutInfo->numFrames;
|
||||
JS_ASSERT(numFrames > 0);
|
||||
BailoutKind bailoutKind = bailoutInfo->bailoutKind;
|
||||
|
@ -388,8 +388,8 @@ BaselineScript::pcMappingReader(size_t indexEntry)
|
||||
return CompactBufferReader(dataStart, dataEnd);
|
||||
}
|
||||
|
||||
ICEntry &
|
||||
BaselineScript::icEntryFromReturnOffset(CodeOffsetLabel returnOffset)
|
||||
ICEntry *
|
||||
BaselineScript::maybeICEntryFromReturnOffset(CodeOffsetLabel returnOffset)
|
||||
{
|
||||
size_t bottom = 0;
|
||||
size_t top = numICEntries();
|
||||
@ -402,8 +402,21 @@ BaselineScript::icEntryFromReturnOffset(CodeOffsetLabel returnOffset)
|
||||
top = mid;
|
||||
mid = (bottom + top) / 2;
|
||||
}
|
||||
JS_ASSERT(icEntry(mid).returnOffset().offset() == returnOffset.offset());
|
||||
return icEntry(mid);
|
||||
if (mid >= numICEntries())
|
||||
return NULL;
|
||||
|
||||
if (icEntry(mid).returnOffset().offset() != returnOffset.offset())
|
||||
return NULL;
|
||||
|
||||
return &icEntry(mid);
|
||||
}
|
||||
|
||||
ICEntry &
|
||||
BaselineScript::icEntryFromReturnOffset(CodeOffsetLabel returnOffset)
|
||||
{
|
||||
ICEntry *result = maybeICEntryFromReturnOffset(returnOffset);
|
||||
JS_ASSERT(result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@ -468,10 +481,20 @@ BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntr
|
||||
return icEntryFromPCOffset(pcOffset);
|
||||
}
|
||||
|
||||
ICEntry *
|
||||
BaselineScript::maybeICEntryFromReturnAddress(uint8_t *returnAddr)
|
||||
{
|
||||
JS_ASSERT(returnAddr > method_->raw());
|
||||
JS_ASSERT(returnAddr < method_->raw() + method_->instructionsSize());
|
||||
CodeOffsetLabel offset(returnAddr - method_->raw());
|
||||
return maybeICEntryFromReturnOffset(offset);
|
||||
}
|
||||
|
||||
ICEntry &
|
||||
BaselineScript::icEntryFromReturnAddress(uint8_t *returnAddr)
|
||||
{
|
||||
JS_ASSERT(returnAddr > method_->raw());
|
||||
JS_ASSERT(returnAddr < method_->raw() + method_->instructionsSize());
|
||||
CodeOffsetLabel offset(returnAddr - method_->raw());
|
||||
return icEntryFromReturnOffset(offset);
|
||||
}
|
||||
@ -581,6 +604,60 @@ BaselineScript::nativeCodeForPC(JSScript *script, jsbytecode *pc, PCMappingSlotI
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsbytecode *
|
||||
BaselineScript::pcForReturnOffset(JSScript *script, uint32_t nativeOffset)
|
||||
{
|
||||
JS_ASSERT(script->baselineScript() == this);
|
||||
JS_ASSERT(nativeOffset < method_->instructionsSize());
|
||||
|
||||
// Look for the first PCMappingIndexEntry with native offset > the native offset we are
|
||||
// interested in.
|
||||
uint32_t i = 1;
|
||||
for (; i < numPCMappingIndexEntries(); i++) {
|
||||
if (pcMappingIndexEntry(i).nativeOffset > nativeOffset)
|
||||
break;
|
||||
}
|
||||
|
||||
// Go back an entry to search forward from.
|
||||
JS_ASSERT(i > 0);
|
||||
i--;
|
||||
|
||||
PCMappingIndexEntry &entry = pcMappingIndexEntry(i);
|
||||
JS_ASSERT(nativeOffset >= entry.nativeOffset);
|
||||
|
||||
CompactBufferReader reader(pcMappingReader(i));
|
||||
jsbytecode *curPC = script->code + entry.pcOffset;
|
||||
uint32_t curNativeOffset = entry.nativeOffset;
|
||||
|
||||
JS_ASSERT(curPC >= script->code);
|
||||
JS_ASSERT(curNativeOffset <= nativeOffset);
|
||||
|
||||
while (true) {
|
||||
// If the high bit is set, the native offset relative to the
|
||||
// previous pc != 0 and comes next.
|
||||
uint8_t b = reader.readByte();
|
||||
if (b & 0x80)
|
||||
curNativeOffset += reader.readUnsigned();
|
||||
|
||||
if (curNativeOffset == nativeOffset)
|
||||
return curPC;
|
||||
|
||||
curPC += GetBytecodeLength(curPC);
|
||||
}
|
||||
|
||||
JS_NOT_REACHED("Invalid pc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsbytecode *
|
||||
BaselineScript::pcForReturnAddress(JSScript *script, uint8_t *nativeAddress)
|
||||
{
|
||||
JS_ASSERT(script->baselineScript() == this);
|
||||
JS_ASSERT(nativeAddress >= method_->raw());
|
||||
JS_ASSERT(nativeAddress < method_->raw() + method_->instructionsSize());
|
||||
return pcForReturnOffset(script, uint32_t(nativeAddress - method_->raw()));
|
||||
}
|
||||
|
||||
void
|
||||
BaselineScript::toggleDebugTraps(RawScript script, jsbytecode *pc)
|
||||
{
|
||||
|
@ -211,9 +211,11 @@ struct BaselineScript
|
||||
}
|
||||
|
||||
ICEntry &icEntry(size_t index);
|
||||
ICEntry *maybeICEntryFromReturnOffset(CodeOffsetLabel returnOffset);
|
||||
ICEntry &icEntryFromReturnOffset(CodeOffsetLabel returnOffset);
|
||||
ICEntry &icEntryFromPCOffset(uint32_t pcOffset);
|
||||
ICEntry &icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntry);
|
||||
ICEntry *maybeICEntryFromReturnAddress(uint8_t *returnAddr);
|
||||
ICEntry &icEntryFromReturnAddress(uint8_t *returnAddr);
|
||||
uint8_t *returnAddressForIC(const ICEntry &ent);
|
||||
|
||||
@ -235,6 +237,8 @@ struct BaselineScript
|
||||
|
||||
void copyPCMappingEntries(const CompactBufferWriter &entries);
|
||||
uint8_t *nativeCodeForPC(JSScript *script, jsbytecode *pc, PCMappingSlotInfo *slotInfo = NULL);
|
||||
jsbytecode *pcForReturnOffset(JSScript *script, uint32_t nativeOffset);
|
||||
jsbytecode *pcForReturnAddress(JSScript *script, uint8_t *nativeAddress);
|
||||
|
||||
// Toggle debug traps (used for breakpoints and step mode) in the script.
|
||||
// If |pc| is NULL, toggle traps for all ops in the script. Else, only
|
||||
|
@ -193,8 +193,25 @@ IonFrameIterator::baselineScriptAndPc(JSScript **scriptRes, jsbytecode **pcRes)
|
||||
if (scriptRes)
|
||||
*scriptRes = script;
|
||||
uint8_t *retAddr = returnAddressToFp();
|
||||
if (pcRes)
|
||||
*pcRes = script->baselineScript()->icEntryFromReturnAddress(retAddr).pc(script);
|
||||
if (pcRes) {
|
||||
// If the return address is into the prologue entry addr, then assume PC 0.
|
||||
if (retAddr == script->baselineScript()->prologueEntryAddr()) {
|
||||
*pcRes = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// The return address _may_ be a return from a callVM or IC chain call done for
|
||||
// some op.
|
||||
ICEntry *icEntry = script->baselineScript()->maybeICEntryFromReturnAddress(retAddr);
|
||||
if (icEntry) {
|
||||
*pcRes = icEntry->pc(script);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not, the return address _must_ be the start address of an op, which can
|
||||
// be computed from the pc mapping table.
|
||||
*pcRes = script->baselineScript()->pcForReturnAddress(script, retAddr);
|
||||
}
|
||||
}
|
||||
|
||||
Value *
|
||||
|
@ -847,7 +847,8 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
load32(Address(temp, BaselineFrame::reverseOffsetOfFrameSize()), temp);
|
||||
makeFrameDescriptor(temp, IonFrame_BaselineJS);
|
||||
push(temp);
|
||||
push(Imm32(0)); // Fake return address.
|
||||
loadPtr(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeAddr)), temp);
|
||||
push(temp);
|
||||
enterFakeExitFrame();
|
||||
|
||||
// If monitorStub is non-null, handle resumeAddr appropriately.
|
||||
|
Loading…
Reference in New Issue
Block a user