uintptr_t WINAPI MemoryManager::CheckPdaRoots(void* arg) { #ifndef _GC_SERIAL EnterCriticalSection(&pda_frame_cs); #endif #ifdef _DEBUG wcout << L"----- PDA frames(s): num=" << pda_frames.size() << L"; thread=" << GetCurrentThread()<< L" -----" << endl; wcout << L"memory types:" << endl; #endif set<StackFrame**, StackFrame**>::iterator iter; for(iter = pda_frames.begin(); iter != pda_frames.end(); ++iter) { StackFrame** frame = *iter; StackMethod* mthd = (*frame)->method; long* mem = (*frame)->mem; #ifdef _DEBUG wcout << L"\t===== PDA method: name=" << mthd->GetName() << L", addr=" << mthd << L", num=" << mthd->GetNumberDeclarations() << L" =====" << endl; #endif // mark self CheckObject((long*)(*mem), true, 1); if(mthd->HasAndOr()) { mem += 2; } else { mem++; } // mark rest of memory CheckMemory(mem, mthd->GetDeclarations(), mthd->GetNumberDeclarations(), 0); } #ifndef _GC_SERIAL LeaveCriticalSection(&pda_frame_cs); #endif #ifndef GC_SERIAL EnterCriticalSection(&pda_monitor_cs); #endif #ifdef _DEBUG wcout << L"----- PDA method root(s): num=" << pda_monitors.size() << L"; thread=" << GetCurrentThread()<< L" -----" << endl; wcout << L"memory types:" << endl; #endif // look at pda methods unordered_map<StackFrameMonitor*, StackFrameMonitor*>::iterator pda_iter; for(pda_iter = pda_monitors.begin(); pda_iter != pda_monitors.end(); ++pda_iter) { // gather stack frames StackFrameMonitor* monitor = pda_iter->first; long call_stack_pos = *(monitor->call_stack_pos); if (call_stack_pos > 0) { StackFrame** call_stack = monitor->call_stack; StackFrame* cur_frame = *(monitor->cur_frame); // copy frames locally vector<StackFrame*> frames; frames.push_back(cur_frame); while (--call_stack_pos > -1) { frames.push_back(call_stack[call_stack_pos]); } for (size_t i = 0; i < frames.size(); ++i) { StackMethod* mthd = frames[i]->method; long* mem = frames[i]->mem; #ifdef _DEBUG wcout << L"\t===== PDA method: name=" << mthd->GetName() << L", addr=" << mthd << L", num=" << mthd->GetNumberDeclarations() << L" =====" << endl; #endif // mark self CheckObject((long*)(*mem), true, 1); if (mthd->HasAndOr()) { mem += 2; } else { mem++; } // mark rest of memory CheckMemory(mem, mthd->GetDeclarations(), mthd->GetNumberDeclarations(), 0); } } } #ifndef GC_SERIAL LeaveCriticalSection(&pda_monitor_cs); #endif return 0; }
int main(const int argc, const char* argv[]) { const char* prgm_path = FCGX_GetParam("PROGRAM_PATH", environ); if(!prgm_path) { cerr << "Unable to find program, please ensure the 'PROGRAM_PATH' variable has been set correctly." << endl; exit(1); } // load program srand(time(NULL)); rand(); Loader loader(prgm_path); loader.Load(); // ignore web applications if(!loader.IsWeb()) { cerr << "Please recompile the code to be a web application." << endl; exit(1); } #ifdef _TIMING clock_t start = clock(); #endif // locate starting class and method StackMethod* mthd = loader.GetStartMethod(); if(!mthd) { cerr << "Unable to locate the 'Request(args)' function." << endl; exit(1); } #ifdef _DEBUG cerr << "### Loaded method: " << mthd->GetName() << " ###" << endl; #endif Runtime::StackInterpreter intpr(Loader::GetProgram()); // go into accept loop... FCGX_Stream*in; FCGX_Stream* out; FCGX_Stream* err; FCGX_ParamArray envp; while(mthd && (FCGX_Accept(&in, &out, &err, &envp) >= 0)) { // execute method long* op_stack = new long[CALC_STACK_SIZE]; long* stack_pos = new long; // create request long* req_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Request", op_stack, *stack_pos, false); if(req_obj) { req_obj[0] = (long)in; req_obj[1] = (long)envp; // create response long* res_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Response", op_stack, *stack_pos, false); if(res_obj) { res_obj[0] = (long)out; res_obj[1] = (long)err; // set calling parameters op_stack[0] = (long)req_obj; op_stack[1] = (long)res_obj; *stack_pos = 2; // execute method intpr.Execute((long*)op_stack, (long*)stack_pos, 0, mthd, NULL, false); } else { cerr << ">>> DLL call: Unable to allocate object FastCgi.Response <<" << endl; // TODO: error return 1; } } else { cerr << ">>> DLL call: Unable to allocate object FastCgi.Request <<<" << endl; // TODO: error return 1; } #ifdef _DEBUG cout << "# final stack: pos=" << (*stack_pos) << " #" << endl; if((*stack_pos) > 0) { for(int i = 0; i < (*stack_pos); i++) { cout << "dump: value=" << (void*)(*stack_pos) << endl; } } #endif // clean up delete[] op_stack; op_stack = NULL; delete stack_pos; stack_pos = NULL; #ifdef _DEBUG PrintEnv(out, "Request environment", envp); PrintEnv(out, "Initial environment", environ); #endif } return 0; }
uintptr_t WINAPI MemoryManager::CheckJitRoots(void* arg) { #ifndef GC_SERIAL EnterCriticalSection(&jit_cs); #endif #ifdef _DEBUG wcout << L"---- Marking JIT method root(s): num=" << jit_roots.size() << L"; thread=" << GetCurrentThread() << L" ------" << endl; wcout << L"memory types: " << endl; #endif unordered_map<long*, ClassMethodId*>::iterator jit_iter; for(jit_iter = jit_roots.begin(); jit_iter != jit_roots.end(); ++jit_iter) { ClassMethodId* id = jit_iter->second; long* mem = id->mem; StackMethod* mthd = prgm->GetClass(id->cls_id)->GetMethod(id->mthd_id); const long dclrs_num = mthd->GetNumberDeclarations(); #ifdef _DEBUG wcout << L"\t===== JIT method: name=" << mthd->GetName() << L", id=" << id->cls_id << L"," << id->mthd_id << L"; addr=" << mthd << L"; num=" << mthd->GetNumberDeclarations() << L" =====" << endl; #endif // check self CheckObject(id->self, true, 1); StackDclr** dclrs = mthd->GetDeclarations(); for(int j = dclrs_num - 1; j > -1; j--) { // update address based upon type switch(dclrs[j]->type) { case FUNC_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": FUNC_PARM: value=" << (*mem) << L"," << *(mem + 1) << endl; #endif // update mem += 2; break; case CHAR_PARM: case INT_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": CHAR_PARM/INT_PARM: value=" << (*mem) << endl; #endif // update mem++; break; case FLOAT_PARM: { #ifdef _DEBUG FLOAT_VALUE value; memcpy(&value, mem, sizeof(FLOAT_VALUE)); wcout << L"\t" << j << L": FLOAT_PARM: value=" << value << endl; #endif // update mem += 2; } break; case BYTE_ARY_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": BYTE_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << L" byte(s)" << endl; #endif // mark data MarkMemory((long*)(*mem)); // update mem++; break; case CHAR_ARY_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": CHAR_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << L" byte(s)" << endl; #endif // mark data MarkMemory((long*)(*mem)); // update mem++; break; case INT_ARY_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": INT_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << L" byte(s)" << endl; #endif // mark data MarkMemory((long*)(*mem)); // update mem++; break; case FLOAT_ARY_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": FLOAT_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), size=" << L" byte(s)" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << endl; #endif // mark data MarkMemory((long*)(*mem)); // update mem++; break; case OBJ_PARM: { #ifdef _DEBUG wcout << L"\t" << j << L": OBJ_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), id="; if(*mem) { StackClass* tmp = (StackClass*)((long*)(*mem))[SIZE_OR_CLS]; wcout << L"'" << tmp->GetName() << L"'" << endl; } else { wcout << L"Unknown" << endl; } #endif // check object CheckObject((long*)(*mem), true, 1); // update mem++; } break; // TODO: test the code below case OBJ_ARY_PARM: #ifdef _DEBUG wcout << L"\t" << j << L": OBJ_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << L" byte(s)" << endl; #endif // mark data if(MarkValidMemory((long*)(*mem))) { long* array = (long*)(*mem); const long size = array[0]; const long dim = array[1]; long* objects = (long*)(array + 2 + dim); for(long k = 0; k < size; k++) { CheckObject((long*)objects[k], true, 2); } } // update mem++; break; default: break; } } // NOTE: this marks temporary variables that are stored in JIT memory // during some method calls. there are 3 integer temp addresses for(int i = 0; i < 8; i++) { CheckObject((long*)mem[i], false, 1); } } #ifndef GC_SERIAL LeaveCriticalSection(&jit_cs); #endif return 0; }