Function that marks memory blocks belonging to GC
| 219 | |
| 220 | // Function that marks memory blocks belonging to GC |
| 221 | void MarkPointer(char* ptr, const ExternTypeInfo& type, bool takeSubtype) |
| 222 | { |
| 223 | // We have pointer to stack that has a pointer inside, so 'ptr' is really a pointer to pointer |
| 224 | char **rPtr = (char**)ptr; |
| 225 | // Check for unmanageable ranges. Range of 0x00000000-0x00010000 is unmanageable by default due to upvalues with offsets inside closures. |
| 226 | if(*rPtr > (char*)0x00010000 && (*rPtr < unmanageableBase || *rPtr > unmanageableTop)) |
| 227 | { |
| 228 | // Get type that pointer points to |
| 229 | GC_DEBUG_PRINT("\tGlobal pointer %s %p (at %p)\r\n", NULLC::commonLinker->exSymbols.data + type.offsetToName, *rPtr, ptr); |
| 230 | |
| 231 | // Get pointer to the start of memory block. Some pointers may point to the middle of memory blocks |
| 232 | unsigned int *basePtr = (unsigned int*)NULLC::GetBasePointer(*rPtr); |
| 233 | // If there is no base, this pointer points to memory that is not GCs memory |
| 234 | if(!basePtr) |
| 235 | return; |
| 236 | GC_DEBUG_PRINT("\tPointer base is %p\r\n", basePtr); |
| 237 | |
| 238 | // Marker is before the block |
| 239 | markerType *marker = (markerType*)((char*)basePtr - sizeof(markerType)); |
| 240 | GC_DEBUG_PRINT("\tMarker is %d\r\n", *marker); |
| 241 | |
| 242 | // If block is unmarked |
| 243 | if(!(*marker & 1)) |
| 244 | { |
| 245 | // Mark block as used |
| 246 | *marker |= 1; |
| 247 | // And if type is not simple, check memory to which pointer points to |
| 248 | if(type.subCat != ExternTypeInfo::CAT_NONE) |
| 249 | next->push_back(RootInfo(*rPtr, takeSubtype ? &NULLC::commonLinker->exTypes[type.subType] : &type)); |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | // Function that checks arrays for pointers |
| 255 | void CheckArray(char* ptr, const ExternTypeInfo& type) |
no test coverage detected