Main function for marking all pointers in a program
| 433 | |
| 434 | // Main function for marking all pointers in a program |
| 435 | void MarkUsedBlocks() |
| 436 | { |
| 437 | GC_DEBUG_PRINT("Unmanageable range: %p-%p\r\n", GC::unmanageableBase, GC::unmanageableTop); |
| 438 | |
| 439 | // Get information about programs' functions, variables, types and symbols (for debug output) |
| 440 | ExternFuncInfo *functions = NULLC::commonLinker->exFunctions.data; |
| 441 | ExternVarInfo *vars = NULLC::commonLinker->exVariables.data; |
| 442 | ExternTypeInfo *types = NULLC::commonLinker->exTypes.data; |
| 443 | char *symbols = NULLC::commonLinker->exSymbols.data; |
| 444 | (void)symbols; |
| 445 | |
| 446 | GC::curr = &GC::rootsA; |
| 447 | GC::next = &GC::rootsB; |
| 448 | GC::curr->clear(); |
| 449 | GC::next->clear(); |
| 450 | |
| 451 | // Mark global variables |
| 452 | for(unsigned int i = 0; i < NULLC::commonLinker->exVariables.size(); i++) |
| 453 | { |
| 454 | GC_DEBUG_PRINT("Global %s %s (with offset of %d)\r\n", symbols + types[vars[i].type].offsetToName, symbols + vars[i].offsetToName, vars[i].offset); |
| 455 | GC::CheckVariable(GC::unmanageableBase + vars[i].offset, types[vars[i].type]); |
| 456 | } |
| 457 | |
| 458 | // To check every stack frame, we have to get it first. But we have two different executors, so flow alternates depending on which executor we are running |
| 459 | void *unknownExec = NULL; |
| 460 | unsigned int execID = nullcGetCurrentExecutor(&unknownExec); |
| 461 | |
| 462 | // Starting stack offset is equal to global variable size |
| 463 | int offset = NULLC::commonLinker->globalVarSize; |
| 464 | |
| 465 | // Init stack trace |
| 466 | if(execID == NULLC_VM) |
| 467 | { |
| 468 | Executor *exec = (Executor*)unknownExec; |
| 469 | exec->BeginCallStack(); |
| 470 | }else{ |
| 471 | #ifdef NULLC_BUILD_X86_JIT |
| 472 | ExecutorX86 *exec = (ExecutorX86*)unknownExec; |
| 473 | exec->BeginCallStack(); |
| 474 | #endif |
| 475 | } |
| 476 | // Mark local variables |
| 477 | while(true) |
| 478 | { |
| 479 | int address = 0; |
| 480 | // Get next address from call stack |
| 481 | if(execID == NULLC_VM) |
| 482 | { |
| 483 | Executor *exec = (Executor*)unknownExec; |
| 484 | address = exec->GetNextAddress(); |
| 485 | }else{ |
| 486 | #ifdef NULLC_BUILD_X86_JIT |
| 487 | ExecutorX86 *exec = (ExecutorX86*)unknownExec; |
| 488 | address = exec->GetNextAddress(); |
| 489 | #endif |
| 490 | } |
| 491 | // If failed, exit |
| 492 | if(address == 0) |
no test coverage detected