本文整理汇总了C++中PolyWord::IsCodePtr方法的典型用法代码示例。如果您正苦于以下问题:C++ PolyWord::IsCodePtr方法的具体用法?C++ PolyWord::IsCodePtr怎么用?C++ PolyWord::IsCodePtr使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PolyWord
的用法示例。
在下文中一共展示了PolyWord::IsCodePtr方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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;
}
示例2: 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());
}
}
示例3: 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;
}
示例4: 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;
}
示例5: 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++;
}
//.........这里部分代码省略.........
示例6: 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)
//.........这里部分代码省略.........