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 # include "incls/_precompiled.incl"
00026
00027 #ifdef DELTA_COMPILER
00028 # include "incls/_uncommonBranch.cpp.incl"
00029
00030
00031
00032
00033
00034 bool patch_uncommon_call(frame* f) {
00035
00036
00037
00038
00039 int* next_inst = (int*) f->pc();
00040 int* dest_addr = next_inst-1;
00041 int dest = *dest_addr + (int) next_inst;
00042
00043
00044 if (dest == (int)StubRoutines::used_uncommon_trap_entry())
00045 return true;
00046
00047 assert(dest == (int)StubRoutines::unused_uncommon_trap_entry(), "Make sure we are patching the right call");
00048
00049
00050 *dest_addr = ((int)StubRoutines::used_uncommon_trap_entry()) - ((int) next_inst);
00051
00052 assert(*dest_addr + (int) next_inst == (int)StubRoutines::used_uncommon_trap_entry(), "Check the patch");
00053
00054
00055 return false;
00056 }
00057
00058
00059
00060
00061 static bool has_invalid_context(frame* f) {
00062
00063 if (!f->is_compiled_frame()) return false;
00064
00065
00066 compiledVFrame* vf = (compiledVFrame*) vframe::new_vframe(f);
00067 assert(vf->is_compiled_frame(), "should be compiled vframe");
00068 while (true) {
00069 contextOop con = vf->compiled_context();
00070
00071
00072 if (con) con->print();
00073
00074 if (con && con->unoptimized_context()) return true;
00075 if (vf->is_top()) break;
00076 vf = (compiledVFrame*) vf->sender();
00077 assert(vf->is_compiled_frame(), "should be compiled vframe");
00078 }
00079 return false;
00080 }
00081
00082
00083 class FrameAndContextElement : public ResourceObj {
00084 public:
00085 frame fr;
00086 contextOop con;
00087
00088 FrameAndContextElement(frame* f, contextOop c) {
00089 fr = *f;
00090 con = c;
00091 }
00092 };
00093
00094
00095 void collect_compiled_contexts_for(frame* f, GrowableArray<FrameAndContextElement*>* elements) {
00096
00097 if (!f->is_compiled_frame()) return;
00098
00099
00100 compiledVFrame* vf = (compiledVFrame*) vframe::new_vframe(f);
00101 assert(vf->is_compiled_frame(), "should be compiled vframe");
00102 while (true) {
00103 contextOop con = vf->compiled_context();
00104 if (con) {
00105 elements->append(new FrameAndContextElement(f, con));
00106 }
00107 if (vf->is_top()) break;
00108 vf = (compiledVFrame*) vf->sender();
00109 assert(vf->is_compiled_frame(), "should be compiled vframe");
00110 }
00111 }
00112
00113
00114 class EnableDeoptimization: StackObj {
00115 public:
00116 EnableDeoptimization() { StackChunkBuilder::begin_deoptimization(); }
00117 ~EnableDeoptimization() { StackChunkBuilder::end_deoptimization(); }
00118 };
00119
00120
00121 void uncommon_trap() {
00122
00123
00124
00125
00126
00127
00128
00129 ResourceMark rm;
00130
00131 DeltaProcess* process = DeltaProcess::active();
00132
00133 #ifdef ASSERT
00134 process->verify();
00135 #endif
00136
00137 FlagSetting fl(processSemaphore, true);
00138
00139 process->enter_uncommon();
00140 frame f = process->last_frame();
00141
00142
00143 bool used = patch_uncommon_call(&f);
00144
00145
00146 compiledVFrame* vf = (compiledVFrame*) vframe::new_vframe(&f);
00147 assert(vf->is_compiled_frame(), "must be compiled frame");
00148 nmethod* nm = vf->code();
00149
00150 nm->inc_uncommon_trap_counter();
00151
00152 LOG_EVENT3("Uncommon trap in 0x%lx@%d #%d", nm, vf->scope()->offset(), nm->uncommon_trap_counter());
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 if (PrintUncommonBranches) {
00165 std->print("%s trap in ", used ? "Uncommon" : "New uncommon");
00166 nm->print_value_on(std);
00167 std->print(" #%d", nm->uncommon_trap_counter());
00168 if (WizardMode) std->print(" @%d called from %#x", vf->scope()->offset(), f.pc() - Assembler::sizeOfCall);
00169 std->cr();
00170 if (TraceDeoptimization) vf->print_activation(0);
00171 process->trace_top(0, 3);
00172 }
00173
00174
00175 if (RecompilationPolicy::shouldRecompileAfterUncommonTrap(nm)) {
00176 if (!nm->isZombie()) nm->makeZombie(false);
00177 Recompilation recomp(vf->receiver(), nm, true);
00178 VMProcess::execute(&recomp);
00179 }
00180
00181
00182 {
00183 FinalResourceMark rm;
00184 EnableDeoptimization ed;
00185
00186 DeltaProcess::deoptimize_redo_last_send();
00187 process->deoptimize_stretch(&f, &f);
00188 if (!nm->is_method()) {
00189
00190
00191
00192
00193
00194
00195
00196 GrowableArray<FrameAndContextElement*>* elements = new GrowableArray<FrameAndContextElement*>(10);
00197 for (frame current_frame = f.sender(); !current_frame.is_first_frame(); current_frame = current_frame.sender()) {
00198 collect_compiled_contexts_for(¤t_frame, elements);
00199 }
00200
00201 bool done = false;
00202
00203 while (!done) {
00204 done = true;
00205 for (int index = 0; index < elements->length() && done; index++) {
00206 FrameAndContextElement* e = elements->at(index);
00207 if (e && e->con->unoptimized_context()) {
00208 process->deoptimize_stretch(&e->fr, &e->fr);
00209
00210 for (int j = 0; j < elements->length(); j++) {
00211 if (elements->at(j) && elements->at(j)->fr.fp() == e->fr.fp())
00212 elements->at_put(j, NULL);
00213 }
00214 done = false;
00215 }
00216 }
00217 }
00218 }
00219 }
00220 process->exit_uncommon();
00221 }
00222
00223 #endif