| 2734 | #endif |
| 2735 | |
| 2736 | void BFGC::MarkFromGCThread(bf::System::Object* obj) |
| 2737 | { |
| 2738 | if (obj == NULL) |
| 2739 | return; |
| 2740 | |
| 2741 | //BP_ZONE("MarkFromGCThread"); |
| 2742 | |
| 2743 | void* addr = obj; |
| 2744 | if ((addr < tcmalloc_obj::PageHeap::sAddressStart) || (addr >= tcmalloc_obj::PageHeap::sAddressEnd)) |
| 2745 | return; |
| 2746 | |
| 2747 | tcmalloc_obj::Span* span = TCGetSpanAt(obj); |
| 2748 | if (span == NULL) |
| 2749 | return; |
| 2750 | if (span->location != tcmalloc_obj::Span::IN_USE) |
| 2751 | return; |
| 2752 | |
| 2753 | intptr pageSize = (intptr) 1 << kPageShift; |
| 2754 | intptr spanSize = pageSize * span->length; |
| 2755 | void* spanStart = (void*)((intptr)span->start << kPageShift); |
| 2756 | void* spanEnd = (void*)((intptr)spanStart + spanSize); |
| 2757 | |
| 2758 | if ((addr < spanStart) || (addr > (uint8*)spanEnd - sizeof(bf::System::Object))) |
| 2759 | return; |
| 2760 | |
| 2761 | // Is it already marked? Ignore. |
| 2762 | if ((obj->mObjectFlags & BF_OBJECTFLAG_MARK_ID_MASK) == mCurMarkId) |
| 2763 | return; |
| 2764 | // Don't do any processing of non-allocated objects (like string literals), or append allocs |
| 2765 | if ((obj->mObjectFlags & BF_OBJECTFLAG_ALLOCATED) == 0) |
| 2766 | return; |
| 2767 | if (obj->mAllocCheckPtr == 0) // It IS in the heap but not allocated |
| 2768 | return; |
| 2769 | |
| 2770 | bool curIsDeleted = false; |
| 2771 | if (mMarkingDeleted) |
| 2772 | { |
| 2773 | if ((obj->mObjectFlags & BF_OBJECTFLAG_DELETED) == 0) |
| 2774 | { |
| 2775 | // Don't allow a deleted object to mark a non-deleted object- |
| 2776 | // That should be handled as a LEAK if there aren't any non-deleted objects referencing it |
| 2777 | return; |
| 2778 | } |
| 2779 | } |
| 2780 | |
| 2781 | intptr elementSize = Static::sizemap()->ByteSizeForClass(span->sizeclass); |
| 2782 | // Large alloc |
| 2783 | if (elementSize == 0) |
| 2784 | { |
| 2785 | if (obj != (bf::System::Object*)spanStart) |
| 2786 | return; |
| 2787 | } |
| 2788 | else |
| 2789 | { |
| 2790 | void* maskedAddr = addr; |
| 2791 | maskedAddr = (uint8*)spanStart + (((uint8*)maskedAddr - (uint8*)spanStart) / elementSize * elementSize); |
| 2792 | if (obj != (bf::System::Object*)maskedAddr) |
| 2793 | return; |
no test coverage detected