methodKlass.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.71 $ */
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/_methodKlass.cpp.incl"
00026 
00027 void set_methodKlass_vtbl(Klass *k) {
00028   methodKlass o;
00029   k->set_vtbl_value(o.vtbl_value());
00030 }
00031 
00032 klassOop methodKlass::create_subclass(mixinOop mixin, Format format) {
00033   return NULL;
00034 }
00035 
00036 void methodKlass::oop_layout_iterate(oop obj, ObjectLayoutClosure* blk) {
00037   // header
00038   memOop(obj)->layout_iterate_header(blk);
00039   methodOop m = methodOop(obj);
00040   blk->do_oop("debugInfo", (oop*) &m->addr()->_debugInfo);
00041   blk->do_oop("selector",  (oop*) &m->addr()->_selector_or_method);
00042   blk->do_oop("sizeCodes", (oop*) &m->addr()->_size_and_flags);
00043   // indexables
00044   lprintf("methodKlass::oop_layout_iterate not implemented yet\n");
00045   CodeIterator c(m);
00046   do {
00047     // Put in the meat here.
00048   } while (c.advance());
00049 }
00050 
00051 void methodKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
00052   // header
00053   memOop(obj)->oop_iterate_header(blk);
00054   methodOop m = methodOop(obj);
00055   blk->do_oop((oop*) &m->addr()->_debugInfo);
00056   blk->do_oop((oop*) &m->addr()->_selector_or_method);
00057   blk->do_oop((oop*) &m->addr()->_size_and_flags);
00058   // codes
00059   CodeIterator c(m);
00060   do {
00061     switch(c.format()) {
00062      case Bytecodes::BBO  : blk->do_oop(c.aligned_oop(2));   break; // BBO
00063      case Bytecodes::BBOO : blk->do_oop(c.aligned_oop(2));
00064      case Bytecodes::BBLO : blk->do_oop(c.aligned_oop(2)+1); break; // BBOO, BBLO
00065      case Bytecodes::BOL  :
00066      case Bytecodes::BO   : blk->do_oop(c.aligned_oop(1));   break; // BOL, BO
00067      case Bytecodes::BOO  :
00068      case Bytecodes::BOOLB: blk->do_oop(c.aligned_oop(1));
00069      case Bytecodes::BLO  : blk->do_oop(c.aligned_oop(1)+1); break; // BOO, BOOLB, BLO
00070     }
00071   } while (c.advance());
00072 }
00073 
00074 void methodKlass::oop_print_layout(oop obj) {
00075   methodOop(obj)->print_codes();
00076 }
00077 
00078 void methodKlass::oop_print_on(oop obj, outputStream* st) {
00079   assert(obj->is_method(), "must be method");
00080   methodOop method = methodOop(obj);
00081 
00082   int indent_col =  3;
00083   int value_col  = 16;
00084 
00085   // header
00086   memOopKlass::oop_print_value_on(obj, st);
00087   st->cr();
00088 
00089   // selector/outer method
00090   st->fill_to(indent_col);
00091   st->print("%s:", method->is_blockMethod() ? "outer" : "selector");
00092   st->fill_to(value_col);
00093   method->selector_or_method()->print_value_on(st);
00094   st->cr();
00095 
00096   // holder
00097   klassOop k = Universe::method_holder_of(method->home());
00098   if (k) {
00099     st->fill_to(indent_col);
00100     st->print("holder:");
00101     st->fill_to(value_col);
00102     k->print_value_on(st);
00103     st->cr();
00104   }
00105 
00106   // incovation counter
00107   st->fill_to(indent_col);
00108   st->print("invocation:");
00109   st->fill_to(value_col);
00110   st->print_cr("%d", method->invocation_count());
00111 
00112   // sharing counter
00113   st->fill_to(indent_col);
00114   st->print("sharing:");
00115   st->fill_to(value_col);
00116   st->print_cr("%d", method->sharing_count());
00117 
00118   // code size
00119   st->fill_to(indent_col);
00120   st->print("code size:");
00121   st->fill_to(value_col);
00122   st->print_cr("%d", method->size_of_codes());
00123 
00124   // arguments
00125   st->fill_to(indent_col);
00126   st->print("arguments:");
00127   st->fill_to(value_col);
00128   st->print_cr("%d", method->nofArgs());
00129 
00130   // debug array
00131   st->fill_to(indent_col);
00132   st->print("debug info:");
00133   st->fill_to(value_col);
00134   method->debugInfo()->print_value_on(st);
00135   st->cr();
00136 
00137   // flags
00138   st->fill_to(indent_col);
00139   st->print("flags:");
00140   st->fill_to(value_col);
00141   st->print("%s", method->is_customized() ? "customized" : "not_customized");
00142   if (method->allocatesInterpretedContext()) {
00143     st->print(" allocates_context"); 
00144   }
00145   if (method->mustBeCustomizedToClass()) {
00146     st->print(" class_specific"); 
00147   }
00148   if (method->containsNLR()) {
00149     st->print(" NLR"); 
00150   }
00151 
00152   // flags for blocks
00153   if (method->is_blockMethod()) {
00154     switch(method->block_info()) {
00155       case methodOopDesc::expects_nil:       st->print(" pure_block");              break;
00156       case methodOopDesc::expects_self:      st->print(" self_copying_block");      break;
00157       case methodOopDesc::expects_parameter: st->print(" parameter_copying_block"); break;
00158       case methodOopDesc::expects_context:   st->print(" full_block");              break;
00159     }
00160   } else { 
00161     switch(method->method_inlining_info()) {
00162       case methodOopDesc::normal_inline:     st->print(" normal inline");           break;
00163       case methodOopDesc::never_inline:      st->print(" never inline");            break;
00164       case methodOopDesc::always_inline:     st->print(" aways inline");            break;
00165     }
00166   }
00167   st->cr();
00168 }
00169 
00170 void methodKlass::oop_print_value_on(oop obj, outputStream* st) {
00171   assert(obj->is_method(), "must be method");
00172   methodOop method = methodOop(obj);
00173   if (PrintObjectID) {
00174     memOop(obj)->print_id_on(st);
00175     st->print("-");
00176   }
00177   if (method->is_blockMethod()) {
00178     st->print("BlockMethod in ");
00179     method->enclosing_method_selector()->print_symbol_on(st);
00180   } else {
00181     st->print("Method ");
00182     method->selector()->print_symbol_on(st);
00183   }
00184   if (ProfilerShowMethodHolder) {
00185     klassOop k = Universe::method_holder_of(method);
00186     st->print(" in ");
00187     if (k) {
00188       k->print_value_on(st);
00189     } else {
00190       st->print("(unknown)");
00191     }
00192   }
00193 }
00194 
00195 int methodKlass::oop_scavenge_contents(oop obj) {
00196   // Methods must reside in old space
00197   ShouldNotCallThis();
00198   return -1;  
00199 }
00200 
00201 int methodKlass::oop_scavenge_tenured_contents(oop obj) {
00202   // There should be no new objects referred insinde a methodOop
00203   return object_size(methodOop(obj)->size_of_codes());  
00204 }
00205 
00206 void methodKlass::oop_follow_contents(oop obj) {
00207   methodOop m = methodOop(obj);
00208   CodeIterator c(m);
00209   do {
00210     switch(c.format()) {
00211      case Bytecodes::BBO  : MarkSweep::reverse_and_push(c.aligned_oop(2));   break; // BBO
00212      case Bytecodes::BBOO : MarkSweep::reverse_and_push(c.aligned_oop(2));
00213      case Bytecodes::BBLO : MarkSweep::reverse_and_push(c.aligned_oop(2)+1); break; // BBOO, BBLO
00214      case Bytecodes::BOL  :
00215      case Bytecodes::BO   : MarkSweep::reverse_and_push(c.aligned_oop(1));   break; // BOL, BO
00216      case Bytecodes::BOO  :
00217      case Bytecodes::BOOLB: MarkSweep::reverse_and_push(c.aligned_oop(1));
00218      case Bytecodes::BLO  : MarkSweep::reverse_and_push(c.aligned_oop(1)+1); break; // BOO, BOOLB, BLO
00219     }
00220   } while (c.advance());
00221   MarkSweep::reverse_and_push((oop*) &m->addr()->_debugInfo);
00222   MarkSweep::reverse_and_push((oop*) &m->addr()->_selector_or_method);
00223   m->follow_header();
00224 }
00225 
00226 static oop tenured(oop obj) {
00227   return obj->is_old() ? obj : obj->shallow_copy(true);
00228 }
00229 
00230 methodOop methodKlass::constructMethod(oop selector_or_method, int flags, int nofArgs, 
00231                                        objArrayOop debugInfo, byteArrayOop bytes, objArrayOop oops) {
00232   klassOop k        = as_klassOop();
00233   int      obj_size = methodOopDesc::header_size() + oops->length();
00234 
00235   assert(oops->length() * oopSize == bytes->length(), "Invalid array sizes");
00236 
00237   // allocate
00238   methodOop method = as_methodOop(Universe::allocate_tenured(obj_size));
00239   memOop(method)->initialize_header(has_untagged_contents(), k);
00240 
00241   // initialize the header
00242   method->set_debugInfo(objArrayOop(tenured(debugInfo)));
00243   method->set_selector_or_method(tenured(selector_or_method));
00244 
00245   method->set_invocation_count(0);
00246   method->set_sharing_count(0);
00247   method->set_size_and_flags(oops->length(), nofArgs, flags);
00248 
00249   // merge the bytes and the oops
00250 
00251   // first copy the byte array into the method
00252   for (int index = 1; index <= bytes->length(); index++) {
00253     method->byte_at_put(index, bytes->byte_at(index));
00254   }
00255 
00256   // then merge in the oops
00257   for (index = 1; index <= oops->length(); index++) {
00258     bool copyOop = true;
00259     int bc_index = index*oopSize-(oopSize-1);
00260     for (int i = 0; i < oopSize; i++) {
00261       // copy oop if bytearray holds 4 consecutive aligned zeroes
00262       if (bytes->byte_at(bc_index+i) != 0) {
00263         copyOop = false;
00264       }
00265     }
00266     if (copyOop) {
00267       oop value = tenured(oops->obj_at(index));
00268       assert(value->is_smi() || value->is_old(), "literal must be tenured");
00269       method->oop_at_put(bc_index, value);
00270     }
00271   }
00272 
00273   assert(method->is_method(), "must be method");
00274   return method;
00275 }

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