本文整理汇总了C++中PolyWord::AsCodePtr方法的典型用法代码示例。如果您正苦于以下问题:C++ PolyWord::AsCodePtr方法的具体用法?C++ PolyWord::AsCodePtr怎么用?C++ PolyWord::AsCodePtr使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PolyWord
的用法示例。
在下文中一共展示了PolyWord::AsCodePtr方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ScanStackAddress
// Process a value within the stack.
PolyWord ScanAddress::ScanStackAddress(PolyWord val, StackSpace *stack, bool isCode)
{
PolyWord *base = stack->bottom;
PolyWord *end = stack->top;
// If isCode is set we definitely have a code address. It may have the
// bottom bit set or it may be word aligned.
if (isCode || val.IsCodePtr())
{
/* Find the start of the code segment */
PolyObject *oldObject = ObjCodePtrToPtr(val.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = val.AsCodePtr() - (byte*)oldObject;
PolyObject *newObject = ScanObjectAddress(oldObject);
return PolyWord::FromCodePtr((byte*)newObject + offset);
}
else if (val.IsTagged() || val == PolyWord::FromUnsigned(0) ||
(val.AsAddress() > base && val.AsAddress() <= end))
/* We don't need to process tagged integers (now we've checked it isn't
a code address) and we don't need to process addresses within the
current stack. */
/* N.B. We have "<= end" rather than "< end" because it is possible for
the stack to be completely empty on a terminated thread. */
return val;
else
{
ASSERT(val.IsDataPtr());
return ScanObjectAddress(val.AsObjPtr());
}
}
示例2: GetNewAddress
// Returns the new address if the argument is the address of an object that
// has moved, otherwise returns the original.
PolyWord SaveFixupAddress::GetNewAddress(PolyWord old)
{
if (old.IsTagged() || old == PolyWord::FromUnsigned(0) || gMem.IsIOPointer(old.AsAddress()))
return old; // Nothing to do.
// When we are updating addresses in the stack or in code segments we may have
// code pointers.
if (old.IsCodePtr())
{
// Find the start of the code segment
PolyObject *oldObject = ObjCodePtrToPtr(old.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = old.AsCodePtr() - (byte*)oldObject;
PolyWord newObject = GetNewAddress(oldObject);
return PolyWord::FromCodePtr(newObject.AsCodePtr() + offset);
}
ASSERT(old.IsDataPtr());
PolyObject *obj = old.AsObjPtr();
if (obj->ContainsForwardingPtr()) // tombstone is a pointer to a moved object
{
PolyObject *newp = obj->GetForwardingPtr();
ASSERT (newp->ContainsNormalLengthWord());
return newp;
}
ASSERT (obj->ContainsNormalLengthWord()); // object is not moved
return old;
}
示例3: ScanAddressAt
// Process the value at a given location and update it as necessary.
POLYUNSIGNED ScanAddress::ScanAddressAt(PolyWord *pt)
{
PolyWord val = *pt;
PolyWord newVal = val;
if (IS_INT(val) || val == PolyWord::FromUnsigned(0))
{
// We can get zeros in the constant area if we garbage collect
// while compiling some code. */
}
else if (val.IsCodePtr())
{
// We can get code pointers either in the stack as return addresses or
// handler pointers or in constants in code segments as the addresses of
// exception handlers.
// Find the start of the code segment
PolyObject *oldObject = ObjCodePtrToPtr(val.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = val.AsCodePtr() - (byte*)oldObject;
// Mustn't use ScanAddressAt here. That's only valid if the value points
// into the area being updated.
PolyObject *newObject = ScanObjectAddress(oldObject);
newVal = PolyWord::FromCodePtr((byte*)newObject + offset);
}
else
{
ASSERT(OBJ_IS_DATAPTR(val));
// Database pointer, local pointer or IO pointer.
// We need to include IO area pointers when we produce an object module.
newVal = ScanObjectAddress(val.AsObjPtr());
}
if (newVal != val) // Only update if we need to.
*pt = newVal;
return 0;
}
示例4: SetConstantValue
// Store a constant value. Also used with a patch table when importing a saved heap which has
// been exported using the C exporter.
void ScanAddress::SetConstantValue(byte *addressOfConstant, PolyWord p, ScanRelocationKind code)
{
switch (code)
{
case PROCESS_RELOC_DIRECT: // 32 or 64 bit address of target
{
POLYUNSIGNED valu = p.AsUnsigned();
for (unsigned i = 0; i < sizeof(PolyWord); i++)
{
addressOfConstant[i] = (byte)(valu & 255);
valu >>= 8;
}
}
break;
case PROCESS_RELOC_I386RELATIVE: // 32 bit relative address
{
POLYSIGNED newDisp = p.AsCodePtr() - addressOfConstant - 4;
#if (SIZEOF_VOIDP != 4)
ASSERT(newDisp < 0x80000000 && newDisp >= -(POLYSIGNED)0x80000000);
#endif
for (unsigned i = 0; i < 4; i++) {
addressOfConstant[i] = (byte)(newDisp & 0xff);
newDisp >>= 8;
}
}
break;
}
}
示例5: printValue
void PExport::printValue(PolyWord q)
{
if (IS_INT(q) || q == PolyWord::FromUnsigned(0))
fprintf(exportFile, "%" POLYSFMT, UNTAGGED(q));
else if (OBJ_IS_CODEPTR(q))
printCodeAddr(q.AsCodePtr());
else
printAddress(q.AsAddress());
}
示例6: GetValue
bool PImport::GetValue(PolyWord *result)
{
int ch = getc(f);
if (ch == '@')
{
/* Address of an object. */
POLYUNSIGNED obj;
fscanf(f, "%" POLYUFMT, &obj);
ASSERT(obj < nObjects);
*result = objMap[obj];
}
else if (ch == '$')
{
/* Code address. */
POLYUNSIGNED obj, offset;
fscanf(f, "%" POLYUFMT "+%" POLYUFMT, &obj, &offset);
ASSERT(obj < nObjects);
PolyObject *q = objMap[obj];
ASSERT(q->IsCodeObject());
*result = PolyWord::FromCodePtr((PolyWord(q)).AsCodePtr() + offset); /* The offset is in bytes. */
}
else if ((ch >= '0' && ch <= '9') || ch == '-')
{
/* Tagged integer. */
POLYSIGNED j;
ungetc(ch, f);
fscanf(f, "%" POLYSFMT, &j);
/* The assertion may be false if we are porting to a machine
with a shorter tagged representation. */
ASSERT(j >= -MAXTAGGED-1 && j <= MAXTAGGED);
*result = TAGGED(j);
}
else if (ch == 'I')
{
/* IO entry number. */
POLYUNSIGNED j;
fscanf(f, "%" POLYUFMT, &j);
ASSERT(j < POLY_SYS_vecsize);
*result = (PolyObject*)&gMem.ioSpace->bottom[j * IO_SPACING];
}
else if (ch == 'J')
{
/* IO entry number with offset. */
POLYUNSIGNED j, offset;
fscanf(f, "%" POLYUFMT "+%" POLYUFMT, &j, &offset);
ASSERT(j < POLY_SYS_vecsize);
PolyWord base = (PolyObject*)&gMem.ioSpace->bottom[j * IO_SPACING];
*result = PolyWord::FromCodePtr(base.AsCodePtr() + offset);
}
else
{
fprintf(stderr, "Unexpected character in stream");
return false;
}
return true;
}
示例7: GetNewAddress
// Returns the new address if the argument is the address of an object that
// has moved, otherwise returns the original.
PolyWord ProcessFixupAddress::GetNewAddress(PolyWord old)
{
if (old.IsTagged() || old == PolyWord::FromUnsigned(0) || gMem.IsIOPointer(old.AsAddress()))
return old; // Nothing to do.
// When we are updating addresses in the stack or in code segments we may have
// code pointers.
if (old.IsCodePtr())
{
// Find the start of the code segment
PolyObject *oldObject = ObjCodePtrToPtr(old.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = old.AsCodePtr() - (byte*)oldObject;
PolyWord newObject = GetNewAddress(oldObject);
return PolyWord::FromCodePtr(newObject.AsCodePtr() + offset);
}
ASSERT(old.IsDataPtr());
PolyObject *obj = old.AsObjPtr();
POLYUNSIGNED L = obj->LengthWord();
// Generally each address will point to an object processed at a lower depth.
// The exception is if we have a cycle and have assigned the rest of the
// structure to a higher depth.
// N.B. We return the original address here but this could actually share
// with something else and not be retained.
if (OBJ_IS_DEPTH(L))
return old;
if (obj->ContainsForwardingPtr()) // tombstone is a pointer to a shared object
{
PolyObject *newp = obj->GetForwardingPtr();
// ASSERT (newp->ContainsNormalLengthWord());
return newp;
}
ASSERT (obj->ContainsNormalLengthWord()); // object is not shared
return old;
}
示例8: ScanAddressesInObject
// This is called via ScanAddressesInRegion to process the permanent mutables. It is
// also called from ScanObjectAddress to process root addresses.
// It processes all the addresses reachable from the object.
void RecursiveScan::ScanAddressesInObject(PolyObject *obj, POLYUNSIGNED lengthWord)
{
if (OBJ_IS_BYTE_OBJECT(lengthWord))
{
Completed(obj);
return;
}
while (true)
{
ASSERT (OBJ_IS_LENGTH(lengthWord));
// Get the length and base address. N.B. If this is a code segment
// these will be side-effected by GetConstSegmentForCode.
POLYUNSIGNED length = OBJ_OBJECT_LENGTH(lengthWord);
PolyWord *baseAddr = (PolyWord*)obj;
if (OBJ_IS_CODE_OBJECT(lengthWord))
{
// It's better to process the whole code object in one go.
ScanAddress::ScanAddressesInObject(obj, lengthWord);
length = 0; // Finished
}
ASSERT(! OBJ_IS_BYTE_OBJECT(lengthWord)); // Check - remove this later
// else it's a normal object,
// If there are only two addresses in this cell that need to be
// followed we follow them immediately and treat this cell as done.
// If there are more than two we push the address of this cell on
// the stack, follow the first address and then rescan it. That way
// list cells are processed once only but we don't overflow the
// stack by pushing all the addresses in a very large vector.
PolyWord *endWord = baseAddr + length;
PolyObject *firstWord = 0;
PolyObject *secondWord = 0;
while (baseAddr != endWord)
{
PolyWord wordAt = *baseAddr;
if (wordAt.IsDataPtr() && wordAt != PolyWord::FromUnsigned(0))
{
// Normal address. We can have words of all zeros at least in the
// situation where we have a partially constructed code segment where
// the constants at the end of the code have not yet been filled in.
if (TestForScan(baseAddr)) // Test value at baseAddr (may side-effect it)
{
PolyObject *wObj = (*baseAddr).AsObjPtr();
if (wObj->IsByteObject())
{
// Can do this now - don't need to push it
MarkAsScanning(wObj);
Completed(wObj);
}
else if (firstWord == 0)
{
firstWord = wObj;
// We mark the word immediately. We can have
// two words in an object that are the same
// and we don't want to process it again.
MarkAsScanning(firstWord);
}
else if (secondWord == 0)
secondWord = wObj;
else break; // More than two words.
}
}
else if (wordAt.IsCodePtr())
{
// If we're processing the constant area of a code segment this could
// be a code address.
PolyObject *oldObject = ObjCodePtrToPtr(wordAt.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = wordAt.AsCodePtr() - (byte*)oldObject;
wordAt = oldObject;
bool test = TestForScan(&wordAt);
// TestForScan may side-effect the word.
PolyObject *newObject = wordAt.AsObjPtr();
wordAt = PolyWord::FromCodePtr((byte*)newObject + offset);
if (wordAt != *baseAddr)
*baseAddr = wordAt;
if (test)
{
if (firstWord == 0)
{
firstWord = newObject;
MarkAsScanning(firstWord);
}
else if (secondWord == 0)
secondWord = newObject;
else break;
}
}
baseAddr++;
}
//.........这里部分代码省略.........
示例9: ScanAddressesInObject
// This is called via ScanAddressesInRegion to process the permanent mutables. It is
// also called from ScanObjectAddress to process root addresses.
// It processes all the addresses reachable from the object.
void MTGCProcessMarkPointers::ScanAddressesInObject(PolyObject *obj, POLYUNSIGNED lengthWord)
{
if (OBJ_IS_BYTE_OBJECT(lengthWord))
return;
while (true)
{
ASSERT (OBJ_IS_LENGTH(lengthWord));
// Get the length and base address. N.B. If this is a code segment
// these will be side-effected by GetConstSegmentForCode.
POLYUNSIGNED length = OBJ_OBJECT_LENGTH(lengthWord);
if (OBJ_IS_WEAKREF_OBJECT(lengthWord))
{
// Special case.
ASSERT(OBJ_IS_MUTABLE_OBJECT(lengthWord)); // Should be a mutable.
ASSERT(OBJ_IS_WORD_OBJECT(lengthWord)); // Should be a plain object.
// We need to mark the "SOME" values in this object but we don't mark
// the references contained within the "SOME".
PolyWord *baseAddr = (PolyWord*)obj;
// Mark every word but ignore the result.
for (POLYUNSIGNED i = 0; i < length; i++)
(void)MarkAndTestForScan(baseAddr+i);
// We've finished with this.
length = 0;
}
else if (OBJ_IS_CODE_OBJECT(lengthWord))
{
// It's better to process the whole code object in one go.
ScanAddress::ScanAddressesInObject(obj, lengthWord);
length = 0; // Finished
}
// else it's a normal object,
// If there are only two addresses in this cell that need to be
// followed we follow them immediately and treat this cell as done.
// If there are more than two we push the address of this cell on
// the stack, follow the first address and then rescan it. That way
// list cells are processed once only but we don't overflow the
// stack by pushing all the addresses in a very large vector.
PolyWord *baseAddr = (PolyWord*)obj;
PolyWord *endWord = baseAddr + length;
PolyObject *firstWord = 0;
PolyObject *secondWord = 0;
PolyWord *restartAddr = 0;
if (obj == largeObjectCache[locPtr].base)
{
baseAddr = largeObjectCache[locPtr].current;
ASSERT(baseAddr > (PolyWord*)obj && baseAddr < ((PolyWord*)obj)+length);
if (locPtr == 0) locPtr = LARGECACHE_SIZE-1; else locPtr--;
}
while (baseAddr != endWord)
{
PolyWord wordAt = *baseAddr;
if (wordAt.IsDataPtr() && wordAt != PolyWord::FromUnsigned(0))
{
// Normal address. We can have words of all zeros at least in the
// situation where we have a partially constructed code segment where
// the constants at the end of the code have not yet been filled in.
if (TestForScan(baseAddr))
{
if (firstWord == 0)
firstWord = baseAddr->AsObjPtr();
else if (secondWord == 0)
{
// If we need to rescan because there are three or more words to do
// this is the place we need to restart (or the start of the cell if it's
// small).
restartAddr = baseAddr;
secondWord = baseAddr->AsObjPtr();
}
else break; // More than two words.
}
}
else if (wordAt.IsCodePtr())
{
// If we're processing the constant area of a code segment this could
// be a code address.
// Check that this is actually an address. If we have had a bad pointer
// earlier we may treat some length fields as values.
ASSERT(gMem.SpaceForAddress(wordAt.AsCodePtr()) != 0);
PolyObject *oldObject = ObjCodePtrToPtr(wordAt.AsCodePtr());
// Calculate the byte offset of this value within the code object.
POLYUNSIGNED offset = wordAt.AsCodePtr() - (byte*)oldObject;
wordAt = oldObject;
bool test = TestForScan(&wordAt);
// If we've changed it because we had a left-over forwarding pointer
// we need to update the original.
PolyObject *newObject = wordAt.AsObjPtr();
wordAt = PolyWord::FromCodePtr((byte*)newObject + offset);
if (wordAt != *baseAddr)
//.........这里部分代码省略.........