Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}