本文整理汇总了C++中PolyWord::IsDataPtr方法的典型用法代码示例。如果您正苦于以下问题:C++ PolyWord::IsDataPtr方法的具体用法?C++ PolyWord::IsDataPtr怎么用?C++ PolyWord::IsDataPtr使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PolyWord
的用法示例。
在下文中一共展示了PolyWord::IsDataPtr方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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: TestForScan
bool GetSharing::TestForScan(PolyWord *pt)
{
PolyObject *obj;
// This may be a forwarding pointer left over from a minor GC that did
// not complete or it may be a sharing chain pointer that we've set up.
while (1)
{
PolyWord p = *pt;
ASSERT(p.IsDataPtr());
obj = p.AsObjPtr();
PolyWord *lengthWord = ((PolyWord*)obj) - 1;
LocalMemSpace *space = gMem.LocalSpaceForAddress(lengthWord);
if (space == 0)
return false; // Ignore it if it points to a permanent area
if (space->bitmap.TestBit(space->wordNo(lengthWord)))
return false;
// Wasn't marked - must be a forwarding pointer.
if (obj->ContainsForwardingPtr())
{
obj = obj->GetForwardingPtr();
*pt = obj;
}
else break;
}
ASSERT(obj->ContainsNormalLengthWord());
totalVisited += 1;
totalSize += obj->Length() + 1;
return true;
}
示例4: GarbageCollect
void ProcessEnvModule::GarbageCollect(ScanAddress *process)
/* Ensures that all the objects are retained and their addresses updated. */
{
if (at_exit_list.IsDataPtr())
{
PolyObject *obj = at_exit_list.AsObjPtr();
process->ScanRuntimeAddress(&obj, ScanAddress::STRENGTH_STRONG);
at_exit_list = obj;
}
}
示例5: DoCheckPointer
void DoCheckPointer (const PolyWord pt)
{
if (pt == PolyWord::FromUnsigned(0)) return;
if (OBJ_IS_AN_INTEGER(pt)) return;
DoCheck (pt);
if (pt.IsDataPtr())
{
PolyObject *obj = pt.AsObjPtr();
DoCheckObject (obj, obj->LengthWord());
}
}
示例6: 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;
}
示例7: ScanAddressesInObject
// Deal with weak objects
void MTGCCheckWeakRef::ScanAddressesInObject(PolyObject *obj, POLYUNSIGNED L)
{
if (! OBJ_IS_WEAKREF_OBJECT(L)) return;
ASSERT(OBJ_IS_MUTABLE_OBJECT(L)); // Should be a mutable.
ASSERT(OBJ_IS_WORD_OBJECT(L)); // Should be a plain object.
// See if any of the SOME objects contain unreferenced refs.
POLYUNSIGNED length = OBJ_OBJECT_LENGTH(L);
PolyWord *baseAddr = (PolyWord*)obj;
for (POLYUNSIGNED i = 0; i < length; i++)
{
PolyWord someAddr = baseAddr[i];
if (someAddr.IsDataPtr())
{
LocalMemSpace *someSpace = gMem.LocalSpaceForAddress(someAddr.AsAddress());
if (someSpace != 0)
{
PolyObject *someObj = someAddr.AsObjPtr();
// If this is a weak object the SOME value may refer to an unreferenced
// ref. If so we have to set this entry to NONE. For safety we also
// set the contents of the SOME to TAGGED(0).
ASSERT(someObj->Length() == 1 && someObj->IsWordObject()); // Should be a SOME node.
PolyWord refAddress = someObj->Get(0);
LocalMemSpace *space = gMem.LocalSpaceForAddress(refAddress.AsAddress());
if (space != 0)
// If the ref is permanent it's always there.
{
POLYUNSIGNED new_bitno = space->wordNo(refAddress.AsStackAddr());
if (! space->bitmap.TestBit(new_bitno))
{
// It wasn't marked so it's otherwise unreferenced.
baseAddr[i] = TAGGED(0); // Set it to NONE.
someObj->Set(0, TAGGED(0)); // For safety.
convertedWeak = true;
}
}
}
}
}
}
示例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)
//.........这里部分代码省略.........
示例10: wordDataTask
// Process one level of the word data.
// N.B. The length words are updated without any locking. This is safe
// because all length words are initially chain entries and a chain entry
// can be replaced by another chain entry, a forwarding pointer or a normal
// length word. Forwarding pointers and normal length words are only ever
// set once. There is a small chance that we could lose some sharing as a
// result of a race condition if a thread defers an object because it
// contains a pointer with a chain entry and later sees an otherwise
// equal object where another thread has replaced the chain with a
// normal address, adds it to the list for immediate processing and
// so never compares the two.
void SortVector::wordDataTask(GCTaskId*, void *a, void *)
{
SortVector *s = (SortVector*)a;
// Partition the objects between those that have pointers to objects that are
// still to be processed and those that have been processed.
if (s->baseObject.objList == ENDOFLIST)
return;
PolyObject *h = s->baseObject.objList;
s->baseObject.objList = ENDOFLIST;
s->baseObject.objCount = 0;
POLYUNSIGNED words = OBJ_OBJECT_LENGTH(s->lengthWord);
s->carryOver = 0;
for (unsigned i = 0; i < 256; i++)
{
// Clear the entries in the hash table but not the sharing count.
s->processObjects[i].objList = ENDOFLIST;
s->processObjects[i].objCount = 0;
}
while (h != ENDOFLIST)
{
PolyObject *next = h->GetForwardingPtr();
bool deferred = false;
for (POLYUNSIGNED i = 0; i < words; i++)
{
PolyWord w = h->Get(i);
if (w.IsDataPtr())
{
PolyObject *p = w.AsObjPtr();
objectState state = getObjectState(p);
if (state == FORWARDED)
{
// Update the addresses of objects that have been merged
h->Set(i, p->GetForwardingPtr());
s->carryOver++;
break;
}
else if (state == CHAINED)
{
// If it is still to be shared leave it
deferred = true;
break; // from the loop
}
}
}
if (deferred)
{
// We can't do it yet: add it back to the list
h->SetForwardingPtr(s->baseObject.objList);
s->baseObject.objList = h;
s->baseObject.objCount++;
}
else
{
// Add it to the hash table.
unsigned char hash = 0;
for (POLYUNSIGNED i = 0; i < words*sizeof(PolyWord); i++)
hash += h->AsBytePtr()[i];
h->SetForwardingPtr(s->processObjects[hash].objList);
s->processObjects[hash].objList = h;
s->processObjects[hash].objCount++;
}
h = next;
}
s->SortData();
}