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 }