blockOop.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.21 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
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; // do nothing if unoptimized
00072 
00073   contextOop con = lexical_scope();
00074   if (con == nilObj) return;     // do nothing if lexical scope is nil
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   // Patch the block closure to unoptimized form
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 // -------------- contextOop --------------------
00095 bool contextOopDesc::is_dead() const { 
00096   // assert(!mark()->has_context_forward(), "checking if context is deoptimized");
00097   return parent() == oop(smiOop_zero) || parent() == nilObj;
00098 }
00099 
00100 bool contextOopDesc::has_parent_fp() const {
00101   // assert(!mark()->has_context_forward(), "checking if context is deoptimized");
00102   return parent()->is_smi() && !is_dead();
00103 }
00104 
00105 bool contextOopDesc::has_outer_context() const {
00106   // assert(!mark()->has_context_forward(), "checking if context is deoptimized");
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 }

Generated on Mon Oct 9 13:37:03 2006 for Strongtalk VM by  doxygen 1.4.7