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/_blockOop.cpp.incl"
00026
00027 methodOop blockClosureOopDesc::method() const {
00028 oop m = addr()->_methodOrJumpAddr;
00029
00030 # ifdef DELTA_COMPILER
00031 if (isCompiledBlock()) {
00032 jumpTableEntry* e = (jumpTableEntry*) m;
00033 assert(e->is_block_closure_stub(), "must be block stub");
00034 return e->block_method();
00035 }
00036 # endif
00037
00038 return methodOop(m);
00039 }
00040
00041 int blockClosureOopDesc::number_of_arguments() {
00042 return ((blockClosureKlass*)klass())->number_of_arguments();
00043 }
00044
00045 bool blockClosureOopDesc::is_pure() const {
00046 return !lexical_scope()->is_context();
00047 }
00048
00049 void blockClosureOopDesc::verify() {
00050 memOopDesc::verify();
00051 oop m = addr()->_methodOrJumpAddr;
00052 # ifdef DELTA_COMPILER
00053 if (isCompiledBlock()) {
00054 jumpTableEntry* e = (jumpTableEntry*) m;
00055 e->verify();
00056 if (!e->is_block_closure_stub()) error("stub %#x of block %#x isn't a closure stub", e, this);
00057 } else {
00058 m->verify();
00059 }
00060 # endif
00061 }
00062
00063 blockClosureOop blockClosureOopDesc::create_clean_block(int nofArgs, char* entry_point) {
00064 blockClosureOop blk = allocateTenuredBlock(as_smiOop(nofArgs));
00065 blk->set_lexical_scope((contextOop)nilObj);
00066 blk->set_jumpAddr(entry_point);
00067 return blk;
00068 }
00069
00070 void blockClosureOopDesc::deoptimize() {
00071 if (!isCompiledBlock()) return;
00072
00073 contextOop con = lexical_scope();
00074 if (con == nilObj) return;
00075
00076 int index;
00077 nmethod* nm = jump_table_entry()->parent_nmethod(index);
00078 NonInlinedBlockScopeDesc* scope = nm->noninlined_block_scope_at(index);
00079
00080 LOG_EVENT1("Deoptimized context in blockClosure -> switch to methodOop 0x%lx", nm);
00081 assert(nm, "nmethod must be present");
00082
00083 assert(!StackChunkBuilder::is_deoptimizing(), "you cannot be in deoptimization mode");
00084 StackChunkBuilder::begin_deoptimization();
00085
00086
00087 set_method(scope->method());
00088 con = compiledVFrame::compute_canonical_context(scope->parent(), NULL, con);
00089 set_lexical_scope(con);
00090
00091 StackChunkBuilder::end_deoptimization();
00092 }
00093
00094
00095 bool contextOopDesc::is_dead() const {
00096
00097 return parent() == oop(smiOop_zero) || parent() == nilObj;
00098 }
00099
00100 bool contextOopDesc::has_parent_fp() const {
00101
00102 return parent()->is_smi() && !is_dead();
00103 }
00104
00105 bool contextOopDesc::has_outer_context() const {
00106
00107 return parent()->is_context();
00108 }
00109
00110 contextOop contextOopDesc::outer_context() const {
00111 if (has_outer_context()) {
00112 contextOop con = contextOop(parent());
00113 assert(con->is_context(), "must be context");
00114 return con;
00115 }
00116 return NULL;
00117 }
00118
00119 void contextOopDesc::set_unoptimized_context(contextOop con) {
00120 assert(!mark()->has_context_forward(), "checking if context is deoptimized");
00121 assert(this != con, "Checking for forward cycle");
00122 set_parent(con);
00123 set_mark(mark()->set_context_forward());
00124 }
00125
00126 contextOop contextOopDesc::unoptimized_context() {
00127 if (mark()->has_context_forward()) {
00128 contextOop con = contextOop(parent());
00129 assert(con->is_context(), "must be context");
00130 return con;
00131 }
00132 return NULL;
00133 }
00134
00135 int contextOopDesc::chain_length() const {
00136 int size = 1;
00137 #ifdef ASSERT
00138 GrowableArray<contextOop>* path = new GrowableArray<contextOop>(10);
00139 for (contextOop cc = contextOop(this); cc->has_outer_context(); cc = cc->outer_context()) {
00140 assert(path->find(cc) < 0, "cycle has been detected in a context chain")
00141 path->append(cc);
00142 }
00143 #endif
00144 for (contextOop con = contextOop(this); con->has_outer_context(); con = con->outer_context()) {
00145 size++;
00146 }
00147 return size;
00148 }
00149
00150 void contextOopDesc::print_home_on(outputStream* st) {
00151 if (mark()->has_context_forward()) {
00152 st->print("deoptimized to (");
00153 unoptimized_context()->print_value();
00154 st->print(")");
00155 } else if (has_parent_fp()) {
00156 st->print("frame 0x%lx", parent_fp());
00157 } else if (has_outer_context()) {
00158 st->print("outer context ");
00159 outer_context()->print_value_on(st);
00160 } else {
00161 assert(is_dead(), "context must be dead");
00162 st->print("dead");
00163 }
00164 }