src/share/vm/ci/ciStreams.cpp

Wed, 02 Jun 2010 22:45:42 -0700

author
jrose
date
Wed, 02 Jun 2010 22:45:42 -0700
changeset 1934
e9ff18c4ace7
parent 1907
c18cbe5936b8
parent 1920
ab102d5d923e
child 1957
136b78722a08
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_ciStreams.cpp.incl"
    28 // ciExceptionHandlerStream
    29 //
    30 // Walk over some selected set of a methods exception handlers.
    32 // ------------------------------------------------------------------
    33 // ciExceptionHandlerStream::count
    34 //
    35 // How many exception handlers are there in this stream?
    36 //
    37 // Implementation note: Compiler2 needs this functionality, so I had
    38 int ciExceptionHandlerStream::count() {
    39   int save_pos = _pos;
    40   int save_end = _end;
    42   int count = 0;
    44   _pos = -1;
    45   _end = _method->_handler_count;
    48   next();
    49   while (!is_done()) {
    50     count++;
    51     next();
    52   }
    54   _pos = save_pos;
    55   _end = save_end;
    57   return count;
    58 }
    60 int ciExceptionHandlerStream::count_remaining() {
    61   int save_pos = _pos;
    62   int save_end = _end;
    64   int count = 0;
    66   while (!is_done()) {
    67     count++;
    68     next();
    69   }
    71   _pos = save_pos;
    72   _end = save_end;
    74   return count;
    75 }
    77 // ciBytecodeStream
    78 //
    79 // The class is used to iterate over the bytecodes of a method.
    80 // It hides the details of constant pool structure/access by
    81 // providing accessors for constant pool items.
    83 // ------------------------------------------------------------------
    84 // ciBytecodeStream::next_wide_or_table
    85 //
    86 // Special handling for switch ops
    87 Bytecodes::Code ciBytecodeStream::next_wide_or_table(Bytecodes::Code bc) {
    88   switch (bc) {                // Check for special bytecode handling
    89   case Bytecodes::_wide:
    90     // Special handling for the wide bytcode
    91     // Get following bytecode; do not return wide
    92     assert(Bytecodes::Code(_pc[0]) == Bytecodes::_wide, "");
    93     bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)_pc[1]);
    94     assert(Bytecodes::wide_length_for(bc) > 2, "must make progress");
    95     _pc += Bytecodes::wide_length_for(bc);
    96     _was_wide = _pc;              // Flag last wide bytecode found
    97     assert(is_wide(), "accessor works right");
    98     break;
   100   case Bytecodes::_lookupswitch:
   101     _pc++;                      // Skip wide bytecode
   102     _pc += (_start-_pc)&3;      // Word align
   103     _table_base = (jint*)_pc;   // Capture for later usage
   104                                 // table_base[0] is default far_dest
   105     // Table has 2 lead elements (default, length), then pairs of u4 values.
   106     // So load table length, and compute address at end of table
   107     _pc = (address)&_table_base[2+ 2*Bytes::get_Java_u4((address)&_table_base[1])];
   108     break;
   110   case Bytecodes::_tableswitch: {
   111     _pc++;                      // Skip wide bytecode
   112     _pc += (_start-_pc)&3;      // Word align
   113     _table_base = (jint*)_pc;   // Capture for later usage
   114                                 // table_base[0] is default far_dest
   115     int lo = Bytes::get_Java_u4((address)&_table_base[1]);// Low bound
   116     int hi = Bytes::get_Java_u4((address)&_table_base[2]);// High bound
   117     int len = hi - lo + 1;      // Dense table size
   118     _pc = (address)&_table_base[3+len]; // Skip past table
   119     break;
   120   }
   122   default:
   123     fatal("unhandled bytecode");
   124   }
   125   return bc;
   126 }
   128 // ------------------------------------------------------------------
   129 // ciBytecodeStream::reset_to_bci
   130 void ciBytecodeStream::reset_to_bci( int bci ) {
   131   _bc_start=_was_wide=0;
   132   _pc = _start+bci;
   133 }
   135 // ------------------------------------------------------------------
   136 // ciBytecodeStream::force_bci
   137 void ciBytecodeStream::force_bci(int bci) {
   138   if (bci < 0) {
   139     reset_to_bci(0);
   140     _bc_start = _start + bci;
   141     _bc = EOBC();
   142   } else {
   143     reset_to_bci(bci);
   144     next();
   145   }
   146 }
   149 // ------------------------------------------------------------------
   150 // Constant pool access
   151 // ------------------------------------------------------------------
   153 // ------------------------------------------------------------------
   154 // ciBytecodeStream::get_klass_index
   155 //
   156 // If this bytecodes references a klass, return the index of the
   157 // referenced klass.
   158 int ciBytecodeStream::get_klass_index() const {
   159   switch(cur_bc()) {
   160   case Bytecodes::_ldc:
   161     return get_index_u1();
   162   case Bytecodes::_ldc_w:
   163   case Bytecodes::_ldc2_w:
   164   case Bytecodes::_checkcast:
   165   case Bytecodes::_instanceof:
   166   case Bytecodes::_anewarray:
   167   case Bytecodes::_multianewarray:
   168   case Bytecodes::_new:
   169   case Bytecodes::_newarray:
   170     return get_index_u2();
   171   default:
   172     ShouldNotReachHere();
   173     return 0;
   174   }
   175 }
   177 // ------------------------------------------------------------------
   178 // ciBytecodeStream::get_klass
   179 //
   180 // If this bytecode is a new, newarray, multianewarray, instanceof,
   181 // or checkcast, get the referenced klass.
   182 ciKlass* ciBytecodeStream::get_klass(bool& will_link) {
   183   VM_ENTRY_MARK;
   184   constantPoolHandle cpool(_method->get_methodOop()->constants());
   185   return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder);
   186 }
   188 // ------------------------------------------------------------------
   189 // ciBytecodeStream::get_constant_index
   190 //
   191 // If this bytecode is one of the ldc variants, get the index of the
   192 // referenced constant.
   193 int ciBytecodeStream::get_constant_index() const {
   194   switch(cur_bc()) {
   195   case Bytecodes::_ldc:
   196     return get_index_u1();
   197   case Bytecodes::_ldc_w:
   198   case Bytecodes::_ldc2_w:
   199     return get_index_u2();
   200   default:
   201     ShouldNotReachHere();
   202     return 0;
   203   }
   204 }
   205 // ------------------------------------------------------------------
   206 // ciBytecodeStream::get_constant
   207 //
   208 // If this bytecode is one of the ldc variants, get the referenced
   209 // constant.
   210 ciConstant ciBytecodeStream::get_constant() {
   211   VM_ENTRY_MARK;
   212   constantPoolHandle cpool(_method->get_methodOop()->constants());
   213   return CURRENT_ENV->get_constant_by_index(cpool, get_constant_index(), _holder);
   214 }
   216 // ------------------------------------------------------------------
   217 bool ciBytecodeStream::is_unresolved_string() const {
   218   return CURRENT_ENV->is_unresolved_string(_holder, get_constant_index());
   219 }
   221 // ------------------------------------------------------------------
   222 bool ciBytecodeStream::is_unresolved_klass() const {
   223   return CURRENT_ENV->is_unresolved_klass(_holder, get_klass_index());
   224 }
   226 // ------------------------------------------------------------------
   227 // ciBytecodeStream::get_field_index
   228 //
   229 // If this is a field access bytecode, get the constant pool
   230 // index of the referenced field.
   231 int ciBytecodeStream::get_field_index() {
   232   assert(cur_bc() == Bytecodes::_getfield ||
   233          cur_bc() == Bytecodes::_putfield ||
   234          cur_bc() == Bytecodes::_getstatic ||
   235          cur_bc() == Bytecodes::_putstatic, "wrong bc");
   236   return get_index_u2_cpcache();
   237 }
   240 // ------------------------------------------------------------------
   241 // ciBytecodeStream::get_field
   242 //
   243 // If this bytecode is one of get_field, get_static, put_field,
   244 // or put_static, get the referenced field.
   245 ciField* ciBytecodeStream::get_field(bool& will_link) {
   246   ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index());
   247   will_link = f->will_link(_holder, _bc);
   248   return f;
   249 }
   252 // ------------------------------------------------------------------
   253 // ciBytecodeStream::get_declared_field_holder
   254 //
   255 // Get the declared holder of the currently referenced field.
   256 //
   257 // Usage note: the holder() of a ciField class returns the canonical
   258 // holder of the field, rather than the holder declared in the
   259 // bytecodes.
   260 //
   261 // There is no "will_link" result passed back.  The user is responsible
   262 // for checking linkability when retrieving the associated field.
   263 ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() {
   264   VM_ENTRY_MARK;
   265   constantPoolHandle cpool(_method->get_methodOop()->constants());
   266   int holder_index = get_field_holder_index();
   267   bool ignore;
   268   return CURRENT_ENV->get_klass_by_index(cpool, holder_index, ignore, _holder)
   269       ->as_instance_klass();
   270 }
   272 // ------------------------------------------------------------------
   273 // ciBytecodeStream::get_field_holder_index
   274 //
   275 // Get the constant pool index of the declared holder of the field
   276 // referenced by the current bytecode.  Used for generating
   277 // deoptimization information.
   278 int ciBytecodeStream::get_field_holder_index() {
   279   GUARDED_VM_ENTRY(
   280     constantPoolOop cpool = _holder->get_instanceKlass()->constants();
   281     return cpool->klass_ref_index_at(get_field_index());
   282   )
   283 }
   285 // ------------------------------------------------------------------
   286 // ciBytecodeStream::get_field_signature_index
   287 //
   288 // Get the constant pool index of the signature of the field
   289 // referenced by the current bytecode.  Used for generating
   290 // deoptimization information.
   291 int ciBytecodeStream::get_field_signature_index() {
   292   VM_ENTRY_MARK;
   293   constantPoolOop cpool = _holder->get_instanceKlass()->constants();
   294   int nt_index = cpool->name_and_type_ref_index_at(get_field_index());
   295   return cpool->signature_ref_index_at(nt_index);
   296 }
   298 // ------------------------------------------------------------------
   299 // ciBytecodeStream::get_method_index
   300 //
   301 // If this is a method invocation bytecode, get the constant pool
   302 // index of the invoked method.
   303 int ciBytecodeStream::get_method_index() {
   304 #ifdef ASSERT
   305   switch (cur_bc()) {
   306   case Bytecodes::_invokeinterface:
   307   case Bytecodes::_invokevirtual:
   308   case Bytecodes::_invokespecial:
   309   case Bytecodes::_invokestatic:
   310   case Bytecodes::_invokedynamic:
   311     break;
   312   default:
   313     ShouldNotReachHere();
   314   }
   315 #endif
   316   if (has_index_u4())
   317     return get_index_u4();  // invokedynamic
   318   return get_index_u2_cpcache();
   319 }
   321 // ------------------------------------------------------------------
   322 // ciBytecodeStream::get_method
   323 //
   324 // If this is a method invocation bytecode, get the invoked method.
   325 ciMethod* ciBytecodeStream::get_method(bool& will_link) {
   326   VM_ENTRY_MARK;
   327   constantPoolHandle cpool(_method->get_methodOop()->constants());
   328   ciMethod* m = CURRENT_ENV->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
   329   will_link = m->is_loaded();
   330   return m;
   331 }
   333 // ------------------------------------------------------------------
   334 // ciBytecodeStream::get_declared_method_holder
   335 //
   336 // Get the declared holder of the currently referenced method.
   337 //
   338 // Usage note: the holder() of a ciMethod class returns the canonical
   339 // holder of the method, rather than the holder declared in the
   340 // bytecodes.
   341 //
   342 // There is no "will_link" result passed back.  The user is responsible
   343 // for checking linkability when retrieving the associated method.
   344 ciKlass* ciBytecodeStream::get_declared_method_holder() {
   345   VM_ENTRY_MARK;
   346   constantPoolHandle cpool(_method->get_methodOop()->constants());
   347   bool ignore;
   348   // report as InvokeDynamic for invokedynamic, which is syntactically classless
   349   if (cur_bc() == Bytecodes::_invokedynamic)
   350     return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_dyn_InvokeDynamic(), false);
   351   return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
   352 }
   354 // ------------------------------------------------------------------
   355 // ciBytecodeStream::get_method_holder_index
   356 //
   357 // Get the constant pool index of the declared holder of the method
   358 // referenced by the current bytecode.  Used for generating
   359 // deoptimization information.
   360 int ciBytecodeStream::get_method_holder_index() {
   361   constantPoolOop cpool = _method->get_methodOop()->constants();
   362   return cpool->klass_ref_index_at(get_method_index());
   363 }
   365 // ------------------------------------------------------------------
   366 // ciBytecodeStream::get_method_signature_index
   367 //
   368 // Get the constant pool index of the signature of the method
   369 // referenced by the current bytecode.  Used for generating
   370 // deoptimization information.
   371 int ciBytecodeStream::get_method_signature_index() {
   372   VM_ENTRY_MARK;
   373   constantPoolOop cpool = _holder->get_instanceKlass()->constants();
   374   int method_index = get_method_index();
   375   int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
   376   return cpool->signature_ref_index_at(name_and_type_index);
   377 }
   379 // ------------------------------------------------------------------
   380 // ciBytecodeStream::get_cpcache
   381 ciCPCache* ciBytecodeStream::get_cpcache() {
   382   VM_ENTRY_MARK;
   383   // Get the constant pool.
   384   constantPoolOop      cpool   = _holder->get_instanceKlass()->constants();
   385   constantPoolCacheOop cpcache = cpool->cache();
   387   return CURRENT_ENV->get_object(cpcache)->as_cpcache();
   388 }
   390 // ------------------------------------------------------------------
   391 // ciBytecodeStream::get_call_site
   392 ciCallSite* ciBytecodeStream::get_call_site() {
   393   VM_ENTRY_MARK;
   394   // Get the constant pool.
   395   constantPoolOop      cpool   = _holder->get_instanceKlass()->constants();
   396   constantPoolCacheOop cpcache = cpool->cache();
   398   // Get the CallSite from the constant pool cache.
   399   int method_index = get_method_index();
   400   ConstantPoolCacheEntry* cpcache_entry = cpcache->secondary_entry_at(method_index);
   401   oop call_site_oop = cpcache_entry->f1();
   403   // Create a CallSite object and return it.
   404   return CURRENT_ENV->get_object(call_site_oop)->as_call_site();
   405 }

mercurial