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 # include "incls/_vframe.cpp.incl"
00027
00028
00029
00030
00031
00032
00033 bool vframe::equal(const vframe* f) const {
00034 return _fr.fp() == f->_fr.fp();
00035 }
00036
00037 oop vframe::callee_argument_at(int index) const {
00038 err->print_cr("vframe::callee_argument_at should be specialized for all vframes calling deltaVFrames");
00039 fatal("aborting");
00040 return NULL;
00041 }
00042
00043 vframe* vframe::new_vframe(frame* f) {
00044 if (f->is_interpreted_frame()) return new interpretedVFrame(f);
00045 if (f->is_entry_frame()) return new cChunk(f);
00046 if (f->is_deoptimized_frame()) return new deoptimizedVFrame(f);
00047 #ifdef DELTA_COMPILER
00048 if (f->is_compiled_frame()) {
00049 nmethod* nm = f->code();
00050 assert(nm, "nmethod not found");
00051
00052
00053
00054 char* pc = f->pc() - 1;
00055 PcDesc* pd = nm->containingPcDesc(pc);
00056 assert(pd, "PcDesc not found");
00057
00058 ScopeDesc* sd = nm->scopes()->at(pd->scope, pc);
00059 assert(sd, "ScopeDesc not found");
00060 return compiledVFrame::new_vframe(f, sd, pd->byteCode);
00061 }
00062 #endif
00063 return new cVFrame(f);
00064 }
00065
00066 vframe* vframe::sender() const {
00067 assert(is_top(), "just checking");
00068 frame s = _fr.sender();
00069 if (s.is_first_frame()) return NULL;
00070 return vframe::new_vframe(&s);
00071 }
00072
00073 vframe* vframe::top() const {
00074 vframe* vf = (vframe*) this;
00075 while (!vf->is_top()) vf = vf->sender();
00076 return vf;
00077 }
00078
00079 void vframe::print() {
00080 if (WizardMode || ActivationShowFrame) {
00081 _fr.print();
00082 }
00083 }
00084
00085 void vframe::print_value() const {
00086 ((vframe*)this)->print();
00087 }
00088
00089
00090
00091 GrowableArray<oop>* deltaVFrame::arguments() const {
00092 int nargs = method()->number_of_arguments();
00093 GrowableArray<oop>* result = new GrowableArray<oop>(nargs);
00094 vframe* s = sender();
00095 for (int index = 0; index < nargs; index++) {
00096 result->push(argument_at(index));
00097 }
00098 return result;
00099 }
00100
00101 oop deltaVFrame::argument_at(int index) const {
00102 return sender()->callee_argument_at(method()->number_of_arguments() - (index+1));
00103 }
00104
00105 oop deltaVFrame::callee_argument_at(int index) const {
00106 return expression_at(index);
00107 }
00108
00109 void deltaVFrame::print() {
00110 lprintf("Delta frame: ");
00111 vframe::print();
00112 }
00113
00114 void deltaVFrame::print_activation(int index) const {
00115 ((vframe*)this)->vframe::print();
00116 prettyPrinter::print(index, (deltaVFrame*) this);
00117 }
00118
00119
00120 deltaVFrame* deltaVFrame::sender_delta_frame() const {
00121 vframe* f = sender();
00122 while (f != NULL) {
00123 if (f->is_delta_frame()) return (deltaVFrame*) f;
00124 f = f->sender();
00125 }
00126 return NULL;
00127 }
00128
00129 void deltaVFrame::verify() const {
00130
00131 fr().verify();
00132
00133 int number_of_arguments = method()->number_of_arguments();
00134 for (int index = 0; index < number_of_arguments; index++) {
00135 oop argument = argument_at(index);
00136 if (argument->is_context()) {
00137 std->print_cr("Argument is a context");
00138 print_activation(0);
00139 warning("verify failed");
00140 }
00141 }
00142 }
00143
00144
00145 bool interpretedVFrame::has_interpreter_context() const {
00146 return method()->activation_has_context();
00147 }
00148
00149 oop interpretedVFrame::temp_at(int offset) const {
00150 assert(offset > 0 || !has_interpreter_context(),
00151 "you cannot use temp(0) when a context is present");
00152 assert(offset < method()->number_of_stack_temporaries(), "checking bounds");
00153 return _fr.temp(offset);
00154 }
00155
00156 oop interpretedVFrame::context_temp_at(int offset) const {
00157 assert(has_interpreter_context(), "must have context when using context_temp_at");
00158 return interpreter_context()->obj_at(offset);
00159 }
00160
00161 contextOop interpretedVFrame::interpreter_context() const {
00162 if (!has_interpreter_context()) return NULL;
00163 contextOop result = contextOop(_fr.temp(0));
00164 assert(method()->in_context_allocation(bci()) || result->is_context(), "context type check");
00165 return result;
00166 }
00167
00168 contextOop interpretedVFrame::canonical_context() const {
00169 return interpreter_context();
00170 }
00171
00172 oop interpretedVFrame::expression_at(int index) const {
00173 return *expression_addr(index);
00174 }
00175
00176 oop* interpretedVFrame::expression_addr(int offset) const {
00177 return (oop*) &((oop*) _fr.sp())[offset];
00178 }
00179
00180 GrowableArray<oop>* interpretedVFrame::expression_stack() const {
00181 int last_temp_number = method()->number_of_stack_temporaries() - 1;
00182 int size = _fr.temp_addr(last_temp_number) - expression_addr(0);
00183 assert(size >= 0, "expr stack size must be non-negative");
00184 GrowableArray<oop>* result = new GrowableArray<oop>(size);
00185 for (int index = 0; index < size; index++) {
00186 oop value = expression_at(index);
00187 assert(!value->is_context(), "checking for contextOop on expression stack");
00188 result->push(expression_at(index));
00189 }
00190 #ifdef ASSERT
00191 int computed_size = method()->expression_stack_mapping(bci())->length();
00192 if (size != computed_size) {
00193 warning("Expression stack size @%d is %d but computed to %d", bci(), size, computed_size);
00194 std->print_cr("[expression stack:");
00195 for (int index = 0; index < result->length(); index++) {
00196 std->print(" - ");
00197 result->at(index)->print_value_on(std);
00198 std->cr();
00199 }
00200 std->print_cr("]");
00201 method()->pretty_print();
00202 method()->print_codes();
00203 }
00204 #endif
00205 return result;
00206 }
00207
00208 u_char* interpretedVFrame::hp() const {
00209 return _fr.hp();
00210 }
00211
00212 void interpretedVFrame::set_hp(u_char* p) {
00213 _fr.set_hp(p);
00214 }
00215
00216 oop interpretedVFrame::receiver() const {
00217
00218
00219
00220 oop r = _fr.receiver();
00221 assert(!r->is_context() || method()->is_blockMethod(), "check: context implies block method");
00222 return r->is_context() ? nilObj : r;
00223 }
00224
00225 void interpretedVFrame::set_receiver(oop obj) {
00226 _fr.set_receiver(obj);
00227 }
00228
00229 void interpretedVFrame::temp_at_put(int offset, oop obj) {
00230 _fr.set_temp(offset, obj);
00231 }
00232
00233 void interpretedVFrame::expression_at_put(int offset, oop obj) {
00234
00235 Unimplemented();
00236 }
00237
00238 bool interpretedVFrame::equal(const vframe* f) const {
00239 if (!f->is_interpreted_frame()) return false;
00240 return vframe::equal(f);
00241 }
00242
00243 int interpretedVFrame::bci() const {
00244 return method()->bci_from(hp());
00245 }
00246
00247 methodOop interpretedVFrame::method() const {
00248 memOop m = as_memOop(Universe::object_start((oop*) (hp() - 1)));
00249 assert(m->is_method(), "must be method");
00250 return methodOop(m);
00251 }
00252
00253 deltaVFrame* interpretedVFrame::parent() const {
00254 methodOop m = method();
00255
00256
00257 if (!m->is_blockMethod()) return NULL;
00258
00259 contextOop target = interpreter_context();
00260 if (!target) return NULL;
00261
00262
00263
00264
00265
00266 for (vframe* p = sender(); p; p = p->sender()) {
00267 if (p->is_interpreted_frame())
00268 if (((interpretedVFrame*)p)->interpreter_context() == target)
00269 return (deltaVFrame*) p;
00270 }
00271
00272 warning("parent frame is not found on same stack");
00273
00274 return NULL;
00275 }
00276
00277 void interpretedVFrame::verify() const {
00278 deltaVFrame::verify();
00279 methodOop m = method();
00280 if(m->activation_has_context()) {
00281 if (!m->in_context_allocation(bci())) {
00282 contextOop con = interpreter_context();
00283 if (!con->is_context()) warning("expecting context");
00284 if (!m->is_blockMethod()) {
00285 if(con->parent_fp() == NULL) warning("expecting frame in context");
00286 }
00287 m->verify_context(con);
00288 }
00289 }
00290 }
00291
00292 # ifdef DELTA_COMPILER
00293
00294
00295
00296 compiledVFrame* compiledVFrame::new_vframe(const frame* fr, ScopeDesc* sd, int bci) {
00297 if (sd->isMethodScope())
00298 return new compiledMethodVFrame(fr, sd, bci);
00299 if (sd->isTopLevelBlockScope())
00300 return new compiledTopLevelBlockVFrame(fr, sd, bci);
00301 if (sd->isBlockScope())
00302 return new compiledBlockVFrame(fr, sd, bci);
00303 fatal("unknown scope desc");
00304 return NULL;
00305 }
00306
00307 void compiledVFrame::rewind_bci() {
00308 int new_bci = method()->find_bci_from(_bci);
00309 assert(new_bci >= 0, "must be real bci");
00310 std->print_cr("%d -> %d", _bci, new_bci);
00311 _bci = new_bci;
00312 }
00313
00314 compiledVFrame::compiledVFrame(const frame* fr, ScopeDesc* sd, int bci) : deltaVFrame(fr) {
00315 this->sd = sd;
00316 this->_bci = bci;
00317 }
00318
00319 vframe* compiledVFrame::sender() const {
00320 if (sd->isTop()) return vframe::sender();
00321 return compiledVFrame::new_vframe(&_fr, sd->sender(), sd->senderBCI());
00322 }
00323
00324 oop compiledVFrame::temp_at(int offset) const {
00325 assert(offset > 0 || !method()->activation_has_context(),
00326 "you cannot use temp(0) when a context is present");
00327 assert(offset < method()->number_of_stack_temporaries(), "checking bounds");
00328 return resolve_name(scope()->temporary(offset), this);
00329 }
00330
00331 class ContextTempFindClosure : public NameDescClosure {
00332 public:
00333 NameDesc* result;
00334 int i;
00335 ContextTempFindClosure(int index) {
00336 i = index;
00337 result = NULL; }
00338 void context_temp (int no, NameDesc* a, char* pc) {
00339 if (no == i) result = a;
00340 }
00341 };
00342
00343 oop compiledVFrame::context_temp_at(int offset) const {
00344 assert(method()->activation_has_context(),
00345 "you cannot use context_temp_at() when methodOop does not allocate context");
00346 ContextTempFindClosure blk(offset);
00347 sd->iterate(&blk);
00348 assert(blk.result, "must find result");
00349 return resolve_name(blk.result, this);
00350 }
00351
00352 oop compiledVFrame::expression_at(int index) const {
00353 GrowableArray<oop>* stack = expression_stack();
00354 if (stack->length() <= index) {
00355
00356 return oopFactory::new_symbol("invalid stack element");
00357 }
00358 return stack->at(index);
00359 }
00360
00361 class CollectContextInfoClosure : public NameDescClosure {
00362 public:
00363 GrowableArray<NameDesc*>* result;
00364 CollectContextInfoClosure() {
00365 result = new GrowableArray<NameDesc*>(10);
00366 }
00367 void context_temp(int no, NameDesc* a, char* pc) {
00368 result->append(a);
00369 }
00370 };
00371
00372 extern "C" contextOop allocateContext(int nofVars);
00373
00374 contextOop compiledVFrame::compiled_context() const {
00375 if (!method()->activation_has_context()) return NULL;
00376
00377
00378
00379
00380
00381 oop con = resolve_name(scope()->temporary(0), this);
00382 if (con == nilObj) return NULL;
00383
00384 assert(con->is_context(), "context type check");
00385 return contextOop(con);
00386 }
00387
00388 GrowableArray<oop>* compiledVFrame::expression_stack() const {
00389 GrowableArray<int>* mapping = method()->expression_stack_mapping(bci());
00390 GrowableArray<oop>* result = new GrowableArray<oop>(mapping->length());
00391 for (int index = 0; index < mapping->length(); index++) {
00392 NameDesc* nd = sd->exprStackElem(mapping->at(index));
00393 oop value = resolve_name(nd, this);
00394 result->push(value);
00395 }
00396 #ifdef ASSERT
00397 int computed_size = method()->expression_stack_mapping(bci())->length();
00398 if (result->length() != computed_size) {
00399 warning("Expression stack size @%d is %d but computed to %d", bci(), result->length(), computed_size);
00400 std->print_cr("[expression stack:");
00401 for (int index = 0; index < result->length(); index++) {
00402 std->print(" - ");
00403 result->at(index)->print_value_on(std);
00404 std->cr();
00405 }
00406 std->print_cr("]");
00407 method()->pretty_print();
00408 method()->print_codes();
00409 }
00410 #endif
00411 return result;
00412 }
00413
00414 bool compiledVFrame::equal(const vframe* f) const {
00415 if (!f->is_compiled_frame()) return false;
00416 return vframe::equal(f)
00417 && scope()->is_equal(((compiledVFrame*)f)->scope());
00418 }
00419
00420 int compiledVFrame::bci() const {
00421 return _bci;
00422 }
00423
00424 methodOop compiledVFrame::method() const {
00425 return sd->method();
00426 }
00427
00428 nmethod* compiledVFrame::code() const {
00429 return _fr.code();
00430 }
00431
00432 oop compiledVFrame::resolve_location(Location loc, const compiledVFrame* vf, contextOop con) {
00433
00434
00435 if (loc.isStackLocation()) {
00436 return vf
00437 ? oop(vf->fr().at(loc.offset()))
00438 : filler_oop();
00439 }
00440
00441
00442 if (loc.isContextLocation()) {
00443 if (vf) {
00444 ScopeDesc* scope = vf->code()->scopes()->at(loc.scopeOffs(), vf->fr().pc());
00445 assert(scope->allocates_compiled_context(), "must have context");
00446 assert(scope->compiled_context()->isLocation(), "context must be a location");
00447 contextOop context = contextOop(resolve_location(scope->compiled_context()->location(), vf));
00448 return context->obj_at(loc.tempNo());
00449 }
00450
00451 if (con) {
00452 return con->obj_at(loc.tempNo());
00453 }
00454
00455 return filler_oop();
00456 }
00457
00458
00459 if (loc.isRegisterLocation()) {
00460 return SavedRegisters::fetch(loc.number(), vf->fr().fp());
00461 }
00462
00463 ShouldNotReachHere();
00464 return NULL;
00465 }
00466
00467 oop compiledVFrame::resolve_name(NameDesc* nd, const compiledVFrame* vf, contextOop con) {
00468
00469
00470
00471 if (nd->isLocation()) {
00472
00473 Location loc = nd->location();
00474 return resolve_location(loc, vf, con);
00475 }
00476
00477 if (nd->isValue()) {
00478
00479 return nd->value();
00480 }
00481
00482 if (nd->isBlockValue()) {
00483
00484 frame f = vf->fr();
00485 oop result = nd->value(&f);
00486 return result;
00487 }
00488
00489 if (nd->isMemoizedBlock()) {
00490
00491
00492 frame f = vf->fr();
00493 oop result = nd->value(&f);
00494 return result;
00495 }
00496
00497 if (nd->isIllegal()) {
00498
00499
00500
00501 if (UseNewBackend) {
00502
00503
00504 return nilObj;
00505 }
00506 warning("Compiler Bug: Illegal name desc found in nmethod 0x%lx @ %d",
00507 vf->fr().code(), vf->scope()->offset());
00508 return oopFactory::new_symbol("illegal nameDesc");
00509 }
00510
00511 ShouldNotReachHere();
00512 return NULL;
00513 }
00514
00515 oop compiledVFrame::filler_oop() {
00516 return nilObj;
00517
00518
00519 }
00520
00521 int compiledVFrame::bci_for(ScopeDesc* d) const {
00522 ScopeDesc* s = sd;
00523 int b = bci();
00524 while (!s->is_equal(d)) {
00525 b = s->senderBCI();
00526 assert(s->sender(), "make sure we have a sender");
00527 s = s->sender();
00528 }
00529 return b;
00530 }
00531
00532 #define CHECK(n) if (n->isIllegal()) ok = false
00533
00534 class VerifyNDClosure : public NameDescClosure {
00535 public:
00536 bool ok;
00537 VerifyNDClosure() { ok = true; }
00538 void arg (int no, NameDesc* a, char* pc) { CHECK(a); }
00539 void temp (int no, NameDesc* a, char* pc) { CHECK(a); }
00540 void context_temp (int no, NameDesc* a, char* pc) { CHECK(a); }
00541 };
00542
00543 void compiledVFrame::verify_debug_info() const {
00544
00545 ResourceMark rm;
00546 bool ok = true;
00547 VerifyNDClosure blk;
00548 sd->iterate(&blk);
00549 CHECK(sd->self());
00550
00551 if (!ok || !blk.ok) {
00552 print_activation(0);
00553 error("illegal nameDescs in vframe");
00554 }
00555 #undef CHECK
00556 }
00557
00558 contextOop compiledVFrame::compute_canonical_context(ScopeDesc* scope, const compiledVFrame* vf, contextOop con) {
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 if (!scope->allocates_interpreted_context()) {
00570
00571 if (scope->isMethodScope()) return NULL;
00572 compiledVFrame* parent_vf = (!vf || scope->isTopLevelBlockScope()) ? NULL : (compiledVFrame*) vf->parent();
00573 return compute_canonical_context(scope->parent(true), parent_vf, con);
00574 }
00575
00576 contextOop result;
00577
00578
00579 if (vf) {
00580 if ((result = StackChunkBuilder::context_at(vf)) != NULL) {
00581 assert(result->unoptimized_context() == NULL, "cannot have deoptimized context");
00582 return result;
00583 }
00584 }
00585
00586
00587 if (con && con->unoptimized_context()) {
00588 result = con->unoptimized_context();
00589 assert(result->unoptimized_context() == NULL, "cannot have deoptimized context");
00590 return result;
00591 }
00592
00593 contextOop comp_context = con;
00594 assert(comp_context == NULL || comp_context->is_context(), "must be context");
00595
00596
00597 if (!MaterializeEliminatedBlocks && !StackChunkBuilder::is_deoptimizing()) {
00598
00599
00600
00601 ResourceMark rm;
00602 stringStream st(50);
00603 st.print("eliminated context in ");
00604 scope->selector()->print_symbol_on(&st);
00605 return (contextOop)oopFactory::new_symbol(st.as_string());
00606 }
00607
00608
00609 CollectContextInfoClosure blk;
00610 scope->iterate(&blk);
00611
00612
00613 result = contextKlass::allocate_context(blk.result->length());
00614
00615
00616 for(int index = 0; index < blk.result->length(); index++) {
00617 NameDesc* nd = blk.result->at(index);
00618 result->obj_at_put(index, resolve_name(nd, vf, comp_context));
00619 }
00620
00621 if (vf) {
00622 StackChunkBuilder::context_at_put(vf, result);
00623 } else {
00624
00625 result->kill();
00626 }
00627
00628 assert(result->unoptimized_context() == NULL, "cannot have deoptimized context");
00629
00630
00631 if (!scope->isMethodScope()) {
00632 contextOop parent = compute_canonical_context(scope->parent(true),
00633 (!vf || scope->isTopLevelBlockScope()) ? NULL : (compiledVFrame*) vf->parent(),
00634 con ? con->outer_context() : NULL);
00635 result->set_parent(parent);
00636 }
00637
00638 if (StackChunkBuilder::is_deoptimizing() && comp_context) {
00639
00640
00641 comp_context->set_unoptimized_context(result);
00642 }
00643
00644 if (TraceDeoptimization && comp_context) {
00645 std->print(" - ");
00646 comp_context->print_value();
00647 std->print_cr(" -> ");
00648 result->print_value();
00649 std->cr();
00650 }
00651
00652 assert(result->unoptimized_context() == NULL, "cannot have deoptimized context");
00653 return result;
00654 }
00655
00656 void compiledVFrame::verify() const {
00657 deltaVFrame::verify();
00658 contextOop con = compiled_context();
00659 if (con) {
00660 if(con->mark()->has_context_forward())
00661 warning("context has forwarder");
00662 }
00663 }
00664
00665
00666 compiledMethodVFrame::compiledMethodVFrame(const frame* fr, ScopeDesc* sd, int bci)
00667 : compiledVFrame(fr, sd, bci) {}
00668
00669
00670 bool compiledMethodVFrame::is_top() const {
00671 return sd->isTop();
00672 }
00673
00674 oop compiledMethodVFrame::receiver() const {
00675 return resolve_name(sd->self(), this);
00676 }
00677
00678 contextOop compiledMethodVFrame::canonical_context() const {
00679 assert(!method()->is_blockMethod(), "check methodOop type");
00680 return compute_canonical_context(scope(), this, compiled_context());
00681 }
00682
00683
00684
00685 compiledBlockVFrame::compiledBlockVFrame(const frame* fr, ScopeDesc* sd, int bci)
00686 : compiledVFrame(fr, sd, bci) {}
00687
00688 bool compiledBlockVFrame::is_top() const {
00689 return sd->isTop();
00690 }
00691
00692 oop compiledBlockVFrame::receiver() const {
00693 NameDesc* nd = sd->self();
00694 if (nd) {
00695 return resolve_name(nd, this);
00696 } else {
00697 fatal("self is unknown");
00698 return NULL;
00699 }
00700 }
00701
00702 deltaVFrame* compiledBlockVFrame::parent() const {
00703 ScopeDesc* ps = parent_scope();
00704 int parent_bci = bci_for(ps);
00705 return compiledVFrame::new_vframe(&_fr, ps, parent_bci);
00706 }
00707
00708 contextOop compiledBlockVFrame::canonical_context() const {
00709 assert(method()->is_blockMethod(), "must be block method");
00710 return compute_canonical_context(scope(), this, compiled_context());
00711 }
00712
00713 ScopeDesc* compiledBlockVFrame::parent_scope() const {
00714 ScopeDesc* result = scope()->parent();
00715 assert(result, "parent should be within same nmethod");
00716 return result;
00717 }
00718
00719
00720
00721 compiledTopLevelBlockVFrame::compiledTopLevelBlockVFrame(const frame* fr, ScopeDesc* sd, int bci)
00722 : compiledVFrame(fr, sd, bci) {}
00723
00724 oop compiledTopLevelBlockVFrame::receiver() const {
00725 return resolve_name(sd->self(), this);
00726 }
00727
00728 deltaVFrame* compiledTopLevelBlockVFrame::parent() const {
00729 methodOop m = method();
00730 if (!m->expectsContext()) return NULL;
00731
00732 contextOop parent_context = m->allocatesInterpretedContext()
00733 ? compiled_context()->outer_context()
00734 : compiled_context();
00735
00736
00737 if (parent_context->is_dead()) return NULL;
00738
00739
00740 ScopeDesc* ps = parent_scope();
00741 nmethod* parent_nmethod = ps->scopes()->my_nmethod();
00742
00743 frame v = fr().sender();
00744 do {
00745 if (v.is_compiled_frame()) {
00746 if (v.code() == parent_nmethod) {
00747 compiledVFrame* result = (compiledVFrame*) vframe::new_vframe(&v);
00748
00749 while (result) {
00750 assert(result->is_compiled_frame(), "must be compiled frame");
00751 if (result->scope()->is_equal(ps)) {
00752 if (result->compiled_context() == parent_context)
00753 return result;
00754 }
00755 result = result->is_top() ? NULL : (compiledVFrame*) result->sender();
00756 }
00757 }
00758 }
00759 v = v.sender();
00760 } while (!v.is_first_frame());
00761 return NULL;
00762 }
00763
00764 contextOop compiledTopLevelBlockVFrame::canonical_context() const {
00765 assert(method()->is_blockMethod(), "must be block method");
00766 return compute_canonical_context(scope(), this, compiled_context());
00767 }
00768
00769 ScopeDesc* compiledTopLevelBlockVFrame::parent_scope() const {
00770 ScopeDesc* result = scope()->parent(true);
00771 assert(result, "parent scope must be present");
00772 return result;
00773 }
00774
00775
00776
00777 objArrayOop deoptimizedVFrame::retrieve_frame_array() const {
00778 objArrayOop array = _fr.frame_array();
00779 assert(array->is_objArray(), "expecting objArray");
00780 return array;
00781 }
00782
00783 oop deoptimizedVFrame::obj_at(int index) const {
00784 return frame_array->obj_at(offset + index);
00785 }
00786
00787 bool deoptimizedVFrame::is_top() const {
00788 return offset + end_of_expressions() > frame_array->length();
00789 }
00790
00791 int deoptimizedVFrame::end_of_expressions() const {
00792 smiOop n = smiOop(obj_at(locals_size_offset));
00793 assert(n->is_smi(), "expecting smi");
00794 return first_temp_offset + n->value();
00795 }
00796
00797 deoptimizedVFrame::deoptimizedVFrame(const frame* fr)
00798 : deltaVFrame(fr) {
00799
00800 this->offset = StackChunkBuilder::first_frame_index;
00801 this->frame_array = retrieve_frame_array();
00802 }
00803
00804 deoptimizedVFrame::deoptimizedVFrame(const frame* fr, int offset)
00805 : deltaVFrame(fr) {
00806 this->offset = offset;
00807 this->frame_array = retrieve_frame_array();
00808 }
00809
00810 oop deoptimizedVFrame::receiver() const {
00811 return obj_at(receiver_offset);
00812 }
00813
00814 methodOop deoptimizedVFrame::method() const {
00815 methodOop m = methodOop(obj_at(method_offset));
00816 assert(m->is_method(), "expecting method");
00817 return m;
00818 }
00819
00820 int deoptimizedVFrame::bci() const {
00821 smiOop b = smiOop(obj_at(bci_offset));
00822 assert(b->is_smi(), "expecting smi");
00823 return b->value();
00824 }
00825
00826 vframe* deoptimizedVFrame::sender() const {
00827 return is_top() ? vframe::sender()
00828 : new deoptimizedVFrame(&_fr, offset + end_of_expressions());
00829 }
00830
00831 bool deoptimizedVFrame::equal(const vframe* f) const {
00832 if (!f->is_deoptimized_frame()) return false;
00833 return vframe::equal(f)
00834 && offset == ((deoptimizedVFrame*)f)->offset;
00835 }
00836
00837 oop deoptimizedVFrame::temp_at(int offset) const {
00838 return obj_at(first_temp_offset + offset);
00839 }
00840
00841 oop deoptimizedVFrame::expression_at(int index) const {
00842 return obj_at(end_of_expressions() - 1 - index);
00843 }
00844
00845 oop deoptimizedVFrame::context_temp_at(int offset) const {
00846 assert(deoptimized_context(), "must have context when using context_temp_at");
00847 return deoptimized_context()->obj_at(offset);
00848 }
00849
00850 contextOop deoptimizedVFrame::deoptimized_context() const {
00851 if (!method()->activation_has_context()) return NULL;
00852 contextOop result = contextOop(temp_at(0));
00853 assert(result->is_context(), "context type check");
00854 return result;
00855 }
00856
00857 contextOop deoptimizedVFrame::canonical_context() const {
00858 return deoptimized_context();
00859 }
00860
00861 GrowableArray<oop>* deoptimizedVFrame::expression_stack() const {
00862 int locals = end_of_expressions() - first_temp_offset;
00863 int temps = method()->number_of_stack_temporaries();
00864 int exp_size = locals - temps;
00865
00866 GrowableArray<oop>* array = new GrowableArray<oop>(exp_size);
00867 for (int index = 0 ; index < exp_size; index++) {
00868 array->push(expression_at(index));
00869 }
00870
00871 #ifdef ASSERT
00872 int computed_size = method()->expression_stack_mapping(bci())->length();
00873 if (exp_size != computed_size)
00874 warning("Expression stack size is %d but computed to %d", exp_size, computed_size);
00875 #endif
00876
00877 return array;
00878 }
00879
00880 #endif
00881
00882
00883
00884 void cVFrame::print() {
00885 vframe::print();
00886 std->print_cr("C frame");
00887 }
00888
00889 void cVFrame::print_value() const {
00890 ((vframe*)this)->print();
00891 }
00892
00893
00894
00895 vframe* cChunk::sender() const {
00896 return cVFrame::sender();
00897 }
00898
00899 void cChunk::print_value() const {
00900 ((cChunk*)this)->print();
00901 }
00902
00903 void cChunk::print() {
00904 vframe::print();
00905 std->print_cr("C Chunk inbetween Delta");
00906 std->print_cr("C link 0x%lx", _fr.link());
00907 }
00908
00909 oop cChunk::callee_argument_at(int index) const {
00910 return oop(_fr.sp()[index]);
00911 }
00912