本文整理汇总了C++中FrameEntry类的典型用法代码示例。如果您正苦于以下问题:C++ FrameEntry类的具体用法?C++ FrameEntry怎么用?C++ FrameEntry使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了FrameEntry类的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: tosFe
void
FrameState::assertValidRegisterState() const
{
Registers checkedFreeRegs;
FrameEntry *tos = tosFe();
for (uint32 i = 0; i < tracker.nentries; i++) {
FrameEntry *fe = tracker[i];
if (fe >= tos)
continue;
JS_ASSERT(i == fe->trackerIndex());
JS_ASSERT_IF(fe->isCopy(),
fe->trackerIndex() > fe->copyOf()->trackerIndex());
JS_ASSERT_IF(fe->isCopy(), !fe->type.inRegister() && !fe->data.inRegister());
JS_ASSERT_IF(fe->isCopy(), fe->copyOf() < tos);
JS_ASSERT_IF(fe->isCopy(), fe->copyOf()->isCopied());
if (fe->isCopy())
continue;
if (fe->type.inRegister()) {
checkedFreeRegs.takeReg(fe->type.reg());
JS_ASSERT(regstate[fe->type.reg()].fe == fe);
}
if (fe->data.inRegister()) {
checkedFreeRegs.takeReg(fe->data.reg());
JS_ASSERT(regstate[fe->data.reg()].fe == fe);
}
}
JS_ASSERT(checkedFreeRegs == freeRegs);
}
示例2: JS_ASSERT
void
ImmutableSync::syncCopy(FrameEntry *fe)
{
JS_ASSERT(fe >= bottom);
FrameEntry *backing = fe->copyOf();
SyncEntry &e = entryFor(backing);
JS_ASSERT(!backing->isConstant());
Address addr = frame.addressOf(fe);
if (fe->isTypeKnown() && !e.learnedType) {
e.learnedType = true;
e.type = fe->getKnownType();
}
if (!fe->data.synced())
masm->storePayload(ensureDataReg(backing, e), addr);
if (!fe->type.synced()) {
if (e.learnedType)
masm->storeTypeTag(ImmType(e.type), addr);
else
masm->storeTypeTag(ensureTypeReg(backing, e), addr);
}
}
示例3: dump
void DWARFDebugFrame::dump(raw_ostream &OS) const {
OS << "\n";
for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end();
I != E; ++I) {
FrameEntry *Entry = *I;
Entry->dumpHeader(OS);
Entry->dumpInstructions(OS);
OS << "\n";
}
}
示例4: JS_ASSERT
CompileStatus
mjit::Compiler::compileArrayWithLength(uint32_t argc)
{
/* Match Array() or Array(n) for constant n. */
JS_ASSERT(argc == 0 || argc == 1);
int32_t length = 0;
if (argc == 1) {
FrameEntry *arg = frame.peek(-1);
if (!arg->isConstant() || !arg->getValue().isInt32())
return Compile_InlineAbort;
length = arg->getValue().toInt32();
if (length < 0)
return Compile_InlineAbort;
}
RootedScript script(cx, script_);
types::TypeObject *type = types::TypeScript::InitObject(cx, script, PC, JSProto_Array);
if (!type)
return Compile_Error;
JSObject *templateObject = NewDenseUnallocatedArray(cx, length, type->proto);
if (!templateObject)
return Compile_Error;
templateObject->setType(type);
RegisterID result = frame.allocReg();
Jump emptyFreeList = getNewObject(cx, result, templateObject);
stubcc.linkExit(emptyFreeList, Uses(0));
stubcc.leave();
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
frame.popn(argc + 2);
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, result);
stubcc.rejoin(Changes(1));
return Compile_Okay;
}
示例5: RegisterID
JSC::MacroAssembler::RegisterID
ImmutableSync::allocReg()
{
if (!avail.empty())
return avail.takeAnyReg();
uint32 lastResort = FrameState::InvalidIndex;
uint32 evictFromFrame = FrameState::InvalidIndex;
/* Find something to evict. */
for (uint32 i = 0; i < JSC::MacroAssembler::TotalRegisters; i++) {
RegisterID reg = RegisterID(i);
if (!(Registers::maskReg(reg) & Registers::AvailRegs))
continue;
lastResort = 0;
if (!regs[i]) {
/* If the frame does not own this register, take it! */
FrameEntry *fe = frame.regstate[i].usedBy();
if (!fe)
return reg;
evictFromFrame = i;
/*
* If not copied, we can sync and not have to load again later.
* That's about as good as it gets, so just break out now.
*/
if (!fe->isCopied())
break;
}
}
if (evictFromFrame != FrameState::InvalidIndex) {
FrameEntry *fe = frame.regstate[evictFromFrame].usedBy();
SyncEntry &e = entryFor(fe);
if (frame.regstate[evictFromFrame].type() == RematInfo::TYPE) {
JS_ASSERT(!e.typeClobbered);
e.typeClobbered = true;
} else {
JS_ASSERT(!e.dataClobbered);
e.dataClobbered = true;
}
return RegisterID(evictFromFrame);
}
JS_ASSERT(lastResort != FrameState::InvalidIndex);
JS_ASSERT(regs[lastResort]);
SyncEntry *e = regs[lastResort];
RegisterID reg = RegisterID(lastResort);
if (e->hasDataReg && e->dataReg == reg) {
e->hasDataReg = false;
} else if (e->hasTypeReg && e->typeReg == reg) {
e->hasTypeReg = false;
} else {
JS_NOT_REACHED("no way");
}
return reg;
}
示例6: data
void
FrameEntry::copy(const FrameEntry& other)
{
U8* dstPixels = data();
assert(dstPixels);
if (!dstPixels) {
return;
}
const U8* srcPixels = other.data();
assert(srcPixels);
if (!srcPixels) {
return;
}
const TextureRect& srcBounds = other.getKey().getTexRect();
const TextureRect& dstBounds = _key.getTexRect();
std::size_t srcRowSize = srcBounds.width();
unsigned int srcPixelSize = 4;
if ( (ImageBitDepthEnum)other.getKey().getBitDepth() == eImageBitDepthFloat ) {
srcPixelSize *= sizeof(float);
}
srcRowSize *= srcPixelSize;
std::size_t dstRowSize = srcBounds.width();
unsigned int dstPixelSize = 4;
if ( (ImageBitDepthEnum)_key.getBitDepth() == eImageBitDepthFloat ) {
dstPixelSize *= sizeof(float);
}
dstRowSize *= dstPixelSize;
// Fill with black and transparent because src might be smaller
bool filledZero = false;
if ( !srcBounds.contains(dstBounds) ) {
std::memset( dstPixels, 0, dstRowSize * dstBounds.height() );
filledZero = true;
}
if ( other.getKey().getBitDepth() != _key.getBitDepth() ) {
if (!filledZero) {
std::memset( dstPixels, 0, dstRowSize * dstBounds.height() );
}
return;
}
// Copy pixels over the intersection
RectI srcBoundsRect;
srcBoundsRect.x1 = srcBounds.x1;
srcBoundsRect.x2 = srcBounds.x2;
srcBoundsRect.y1 = srcBounds.y1;
srcBoundsRect.y2 = srcBounds.y2;
RectI roi;
if ( !dstBounds.intersect(srcBoundsRect, &roi) ) {
return;
}
dstPixels += (roi.y1 - dstBounds.y1) * dstRowSize + (roi.x1 - dstBounds.x1) * dstPixelSize;
srcPixels += (roi.y1 - srcBounds.y1) * srcRowSize + (roi.x1 - srcBounds.x1) * srcPixelSize;
std::size_t roiRowSize = dstPixelSize * roi.width();
//Align dstPixel to srcPixels point
for (int y = roi.y1; y < roi.y2; ++y,
srcPixels += srcRowSize,
dstPixels += dstRowSize) {
std::memcpy(dstPixels, srcPixels, roiRowSize);
}
} // FrameEntry::copy
示例7: knownPushedType
CompileStatus
mjit::Compiler::inlineNativeFunction(uint32_t argc, bool callingNew)
{
if (!cx->typeInferenceEnabled())
return Compile_InlineAbort;
if (applyTricks == LazyArgsObj)
return Compile_InlineAbort;
FrameEntry *origCallee = frame.peek(-((int)argc + 2));
FrameEntry *thisValue = frame.peek(-((int)argc + 1));
types::TypeSet *thisTypes = analysis->poppedTypes(PC, argc);
if (!origCallee->isConstant() || !origCallee->isType(JSVAL_TYPE_OBJECT))
return Compile_InlineAbort;
JSObject *callee = &origCallee->getValue().toObject();
if (!callee->isFunction())
return Compile_InlineAbort;
/*
* The callee must have the same parent as the script's global, otherwise
* inference may not have accounted for any side effects correctly.
*/
if (!globalObj || globalObj != &callee->global())
return Compile_InlineAbort;
Native native = callee->toFunction()->maybeNative();
if (!native)
return Compile_InlineAbort;
JSValueType type = knownPushedType(0);
JSValueType thisType = thisValue->isTypeKnown()
? thisValue->getKnownType()
: JSVAL_TYPE_UNKNOWN;
/*
* Note: when adding new natives which operate on properties, add relevant
* constraint generation to the behavior of TypeConstraintCall.
*/
/* Handle natives that can be called either with or without 'new'. */
if (native == js_Array && type == JSVAL_TYPE_OBJECT && globalObj) {
if (argc == 0 || argc == 1)
return compileArrayWithLength(argc);
return compileArrayWithArgs(argc);
}
/* Remaining natives must not be called with 'new'. */
if (callingNew)
return Compile_InlineAbort;
if (native == js::num_parseInt && argc >= 1) {
FrameEntry *arg = frame.peek(-(int32_t)argc);
JSValueType argType = arg->isTypeKnown() ? arg->getKnownType() : JSVAL_TYPE_UNKNOWN;
if ((argType == JSVAL_TYPE_DOUBLE || argType == JSVAL_TYPE_INT32) &&
type == JSVAL_TYPE_INT32) {
return compileParseInt(argType, argc);
}
}
if (argc == 0) {
if ((native == js::array_pop || native == js::array_shift) && thisType == JSVAL_TYPE_OBJECT) {
/*
* Only handle pop/shift on dense arrays which have never been used
* in an iterator --- when popping elements we don't account for
* suppressing deleted properties in active iterators.
*
* Constraints propagating properties directly into the result
* type set are generated by TypeConstraintCall during inference.
*/
if (!thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY |
types::OBJECT_FLAG_ITERATED) &&
!types::ArrayPrototypeHasIndexedProperty(cx, outerScript)) {
bool packed = !thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY);
return compileArrayPopShift(thisValue, packed, native == js::array_pop);
}
}
} else if (argc == 1) {
FrameEntry *arg = frame.peek(-1);
types::TypeSet *argTypes = frame.extra(arg).types;
if (!argTypes)
return Compile_InlineAbort;
JSValueType argType = arg->isTypeKnown() ? arg->getKnownType() : JSVAL_TYPE_UNKNOWN;
if (native == js_math_abs) {
if (argType == JSVAL_TYPE_INT32 && type == JSVAL_TYPE_INT32)
return compileMathAbsInt(arg);
if (argType == JSVAL_TYPE_DOUBLE && type == JSVAL_TYPE_DOUBLE)
return compileMathAbsDouble(arg);
}
if (native == js_math_floor && argType == JSVAL_TYPE_DOUBLE &&
type == JSVAL_TYPE_INT32) {
return compileRound(arg, Floor);
}
if (native == js_math_round && argType == JSVAL_TYPE_DOUBLE &&
//.........这里部分代码省略.........
示例8: Imm32
CompileStatus
mjit::Compiler::compileParseInt(JSValueType argType, uint32_t argc)
{
bool needStubCall = false;
if (argc > 1) {
FrameEntry *arg = frame.peek(-(int32_t)argc + 1);
if (!arg->isTypeKnown() || arg->getKnownType() != JSVAL_TYPE_INT32)
return Compile_InlineAbort;
if (arg->isConstant()) {
int32_t base = arg->getValue().toInt32();
if (base != 0 && base != 10)
return Compile_InlineAbort;
} else {
RegisterID baseReg = frame.tempRegForData(arg);
needStubCall = true;
Jump isTen = masm.branch32(Assembler::Equal, baseReg, Imm32(10));
Jump isNotZero = masm.branch32(Assembler::NotEqual, baseReg, Imm32(0));
stubcc.linkExit(isNotZero, Uses(2 + argc));
isTen.linkTo(masm.label(), &masm);
}
}
if (argType == JSVAL_TYPE_INT32) {
if (needStubCall) {
stubcc.leave();
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
}
/*
* Stack looks like callee, this, arg1, arg2, argN.
* First pop all args other than arg1.
*/
frame.popn(argc - 1);
/* "Shimmy" arg1 to the callee slot and pop this + arg1. */
frame.shimmy(2);
if (needStubCall) {
stubcc.rejoin(Changes(1));
}
} else {
FrameEntry *arg = frame.peek(-(int32_t)argc);
FPRegisterID fpScratchReg = frame.allocFPReg();
FPRegisterID fpReg;
bool allocate;
DebugOnly<MaybeJump> notNumber = loadDouble(arg, &fpReg, &allocate);
JS_ASSERT(!((MaybeJump)notNumber).isSet());
masm.slowLoadConstantDouble(1, fpScratchReg);
/* Slow path for NaN and numbers < 1. */
Jump lessThanOneOrNan = masm.branchDouble(Assembler::DoubleLessThanOrUnordered,
fpReg, fpScratchReg);
stubcc.linkExit(lessThanOneOrNan, Uses(2 + argc));
frame.freeReg(fpScratchReg);
/* Truncate to integer, slow path if this overflows. */
RegisterID reg = frame.allocReg();
Jump overflow = masm.branchTruncateDoubleToInt32(fpReg, reg);
stubcc.linkExit(overflow, Uses(2 + argc));
if (allocate)
frame.freeReg(fpReg);
stubcc.leave();
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
frame.popn(2 + argc);
frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
stubcc.rejoin(Changes(1));
}
return Compile_Okay;
}
示例9: getLocal
void
FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange)
{
FrameEntry *localFe = getLocal(n);
bool cacheable = !eval && !escaping[n];
if (!popGuaranteed && !cacheable) {
JS_ASSERT_IF(base[localIndex(n)] && (!eval || n < script->nfixed),
entries[localIndex(n)].type.inMemory() &&
entries[localIndex(n)].data.inMemory());
Address local(JSFrameReg, sizeof(JSStackFrame) + n * sizeof(Value));
storeTo(peek(-1), local, false);
forgetAllRegs(getLocal(n));
localFe->resetSynced();
return;
}
bool wasSynced = localFe->type.synced();
/* Detect something like (x = x) which is a no-op. */
FrameEntry *top = peek(-1);
if (top->isCopy() && top->copyOf() == localFe) {
JS_ASSERT(localFe->isCopied());
return;
}
/* Completely invalidate the local variable. */
if (localFe->isCopied()) {
uncopy(localFe);
if (!localFe->isCopied())
forgetAllRegs(localFe);
} else {
forgetAllRegs(localFe);
}
localFe->resetUnsynced();
/* Constants are easy to propagate. */
if (top->isConstant()) {
localFe->setCopyOf(NULL);
localFe->setNotCopied();
localFe->setConstant(Jsvalify(top->getValue()));
return;
}
/*
* When dealing with copies, there are two important invariants:
*
* 1) The backing store precedes all copies in the tracker.
* 2) The backing store of a local is never a stack slot, UNLESS the local
* variable itself is a stack slot (blocks) that precedes the stack
* slot.
*
* If the top is a copy, and the second condition holds true, the local
* can be rewritten as a copy of the original backing slot. If the first
* condition does not hold, force it to hold by swapping in-place.
*/
FrameEntry *backing = top;
if (top->isCopy()) {
backing = top->copyOf();
JS_ASSERT(backing->trackerIndex() < top->trackerIndex());
uint32 backingIndex = indexOfFe(backing);
uint32 tol = uint32(spBase - base);
if (backingIndex < tol || backingIndex < localIndex(n)) {
/* local.idx < backing.idx means local cannot be a copy yet */
if (localFe->trackerIndex() < backing->trackerIndex())
swapInTracker(backing, localFe);
localFe->setNotCopied();
localFe->setCopyOf(backing);
if (backing->isTypeKnown())
localFe->setType(backing->getKnownType());
else
localFe->type.invalidate();
localFe->data.invalidate();
localFe->isNumber = backing->isNumber;
return;
}
/*
* If control flow lands here, then there was a bytecode sequence like
*
* ENTERBLOCK 2
* GETLOCAL 1
* SETLOCAL 0
*
* The problem is slot N can't be backed by M if M could be popped
* before N. We want a guarantee that when we pop M, even if it was
* copied, it has no outstanding copies.
*
* Because of |let| expressions, it's kind of hard to really know
* whether a region on the stack will be popped all at once. Bleh!
*
* This should be rare except in browser code (and maybe even then),
* but even so there's a quick workaround. We take all copies of the
* backing fe, and redirect them to be copies of the destination.
*/
FrameEntry *tos = tosFe();
for (uint32 i = backing->trackerIndex() + 1; i < tracker.nentries; i++) {
FrameEntry *fe = tracker[i];
//.........这里部分代码省略.........
示例10: JS_ASSERT
FrameEntry *
FrameState::uncopy(FrameEntry *original)
{
JS_ASSERT(original->isCopied());
/*
* Copies have two critical invariants:
* 1) The backing store precedes all copies in the tracker.
* 2) The backing store of a copy cannot be popped from the stack
* while the copy is still live.
*
* Maintaining this invariant iteratively is kind of hard, so we choose
* the "lowest" copy in the frame up-front.
*
* For example, if the stack is:
* [A, B, C, D]
* And the tracker has:
* [A, D, C, B]
*
* If B, C, and D are copies of A - we will walk the tracker to the end
* and select D, not B (see bug 583684).
*/
uint32 firstCopy = InvalidIndex;
FrameEntry *tos = tosFe();
FrameEntry *bestFe = NULL;
uint32 ncopies = 0;
for (uint32 i = 0; i < tracker.nentries; i++) {
FrameEntry *fe = tracker[i];
if (fe >= tos)
continue;
if (fe->isCopy() && fe->copyOf() == original) {
if (firstCopy == InvalidIndex) {
firstCopy = i;
bestFe = fe;
} else if (fe < bestFe) {
bestFe = fe;
}
ncopies++;
}
}
if (!ncopies) {
JS_ASSERT(firstCopy == InvalidIndex);
JS_ASSERT(!bestFe);
original->copied = false;
return NULL;
}
JS_ASSERT(firstCopy != InvalidIndex);
JS_ASSERT(bestFe);
/* Mark all extra copies as copies of the new backing index. */
bestFe->setCopyOf(NULL);
if (ncopies > 1) {
bestFe->setCopied();
for (uint32 i = firstCopy; i < tracker.nentries; i++) {
FrameEntry *other = tracker[i];
if (other >= tos || other == bestFe)
continue;
/* The original must be tracked before copies. */
JS_ASSERT(other != original);
if (!other->isCopy() || other->copyOf() != original)
continue;
other->setCopyOf(bestFe);
/*
* This is safe even though we're mutating during iteration. There
* are two cases. The first is that both indexes are <= i, and :.
* will never be observed. The other case is we're placing the
* other FE such that it will be observed later. Luckily, copyOf()
* will return != original, so nothing will happen.
*/
if (other->trackerIndex() < bestFe->trackerIndex())
swapInTracker(bestFe, other);
}
} else {
bestFe->setNotCopied();
}
FrameEntry *fe = bestFe;
/*
* Switch the new backing store to the old backing store. During
* this process we also necessarily make sure the copy can be
* synced.
*/
if (!original->isTypeKnown()) {
/*
* If the copy is unsynced, and the original is in memory,
* give the original a register. We do this below too; it's
* okay if it's spilled.
*/
if (original->type.inMemory() && !fe->type.synced())
tempRegForType(original);
fe->type.inherit(original->type);
if (fe->type.inRegister())
moveOwnership(fe->type.reg(), fe);
//.........这里部分代码省略.........
示例11: entryFor
void
FrameState::pushCopyOf(uint32 index)
{
FrameEntry *backing = entryFor(index);
FrameEntry *fe = rawPush();
fe->resetUnsynced();
if (backing->isConstant()) {
fe->setConstant(Jsvalify(backing->getValue()));
} else {
if (backing->isTypeKnown())
fe->setType(backing->getKnownType());
else
fe->type.invalidate();
fe->isNumber = backing->isNumber;
fe->data.invalidate();
if (backing->isCopy()) {
backing = backing->copyOf();
fe->setCopyOf(backing);
} else {
fe->setCopyOf(backing);
backing->setCopied();
}
/* Maintain tracker ordering guarantees for copies. */
JS_ASSERT(backing->isCopied());
if (fe->trackerIndex() < backing->trackerIndex())
swapInTracker(fe, backing);
}
}
示例12: avail
void
FrameState::sync(Assembler &masm, Uses uses) const
{
/*
* Keep track of free registers using a bitmask. If we have to drop into
* syncFancy(), then this mask will help avoid eviction.
*/
Registers avail(freeRegs);
Registers temp(Registers::TempRegs);
FrameEntry *tos = tosFe();
FrameEntry *bottom = tos - uses.nuses;
if (inTryBlock)
bottom = NULL;
for (uint32 i = tracker.nentries - 1; i < tracker.nentries; i--) {
FrameEntry *fe = tracker[i];
if (fe >= tos)
continue;
Address address = addressOf(fe);
if (!fe->isCopy()) {
/* Keep track of registers that can be clobbered. */
if (fe->data.inRegister())
avail.putReg(fe->data.reg());
if (fe->type.inRegister())
avail.putReg(fe->type.reg());
/* Sync. */
if (!fe->data.synced() && (fe->data.inRegister() || fe >= bottom)) {
syncData(fe, address, masm);
if (fe->isConstant())
continue;
}
if (!fe->type.synced() && (fe->type.inRegister() || fe >= bottom))
syncType(fe, addressOf(fe), masm);
} else if (fe >= bottom) {
FrameEntry *backing = fe->copyOf();
JS_ASSERT(backing != fe);
JS_ASSERT(!backing->isConstant() && !fe->isConstant());
/*
* If the copy is backed by something not in a register, fall back
* to a slower sync algorithm.
*/
if ((!fe->type.synced() && !backing->type.inRegister()) ||
(!fe->data.synced() && !backing->data.inRegister())) {
syncFancy(masm, avail, i, bottom);
return;
}
if (!fe->type.synced()) {
/* :TODO: we can do better, the type is learned for all copies. */
if (fe->isTypeKnown()) {
//JS_ASSERT(fe->getTypeTag() == backing->getTypeTag());
masm.storeTypeTag(ImmType(fe->getKnownType()), address);
} else {
masm.storeTypeTag(backing->type.reg(), address);
}
}
if (!fe->data.synced())
masm.storePayload(backing->data.reg(), address);
}
}
}
示例13: pinReg
void
FrameState::allocForBinary(FrameEntry *lhs, FrameEntry *rhs, JSOp op, BinaryAlloc &alloc,
bool needsResult)
{
FrameEntry *backingLeft = lhs;
FrameEntry *backingRight = rhs;
if (backingLeft->isCopy())
backingLeft = backingLeft->copyOf();
if (backingRight->isCopy())
backingRight = backingRight->copyOf();
/*
* For each remat piece of both FEs, if a register is assigned, get it now
* and pin it. This is safe - constants and known types will be avoided.
*/
if (AllocHelper(backingLeft->type, alloc.lhsType))
pinReg(alloc.lhsType.reg());
if (AllocHelper(backingLeft->data, alloc.lhsData))
pinReg(alloc.lhsData.reg());
if (AllocHelper(backingRight->type, alloc.rhsType))
pinReg(alloc.rhsType.reg());
if (AllocHelper(backingRight->data, alloc.rhsData))
pinReg(alloc.rhsData.reg());
/* For each type without a register, give it a register if needed. */
if (!alloc.lhsType.isSet() && backingLeft->type.inMemory()) {
alloc.lhsType = tempRegForType(lhs);
pinReg(alloc.lhsType.reg());
}
if (!alloc.rhsType.isSet() && backingRight->type.inMemory()) {
alloc.rhsType = tempRegForType(rhs);
pinReg(alloc.rhsType.reg());
}
bool commu;
switch (op) {
case JSOP_EQ:
case JSOP_GT:
case JSOP_GE:
case JSOP_LT:
case JSOP_LE:
/* fall through */
case JSOP_ADD:
case JSOP_MUL:
case JSOP_SUB:
commu = true;
break;
case JSOP_DIV:
commu = false;
break;
default:
JS_NOT_REACHED("unknown op");
return;
}
/*
* Data is a little more complicated. If the op is MUL, not all CPUs
* have multiplication on immediates, so a register is needed. Also,
* if the op is not commutative, the LHS _must_ be in a register.
*/
JS_ASSERT_IF(lhs->isConstant(), !rhs->isConstant());
JS_ASSERT_IF(rhs->isConstant(), !lhs->isConstant());
if (!alloc.lhsData.isSet()) {
if (backingLeft->data.inMemory()) {
alloc.lhsData = tempRegForData(lhs);
pinReg(alloc.lhsData.reg());
} else if (op == JSOP_MUL || !commu) {
JS_ASSERT(lhs->isConstant());
alloc.lhsData = allocReg();
alloc.extraFree = alloc.lhsData;
masm.move(Imm32(lhs->getValue().toInt32()), alloc.lhsData.reg());
}
}
if (!alloc.rhsData.isSet()) {
if (backingRight->data.inMemory()) {
alloc.rhsData = tempRegForData(rhs);
pinReg(alloc.rhsData.reg());
} else if (op == JSOP_MUL) {
JS_ASSERT(rhs->isConstant());
alloc.rhsData = allocReg();
alloc.extraFree = alloc.rhsData;
masm.move(Imm32(rhs->getValue().toInt32()), alloc.rhsData.reg());
}
}
alloc.lhsNeedsRemat = false;
alloc.rhsNeedsRemat = false;
if (!needsResult)
goto skip;
/*
* Now a result register is needed. It must contain a mutable copy of the
* LHS. For commutative operations, we can opt to use the RHS instead. At
* this point, if for some reason either must be in a register, that has
* already been guaranteed at this point.
//.........这里部分代码省略.........
示例14: while
void DWARFDebugFrame::parse(DataExtractor Data) {
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
uint32_t StartOffset = Offset;
bool IsDWARF64 = false;
uint64_t Length = Data.getU32(&Offset);
uint64_t Id;
if (Length == UINT32_MAX) {
// DWARF-64 is distinguished by the first 32 bits of the initial length
// field being 0xffffffff. Then, the next 64 bits are the actual entry
// length.
IsDWARF64 = true;
Length = Data.getU64(&Offset);
}
// At this point, Offset points to the next field after Length.
// Length is the structure size excluding itself. Compute an offset one
// past the end of the structure (needed to know how many instructions to
// read).
// TODO: For honest DWARF64 support, DataExtractor will have to treat
// offset_ptr as uint64_t*
uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
// The Id field's size depends on the DWARF format
Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
FrameEntry *Entry = 0;
if (IsCIE) {
// Note: this is specifically DWARFv3 CIE header structure. It was
// changed in DWARFv4. We currently don't support reading DWARFv4
// here because LLVM itself does not emit it (and LLDB doesn't
// support it either).
uint8_t Version = Data.getU8(&Offset);
const char *Augmentation = Data.getCStr(&Offset);
uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
Entry = new CIE(Data, StartOffset, Length, Version,
StringRef(Augmentation), CodeAlignmentFactor,
DataAlignmentFactor, ReturnAddressRegister);
} else {
// FDE
uint64_t CIEPointer = Id;
uint64_t InitialLocation = Data.getAddress(&Offset);
uint64_t AddressRange = Data.getAddress(&Offset);
Entry = new FDE(Data, StartOffset, Length, CIEPointer,
InitialLocation, AddressRange);
}
assert(Entry && "Expected Entry to be populated with CIE or FDE");
Entry->parseInstructions(&Offset, EndStructureOffset);
if (Offset == EndStructureOffset) {
// Entry instrucitons parsed successfully.
Entries.push_back(Entry);
} else {
std::string Str;
raw_string_ostream OS(Str);
OS << format("Parsing entry instructions at %lx failed",
Entry->getOffset());
report_fatal_error(Str);
}
}
}