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/_frame.cpp.incl"
00026
00027 u_char* frame::hp() const {
00028
00029
00030 return *hp_addr();
00031 }
00032
00033 void frame::set_hp(u_char* hp) {
00034
00035 *hp_addr() = hp;
00036 }
00037
00038 void frame::patch_pc(char* pc) {
00039 char** pc_addr = (char**) sp() - 1;
00040 *pc_addr = pc;
00041 }
00042
00043 objArrayOop* frame::frame_array_addr() const {
00044 assert(frame_size() >= minimum_size_for_deoptimized_frame, "Compiler frame is too small for deoptimization");
00045
00046 return (objArrayOop*) addr_at(frame_frame_array_offset);
00047 }
00048
00049 objArrayOop frame::frame_array() const {
00050 objArrayOop result = *frame_array_addr();
00051 assert(result->is_objArray(), "must be objArray");
00052 return result;
00053 }
00054
00055 oop** frame::real_sender_sp_addr() const {
00056
00057 return (oop**) addr_at(frame_real_sender_sp_offset);
00058 }
00059
00060 void frame::patch_fp(int* fp) {
00061 frame previous(NULL, ((int*) sp()) - frame_sender_sp_offset, NULL);
00062 previous.set_link(fp);
00063 }
00064
00065 methodOop frame::method() const {
00066 assert(is_interpreted_frame(), "must be interpreter frame");
00067
00068
00069
00070 if (frame_size() < minimum_size_for_deoptimized_frame) return NULL;
00071
00072 u_char* h = hp();
00073 if (!Universe::old_gen.contains(h)) return NULL;
00074 memOop obj = as_memOop(Universe::object_start((oop*) h));
00075 return obj->is_method() ? methodOop(obj) : NULL;
00076 }
00077
00078 nmethod* frame::code() const {
00079 assert(is_compiled_frame(), "no code");
00080 return findNMethod(pc());
00081 }
00082
00083 bool frame::is_interpreted_frame() const {
00084 return Interpreter::contains(pc());
00085 }
00086
00087 bool frame::is_compiled_frame() const {
00088 #ifdef DELTA_COMPILER
00089 return Universe::code->contains(pc());
00090 #else
00091 return false;
00092 #endif
00093 }
00094
00095 extern "C" void unpack_unoptimized_frames();
00096
00097 bool frame::is_deoptimized_frame() const {
00098 return pc() == (char*) &unpack_unoptimized_frames;
00099 }
00100
00101 IC_Iterator* frame::sender_ic_iterator() const {
00102 return is_entry_frame() ? NULL : sender().current_ic_iterator();
00103 }
00104
00105 IC_Iterator* frame::current_ic_iterator() const {
00106
00107 if (is_interpreted_frame()) {
00108 InterpretedIC* ic = current_interpretedIC();
00109 if (ic && !Bytecodes::is_send_code(ic->send_code())) return NULL;
00110 return ic ? new InterpretedIC_Iterator(ic) : NULL;
00111 }
00112
00113 if (is_compiled_frame()) {
00114 CompiledIC* ic = current_compiledIC();
00115 return ic->inlineCache()
00116 ? new CompiledIC_Iterator(ic)
00117 : NULL;
00118 }
00119
00120
00121 return NULL;
00122 }
00123
00124 InterpretedIC* frame::current_interpretedIC() const {
00125
00126 if (is_interpreted_frame()) {
00127 methodOop m = method();
00128 int bci = m->bci_from(hp());
00129 u_char* codeptr = m->codes(bci);
00130 if (Bytecodes::is_send_code(Bytecodes::Code(*codeptr))) {
00131 InterpretedIC* ic = as_InterpretedIC((char*)hp());
00132 assert(ic->send_code_addr() == codeptr, "found wrong ic");
00133 return ic;
00134 } else {
00135 return NULL;
00136 }
00137 }
00138
00139 return NULL;
00140 }
00141
00142 CompiledIC* frame::current_compiledIC() const {
00143 return is_compiled_frame()
00144 ? CompiledIC_from_return_addr(pc())
00145 : NULL;
00146 }
00147
00148 extern "C" void return_from_Delta();
00149
00150 bool frame::is_entry_frame() const {
00151 return pc() == (char*) &return_from_Delta;
00152 }
00153
00154 bool frame::has_next_Delta_fp() const {
00155 return at(frame_next_Delta_fp_offset) != NULL;
00156 }
00157
00158 int* frame::next_Delta_fp() const {
00159 return (int*) at(frame_next_Delta_fp_offset);
00160 }
00161
00162 oop* frame::next_Delta_sp() const {
00163 return (oop*) at(frame_next_Delta_sp_offset);
00164 }
00165
00166 bool frame::is_first_frame() const {
00167 return is_entry_frame() && !has_next_Delta_fp();
00168 }
00169
00170 bool frame::is_first_delta_frame() const {
00171
00172
00173 frame s;
00174 for (s = sender(); !(s.is_delta_frame() || s.is_first_frame()); s = s.sender()) ;
00175 return s.is_first_frame();
00176 }
00177
00178 char* frame::print_name() const {
00179 if (is_interpreted_frame()) return "interpreted";
00180 if (is_compiled_frame()) return "compiled";
00181 if (is_deoptimized_frame()) return "deoptimized";
00182 return "C";
00183 }
00184
00185 void frame::print() const {
00186 std->print("[%s frame: fp = %#lx, sp = %#lx, pc = %#lx", print_name(), fp(), sp(), pc());
00187 if (is_compiled_frame()) {
00188 std->print(", nm = %#x", findNMethod(pc()));
00189 } else if (is_interpreted_frame()) {
00190 std->print(", hp = %#x, method = %#x", hp(), method());
00191 }
00192 std->print_cr("]");
00193
00194 if (PrintLongFrames) {
00195 for (oop* p = sp(); p < (oop*)fp(); p++)
00196 std->print_cr(" - 0x%lx: 0x%lx", p, *p);
00197 }
00198 }
00199
00200
00201 static void print_context_chain(contextOop con, outputStream* st) {
00202 if (con) {
00203
00204 st->print(" context ");
00205 con->print_value_on(st);
00206 while (con->has_outer_context()) {
00207 con = con->outer_context();
00208 st->print(" -> ");
00209 con->print_value_on(st);
00210 }
00211 st->cr();
00212 }
00213 }
00214
00215 void frame::print_for_deoptimization(outputStream* st) {
00216 ResourceMark rm;
00217 st->print(" - ");
00218 if (is_interpreted_frame()) {
00219 st->print("I ");
00220 interpretedVFrame* vf = (interpretedVFrame*) vframe::new_vframe(this);
00221 vf->method()->print_value_on(st);
00222 if (ActivationShowBCI) {
00223 st->print(" bci=%d ", vf->bci());
00224 }
00225 std->print_cr(" @ 0x%lx", fp());
00226 print_context_chain(vf->interpreter_context(), st);
00227 if (ActivationShowExpressionStack) {
00228 GrowableArray<oop>* stack = vf->expression_stack();
00229 for (int index = 0; index < stack->length(); index++) {
00230 st->print(" %3d: ", index);
00231 stack->at(index)->print_value_on(st);
00232 st->cr();
00233 }
00234 }
00235 return;
00236 }
00237
00238 if (is_compiled_frame()) {
00239 st->print("C ");
00240 compiledVFrame* vf = (compiledVFrame*) vframe::new_vframe(this);
00241 assert(vf->is_compiled_frame(), "should be compiled vframe");
00242 vf->code()->print_value_on(st);
00243 std->print_cr(" @ 0x%lx", fp());
00244
00245 while (true) {
00246 st->print(" ");
00247 vf->method()->print_value_on(st);
00248 std->print_cr(" @ %d", vf->scope()->offset());
00249 print_context_chain(vf->compiled_context(), st);
00250 if (vf->is_top()) break;
00251 vf = (compiledVFrame*) vf->sender();
00252 assert(vf->is_compiled_frame(), "should be compiled vframe");
00253 }
00254 return;
00255 }
00256
00257 if (is_deoptimized_frame()) {
00258 st->print("D ");
00259 frame_array()->print_value();
00260 std->print_cr(" @ 0x%lx", fp());
00261
00262 deoptimizedVFrame* vf = (deoptimizedVFrame*) vframe::new_vframe(this);
00263 assert(vf->is_deoptimized_frame(), "should be deoptimized vframe");
00264 while (true) {
00265 st->print(" ");
00266 vf->method()->print_value_on(st);
00267 std->cr();
00268 print_context_chain(vf->deoptimized_context(), st);
00269 if (vf->is_top()) break;
00270 vf = (deoptimizedVFrame*) vf->sender();
00271 assert(vf->is_deoptimized_frame(), "should be deoptimized vframe");
00272 }
00273 return;
00274 }
00275
00276 st->print("E foreign frame @ 0x%lx", fp());
00277 }
00278
00279 void frame::layout_iterate(FrameLayoutClosure* blk) {
00280 if (is_interpreted_frame()){
00281 oop* eos = temp_addr(0);
00282 for (oop* p = sp(); p <= eos; p++)
00283 blk->do_stack(eos-p, p);
00284 blk->do_hp(hp_addr());
00285 blk->do_receiver(receiver_addr());
00286 blk->do_link(link_addr());
00287 blk->do_return_addr(return_addr_addr());
00288 }
00289 }
00290
00291 bool frame::has_interpreted_float_marker() const {
00292 return oop(at(interpreted_frame_float_magic_offset)) == Floats::magic_value();
00293 }
00294
00295 bool frame::has_compiled_float_marker() const {
00296 return oop(at(compiled_frame_magic_oop_offset)) == Floats::magic_value();
00297 }
00298
00299 bool frame::oop_iterate_interpreted_float_frame(OopClosure* blk) {
00300 methodOop m = methodOopDesc::methodOop_from_hcode(hp());
00301
00302 if (!m->has_float_temporaries()) return false;
00303
00304
00305 oop* end = (oop*) addr_at(m->float_section_start_offset() - m->float_section_size());
00306 for (oop* p = sp(); p <= end; p++) {
00307 blk->do_oop(p);
00308 }
00309
00310
00311
00312
00313 for (oop* q = (oop*) addr_at(m->float_section_start_offset() + 2); q <= temp_addr(0); q++) {
00314 blk->do_oop(q);
00315 }
00316
00317
00318 blk->do_oop(receiver_addr());
00319
00320 return true;
00321 }
00322
00323 bool frame::oop_iterate_compiled_float_frame(OopClosure* blk) {
00324 warning("oop_iterate_compiled_float_frame not implemented");
00325 return false;
00326 }
00327
00328 void frame::oop_iterate(OopClosure* blk) {
00329 if (is_interpreted_frame()) {
00330 if (has_interpreted_float_marker() && oop_iterate_interpreted_float_frame(blk)) return;
00331
00332
00333 for (oop* p = sp(); p <= temp_addr(0); p++) {
00334
00335
00336
00337 blk->do_oop(p);
00338 }
00339
00340
00341
00342 blk->do_oop(receiver_addr());
00343 return;
00344 }
00345
00346 if (is_compiled_frame()) {
00347 if (has_compiled_float_marker() && oop_iterate_compiled_float_frame(blk)) return;
00348
00349
00350 for (oop* p = sp(); p < (oop*)fp(); p++) {
00351 blk->do_oop(p);
00352 }
00353 return;
00354 }
00355
00356 if (is_entry_frame()) {
00357
00358 for (oop* p = sp(); p < (oop*)fp(); p++) {
00359 blk->do_oop(p);
00360 }
00361 return;
00362 }
00363
00364 if (is_deoptimized_frame()) {
00365
00366 oop* end = (oop*)fp() + frame_real_sender_sp_offset;
00367
00368 for (oop* p = sp(); p < end; p++) {
00369 blk->do_oop(p);
00370 }
00371 blk->do_oop((oop*)frame_array_addr());
00372 return;
00373 }
00374 }
00375
00376 bool frame::follow_roots_interpreted_float_frame() {
00377 methodOop m = methodOop(hp());
00378 assert(m->is_method(), "must be method");
00379
00380 if (!m->has_float_temporaries()) return false;
00381
00382
00383 oop* end = (oop*) addr_at(m->float_section_start_offset() - m->float_section_size());
00384 for (oop* p = sp(); p <= end; p++) {
00385 MarkSweep::follow_root(p);
00386 }
00387
00388
00389
00390
00391 for (oop* q = (oop*) addr_at(m->float_section_start_offset() + 2); q <= temp_addr(0); q++) {
00392 MarkSweep::follow_root(q);
00393 }
00394
00395
00396 MarkSweep::follow_root(receiver_addr());
00397
00398 return true;
00399 }
00400
00401 bool frame::follow_roots_compiled_float_frame() {
00402 warning("follow_roots_compiled_float_frame not implemented");
00403 return true;
00404 }
00405
00406 void frame::follow_roots() {
00407 if (is_interpreted_frame()) {
00408 if (has_interpreted_float_marker() && follow_roots_interpreted_float_frame()) return;
00409
00410
00411 for (oop* p = sp(); p <= temp_addr(0); p++) {
00412 MarkSweep::follow_root(p);
00413 }
00414 MarkSweep::follow_root((oop*)hp_addr());
00415 MarkSweep::follow_root(receiver_addr());
00416 return;
00417 }
00418
00419 if (is_compiled_frame()) {
00420 if (has_compiled_float_marker() && follow_roots_compiled_float_frame()) return;
00421
00422 for (oop* p = sp(); p < (oop*)fp(); p++) MarkSweep::follow_root(p);
00423 return;
00424 }
00425
00426 if (is_entry_frame()) {
00427 for (oop* p = sp(); p < (oop*)fp(); p++) MarkSweep::follow_root(p);
00428 return;
00429 }
00430
00431 if (is_deoptimized_frame()) {
00432
00433 oop* end = (oop*)fp() + frame_real_sender_sp_offset;
00434 for (oop* p = sp(); p < end; p++) MarkSweep::follow_root(p);
00435 MarkSweep::follow_root((oop*)frame_array_addr());
00436 return;
00437 }
00438 }
00439
00440 void frame::convert_hcode_pointer() {
00441 if (!is_interpreted_frame()) return;
00442
00443 u_char* h = hp();
00444 u_char* obj = (u_char*) as_memOop(Universe::object_start((oop*) h));
00445 set_hp(obj);
00446
00447 MarkSweep::add_hcode_offset(h - obj);
00448
00449 }
00450
00451 void frame::restore_hcode_pointer() {
00452 if (!is_interpreted_frame()) return;
00453
00454 u_char* obj = hp();
00455 int offset = MarkSweep::next_hcode_offset();
00456
00457 set_hp(obj + offset);
00458 }
00459
00460 class VerifyOopClosure : public OopClosure {
00461 public:
00462 frame* fr;
00463 void do_oop(oop* o) {
00464 oop obj = *o;
00465 if (!obj->verify()) {
00466 lprintf("Verify failed in frame:\n");
00467 fr->print();
00468 }
00469 }
00470 };
00471
00472 void frame::verify() const {
00473 if (fp() == NULL) fatal("fp cannot be NULL");
00474 if (sp() == NULL) fatal("fp cannot be NULL");
00475 VerifyOopClosure blk;
00476 blk.fr = (frame*) this;
00477 ((frame*) this)->oop_iterate(&blk);
00478 }
00479
00480 frame frame::sender() const {
00481 frame result;
00482 if (is_entry_frame()) {
00483
00484
00485 assert(has_next_Delta_fp(), "next Delta fp must be non zero");
00486 assert(next_Delta_fp() > _fp, "must be above this frame on stack");
00487 result = frame(next_Delta_sp(), next_Delta_fp());
00488 } else if (is_deoptimized_frame()) {
00489 result = frame(real_sender_sp(), link(), return_addr());
00490 } else {
00491 result = frame(sender_sp(), link(), return_addr());
00492 }
00493 return result;
00494 }
00495
00496 frame frame::delta_sender() const {
00497 for (frame s = sender(); !s.is_delta_frame(); s = s.sender()) ;
00498 return s;
00499 }
00500
00501 bool frame::should_be_deoptimized() const {
00502 if (!is_compiled_frame()) return false;
00503 nmethod* nm = code();
00504 if (TraceApplyChange) {
00505 std->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false");
00506 nm->print_value_on(std);
00507 std->cr();
00508 }
00509 return nm->is_marked_for_deoptimization();
00510 }