src/share/vm/interpreter/bytecode.cpp

Tue, 23 Nov 2010 13:22:55 -0800

author
stefank
date
Tue, 23 Nov 2010 13:22:55 -0800
changeset 2314
f95d63e2154a
parent 1957
136b78722a08
child 2462
8012aa3ccede
permissions
-rw-r--r--

6989984: Use standard include model for Hospot
Summary: Replaced MakeDeps and the includeDB files with more standardized solutions.
Reviewed-by: coleenp, kvn, kamg

     1 /*
     2  * Copyright (c) 1997, 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 "precompiled.hpp"
    26 #include "interpreter/bytecode.hpp"
    27 #include "interpreter/linkResolver.hpp"
    28 #include "oops/constantPoolOop.hpp"
    29 #include "oops/oop.inline.hpp"
    30 #include "runtime/fieldType.hpp"
    31 #include "runtime/handles.inline.hpp"
    32 #include "runtime/safepoint.hpp"
    33 #include "runtime/signature.hpp"
    35 // Implementation of Bytecode
    37 bool Bytecode::check_must_rewrite(Bytecodes::Code code) const {
    38   assert(Bytecodes::can_rewrite(code), "post-check only");
    40   // Some codes are conditionally rewriting.  Look closely at them.
    41   switch (code) {
    42   case Bytecodes::_aload_0:
    43     // Even if RewriteFrequentPairs is turned on,
    44     // the _aload_0 code might delay its rewrite until
    45     // a following _getfield rewrites itself.
    46     return false;
    48   case Bytecodes::_lookupswitch:
    49     return false;  // the rewrite is not done by the interpreter
    51   case Bytecodes::_new:
    52     // (Could actually look at the class here, but the profit would be small.)
    53     return false;  // the rewrite is not always done
    54   }
    56   // No other special cases.
    57   return true;
    58 }
    61 #ifdef ASSERT
    63 void Bytecode::assert_same_format_as(Bytecodes::Code testbc, bool is_wide) const {
    64   Bytecodes::Code thisbc = Bytecodes::cast(byte_at(0));
    65   if (thisbc == Bytecodes::_breakpoint)  return;  // let the assertion fail silently
    66   if (is_wide) {
    67     assert(thisbc == Bytecodes::_wide, "expected a wide instruction");
    68     thisbc = Bytecodes::cast(byte_at(1));
    69     if (thisbc == Bytecodes::_breakpoint)  return;
    70   }
    71   int thisflags = Bytecodes::flags(testbc, is_wide) & Bytecodes::_all_fmt_bits;
    72   int testflags = Bytecodes::flags(thisbc, is_wide) & Bytecodes::_all_fmt_bits;
    73   if (thisflags != testflags)
    74     tty->print_cr("assert_same_format_as(%d) failed on bc=%d%s; %d != %d",
    75                   (int)testbc, (int)thisbc, (is_wide?"/wide":""), testflags, thisflags);
    76   assert(thisflags == testflags, "expected format");
    77 }
    79 void Bytecode::assert_index_size(int size, Bytecodes::Code bc, bool is_wide) {
    80   int have_fmt = (Bytecodes::flags(bc, is_wide)
    81                   & (Bytecodes::_fmt_has_u2 | Bytecodes::_fmt_has_u4 |
    82                      Bytecodes::_fmt_not_simple |
    83                      // Not an offset field:
    84                      Bytecodes::_fmt_has_o));
    85   int need_fmt = -1;
    86   switch (size) {
    87   case 1: need_fmt = 0;                      break;
    88   case 2: need_fmt = Bytecodes::_fmt_has_u2; break;
    89   case 4: need_fmt = Bytecodes::_fmt_has_u4; break;
    90   }
    91   if (is_wide)  need_fmt |= Bytecodes::_fmt_not_simple;
    92   if (have_fmt != need_fmt) {
    93     tty->print_cr("assert_index_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt);
    94     assert(have_fmt == need_fmt, "assert_index_size");
    95   }
    96 }
    98 void Bytecode::assert_offset_size(int size, Bytecodes::Code bc, bool is_wide) {
    99   int have_fmt = Bytecodes::flags(bc, is_wide) & Bytecodes::_all_fmt_bits;
   100   int need_fmt = -1;
   101   switch (size) {
   102   case 2: need_fmt = Bytecodes::_fmt_bo2; break;
   103   case 4: need_fmt = Bytecodes::_fmt_bo4; break;
   104   }
   105   if (is_wide)  need_fmt |= Bytecodes::_fmt_not_simple;
   106   if (have_fmt != need_fmt) {
   107     tty->print_cr("assert_offset_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt);
   108     assert(have_fmt == need_fmt, "assert_offset_size");
   109   }
   110 }
   112 void Bytecode::assert_constant_size(int size, int where, Bytecodes::Code bc, bool is_wide) {
   113   int have_fmt = Bytecodes::flags(bc, is_wide) & (Bytecodes::_all_fmt_bits
   114                                                   // Ignore any 'i' field (for iinc):
   115                                                   & ~Bytecodes::_fmt_has_i);
   116   int need_fmt = -1;
   117   switch (size) {
   118   case 1: need_fmt = Bytecodes::_fmt_bc;                          break;
   119   case 2: need_fmt = Bytecodes::_fmt_bc | Bytecodes::_fmt_has_u2; break;
   120   }
   121   if (is_wide)  need_fmt |= Bytecodes::_fmt_not_simple;
   122   int length = is_wide ? Bytecodes::wide_length_for(bc) : Bytecodes::length_for(bc);
   123   if (have_fmt != need_fmt || where + size != length) {
   124     tty->print_cr("assert_constant_size %d @%d: bc=%d%s %d != %d", size, where, bc, (is_wide?"/wide":""), have_fmt, need_fmt);
   125   }
   126   assert(have_fmt == need_fmt, "assert_constant_size");
   127   assert(where + size == length, "assert_constant_size oob");
   128 }
   130 void Bytecode::assert_native_index(Bytecodes::Code bc, bool is_wide) {
   131   assert((Bytecodes::flags(bc, is_wide) & Bytecodes::_fmt_has_nbo) != 0, "native index");
   132 }
   134 #endif //ASSERT
   136 // Implementation of Bytecode_tableupswitch
   138 int Bytecode_tableswitch::dest_offset_at(int i) const {
   139   return get_Java_u4_at(aligned_offset(1 + (3 + i)*jintSize));
   140 }
   143 // Implementation of Bytecode_invoke
   145 void Bytecode_invoke::verify() const {
   146   assert(is_valid(), "check invoke");
   147   assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter");
   148 }
   151 symbolOop Bytecode_member_ref::signature() const {
   152   constantPoolOop constants = method()->constants();
   153   return constants->signature_ref_at(index());
   154 }
   157 symbolOop Bytecode_member_ref::name() const {
   158   constantPoolOop constants = method()->constants();
   159   return constants->name_ref_at(index());
   160 }
   163 BasicType Bytecode_member_ref::result_type(Thread *thread) const {
   164   symbolHandle sh(thread, signature());
   165   ResultTypeFinder rts(sh);
   166   rts.iterate();
   167   return rts.type();
   168 }
   171 methodHandle Bytecode_invoke::static_target(TRAPS) {
   172   methodHandle m;
   173   KlassHandle resolved_klass;
   174   constantPoolHandle constants(THREAD, _method->constants());
   176   if (java_code() == Bytecodes::_invokedynamic) {
   177     LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   178   } else if (java_code() != Bytecodes::_invokeinterface) {
   179     LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   180   } else {
   181     LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   182   }
   183   return m;
   184 }
   187 int Bytecode_member_ref::index() const {
   188   // Note:  Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
   189   // at the same time it allocates per-call-site CP cache entries.
   190   Bytecodes::Code rawc = code();
   191   Bytecode* invoke = bytecode();
   192   if (invoke->has_index_u4(rawc))
   193     return invoke->get_index_u4(rawc);
   194   else
   195     return invoke->get_index_u2_cpcache(rawc);
   196 }
   198 int Bytecode_member_ref::pool_index() const {
   199   int index = this->index();
   200   DEBUG_ONLY({
   201       if (!bytecode()->has_index_u4(code()))
   202         index -= constantPoolOopDesc::CPCACHE_INDEX_TAG;
   203     });
   204   return _method->constants()->cache()->entry_at(index)->constant_pool_index();
   205 }
   207 // Implementation of Bytecode_field
   209 void Bytecode_field::verify() const {
   210   assert(is_valid(), "check field");
   211 }
   214 // Implementation of Bytecode_loadconstant
   216 int Bytecode_loadconstant::raw_index() const {
   217   Bytecode* bcp = bytecode();
   218   Bytecodes::Code rawc = bcp->code();
   219   assert(rawc != Bytecodes::_wide, "verifier prevents this");
   220   if (Bytecodes::java_code(rawc) == Bytecodes::_ldc)
   221     return bcp->get_index_u1(rawc);
   222   else
   223     return bcp->get_index_u2(rawc, false);
   224 }
   226 int Bytecode_loadconstant::pool_index() const {
   227   int index = raw_index();
   228   if (has_cache_index()) {
   229     return _method->constants()->cache()->entry_at(index)->constant_pool_index();
   230   }
   231   return index;
   232 }
   234 BasicType Bytecode_loadconstant::result_type() const {
   235   int index = pool_index();
   236   constantTag tag = _method->constants()->tag_at(index);
   237   return tag.basic_type();
   238 }
   240 oop Bytecode_loadconstant::resolve_constant(TRAPS) const {
   241   assert(_method.not_null(), "must supply method to resolve constant");
   242   int index = raw_index();
   243   constantPoolOop constants = _method->constants();
   244   if (has_cache_index()) {
   245     return constants->resolve_cached_constant_at(index, THREAD);
   246   } else {
   247     return constants->resolve_constant_at(index, THREAD);
   248   }
   249 }
   251 //------------------------------------------------------------------------------
   252 // Non-product code
   254 #ifndef PRODUCT
   256 void Bytecode_lookupswitch::verify() const {
   257   switch (Bytecodes::java_code(code())) {
   258     case Bytecodes::_lookupswitch:
   259       { int i = number_of_pairs() - 1;
   260         while (i-- > 0) {
   261           assert(pair_at(i)->match() < pair_at(i+1)->match(), "unsorted table entries");
   262         }
   263       }
   264       break;
   265     default:
   266       fatal("not a lookupswitch bytecode");
   267   }
   268 }
   270 void Bytecode_tableswitch::verify() const {
   271   switch (Bytecodes::java_code(code())) {
   272     case Bytecodes::_tableswitch:
   273       { int lo = low_key();
   274         int hi = high_key();
   275         assert (hi >= lo, "incorrect hi/lo values in tableswitch");
   276         int i  = hi - lo - 1 ;
   277         while (i-- > 0) {
   278           // no special check needed
   279         }
   280       }
   281       break;
   282     default:
   283       fatal("not a tableswitch bytecode");
   284   }
   285 }
   287 #endif

mercurial