00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 class unwindInfo : public StackObj {
00028 private:
00029
00030 int _nlr_home;
00031 int _nlr_home_id;
00032 contextOop _nlr_home_context;
00033 public:
00034 oop _nlr_result;
00035 private:
00036
00037 bool _is_compiled;
00038
00039
00040 unwindInfo* _next;
00041
00042
00043 char* saved_C_frame_return_addr;
00044 char** saved_C_frame_return_addr_location;
00045 char* saved_patch_return_address;
00046 public:
00047 unwindInfo();
00048 ~unwindInfo();
00049
00050 unwindInfo* next() const { return _next; }
00051 void set_next(unwindInfo* next) { _next = next; }
00052
00053 int nlr_home() const { return _nlr_home; }
00054 int nlr_home_id() const { return _nlr_home_id; }
00055 contextOop nlr_home_context() const { return _nlr_home_context; }
00056 void update_nlr_targets(compiledVFrame* f, contextOop con);
00057 };
00058
00059
00060
00061
00062
00063
00064 class Process: public PrintableCHeapObj {
00065 public:
00066
00067 virtual bool is_vmProcess() const { return false; }
00068 virtual bool is_deltaProcess() const { return false; }
00069
00070
00071 void abort();
00072
00073 int thread_id() const { return _thread_id; }
00074
00075 static bool external_suspend_current();
00076 static void external_resume_current();
00077
00078
00079 static void set_current(Process* p) { _current_process = p; }
00080
00081 static Process* current() { return _current_process; }
00082
00083 protected:
00084
00085 void basic_transfer(Process* target);
00086
00087
00088 Thread* _thread;
00089 int _thread_id;
00090 Event* _event;
00091
00092 static Process* _current_process;
00093 };
00094
00095
00096
00097
00098 class VMProcess: public Process {
00099 public:
00100
00101 VMProcess();
00102
00103
00104 bool is_vmProcess() const { return true; }
00105
00106
00107 void activate_system();
00108
00109
00110 void loop();
00111
00112
00113 void transfer_to(DeltaProcess* target_process);
00114
00115
00116 void print();
00117
00118
00119 static void terminate(DeltaProcess* proc);
00120
00121
00122 static void execute(VM_Operation* op);
00123
00124
00125 static VM_Operation* vm_operation() { return _vm_operation; }
00126
00127
00128 static VMProcess* vm_process() { return _vm_process; }
00129
00130 private:
00131 static VM_Operation* _vm_operation;
00132 static VMProcess* _vm_process;
00133 };
00134
00135
00136 enum ProcessState {
00137 initialized,
00138 running,
00139 yielded,
00140 stopped,
00141 preempted,
00142 uncommon,
00143 in_async_dll,
00144 yielded_after_async_dll,
00145 completed,
00146 boolean_error,
00147 lookup_error,
00148 primitive_lookup_error,
00149 DLL_lookup_error,
00150 float_error,
00151 NLR_error,
00152 stack_overflow,
00153 aborted
00154 };
00155
00156
00157 class DeltaProcess: public Process {
00158 private:
00159 oop _receiver;
00160 symbolOop _selector;
00161 DeltaProcess* _next;
00162 processOop _processObj;
00163 ProcessState _state;
00164
00165 int* _last_Delta_fp;
00166 oop* _last_Delta_sp;
00167 char* _last_Delta_pc;
00168
00169 bool _is_terminating;
00170
00171 int _time_stamp;
00172
00173 friend class VMProcess;
00174 public:
00175
00176 DeltaProcess(oop receiver, symbolOop selector);
00177 ~DeltaProcess();
00178
00179
00180 bool is_deltaProcess() const { return true; }
00181 bool isUncommon() const { return _state == uncommon; }
00182
00183
00184 oop receiver() const { return _receiver; }
00185 symbolOop selector() const { return _selector; }
00186
00187
00188 DeltaProcess* next() const { return _next; }
00189 void set_next(DeltaProcess* p) { _next = p; }
00190
00191
00192 processOop processObj() const { return _processObj; }
00193 void set_processObj(processOop p) { _processObj = p; }
00194
00195 bool is_terminating() { return _is_terminating; }
00196 void set_terminating() { _is_terminating = true; }
00197
00198 int time_stamp() const { return _time_stamp; }
00199
00200 void inc_time_stamp() { _time_stamp++; }
00201
00202
00203 int* last_Delta_fp() const;
00204 void set_last_Delta_fp(int* fp);
00205
00206
00207 oop* last_Delta_sp() const;
00208 void set_last_Delta_sp(oop* sp);
00209
00210
00211 char* last_Delta_pc() const;
00212 void set_last_Delta_pc(char* pc);
00213
00214 ProcessState state() const { return _state; }
00215
00216 symbolOop status_symbol() const { return symbol_from_state(state()); }
00217
00218 static symbolOop symbol_from_state(ProcessState state);
00219
00220
00221
00222
00223
00224
00225 public:
00226 void push_unwind(unwindInfo *info) {
00227 info->set_next(_unwind_head);
00228 _unwind_head = info;
00229 }
00230
00231 void pop_unwind() {
00232 _unwind_head = _unwind_head->next();
00233 }
00234
00235 void unwinds_do(void f(unwindInfo* info)) {
00236 for (unwindInfo* p = _unwind_head; p; p = p->next())
00237 f(p);
00238 };
00239
00240 void update_nlr_targets(compiledVFrame* f, contextOop con);
00241
00242 private:
00243 unwindInfo* _unwind_head;
00244
00245 private:
00246 void set_state(ProcessState s) { _state = s; }
00247
00248 public:
00249
00250
00251
00252 bool has_stack() const;
00253
00254 bool is_ready() const { return state() == initialized || state() == yielded; }
00255
00256
00257 void follow_roots();
00258
00259
00260 void frame_iterate(FrameClosure* blk);
00261 void oop_iterate(OopClosure* blk);
00262
00263
00264 void deoptimized_wrt_marked_nmethods();
00265 void deoptimize_stretch(frame* first_frame, frame* last_frame);
00266 static void deoptimize_redo_last_send();
00267
00268
00269 void enter_uncommon();
00270 void exit_uncommon();
00271
00272
00273 void print();
00274 void verify();
00275
00276
00277 frame last_frame();
00278 deltaVFrame* last_delta_vframe();
00279
00280
00281 void trace_stack();
00282 void trace_top(int start_frame, int number_of_frames);
00283 void trace_stack_for_deoptimization(frame* f = NULL);
00284
00285
00286 static void trace_stack_from(vframe* top_frame);
00287
00288
00289 double user_time();
00290 double system_time();
00291
00292 int depth();
00293 int vdepth(frame* f = NULL);
00294
00295 #ifdef unused
00296
00297 bool stepping;
00298 bool stopping;
00299 #endif
00300
00301
00302 frame profile_top_frame();
00303
00304 private:
00305 void transfer(ProcessState reason, DeltaProcess* destination);
00306
00307 public:
00308
00309
00310 bool is_active() const { return this == active(); }
00311
00312
00313 bool is_scheduler() const { return this == scheduler(); }
00314
00315
00316 bool in_vm_operation() const { return is_active() && VMProcess::vm_operation() != NULL; }
00317
00318
00319 void suspend(ProcessState reason);
00320 void suspend_at_creation();
00321
00322
00323 void transfer_and_continue();
00324 void wait_for_control();
00325
00326
00327 ProcessState transfer_to(DeltaProcess* target);
00328
00329
00330 void transfer_to_vm();
00331
00332
00333 private:
00334 static DeltaProcess* _active_delta_process;
00335 static DeltaProcess* _scheduler_process;
00336 static bool _is_idle;
00337
00338
00339 static void set_active(DeltaProcess* p) {
00340 _active_delta_process = p;
00341 if (_active_delta_process->state() != uncommon) {
00342 _active_delta_process->set_state(running);
00343 }
00344 }
00345
00346
00347 static void set_scheduler(DeltaProcess* p) { _scheduler_process = p; }
00348
00349
00350 static int launch_delta(DeltaProcess* process);
00351
00352 public:
00353
00354
00355 static DeltaProcess* active() { return _active_delta_process; }
00356
00357
00358 static bool is_idle() { return _is_idle; }
00359
00360
00361 static DeltaProcess* scheduler() { return _scheduler_process; }
00362
00363 static void set_terminating_process(ProcessState state) {
00364 _state_of_terminated_process = state;
00365 _process_has_terminated = true;
00366 }
00367
00368 static bool process_has_terminated() {
00369 bool result = _process_has_terminated;
00370 _process_has_terminated = false;
00371 return result;
00372 }
00373 static ProcessState state_of_terminated_process() {
00374 return _state_of_terminated_process;
00375 }
00376
00377 private:
00378 static bool _process_has_terminated;
00379 static ProcessState _state_of_terminated_process;
00380
00381 public:
00382
00383 static void async_dll_call_completed();
00384 static void initialize_async_dll_event();
00385
00386
00387 static bool wait_for_async_dll(int timeout_in_ms);
00388 private:
00389
00390
00391 static Event* _async_dll_completion_event;
00392 };
00393
00394
00395 class Processes: AllStatic {
00396 private:
00397 static DeltaProcess* processList;
00398 public:
00399
00400 static void add(DeltaProcess* p);
00401 static void remove(DeltaProcess* p);
00402 static bool includes(DeltaProcess* p);
00403 static DeltaProcess* last();
00404
00405 static DeltaProcess* find_from_thread_id(int id);
00406
00407
00408 static void start(VMProcess* p);
00409
00410
00411 static bool has_completed_async_call();
00412
00413
00414 static void kill_all();
00415
00416
00417 static void frame_iterate(FrameClosure* blk);
00418 static void oop_iterate(OopClosure* blk);
00419 static void process_iterate(ProcessClosure* blk);
00420
00421
00422 static void scavenge_contents();
00423
00424
00425 static void follow_roots();
00426 static void convert_hcode_pointers();
00427 static void restore_hcode_pointers();
00428
00429
00430 static void verify();
00431 static void print();
00432
00433
00434 public:
00435
00436 static void deoptimize_wrt(nmethod* nm);
00437
00438 static void deoptimize_wrt(GrowableArray<nmethod*>* list);
00439
00440 static void deoptimize_all();
00441
00442 static void deoptimized_wrt_marked_nmethods();
00443
00444
00445 static void update_nlr_targets(compiledVFrame* f, contextOop con);
00446 };
00447
00448
00449
00450 extern "C" bool processSemaphore;
00451
00452 extern "C" int* last_Delta_fp;
00453 extern "C" oop* last_Delta_sp;
00454
00455 extern int CurrentHash;
00456
00457 extern "C" void set_stack_overflow_for(DeltaProcess* currentProcess);
00458
00459
00460
00461 extern "C" void suspend_on_NLR_error();
00462
00463
00464 enum InterpreterErrorConstants {
00465 start_of_runtime_system_errors = 512,
00466 primitive_lookup_failed = 1 + start_of_runtime_system_errors,
00467 boolean_expected = 2 + start_of_runtime_system_errors,
00468 nonlocal_return_error = 3 + start_of_runtime_system_errors,
00469 halted = 4 + start_of_runtime_system_errors,
00470 illegal_code = 5 + start_of_runtime_system_errors,
00471 not_implemented = 6 + start_of_runtime_system_errors,
00472 stack_missaligned = 7 + start_of_runtime_system_errors,
00473 ebx_wrong = 8 + start_of_runtime_system_errors,
00474 obj_wrong = 9 + start_of_runtime_system_errors,
00475 nlr_offset_wrong = 10 + start_of_runtime_system_errors,
00476 last_Delta_fp_wrong = 11 + start_of_runtime_system_errors,
00477 primitive_result_wrong = 12 + start_of_runtime_system_errors,
00478 float_expected = 13 + start_of_runtime_system_errors,
00479 };
00480