00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_process.cpp.incl"
00026 
00027 
00028 
00029 extern "C" char*  C_frame_return_addr;
00030 extern "C" bool have_nlr_through_C;
00031 extern "C" int  nlr_home;
00032 extern "C" int  nlr_home_id;
00033 extern "C" oop  nlr_result;
00034 
00035 unwindInfo::unwindInfo() {
00036    assert(have_nlr_through_C, "you must have have_nlr_through_C before using unwindInfo");
00037 
00038    
00039    _nlr_home    = ::nlr_home;
00040    _nlr_home_id = ::nlr_home_id;
00041    _nlr_result  = ::nlr_result;
00042 
00043    
00044    assert(last_Delta_fp, "last_Delta_fp must be set");
00045    saved_C_frame_return_addr          = C_frame_return_addr;
00046    saved_C_frame_return_addr_location = (char**) (last_Delta_sp - 1);
00047    saved_patch_return_address         = *saved_C_frame_return_addr_location;
00048 
00049    
00050    *saved_C_frame_return_addr_location = saved_C_frame_return_addr;
00051 
00052    _is_compiled = _nlr_home_id >= 0;
00053    DeltaProcess::active()->push_unwind(this);
00054 }
00055 
00056 unwindInfo::~unwindInfo() {
00057   
00058   
00059   if (::nlr_home != 0) {
00060     
00061     ::nlr_home    = _nlr_home;
00062     ::nlr_home_id = _nlr_home_id;
00063     ::nlr_result  = _nlr_result;
00064   }
00065   
00066   *saved_C_frame_return_addr_location = saved_patch_return_address;
00067   C_frame_return_addr                 = saved_C_frame_return_addr;
00068 
00069   DeltaProcess::active()->pop_unwind();
00070 }
00071 
00072 void unwindInfo::update_nlr_targets(compiledVFrame* f, contextOop con) {
00073   
00074   
00075   
00076   if (f->fr().fp() == (int*) nlr_home() && f->scope()->offset() == nlr_home_id()) {
00077     _nlr_home_context = con;
00078   }
00079 }
00080 
00081 bool processSemaphore = false;
00082 
00083 
00084 
00085 int* last_Delta_fp = NULL;
00086 oop* last_Delta_sp = NULL;
00087 
00088 
00089 int* DeltaProcess::last_Delta_fp() const { 
00090   return this == _active_delta_process ? ::last_Delta_fp : _last_Delta_fp; 
00091 }
00092 
00093 void DeltaProcess::set_last_Delta_fp(int* fp) { 
00094   if (this == _active_delta_process) {
00095     ::last_Delta_fp = fp;
00096   } else {
00097     _last_Delta_fp = fp;   
00098   }
00099 }
00100 
00101 
00102 oop* DeltaProcess::last_Delta_sp() const { 
00103   return this == _active_delta_process ? ::last_Delta_sp : _last_Delta_sp; 
00104 }
00105 
00106 void DeltaProcess::set_last_Delta_sp(oop* sp) { 
00107   if (this == _active_delta_process) {
00108     ::last_Delta_sp = sp;
00109   } else {
00110     _last_Delta_sp = sp;   
00111   }
00112 }
00113 
00114 
00115 char* DeltaProcess::last_Delta_pc() const { 
00116   return _last_Delta_pc; 
00117 }
00118 
00119 void DeltaProcess::set_last_Delta_pc(char* pc) { 
00120   _last_Delta_pc = pc;   
00121 }
00122 
00123 int CurrentHash = 23;
00124 
00125 bool Process::external_suspend_current() {
00126   if (current() == NULL) return false;
00127   os::suspend_thread(current()->_thread);
00128   return true;
00129 }
00130 
00131 void Process::external_resume_current() {
00132   os::resume_thread(current()->_thread);
00133 }
00134 
00135 void Process::basic_transfer(Process* target) {
00136   if (TraceProcessEvents) {
00137     std->print("Process: "); print();
00138     std->print(" -> "); target->print();
00139     std->cr();
00140   }
00141   os::transfer(_thread, _event, target->_thread, target->_event);
00142 }
00143 
00144 
00145 
00146 VMProcess::VMProcess() {
00147   assert(vm_process() == NULL, "we can only allocate one VMProcess");
00148 
00149   _vm_process   = this;
00150   _vm_operation = NULL;
00151 
00152   _thread    = os::starting_thread(&_thread_id);
00153   _event     = os::create_event(true);
00154 }
00155 
00156 void VMProcess::transfer_to(DeltaProcess* target) {
00157   {
00158     ThreadCritical tc;
00159 
00160     
00161     ::last_Delta_fp = target->_last_Delta_fp;   
00162     ::last_Delta_sp = target->_last_Delta_sp;
00163     DeltaProcess::set_active(target);
00164     DeltaProcess::set_current(target);
00165   }
00166   basic_transfer(target);
00167 }
00168 
00169 
00170 void VMProcess::terminate(DeltaProcess* proc) {
00171   assert(Process::current()->is_vmProcess(), "can only be called from vm process");
00172   assert(proc->is_deltaProcess(),            "must be deltaProcess");
00173   assert(proc->_thread,                      "thread must be present");
00174   assert(proc->_event,                       "event must be present");
00175 
00176   os::terminate_thread(proc->_thread);
00177   proc->_thread = NULL;
00178   os::delete_event(proc->_event);
00179   proc->_event  = NULL;
00180 
00181   DeltaProcess::set_terminating_process(proc->state());
00182 }
00183 
00184 void VMProcess::activate_system() {
00185   
00186   processOop proc = processOop(Universe::find_global("Processor"));
00187   if (!proc->is_process()) {
00188     klassOop scheduler_klass = klassOop(Universe::find_global("ProcessorScheduler"));
00189     proc = processOop(scheduler_klass->klass_part()->allocateObject());
00190     associationOop assoc = Universe::find_global_association("Processor");
00191     assoc->set_value(proc);
00192   }
00193 
00194   DeltaProcess::initialize_async_dll_event();
00195 
00196   
00197   DeltaProcess::set_scheduler(new DeltaProcess(proc, oopFactory::new_symbol("start")));
00198 
00199   
00200   proc->set_process(DeltaProcess::scheduler());
00201   DeltaProcess::scheduler()->set_processObj(proc);
00202 
00203   
00204   transfer_to(DeltaProcess::scheduler());
00205 
00206   
00207   loop();
00208 }
00209 
00210 void VMProcess::loop() {
00211   while (true) {
00212     assert(vm_operation(), "A VM_Operation should be present");
00213     vm_operation()->evaluate();
00214     DeltaProcess* p = vm_operation()->calling_process();
00215     _vm_operation = NULL;
00216     if (p) {
00217       transfer_to(p);
00218     } else {
00219       transfer_to(DeltaProcess::scheduler());
00220     }
00221   }
00222 }
00223 
00224 void VMProcess::print() {
00225   std->print_cr("VMProcess");
00226 }
00227 
00228 void VMProcess::execute(VM_Operation* op) {
00229 
00230   if (Sweeper::is_running()) {
00231     
00232     
00233     fatal("VMProcess is called during sweeper run");
00234   }
00235 
00236   if (DeltaProcess::active()->in_vm_operation()) {
00237     
00238     op->evaluate();
00239   } else {
00240     op->set_calling_process(DeltaProcess::active());
00241     _vm_operation = op;
00242     
00243     DeltaProcess::active()->transfer_to_vm();
00244   }
00245 }
00246 
00247 VMProcess*    VMProcess::_vm_process   = NULL;
00248 VM_Operation* VMProcess::_vm_operation = NULL;
00249 
00250 
00251 
00252 Process*      DeltaProcess::_current_process             = NULL;
00253 DeltaProcess* DeltaProcess::_active_delta_process        = NULL;
00254 DeltaProcess* DeltaProcess::_scheduler_process           = NULL;
00255 bool          DeltaProcess::_is_idle                     = false;
00256 
00257 bool          DeltaProcess::_process_has_terminated      = false;
00258 ProcessState  DeltaProcess::_state_of_terminated_process = initialized;
00259 
00260 Event*        DeltaProcess::_async_dll_completion_event  = NULL;
00261 
00262 void DeltaProcess::transfer(ProcessState reason, DeltaProcess* target) {
00263   
00264   target->inc_time_stamp();
00265 
00266   {
00267     ThreadCritical tc;
00268 
00269     assert(this == active(), "receiver must be the active process");
00270 
00271     
00272     _last_Delta_fp = ::last_Delta_fp;   
00273     _last_Delta_sp = ::last_Delta_sp;
00274     set_state(reason);
00275 
00276     
00277     ::last_Delta_fp = target->_last_Delta_fp;   
00278     ::last_Delta_sp = target->_last_Delta_sp;
00279     set_current(target);
00280     set_active(target);
00281   }
00282 
00283   
00284   basic_transfer(target);
00285 }
00286 
00287 void DeltaProcess::suspend(ProcessState reason) {
00288   assert(!is_scheduler(), "active must be other than scheduler");
00289   assert(!in_vm_operation(), "must not be in VM operation");
00290 
00291   transfer(reason, scheduler());
00292   if (is_terminating()) 
00293     ErrorHandler::abort_current_process();
00294 }
00295 
00296 ProcessState DeltaProcess::transfer_to(DeltaProcess* destination) {
00297   assert(is_scheduler(), "active must be scheduler");
00298   assert(!in_vm_operation(), "must not be in VM operation");
00299   
00300   if (destination->state() == in_async_dll)
00301     return destination->state();
00302 
00303   transfer(yielded, destination);
00304   if (process_has_terminated()) {
00305     return state_of_terminated_process();
00306   }
00307   return destination->state();
00308 }
00309 
00310 void DeltaProcess::transfer_to_vm() {
00311   {
00312     ThreadCritical tc;
00313 
00314     assert(this == active(), "receiver must be the active process");
00315 
00316     
00317     _last_Delta_fp = ::last_Delta_fp;   
00318     _last_Delta_sp = ::last_Delta_sp;
00319     set_current(VMProcess::vm_process());
00320   }
00321   basic_transfer(VMProcess::vm_process());
00322 }
00323 
00324 void DeltaProcess::suspend_at_creation() {
00325   
00326   
00327   os::wait_for_event(_event);
00328 }
00329 
00330 void DeltaProcess::transfer_and_continue() {
00331   {
00332     ThreadCritical tc;
00333 
00334     assert(!is_scheduler(), "active must be other than scheduler");
00335     assert(!in_vm_operation(), "must not be in VM operation");
00336     assert(this == active(), "receiver must be the active process");
00337 
00338 
00339     
00340     _last_Delta_fp = ::last_Delta_fp;   
00341     _last_Delta_sp = ::last_Delta_sp;
00342     set_state(in_async_dll);
00343 
00344 
00345     
00346     ::last_Delta_fp = scheduler()->_last_Delta_fp;      
00347     ::last_Delta_sp = scheduler()->_last_Delta_sp;
00348     set_current(scheduler());
00349     set_active(scheduler());
00350 
00351     if (TraceProcessEvents) {
00352       std->print("Async call: "); print();
00353       std->print("        to: "); scheduler()->print();
00354       std->cr();
00355     }
00356   }
00357   os::transfer_and_continue(_thread, _event, scheduler()->_thread, scheduler()->_event);
00358 }
00359 
00360 bool DeltaProcess::wait_for_async_dll(int timeout_in_ms) {
00361   os::reset_event(_async_dll_completion_event);
00362   if (Processes::has_completed_async_call()) return true;
00363 
00364   if (TraceProcessEvents) {
00365     std->print("Waiting for async %d ms", timeout_in_ms);
00366   }
00367 
00368   _is_idle = true;
00369   bool result = os::wait_for_event_or_timer(_async_dll_completion_event, timeout_in_ms);
00370   _is_idle = false;
00371 
00372 
00373   if (TraceProcessEvents) {
00374     std->print_cr(result ? " {timeout}" : " {async}");
00375   }
00376 
00377   return result;
00378 }
00379 
00380 void DeltaProcess::initialize_async_dll_event() {
00381   _async_dll_completion_event = os::create_event(false);
00382 }
00383 
00384 void DeltaProcess::async_dll_call_completed() {
00385   os::signal_event(_async_dll_completion_event);
00386 }
00387 
00388 void DeltaProcess::wait_for_control() {
00389   if (TraceProcessEvents) {
00390     std->print("*");
00391   }
00392 
00393   set_state(yielded_after_async_dll);
00394   async_dll_call_completed();
00395   os::wait_for_event(_event);
00396   if (is_terminating()) 
00397     ErrorHandler::abort_current_process();
00398 }
00399 
00400 extern "C" bool have_nlr_through_C;
00401 
00402 
00403 int DeltaProcess::launch_delta(DeltaProcess* process) {
00404   
00405   process->suspend_at_creation();
00406 
00407   
00408   assert(process == DeltaProcess::active(),  "process consistency check");
00409   assert(process->is_deltaProcess(), "this should be a deltaProcess");
00410 
00411   DeltaProcess* p = (DeltaProcess*) process;
00412   oop result = Delta::call(p->receiver(), p->selector());
00413 
00414   if (have_nlr_through_C) {
00415     if (nlr_home_id == ErrorHandler::aborting_nlr_home_id()) {
00416       p->set_state(aborted);
00417     } else {
00418       p->set_state(NLR_error);
00419     }
00420   } else {
00421     p->set_state(completed);
00422   }
00423   assert(process == DeltaProcess::active(),  "process consistency check");
00424 
00425   VM_TerminateProcess op(process);
00426   VMProcess::execute(&op);
00427   return 0;
00428 }
00429 
00430 DeltaProcess::DeltaProcess(oop receiver, symbolOop selector) {
00431   _receiver    = receiver;
00432   _selector    = selector;
00433 
00434   _state       = initialized;
00435 
00436   _is_terminating = false;
00437 
00438   _event       = os::create_event(false);
00439   _thread      = os::create_thread((int (*)(void*)) &launch_delta, (void*) this, &_thread_id);
00440 
00441   _unwind_head = NULL;
00442 
00443   _time_stamp  = 0;
00444 
00445   LOG_EVENT1("creating process %#lx", this);
00446 
00447   set_last_Delta_fp(NULL);
00448   set_last_Delta_sp(NULL);
00449   set_last_Delta_pc(NULL);
00450   Processes::add(this);
00451 }
00452 
00453 frame DeltaProcess::profile_top_frame() {
00454   int*  sp;
00455   int*  fp;
00456   char* pc;
00457   os::fetch_top_frame(_thread, &sp, &fp, &pc);
00458   frame result((oop*)sp, fp, pc);
00459   return result;
00460 }
00461 
00462 
00463 DeltaProcess::~DeltaProcess() {
00464   processObj()->set_process(NULL);
00465   if (Processes::includes(this)) {
00466     Processes::remove(this);
00467   }
00468 }
00469 
00470 void DeltaProcess::print() {
00471   processObj()->print_value();
00472   std->print(" ");
00473   switch (state()) {
00474     case initialized:             std->print_cr("initialized");            break;
00475     case running:                 std->print_cr("running");                break;
00476     case yielded:                 std->print_cr("yielded");                break;
00477     case in_async_dll:            std->print_cr("in asynchronous dll all");break;
00478     case yielded_after_async_dll: std->print_cr("yielded after asynchronous dll"); break;
00479     case preempted:               std->print_cr("preempted");              break;
00480     case completed:               std->print_cr("completed");              break;
00481     case boolean_error:           std->print_cr("boolean error");          break;
00482     case lookup_error:            std->print_cr("lookup error");           break;
00483     case primitive_lookup_error:  std->print_cr("primitive lookup error"); break;
00484     case DLL_lookup_error:        std->print_cr("DLL lookup error");       break;
00485     case NLR_error:               std->print_cr("NLR error");              break;
00486     case stack_overflow:          std->print_cr("stack overflow");         break;
00487   }
00488 }
00489 
00490 void DeltaProcess::frame_iterate(FrameClosure* blk) {
00491   blk->begin_process(this);
00492   
00493   if (has_stack()) {
00494     frame v = last_frame();
00495     do {
00496       blk->do_frame(&v);
00497       v = v.sender();
00498     } while (!v.is_first_frame());
00499   }
00500 
00501   blk->end_process(this);
00502 }
00503 
00504 void DeltaProcess::oop_iterate(OopClosure* blk) {
00505   blk->do_oop((oop*) &_receiver);
00506   blk->do_oop((oop*) &_selector);
00507   blk->do_oop((oop*) &_processObj);
00508 
00509   for (unwindInfo* p = _unwind_head; p; p = p->next())
00510     blk->do_oop((oop*) &p->_nlr_result);
00511 
00512   if (has_stack()) {
00513     frame v = last_frame();
00514     do {
00515       v.oop_iterate(blk);
00516       v = v.sender();
00517     } while (!v.is_first_frame());
00518   }
00519 }
00520 
00521 symbolOop DeltaProcess::symbol_from_state(ProcessState state) {
00522   switch(state) {
00523     case initialized:             return vmSymbols::initialized();
00524     case yielded:                 return vmSymbols::yielded();
00525     case running:                 return vmSymbols::running();
00526     case stopped:                 return vmSymbols::stopped();
00527     case preempted:               return vmSymbols::preempted();
00528     case aborted:                 return vmSymbols::aborted();
00529     case in_async_dll:            return vmSymbols::in_async_dll();
00530     case yielded_after_async_dll: return vmSymbols::yielded();
00531     case completed:               return vmSymbols::completed();
00532     case boolean_error:           return vmSymbols::boolean_error();
00533     case lookup_error:            return vmSymbols::lookup_error();
00534     case primitive_lookup_error:  return vmSymbols::primitive_lookup_error();
00535     case DLL_lookup_error:        return vmSymbols::DLL_lookup_error();
00536     case float_error:             return vmSymbols::float_error();
00537     case NLR_error:               return vmSymbols::NLR_error();
00538     case stack_overflow:          return vmSymbols::stack_overflow();
00539   }
00540   return vmSymbols::not_found();
00541 }
00542 
00543 bool DeltaProcess::has_stack() const {
00544   if (state() == initialized) return false;
00545   if (state() == completed)   return false;
00546   return true;
00547 }
00548 
00549 
00550 void DeltaProcess::follow_roots() {
00551   MarkSweep::follow_root((oop*) &_receiver);
00552   MarkSweep::follow_root((oop*) &_selector);
00553   MarkSweep::follow_root((oop*) &_processObj);
00554 
00555   if (has_stack()) {
00556     frame v = last_frame();
00557     do {
00558       v.follow_roots();
00559       v = v.sender();
00560     } while (!v.is_first_frame());
00561   }
00562 }
00563 
00564 void DeltaProcess::verify() {
00565   ResourceMark rm;
00566   BlockScavenge bs;
00567 
00568   vframe* f = last_delta_vframe();
00569   if (f == NULL) return;
00570 
00571   
00572   
00573   for (f = f->sender(); f; f = f->sender()) {
00574     f->verify();
00575   }
00576 }
00577 
00578 
00579 void DeltaProcess::enter_uncommon() {
00580   assert(_state == running, "must be running");
00581   _state = uncommon;
00582 }
00583 
00584 void DeltaProcess::exit_uncommon() {
00585   assert(_state == uncommon, "must be uncommon");
00586   _state = running;
00587 }
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 static oop*        old_sp;
00599 static oop*        new_sp;
00600 static int*        old_fp;
00601 static int*        cur_fp;
00602 static objArrayOop frame_array;
00603 
00604 extern "C" oop* setup_deoptimization_and_return_new_sp(oop* old_sp, int* old_fp, objArrayOop frame_array, int* current_frame) {
00605   ResourceMark rm;
00606 
00607   
00608   ::old_sp      = old_sp;
00609   ::old_fp      = old_fp;
00610   ::frame_array = frame_array;
00611   ::cur_fp      = current_frame;
00612 
00613   smiOop number_of_vframes = smiOop(frame_array->obj_at(StackChunkBuilder::number_of_vframes_index));
00614   smiOop number_of_locals  = smiOop(frame_array->obj_at(StackChunkBuilder::number_of_locals_index));
00615 
00616   assert(number_of_vframes->is_smi(), "must be smi");
00617   assert(number_of_locals->is_smi(), "must be smi");
00618 
00619   new_sp = old_sp - frame::interpreter_stack_size(number_of_vframes->value(),
00620                                                   number_of_locals->value());
00621   return new_sp;
00622 }
00623 
00624 
00625 
00626 static bool redo_the_send;
00627 
00628 extern "C" int redo_send_offset = 0;
00629 
00630 void DeltaProcess::deoptimize_redo_last_send() {
00631   redo_the_send = true;
00632 }
00633 
00634 
00635 extern "C" void redo_bytecode_after_deoptimization();
00636 
00637 extern "C" bool       nlr_through_unpacking = false;
00638 extern "C" oop        result_through_unpacking = NULL;
00639 extern "C" int        number_of_arguments_through_unpacking = 0;
00640 extern "C" char*      C_frame_return_addr = NULL;
00641 extern "C" contextOop nlr_home_context;
00642 
00643 
00644 
00645 
00646 
00647 extern "C" void unpack_frame_array() {
00648   BlockScavenge bs;
00649   ResourceMark rm;
00650 
00651   int* pc_addr = (int*) new_sp - 1;
00652   assert(*pc_addr = -1, "just checking");
00653 
00654   if (TraceDeoptimization) {
00655     std->print("[Unpacking]");
00656     if (nlr_through_unpacking) {
00657       std->print(" NLR %s", (nlr_home == (int) cur_fp) ? "inside" : "outside");
00658     }
00659     std->cr();
00660     std->print(" - array ");
00661     frame_array->print_value();
00662     std->print_cr(" @ 0x%lx", old_fp);
00663   }
00664 
00665   bool must_find_nlr_target = nlr_through_unpacking && nlr_home == (int) cur_fp;
00666   bool nlr_target_found     = false; 
00667 
00668   
00669   int* link_addr = (int*) new_sp - 2;
00670 
00671   oop* current_sp = new_sp;
00672   int  pos        = 3;
00673   int  length     = frame_array->length();
00674   bool first = true;
00675   frame current;
00676   
00677   do {
00678     oop receiver     = frame_array->obj_at(pos++);
00679     methodOop method = methodOop(frame_array->obj_at(pos++));
00680     assert(method->is_method(), "expecting method");
00681 
00682     smiOop bci_obj = smiOop(frame_array->obj_at(pos++));
00683     assert(bci_obj->is_smi(), "expecting smi");
00684     int bci        = bci_obj->value();
00685 
00686     smiOop locals_obj = smiOop(frame_array->obj_at(pos++));
00687     assert(locals_obj->is_smi(), "expecting smi");
00688     int locals   = locals_obj->value();
00689 
00690     current = frame(current_sp, (int*) current_sp + locals + 2);
00691 
00692     
00693     for (int index = 0; index < locals; index++) {
00694       current.set_temp(index, frame_array->obj_at(pos++));
00695     }
00696 
00697     CodeIterator c(method, bci);
00698 
00699     char* current_pc;
00700 
00701     if (first) {
00702       
00703       if (nlr_through_unpacking) {
00704         
00705         current_pc = c.interpreter_return_point();
00706         
00707         
00708         current_pc = ic_info_at(current_pc)->NLR_target();
00709         current.set_hp(c.next_hp());
00710       } else if (redo_the_send) {
00711         
00712         current_pc = (char*) redo_bytecode_after_deoptimization;
00713         current.set_hp(c.next_hp());
00714         redo_send_offset = c.next_hp() - c.hp();
00715         redo_the_send = false;
00716       } else {
00717         
00718         current_pc = c.interpreter_return_point(true);
00719         current.set_hp(c.next_hp());
00720  
00721         if (c.is_message_send()) {
00722           number_of_arguments_through_unpacking = c.ic()->nof_arguments();        
00723         } else if (c.is_primitive_call()) {
00724           number_of_arguments_through_unpacking = c.prim_cache()->number_of_parameters();
00725         } else if (c.is_dll_call()) {
00726           
00727           
00728           number_of_arguments_through_unpacking = 0;
00729         }
00730       }
00731     } else {
00732       current_pc = c.interpreter_return_point();
00733       current.set_hp(c.next_hp());
00734     }
00735     current.set_receiver(receiver);
00736 
00737     current.patch_pc(current_pc);
00738     current.patch_fp(current.fp());
00739     
00740     
00741     if (!method->is_blockMethod() && method->activation_has_context()) {
00742       contextOop con = contextOop(current.temp(0));
00743       assert(con->is_context(), "must be context");
00744       oop frame_oop = oop(current.fp());
00745       con->set_parent(frame_oop);
00746 
00747       if (nlr_through_unpacking && nlr_home == (int) cur_fp) {
00748         if (nlr_home_context == con) {
00749           
00750           
00751           nlr_home = (int) current.fp();
00752           
00753           nlr_home_id = ~method->number_of_arguments();
00754           nlr_target_found = true;
00755           
00756         }
00757       }
00758     }
00759 
00760     if (TraceDeoptimization) {
00761       frame v(current_sp, current.fp(), current_pc);
00762       v.print_for_deoptimization(std);
00763     }
00764 
00765     first = false;
00766     
00767     current_sp += frame::interpreter_frame_size(locals);
00768 
00769   } while (pos <= length);
00770 
00771   if (must_find_nlr_target && !nlr_target_found) {
00772     fatal("Target for NLR not found when unpacking frame");
00773   }
00774 
00775   assert (current_sp == old_sp, "We have not reached the end");
00776   current.set_link(old_fp);
00777 }
00778 
00779 extern "C" void verify_at_end_of_deoptimization() {
00780   if (PrintStackAfterUnpacking) {
00781     BlockScavenge bs;
00782     ResourceMark rm;
00783     DeltaProcess::active()->verify();
00784     std->print_cr("[Stack after unpacking]");
00785     DeltaProcess::active()->trace_stack_for_deoptimization();
00786   }
00787 }
00788 
00789 
00790 
00791 extern "C" void unpack_unoptimized_frames();
00792 
00793 void DeltaProcess::deoptimize_stretch(frame* first_frame, frame* last_frame) {
00794   if (TraceDeoptimization) {
00795     std->print_cr("[Deoptimizing]");
00796     frame c = *first_frame;
00797     c.print_for_deoptimization(std);
00798     while (c.fp() != last_frame->fp()) {
00799       c = c.sender();
00800       c.print_for_deoptimization(std);
00801     }
00802   }
00803 
00804   StackChunkBuilder packer(first_frame->fp());
00805 
00806   vframe* vf = vframe::new_vframe(first_frame);
00807   assert(vf->is_compiled_frame(), "must be Delta frame");
00808 
00809   for (deltaVFrame* current = (deltaVFrame*) vf; 
00810        current && (current->fr().fp() <= last_frame->fp()); 
00811        current = (deltaVFrame*) current->sender()) {
00812     packer.append(current);
00813   }
00814 
00815   
00816   
00817   first_frame->patch_pc((char*) &unpack_unoptimized_frames); 
00818   first_frame->set_return_addr(last_frame->return_addr());
00819   first_frame->set_real_sender_sp(last_frame->sender_sp());
00820   first_frame->set_frame_array(packer.as_objArray());
00821   first_frame->set_link(last_frame->link());
00822 }
00823 
00824 void DeltaProcess::deoptimized_wrt_marked_nmethods() {
00825   
00826   if (!has_stack()) return;
00827 
00828   frame v = last_frame();
00829   do {
00830     if (v.should_be_deoptimized())
00831       deoptimize_stretch(&v, &v);
00832     v = v.sender();
00833   } while (!v.is_first_frame());
00834 }
00835 
00836 frame DeltaProcess::last_frame() {
00837   assert(last_Delta_fp(), "must have last_Delta_fp() when suspended");
00838   if (last_Delta_pc() == NULL) {
00839     frame c(last_Delta_sp(), last_Delta_fp());
00840     return c;
00841   } else {
00842     frame c(last_Delta_sp(), last_Delta_fp(), last_Delta_pc());
00843     return c;
00844   }
00845 }
00846 
00847 deltaVFrame* DeltaProcess::last_delta_vframe() {
00848   
00849   if (!has_stack()) return NULL;
00850 
00851   frame f = last_frame();
00852   for (vframe* vf = vframe::new_vframe(&f); vf; vf = vf->sender() ) {
00853     if (vf->is_delta_frame()) return (deltaVFrame*) vf;
00854   }
00855   return NULL;
00856 }
00857 
00858 
00859 int DeltaProcess::depth() {
00860   int d = 0;
00861   for(frame v = last_frame(); v.link(); v = v.sender()) d++;
00862   return d;
00863 }
00864 
00865 int DeltaProcess::vdepth(frame* f) {
00866   Unimplemented();
00867   return 0;
00868 }
00869 
00870 void DeltaProcess::trace_stack() {
00871   trace_stack_from(last_delta_vframe());
00872 }
00873 
00874 void DeltaProcess::trace_stack_from(vframe* start_frame) {
00875   std->print_cr("- Stack trace");
00876   int  vframe_no   = 1;
00877   for (vframe* f = start_frame; f; f = f->sender() ) {
00878     if (f->is_delta_frame()) {
00879       ((deltaVFrame*) f)->print_activation(vframe_no++);
00880     } else {
00881       f->print();
00882     }
00883     if (vframe_no == StackPrintLimit) {
00884       std->print_cr("...<more frames>...");
00885       return;
00886     }
00887   }
00888 }
00889 
00890 void DeltaProcess::trace_stack_for_deoptimization(frame* f) {
00891   if (has_stack()) {
00892     int  vframe_no   = 1;
00893     frame v = f ? *f : last_frame();
00894     do {
00895       v.print_for_deoptimization(std);
00896       v = v.sender();
00897       if (vframe_no == StackPrintLimit) {
00898         std->print_cr("...<more frames>...");
00899         return;
00900       }
00901       vframe_no++;
00902     } while (!v.is_first_frame());
00903   }
00904 }
00905 
00906 void DeltaProcess::trace_top(int start_frame, int number_of_frames) {
00907   FlagSetting fs(ActivationShowCode, true);
00908 
00909   std->print_cr("- Stack trace (%d, %d)", start_frame, number_of_frames);
00910   int  vframe_no = 1;
00911 
00912   for (vframe* f = last_delta_vframe(); f; f = f->sender() ) {
00913     if (vframe_no >= start_frame) {
00914       if (f->is_delta_frame()) {
00915         ((deltaVFrame*) f)->print_activation(vframe_no);
00916       } else f->print();
00917       if (vframe_no - start_frame + 1 >= number_of_frames) return;
00918     }
00919     vframe_no++;
00920   }
00921 }
00922 
00923 void DeltaProcess::update_nlr_targets(compiledVFrame* f, contextOop con) {
00924   for (unwindInfo* p = _unwind_head; p; p = p->next()) {
00925     p->update_nlr_targets(f, con);
00926   }
00927 }
00928 
00929 double DeltaProcess::user_time() {
00930   return _thread
00931        ? os:: user_time_for(_thread)
00932        : 0.0;
00933 }   
00934 
00935 double DeltaProcess::system_time() {
00936   return _thread
00937        ? os:: system_time_for(_thread)
00938        : 0.0;
00939 }
00940 
00941 
00942 
00943 DeltaProcess* Processes::processList = NULL;
00944 
00945 void Processes::start(VMProcess* p) {
00946   processList = NULL;
00947   
00948   p->activate_system();
00949 }
00950 
00951 void Processes::add(DeltaProcess* p) {
00952   p->set_next(processList);
00953   processList = p;
00954 }
00955 
00956 #define ALL_PROCESSES(X) for (DeltaProcess* X = processList; X; X = X->next())
00957 
00958 DeltaProcess* Processes::find_from_thread_id(int id) {
00959   ALL_PROCESSES(p) 
00960     if (p->thread_id() == id)
00961       return p;
00962   return NULL;
00963 }
00964 
00965 void Processes::frame_iterate(FrameClosure* blk) {
00966   ALL_PROCESSES(p) p->frame_iterate(blk);
00967 }
00968 
00969 void Processes::oop_iterate(OopClosure* blk) {
00970   ALL_PROCESSES(p) p->oop_iterate(blk);
00971 }
00972 
00973 void Processes::process_iterate(ProcessClosure* blk) {
00974   ALL_PROCESSES(p) blk->do_process(p);
00975 }
00976 
00977 void Processes::verify() {
00978   ALL_PROCESSES(p) p->verify();
00979 }
00980 
00981 bool Processes::has_completed_async_call() {
00982   ALL_PROCESSES(p) {
00983     if (p->state() == yielded_after_async_dll)
00984       return true;
00985   }
00986   return false;
00987 }
00988 
00989 void Processes::print() {
00990   std->print_cr("All processes:");
00991   ALL_PROCESSES(p) {
00992     ResourceMark rm;
00993     p->print();
00994     p->trace_stack();
00995   }
00996 }
00997 
00998 void Processes::remove(DeltaProcess* p) {
00999   assert(includes(p), "p must be present");
01000   DeltaProcess* current = processList; 
01001   DeltaProcess* prev    = NULL;
01002   
01003   while (current != p) {
01004     prev    = current;
01005     current = current->next();
01006   }
01007 
01008   if (prev) {
01009     prev->set_next(current->next());
01010   } else {
01011     processList = p->next();
01012   }
01013 }
01014 
01015 bool Processes::includes(DeltaProcess* p) {
01016   ALL_PROCESSES(q)
01017     if (q == p ) return true;
01018   return false;
01019 }
01020 
01021 
01022 DeltaProcess* Processes::last() {
01023   DeltaProcess* last = NULL;
01024   ALL_PROCESSES(q) last = q;
01025   return last;
01026 }
01027 
01028 void Processes::kill_all() {
01029   DeltaProcess* current = processList;
01030   while (current) {
01031     DeltaProcess* next = current->next();
01032     VMProcess::terminate(current);
01033     current->set_next(NULL);
01034     delete current;
01035     current = next;
01036   }
01037   processList = NULL;
01038 }
01039 
01040 class ScavengeOopClosure : public OopClosure {
01041   void do_oop(oop* o) { SCAVENGE_TEMPLATE(o); }
01042 };
01043 
01044 void Processes::scavenge_contents() {
01045   ScavengeOopClosure blk;
01046   oop_iterate(&blk);
01047 }
01048 
01049 void Processes::follow_roots() {
01050   ALL_PROCESSES(p) p->follow_roots();
01051 }
01052    
01053 class ConvertHCodePointersClosure : public FrameClosure {
01054   void do_frame(frame* f) {
01055     if (f->is_interpreted_frame()) {
01056       f->convert_hcode_pointer();
01057     }
01058   }
01059 };
01060 
01061 void Processes::convert_hcode_pointers() {
01062   ConvertHCodePointersClosure blk;
01063   frame_iterate(&blk);
01064 }
01065 
01066 class RestoreHCodePointersClosure : public FrameClosure {
01067   void do_frame(frame* f) {
01068     if (f->is_interpreted_frame()) {
01069       f->restore_hcode_pointer();
01070     }
01071   }
01072 };
01073 
01074 void Processes::restore_hcode_pointers() {
01075   RestoreHCodePointersClosure blk;
01076   frame_iterate(&blk);
01077 }
01078 
01079 void Processes::deoptimized_wrt_marked_nmethods() {
01080   StackChunkBuilder::begin_deoptimization();
01081   ALL_PROCESSES(p) p->deoptimized_wrt_marked_nmethods();
01082   StackChunkBuilder::end_deoptimization();
01083 }
01084 
01085 void Processes::deoptimize_wrt(nmethod* nm) {
01086   GrowableArray<nmethod*>* nms = nm->invalidation_family();
01087   
01088   for (int index = 0; index < nms->length(); index++)
01089     nms->at(index)->mark_for_deoptimization();
01090 
01091   
01092   deoptimized_wrt_marked_nmethods();
01093 
01094   
01095   for (index = 0; index < nms->length(); index++)
01096     nms->at(index)->unmark_for_deoptimization();
01097 }
01098 
01099 void Processes::deoptimize_wrt(GrowableArray<nmethod*>* list) {
01100   
01101   for (int i = 0; i < list->length(); i++) {
01102     nmethod* nm = list->at(i);
01103     GrowableArray<nmethod*>* nms = nm->invalidation_family();
01104     for (int index = 0; index < nms->length(); index++)
01105       nms->at(index)->mark_for_deoptimization();
01106   }
01107 
01108   
01109   deoptimized_wrt_marked_nmethods();
01110 
01111   
01112   for (i = 0; i < list->length(); i++) {
01113     nmethod* nm = list->at(i);
01114     GrowableArray<nmethod*>* nms = nm->invalidation_family();
01115     for (int index = 0; index < nms->length(); index++)
01116       nms->at(index)->unmark_for_deoptimization();
01117   }
01118 }
01119 
01120 void Processes::update_nlr_targets(compiledVFrame* f, contextOop con) {
01121  ALL_PROCESSES(p) p->update_nlr_targets(f, con);
01122 }
01123 
01124 void Processes::deoptimize_all() {
01125   Universe::code->mark_all_for_deoptimization();
01126   deoptimized_wrt_marked_nmethods();
01127   Universe::code->unmark_all_for_deoptimization();
01128 }
01129 
01130 
01131 void handle_error(ProcessState error) {
01132   DeltaProcess* proc = DeltaProcess::active();
01133   if (proc->is_scheduler()) {
01134     std->print_cr("Error happend in the scheduler");
01135     std->print("Status: ");
01136     proc->status_symbol()->print_symbol_on(std);
01137     std->cr();
01138     evaluator::read_eval_loop();
01139   } else {
01140     proc->suspend(error);
01141   }
01142   ErrorHandler::abort_current_process();
01143   ShouldNotReachHere();
01144 }
01145 
01146 void handle_interpreter_error(char* message) {
01147   warning("Interpreter error: %s", message);
01148   handle_error(stopped);
01149 }
01150 
01151 
01152 extern "C" void suspend_on_error(InterpreterErrorConstants error_code) {
01153   
01154 
01155   
01156   switch (error_code) {
01157     case primitive_lookup_failed: handle_error(primitive_lookup_error);
01158     case boolean_expected       : handle_error(boolean_error);
01159     case nonlocal_return_error  : handle_error(NLR_error);
01160     case float_expected         : handle_error(float_error);
01161   }
01162 
01163   
01164   switch (error_code) {
01165     case halted                 : handle_interpreter_error("executed halt bytecode");
01166     case illegal_code           : handle_interpreter_error("illegal code");
01167     case not_implemented        : handle_interpreter_error("not implemented");
01168     case stack_missaligned      : handle_interpreter_error("stack misaligned");
01169     case ebx_wrong              : handle_interpreter_error("ebx wrong");
01170     case obj_wrong              : handle_interpreter_error("obj wrong");
01171     case nlr_offset_wrong       : handle_interpreter_error("NLR offset wrong");
01172     case last_Delta_fp_wrong    : handle_interpreter_error("last Delta frame wrong");
01173     case primitive_result_wrong : handle_interpreter_error("ilast C entry frame wrong");
01174   }
01175   ShouldNotReachHere();
01176 }
01177 
01178 extern "C" void suspend_on_NLR_error() {
01179   
01180   DeltaProcess::active()->suspend(NLR_error);
01181 }
01182 
01183 
01184 void trace_stack_at_exception(int* sp, int* fp, char* pc) {
01185   ResourceMark rm;
01186 
01187   std->print_cr("Trace at exception");
01188 
01189   vframe* vf;
01190   if (last_Delta_fp) {
01191     frame c(last_Delta_sp, last_Delta_fp);
01192     vf = vframe::new_vframe(&c);
01193   } else {
01194     frame c((oop*) sp, fp, pc);
01195     vf = vframe::new_vframe(&c);
01196   }
01197   DeltaProcess::trace_stack_from(vf);
01198 }
01199 
01200 void suspend_process_at_stack_overflow(int *sp, int* fp, char* pc) {
01201   DeltaProcess* proc = DeltaProcess::active();
01202 
01203   proc->set_last_Delta_pc(pc);
01204   last_Delta_fp = fp;
01205   last_Delta_sp = (oop*) sp;
01206 
01207   if (proc->is_scheduler()) {
01208     std->print_cr("Stack overflow happend in scheduler");
01209   } else {
01210     proc->suspend(stack_overflow);
01211     proc->set_terminating();
01212   }
01213 }