vmSymbols.cpp revision 9801:80f8be586fae
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41541Srgrimes *
51541Srgrimes * This code is free software; you can redistribute it and/or modify it
61541Srgrimes * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181541Srgrimes *
191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201541Srgrimes * or visit www.oracle.com if you need additional information or have any
211541Srgrimes * questions.
221541Srgrimes *
231541Srgrimes */
241541Srgrimes
251541Srgrimes#include "precompiled.hpp"
261541Srgrimes#include "classfile/vmSymbols.hpp"
271541Srgrimes#include "memory/oopFactory.hpp"
281541Srgrimes#include "oops/oop.inline.hpp"
291541Srgrimes#include "runtime/handles.inline.hpp"
301541Srgrimes#include "utilities/xmlstream.hpp"
311541Srgrimes
321541Srgrimes
3322521SdysonSymbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT];
3450477Speter
351541SrgrimesSymbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ };
361541Srgrimes
372165Spaulinline int compare_symbol(const Symbol* a, const Symbol* b) {
382165Spaul  if (a == b)  return 0;
392165Spaul  // follow the natural address order:
401541Srgrimes  return (address)a > (address)b ? +1 : -1;
411541Srgrimes}
4222521Sdyson
431541Srgrimesstatic vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT];
4422521Sdysonextern "C" {
451541Srgrimes  static int compare_vmsymbol_sid(const void* void_a, const void* void_b) {
461541Srgrimes    const Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a));
471541Srgrimes    const Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b));
481541Srgrimes    return compare_symbol(a, b);
491541Srgrimes  }
501541Srgrimes}
511541Srgrimes
521541Srgrimes#ifdef ASSERT
531541Srgrimes#define VM_SYMBOL_ENUM_NAME_BODY(name, string) #name "\0"
541541Srgrimesstatic const char* vm_symbol_enum_names =
551541Srgrimes  VM_SYMBOLS_DO(VM_SYMBOL_ENUM_NAME_BODY, VM_ALIAS_IGNORE)
561541Srgrimes  "\0";
571541Srgrimesstatic const char* vm_symbol_enum_name(vmSymbols::SID sid) {
581541Srgrimes  const char* string = &vm_symbol_enum_names[0];
591541Srgrimes  int skip = (int)sid - (int)vmSymbols::FIRST_SID;
601541Srgrimes  for (; skip != 0; skip--) {
611541Srgrimes    size_t skiplen = strlen(string);
6222521Sdyson    if (skiplen == 0)  return "<unknown>";  // overflow
6322521Sdyson    string += skiplen+1;
641541Srgrimes  }
651541Srgrimes  return string;
6618006Sdg}
671541Srgrimes#endif //ASSERT
681541Srgrimes
691541Srgrimes// Put all the VM symbol strings in one place.
701541Srgrimes// Makes for a more compact libjvm.
711541Srgrimes#define VM_SYMBOL_BODY(name, string) string "\0"
721541Srgrimesstatic const char* vm_symbol_bodies = VM_SYMBOLS_DO(VM_SYMBOL_BODY, VM_ALIAS_IGNORE);
731541Srgrimes
741541Srgrimesvoid vmSymbols::initialize(TRAPS) {
7518006Sdg  assert((int)SID_LIMIT <= (1<<log2_SID_LIMIT), "must fit in this bitfield");
7641169Sbde  assert((int)SID_LIMIT*5 > (1<<log2_SID_LIMIT), "make the bitfield smaller, please");
7731132Sjulian  assert(vmIntrinsics::FLAG_LIMIT <= (1 << vmIntrinsics::log2_FLAG_LIMIT), "must fit in this bitfield");
7834266Sjulian
7934266Sjulian  if (!UseSharedSpaces) {
8022521Sdyson    const char* string = &vm_symbol_bodies[0];
811541Srgrimes    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
821541Srgrimes      Symbol* sym = SymbolTable::new_permanent_symbol(string, CHECK);
831541Srgrimes      _symbols[index] = sym;
841541Srgrimes      string += strlen(string); // skip string body
851541Srgrimes      string += 1;              // skip trailing null
861541Srgrimes    }
871541Srgrimes
881541Srgrimes    _type_signatures[T_BYTE]    = byte_signature();
891541Srgrimes    _type_signatures[T_CHAR]    = char_signature();
901541Srgrimes    _type_signatures[T_DOUBLE]  = double_signature();
911541Srgrimes    _type_signatures[T_FLOAT]   = float_signature();
921541Srgrimes    _type_signatures[T_INT]     = int_signature();
9310027Sdg    _type_signatures[T_LONG]    = long_signature();
941541Srgrimes    _type_signatures[T_SHORT]   = short_signature();
9510027Sdg    _type_signatures[T_BOOLEAN] = bool_signature();
961541Srgrimes    _type_signatures[T_VOID]    = void_signature();
9734266Sjulian    // no single signatures for T_OBJECT or T_ARRAY
981541Srgrimes  }
9922521Sdyson
10031144Sjulian#ifdef ASSERT
10131132Sjulian  // Check for duplicates:
1021541Srgrimes  for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) {
1031541Srgrimes    Symbol* sym = symbol_at((SID)i1);
1041541Srgrimes    for (int i2 = (int)FIRST_SID; i2 < i1; i2++) {
10510358Sjulian      if (symbol_at((SID)i2) == sym) {
1061541Srgrimes        tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"",
1071541Srgrimes                   vm_symbol_enum_name((SID)i2), i2,
1081541Srgrimes                   vm_symbol_enum_name((SID)i1), i1);
10931144Sjulian        sym->print_symbol_on(tty);
1101541Srgrimes        tty->print_cr("\"");
1111541Srgrimes      }
1121541Srgrimes    }
1131541Srgrimes  }
1141541Srgrimes#endif //ASSERT
1151541Srgrimes
1161541Srgrimes  // Create an index for find_id:
1171541Srgrimes  {
11831346Sbde    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
11934266Sjulian      vm_symbol_index[index] = (SID)index;
12035105Swosch    }
12131346Sbde    int num_sids = SID_LIMIT-FIRST_SID;
12231346Sbde    qsort(&vm_symbol_index[FIRST_SID], num_sids, sizeof(vm_symbol_index[0]),
12331346Sbde          compare_vmsymbol_sid);
1241541Srgrimes  }
1251541Srgrimes
12631144Sjulian#ifdef ASSERT
1271541Srgrimes  {
1281541Srgrimes    // Spot-check correspondence between strings, symbols, and enums:
1291541Srgrimes    assert(_symbols[NO_SID] == NULL, "must be");
1301541Srgrimes    const char* str = "java/lang/Object";
1311541Srgrimes    TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str, CHECK);
1321541Srgrimes    assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
13327606Sbde    assert(jlo == java_lang_Object(), "");
1341541Srgrimes    SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
1351541Srgrimes    assert(find_sid(jlo) == sid, "");
13631144Sjulian    assert(symbol_at(sid) == jlo, "");
13731144Sjulian
13831144Sjulian    // Make sure find_sid produces the right answer in each case.
1391541Srgrimes    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
1401541Srgrimes      Symbol* sym = symbol_at((SID)index);
1411541Srgrimes      sid = find_sid(sym);
1421541Srgrimes      assert(sid == (SID)index, "symbol index works");
1431541Srgrimes      // Note:  If there are duplicates, this assert will fail.
1441541Srgrimes      // A "Duplicate VM symbol" message will have already been printed.
1451541Srgrimes    }
1461541Srgrimes
14731144Sjulian    // The string "format" happens (at the moment) not to be a vmSymbol,
14831144Sjulian    // though it is a method name in java.lang.String.
14931144Sjulian    str = "format";
1501541Srgrimes    TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str, CHECK);
15131144Sjulian    sid = find_sid(fmt);
15231144Sjulian    assert(sid == NO_SID, "symbol index works (negative test)");
15331144Sjulian  }
15431144Sjulian#endif
15531144Sjulian}
15631144Sjulian
15734266Sjulian
15834266Sjulian#ifndef PRODUCT
1591541Srgrimesconst char* vmSymbols::name_for(vmSymbols::SID sid) {
16031144Sjulian  if (sid == NO_SID)
16131144Sjulian    return "NO_SID";
16231144Sjulian  const char* string = &vm_symbol_bodies[0];
1631541Srgrimes  for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
1641541Srgrimes    if (index == (int)sid)
1651541Srgrimes      return string;
1661541Srgrimes    string += strlen(string); // skip string body
1671541Srgrimes    string += 1;              // skip trailing null
16831144Sjulian  }
16922521Sdyson  return "BAD_SID";
17031144Sjulian}
17122521Sdyson#endif
17231144Sjulian
17322521Sdyson
17422521Sdyson
17522521Sdysonvoid vmSymbols::symbols_do(SymbolClosure* f) {
17631132Sjulian  for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
17731132Sjulian    f->do_symbol(&_symbols[index]);
17831132Sjulian  }
1791541Srgrimes  for (int i = 0; i < T_VOID+1; i++) {
1801541Srgrimes    f->do_symbol(&_type_signatures[i]);
18122521Sdyson  }
18222521Sdyson}
18322521Sdyson
18423289Sbdevoid vmSymbols::serialize(SerializeClosure* soc) {
18523289Sbde  soc->do_region((u_char*)&_symbols[FIRST_SID],
1862946Swollman                 (SID_LIMIT - FIRST_SID) * sizeof(_symbols[0]));
18723289Sbde  soc->do_region((u_char*)_type_signatures, sizeof(_type_signatures));
18822521Sdyson}
18922521Sdyson
19022521Sdyson
19122521SdysonBasicType vmSymbols::signature_type(const Symbol* s) {
19222521Sdyson  assert(s != NULL, "checking");
19322521Sdyson  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
19422521Sdyson    if (s == _type_signatures[i]) {
19522521Sdyson      return (BasicType)i;
19622521Sdyson    }
19722521Sdyson  }
19822521Sdyson  return T_OBJECT;
19922521Sdyson}
20022521Sdyson
20122521Sdyson
20222521Sdysonstatic int mid_hint = (int)vmSymbols::FIRST_SID+1;
20334266Sjulian
20434266Sjulian#ifndef PRODUCT
20533122Sdysonstatic int find_sid_calls, find_sid_probes;
20622521Sdyson// (Typical counts are calls=7000 and probes=17000.)
20722521Sdyson#endif
20822521Sdyson
20922521SdysonvmSymbols::SID vmSymbols::find_sid(const Symbol* symbol) {
21022521Sdyson  // Handle the majority of misses by a bounds check.
21122521Sdyson  // Then, use a binary search over the index.
21222521Sdyson  // Expected trip count is less than log2_SID_LIMIT, about eight.
21322521Sdyson  // This is slow but acceptable, given that calls are not
21422521Sdyson  // dynamically common.  (Method*::intrinsic_id has a cache.)
21522521Sdyson  NOT_PRODUCT(find_sid_calls++);
21622521Sdyson  int min = (int)FIRST_SID, max = (int)SID_LIMIT - 1;
21722521Sdyson  SID sid = NO_SID, sid1;
21822521Sdyson  int cmp1;
21922521Sdyson  sid1 = vm_symbol_index[min];
22022521Sdyson  cmp1 = compare_symbol(symbol, symbol_at(sid1));
22122521Sdyson  if (cmp1 <= 0) {              // before the first
22222521Sdyson    if (cmp1 == 0)  sid = sid1;
22322521Sdyson  } else {
22422521Sdyson    sid1 = vm_symbol_index[max];
22522521Sdyson    cmp1 = compare_symbol(symbol, symbol_at(sid1));
22622521Sdyson    if (cmp1 >= 0) {            // after the last
22727461Sdfr      if (cmp1 == 0)  sid = sid1;
22822521Sdyson    } else {
22922521Sdyson      // After checking the extremes, do a binary search.
23022521Sdyson      ++min; --max;             // endpoints are done
23127461Sdfr      int mid = mid_hint;       // start at previous success
23227461Sdfr      while (max >= min) {
23327461Sdfr        assert(mid >= min && mid <= max, "");
23427461Sdfr        NOT_PRODUCT(find_sid_probes++);
23527461Sdfr        sid1 = vm_symbol_index[mid];
23627461Sdfr        cmp1 = compare_symbol(symbol, symbol_at(sid1));
23727461Sdfr        if (cmp1 == 0) {
23827461Sdfr          mid_hint = mid;
23927461Sdfr          sid = sid1;
24027461Sdfr          break;
24127461Sdfr        }
24222521Sdyson        if (cmp1 < 0)
24322521Sdyson          max = mid - 1;        // symbol < symbol_at(sid)
24422521Sdyson        else
24522521Sdyson          min = mid + 1;
2462946Swollman
24722521Sdyson        // Pick a new probe point:
24822521Sdyson        mid = (max + min) / 2;
24922521Sdyson      }
25022521Sdyson    }
25122521Sdyson  }
25222521Sdyson
2532946Swollman#ifdef ASSERT
2542946Swollman  // Perform the exhaustive self-check the first 1000 calls,
25523289Sbde  // and every 100 calls thereafter.
25623289Sbde  static int find_sid_check_count = -2000;
25723289Sbde  if ((uint)++find_sid_check_count > (uint)100) {
25823289Sbde    if (find_sid_check_count > 0)  find_sid_check_count = 0;
25923289Sbde
26023289Sbde    // Make sure this is the right answer, using linear search.
26123289Sbde    // (We have already proven that there are no duplicates in the list.)
26223289Sbde    SID sid2 = NO_SID;
2637095Swollman    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
2647095Swollman      Symbol* sym2 = symbol_at((SID)index);
2657095Swollman      if (sym2 == symbol) {
2667095Swollman        sid2 = (SID)index;
26722521Sdyson        break;
26822521Sdyson      }
26922521Sdyson    }
27022521Sdyson    // Unless it's a duplicate, assert that the sids are the same.
27122521Sdyson    if (_symbols[sid] != _symbols[sid2]) {
27222521Sdyson      assert(sid == sid2, "binary same as linear search");
2737093Swollman    }
27422521Sdyson  }
27522521Sdyson#endif //ASSERT
27630354Sphk
27730354Sphk  return sid;
27830354Sphk}
27922521Sdyson
28038866SbdevmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
28122521Sdyson  Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name));
28222521Sdyson  if (symbol == NULL)  return NO_SID;
2832946Swollman  return find_sid(symbol);
2841541Srgrimes}
2851541Srgrimes
2861541Srgrimesstatic vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
2871541Srgrimes#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
2881541Srgrimes  switch (TYPE2(type, unboxing)) {
2891541Srgrimes#define BASIC_TYPE_CASE(type, box, unbox) \
2901541Srgrimes    case TYPE2(type, false):  return vmIntrinsics::box; \
2911541Srgrimes    case TYPE2(type, true):   return vmIntrinsics::unbox
2921541Srgrimes    BASIC_TYPE_CASE(T_BOOLEAN, _Boolean_valueOf,   _booleanValue);
2931541Srgrimes    BASIC_TYPE_CASE(T_BYTE,    _Byte_valueOf,      _byteValue);
2941541Srgrimes    BASIC_TYPE_CASE(T_CHAR,    _Character_valueOf, _charValue);
2951541Srgrimes    BASIC_TYPE_CASE(T_SHORT,   _Short_valueOf,     _shortValue);
2961541Srgrimes    BASIC_TYPE_CASE(T_INT,     _Integer_valueOf,   _intValue);
2971541Srgrimes    BASIC_TYPE_CASE(T_LONG,    _Long_valueOf,      _longValue);
2981541Srgrimes    BASIC_TYPE_CASE(T_FLOAT,   _Float_valueOf,     _floatValue);
2991541Srgrimes    BASIC_TYPE_CASE(T_DOUBLE,  _Double_valueOf,    _doubleValue);
3001541Srgrimes#undef BASIC_TYPE_CASE
3011541Srgrimes  }
3021541Srgrimes#undef TYPE2
3031541Srgrimes  return vmIntrinsics::_none;
3041541Srgrimes}
3051541Srgrimes
3061541SrgrimesvmIntrinsics::ID vmIntrinsics::for_boxing(BasicType type) {
3071541Srgrimes  return wrapper_intrinsic(type, false);
30828270Swollman}
3091541SrgrimesvmIntrinsics::ID vmIntrinsics::for_unboxing(BasicType type) {
3101541Srgrimes  return wrapper_intrinsic(type, true);
31122521Sdyson}
31238757Sbde
3131541SrgrimesvmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest) {
3141541Srgrimes#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
3151541Srgrimes  switch (SRC_DEST(src, dest)) {
3161541Srgrimes  case SRC_DEST(T_INT, T_FLOAT):   return vmIntrinsics::_intBitsToFloat;
3171541Srgrimes  case SRC_DEST(T_FLOAT, T_INT):   return vmIntrinsics::_floatToRawIntBits;
3181541Srgrimes
3191541Srgrimes  case SRC_DEST(T_LONG, T_DOUBLE): return vmIntrinsics::_longBitsToDouble;
3201541Srgrimes  case SRC_DEST(T_DOUBLE, T_LONG): return vmIntrinsics::_doubleToRawLongBits;
3211541Srgrimes  }
3221541Srgrimes#undef SRC_DEST
3231541Srgrimes
3241541Srgrimes  return vmIntrinsics::_none;
3251541Srgrimes}
3261541Srgrimes
3272946Swollmanbool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
32840435Speter  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
32941056Speter  switch(id) {
33038909Sbde#ifdef TRACE_HAVE_INTRINSICS
33141056Speter  case vmIntrinsics::_classID:
33241056Speter  case vmIntrinsics::_threadID:
33341056Speter  case vmIntrinsics::_counterTime:
33441056Speter#endif
33541056Speter  case vmIntrinsics::_currentTimeMillis:
33641056Speter  case vmIntrinsics::_nanoTime:
33741056Speter  case vmIntrinsics::_floatToRawIntBits:
33841056Speter  case vmIntrinsics::_intBitsToFloat:
33941056Speter  case vmIntrinsics::_doubleToRawLongBits:
34041056Speter  case vmIntrinsics::_longBitsToDouble:
34141056Speter  case vmIntrinsics::_getClass:
34241056Speter  case vmIntrinsics::_isInstance:
34340966Speter  case vmIntrinsics::_currentThread:
34440435Speter  case vmIntrinsics::_dabs:
3451541Srgrimes  case vmIntrinsics::_dsqrt:
3461541Srgrimes  case vmIntrinsics::_dsin:
34739271Sphk  case vmIntrinsics::_dcos:
34834927Sbde  case vmIntrinsics::_dtan:
3491541Srgrimes  case vmIntrinsics::_dlog:
3501541Srgrimes  case vmIntrinsics::_dlog10:
3511541Srgrimes  case vmIntrinsics::_dexp:
3521541Srgrimes  case vmIntrinsics::_dpow:
3531541Srgrimes  case vmIntrinsics::_checkIndex:
3541541Srgrimes  case vmIntrinsics::_Reference_get:
3551541Srgrimes  case vmIntrinsics::_updateCRC32:
3561541Srgrimes  case vmIntrinsics::_updateBytesCRC32:
3571541Srgrimes  case vmIntrinsics::_updateByteBufferCRC32:
3581541Srgrimes    return true;
3591541Srgrimes  default:
3601541Srgrimes    return false;
3611541Srgrimes  }
3621541Srgrimes}
3631541Srgrimes
3641541Srgrimesbool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
3651541Srgrimes  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
36622521Sdyson  switch(id) {
3671541Srgrimes#ifdef TRACE_HAVE_INTRINSICS
3681541Srgrimes  case vmIntrinsics::_counterTime:
3691541Srgrimes#endif
3701541Srgrimes  case vmIntrinsics::_currentTimeMillis:
3712213Sbde  case vmIntrinsics::_nanoTime:
37227461Sdfr  case vmIntrinsics::_floatToRawIntBits:
37327461Sdfr  case vmIntrinsics::_intBitsToFloat:
37422521Sdyson  case vmIntrinsics::_doubleToRawLongBits:
37522521Sdyson  case vmIntrinsics::_longBitsToDouble:
37622521Sdyson  case vmIntrinsics::_currentThread:
37722521Sdyson  case vmIntrinsics::_dabs:
3781541Srgrimes  case vmIntrinsics::_dsqrt:
3791541Srgrimes  case vmIntrinsics::_dsin:
3801541Srgrimes  case vmIntrinsics::_dcos:
38128270Swollman  case vmIntrinsics::_dtan:
38234266Sjulian  case vmIntrinsics::_dlog:
38322521Sdyson  case vmIntrinsics::_dlog10:
38422521Sdyson  case vmIntrinsics::_dexp:
38541169Sbde  case vmIntrinsics::_dpow:
3863151Sphk  case vmIntrinsics::_updateCRC32:
38722521Sdyson  case vmIntrinsics::_updateBytesCRC32:
38822521Sdyson  case vmIntrinsics::_updateByteBufferCRC32:
3897090Sbde    return false;
39040435Speter  default:
39140435Speter    return true;
39210027Sdg  }
39322521Sdyson}
39427461Sdfr
3951541Srgrimesbool vmIntrinsics::does_virtual_dispatch(vmIntrinsics::ID id) {
39622521Sdyson  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
3971541Srgrimes  switch(id) {
3981541Srgrimes  case vmIntrinsics::_hashCode:
3991541Srgrimes  case vmIntrinsics::_clone:
4001541Srgrimes    return true;
4011541Srgrimes    break;
4021541Srgrimes  default:
4031541Srgrimes    return false;
4041541Srgrimes  }
40522521Sdyson}
4061541Srgrimes
4071541Srgrimesint vmIntrinsics::predicates_needed(vmIntrinsics::ID id) {
4082962Swollman  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
4092962Swollman  switch (id) {
41032644Sbde  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
41123289Sbde  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
41223289Sbde    return 1;
41323289Sbde  case vmIntrinsics::_digestBase_implCompressMB:
41432644Sbde    return 3;
41532644Sbde  default:
4162962Swollman    return 0;
4172962Swollman  }
4182962Swollman}
4191541Srgrimes
4201541Srgrimesbool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
4212213Sbde  vmIntrinsics::ID id = method->intrinsic_id();
4222165Spaul  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
4232213Sbde
424  // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in
425  // the following switch statement.
426  if (!InlineNatives) {
427    switch (id) {
428    case vmIntrinsics::_indexOfL:
429    case vmIntrinsics::_indexOfU:
430    case vmIntrinsics::_indexOfUL:
431    case vmIntrinsics::_indexOfIL:
432    case vmIntrinsics::_indexOfIU:
433    case vmIntrinsics::_indexOfIUL:
434    case vmIntrinsics::_indexOfU_char:
435    case vmIntrinsics::_compareToL:
436    case vmIntrinsics::_compareToU:
437    case vmIntrinsics::_compareToLU:
438    case vmIntrinsics::_compareToUL:
439    case vmIntrinsics::_equalsL:
440    case vmIntrinsics::_equalsU:
441    case vmIntrinsics::_equalsC:
442    case vmIntrinsics::_getCharStringU:
443    case vmIntrinsics::_putCharStringU:
444    case vmIntrinsics::_compressStringC:
445    case vmIntrinsics::_compressStringB:
446    case vmIntrinsics::_inflateStringC:
447    case vmIntrinsics::_inflateStringB:
448    case vmIntrinsics::_getAndAddInt:
449    case vmIntrinsics::_getAndAddLong:
450    case vmIntrinsics::_getAndSetInt:
451    case vmIntrinsics::_getAndSetLong:
452    case vmIntrinsics::_getAndSetObject:
453    case vmIntrinsics::_loadFence:
454    case vmIntrinsics::_storeFence:
455    case vmIntrinsics::_fullFence:
456    case vmIntrinsics::_hasNegatives:
457    case vmIntrinsics::_Reference_get:
458      break;
459    default:
460      return true;
461    }
462  }
463
464  switch (id) {
465  case vmIntrinsics::_isInstance:
466  case vmIntrinsics::_isAssignableFrom:
467  case vmIntrinsics::_getModifiers:
468  case vmIntrinsics::_isInterface:
469  case vmIntrinsics::_isArray:
470  case vmIntrinsics::_isPrimitive:
471  case vmIntrinsics::_getSuperclass:
472  case vmIntrinsics::_Class_cast:
473  case vmIntrinsics::_getLength:
474  case vmIntrinsics::_newArray:
475  case vmIntrinsics::_getClass:
476    if (!InlineClassNatives) return true;
477    break;
478  case vmIntrinsics::_currentThread:
479  case vmIntrinsics::_isInterrupted:
480    if (!InlineThreadNatives) return true;
481    break;
482  case vmIntrinsics::_floatToRawIntBits:
483  case vmIntrinsics::_intBitsToFloat:
484  case vmIntrinsics::_doubleToRawLongBits:
485  case vmIntrinsics::_longBitsToDouble:
486  case vmIntrinsics::_dabs:
487  case vmIntrinsics::_dsqrt:
488  case vmIntrinsics::_dsin:
489  case vmIntrinsics::_dcos:
490  case vmIntrinsics::_dtan:
491  case vmIntrinsics::_dlog:
492  case vmIntrinsics::_dexp:
493  case vmIntrinsics::_dpow:
494  case vmIntrinsics::_dlog10:
495  case vmIntrinsics::_datan2:
496  case vmIntrinsics::_min:
497  case vmIntrinsics::_max:
498  case vmIntrinsics::_floatToIntBits:
499  case vmIntrinsics::_doubleToLongBits:
500    if (!InlineMathNatives) return true;
501    break;
502  case vmIntrinsics::_arraycopy:
503    if (!InlineArrayCopy) return true;
504    break;
505  case vmIntrinsics::_updateCRC32:
506  case vmIntrinsics::_updateBytesCRC32:
507  case vmIntrinsics::_updateByteBufferCRC32:
508    if (!UseCRC32Intrinsics) return true;
509    break;
510  case vmIntrinsics::_getObject:
511  case vmIntrinsics::_getBoolean:
512  case vmIntrinsics::_getByte:
513  case vmIntrinsics::_getShort:
514  case vmIntrinsics::_getChar:
515  case vmIntrinsics::_getInt:
516  case vmIntrinsics::_getLong:
517  case vmIntrinsics::_getFloat:
518  case vmIntrinsics::_getDouble:
519  case vmIntrinsics::_putObject:
520  case vmIntrinsics::_putBoolean:
521  case vmIntrinsics::_putByte:
522  case vmIntrinsics::_putShort:
523  case vmIntrinsics::_putChar:
524  case vmIntrinsics::_putInt:
525  case vmIntrinsics::_putLong:
526  case vmIntrinsics::_putFloat:
527  case vmIntrinsics::_putDouble:
528  case vmIntrinsics::_getObjectVolatile:
529  case vmIntrinsics::_getBooleanVolatile:
530  case vmIntrinsics::_getByteVolatile:
531  case vmIntrinsics::_getShortVolatile:
532  case vmIntrinsics::_getCharVolatile:
533  case vmIntrinsics::_getIntVolatile:
534  case vmIntrinsics::_getLongVolatile:
535  case vmIntrinsics::_getFloatVolatile:
536  case vmIntrinsics::_getDoubleVolatile:
537  case vmIntrinsics::_putObjectVolatile:
538  case vmIntrinsics::_putBooleanVolatile:
539  case vmIntrinsics::_putByteVolatile:
540  case vmIntrinsics::_putShortVolatile:
541  case vmIntrinsics::_putCharVolatile:
542  case vmIntrinsics::_putIntVolatile:
543  case vmIntrinsics::_putLongVolatile:
544  case vmIntrinsics::_putFloatVolatile:
545  case vmIntrinsics::_putDoubleVolatile:
546  case vmIntrinsics::_getByte_raw:
547  case vmIntrinsics::_getShort_raw:
548  case vmIntrinsics::_getChar_raw:
549  case vmIntrinsics::_getInt_raw:
550  case vmIntrinsics::_getLong_raw:
551  case vmIntrinsics::_getFloat_raw:
552  case vmIntrinsics::_getDouble_raw:
553  case vmIntrinsics::_putByte_raw:
554  case vmIntrinsics::_putShort_raw:
555  case vmIntrinsics::_putChar_raw:
556  case vmIntrinsics::_putInt_raw:
557  case vmIntrinsics::_putLong_raw:
558  case vmIntrinsics::_putFloat_raw:
559  case vmIntrinsics::_putDouble_raw:
560  case vmIntrinsics::_putOrderedObject:
561  case vmIntrinsics::_putOrderedLong:
562  case vmIntrinsics::_putOrderedInt:
563  case vmIntrinsics::_getAndAddInt:
564  case vmIntrinsics::_getAndAddLong:
565  case vmIntrinsics::_getAndSetInt:
566  case vmIntrinsics::_getAndSetLong:
567  case vmIntrinsics::_getAndSetObject:
568  case vmIntrinsics::_loadFence:
569  case vmIntrinsics::_storeFence:
570  case vmIntrinsics::_fullFence:
571  case vmIntrinsics::_compareAndSwapObject:
572  case vmIntrinsics::_compareAndSwapLong:
573  case vmIntrinsics::_compareAndSwapInt:
574    if (!InlineUnsafeOps) return true;
575    break;
576  case vmIntrinsics::_getShortUnaligned:
577  case vmIntrinsics::_getCharUnaligned:
578  case vmIntrinsics::_getIntUnaligned:
579  case vmIntrinsics::_getLongUnaligned:
580  case vmIntrinsics::_putShortUnaligned:
581  case vmIntrinsics::_putCharUnaligned:
582  case vmIntrinsics::_putIntUnaligned:
583  case vmIntrinsics::_putLongUnaligned:
584  case vmIntrinsics::_allocateInstance:
585  case vmIntrinsics::_getAddress_raw:
586  case vmIntrinsics::_putAddress_raw:
587    if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
588    break;
589  case vmIntrinsics::_hashCode:
590    if (!InlineObjectHash) return true;
591    break;
592  case vmIntrinsics::_aescrypt_encryptBlock:
593  case vmIntrinsics::_aescrypt_decryptBlock:
594    if (!UseAESIntrinsics) return true;
595    break;
596  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
597  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
598    if (!UseAESIntrinsics) return true;
599    break;
600  case vmIntrinsics::_sha_implCompress:
601    if (!UseSHA1Intrinsics) return true;
602    break;
603  case vmIntrinsics::_sha2_implCompress:
604    if (!UseSHA256Intrinsics) return true;
605    break;
606  case vmIntrinsics::_sha5_implCompress:
607    if (!UseSHA512Intrinsics) return true;
608    break;
609  case vmIntrinsics::_digestBase_implCompressMB:
610    if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
611    break;
612  case vmIntrinsics::_ghash_processBlocks:
613    if (!UseGHASHIntrinsics) return true;
614    break;
615  case vmIntrinsics::_updateBytesCRC32C:
616  case vmIntrinsics::_updateDirectByteBufferCRC32C:
617    if (!UseCRC32CIntrinsics) return true;
618    break;
619  case vmIntrinsics::_updateBytesAdler32:
620  case vmIntrinsics::_updateByteBufferAdler32:
621    if (!UseAdler32Intrinsics) return true;
622    break;
623  case vmIntrinsics::_copyMemory:
624    if (!InlineArrayCopy || !InlineUnsafeOps) return true;
625    break;
626#ifdef COMPILER1
627  case vmIntrinsics::_checkIndex:
628    if (!InlineNIOCheckIndex) return true;
629    break;
630#endif // COMPILER1
631#ifdef COMPILER2
632  case vmIntrinsics::_clone:
633  case vmIntrinsics::_copyOf:
634  case vmIntrinsics::_copyOfRange:
635    // These intrinsics use both the objectcopy and the arraycopy
636    // intrinsic mechanism.
637    if (!InlineObjectCopy || !InlineArrayCopy) return true;
638    break;
639  case vmIntrinsics::_compareToL:
640  case vmIntrinsics::_compareToU:
641  case vmIntrinsics::_compareToLU:
642  case vmIntrinsics::_compareToUL:
643    if (!SpecialStringCompareTo) return true;
644    break;
645  case vmIntrinsics::_indexOfL:
646  case vmIntrinsics::_indexOfU:
647  case vmIntrinsics::_indexOfUL:
648  case vmIntrinsics::_indexOfIL:
649  case vmIntrinsics::_indexOfIU:
650  case vmIntrinsics::_indexOfIUL:
651  case vmIntrinsics::_indexOfU_char:
652    if (!SpecialStringIndexOf) return true;
653    break;
654  case vmIntrinsics::_equalsL:
655  case vmIntrinsics::_equalsU:
656    if (!SpecialStringEquals) return true;
657    break;
658  case vmIntrinsics::_equalsB:
659  case vmIntrinsics::_equalsC:
660    if (!SpecialArraysEquals) return true;
661    break;
662  case vmIntrinsics::_encodeISOArray:
663  case vmIntrinsics::_encodeByteISOArray:
664    if (!SpecialEncodeISOArray) return true;
665    break;
666  case vmIntrinsics::_getCallerClass:
667    if (!InlineReflectionGetCallerClass) return true;
668    break;
669  case vmIntrinsics::_multiplyToLen:
670    if (!UseMultiplyToLenIntrinsic) return true;
671    break;
672  case vmIntrinsics::_squareToLen:
673    if (!UseSquareToLenIntrinsic) return true;
674    break;
675  case vmIntrinsics::_mulAdd:
676    if (!UseMulAddIntrinsic) return true;
677    break;
678  case vmIntrinsics::_montgomeryMultiply:
679    if (!UseMontgomeryMultiplyIntrinsic) return true;
680    break;
681  case vmIntrinsics::_montgomerySquare:
682    if (!UseMontgomerySquareIntrinsic) return true;
683    break;
684  case vmIntrinsics::_vectorizedMismatch:
685    if (!UseVectorizedMismatchIntrinsic) return true;
686    break;
687  case vmIntrinsics::_addExactI:
688  case vmIntrinsics::_addExactL:
689  case vmIntrinsics::_decrementExactI:
690  case vmIntrinsics::_decrementExactL:
691  case vmIntrinsics::_incrementExactI:
692  case vmIntrinsics::_incrementExactL:
693  case vmIntrinsics::_multiplyExactI:
694  case vmIntrinsics::_multiplyExactL:
695  case vmIntrinsics::_negateExactI:
696  case vmIntrinsics::_negateExactL:
697  case vmIntrinsics::_subtractExactI:
698  case vmIntrinsics::_subtractExactL:
699    if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
700    break;
701#endif // COMPILER2
702  default:
703    return false;
704  }
705
706  return false;
707}
708
709#define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0"
710static const char* vm_intrinsic_name_bodies =
711  VM_INTRINSICS_DO(VM_INTRINSIC_INITIALIZE,
712                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
713
714static const char* vm_intrinsic_name_table[vmIntrinsics::ID_LIMIT];
715
716const char* vmIntrinsics::name_at(vmIntrinsics::ID id) {
717  const char** nt = &vm_intrinsic_name_table[0];
718  if (nt[_none] == NULL) {
719    char* string = (char*) &vm_intrinsic_name_bodies[0];
720    for (int index = FIRST_ID; index < ID_LIMIT; index++) {
721      nt[index] = string;
722      string += strlen(string); // skip string body
723      string += 1;              // skip trailing null
724    }
725    assert(!strcmp(nt[_hashCode], "_hashCode"), "lined up");
726    nt[_none] = "_none";
727  }
728  if ((uint)id < (uint)ID_LIMIT)
729    return vm_intrinsic_name_table[(uint)id];
730  else
731    return "(unknown intrinsic)";
732}
733
734// These are flag-matching functions:
735inline bool match_F_R(jshort flags) {
736  const int req = 0;
737  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
738  return (flags & (req | neg)) == req;
739}
740inline bool match_F_Y(jshort flags) {
741  const int req = JVM_ACC_SYNCHRONIZED;
742  const int neg = JVM_ACC_STATIC;
743  return (flags & (req | neg)) == req;
744}
745inline bool match_F_RN(jshort flags) {
746  const int req = JVM_ACC_NATIVE;
747  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
748  return (flags & (req | neg)) == req;
749}
750inline bool match_F_S(jshort flags) {
751  const int req = JVM_ACC_STATIC;
752  const int neg = JVM_ACC_SYNCHRONIZED;
753  return (flags & (req | neg)) == req;
754}
755inline bool match_F_SN(jshort flags) {
756  const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE;
757  const int neg = JVM_ACC_SYNCHRONIZED;
758  return (flags & (req | neg)) == req;
759}
760inline bool match_F_RNY(jshort flags) {
761  const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED;
762  const int neg = JVM_ACC_STATIC;
763  return (flags & (req | neg)) == req;
764}
765
766// These are for forming case labels:
767#define ID3(x, y, z) (( jlong)(z) +                                  \
768                      ((jlong)(y) <<    vmSymbols::log2_SID_LIMIT) + \
769                      ((jlong)(x) << (2*vmSymbols::log2_SID_LIMIT))  )
770#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
771
772vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbols::SID holder,
773                                            vmSymbols::SID name,
774                                            vmSymbols::SID sig,
775                                            jshort flags) {
776  assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit");
777
778  // Let the C compiler build the decision tree.
779
780#define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \
781  case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \
782    if (!match_##fcode(flags))  break; \
783    return id;
784
785  switch (ID3(holder, name, sig)) {
786    VM_INTRINSICS_DO(VM_INTRINSIC_CASE,
787                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
788  }
789  return vmIntrinsics::_none;
790
791#undef VM_INTRINSIC_CASE
792}
793
794
795const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) {
796  const char* str = name_at(id);
797#ifndef PRODUCT
798  const char* kname = vmSymbols::name_for(class_for(id));
799  const char* mname = vmSymbols::name_for(name_for(id));
800  const char* sname = vmSymbols::name_for(signature_for(id));
801  const char* fname = "";
802  switch (flags_for(id)) {
803  case F_Y:  fname = "synchronized ";  break;
804  case F_RN: fname = "native ";        break;
805  case F_SN: fname = "native static "; break;
806  case F_S:  fname = "static ";        break;
807  case F_RNY:fname = "native synchronized "; break;
808  }
809  const char* kptr = strrchr(kname, '/');
810  if (kptr != NULL)  kname = kptr + 1;
811  int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s",
812                         str, fname, kname, mname, sname);
813  if (len < buflen)
814    str = buf;
815#endif //PRODUCT
816  return str;
817}
818
819
820// These are to get information about intrinsics.
821
822#define ID4(x, y, z, f) ((ID3(x, y, z) << vmIntrinsics::log2_FLAG_LIMIT) | (jlong) (f))
823
824static const jlong intrinsic_info_array[vmIntrinsics::ID_LIMIT+1] = {
825#define VM_INTRINSIC_INFO(ignore_id, klass, name, sig, fcode) \
826  ID4(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig), vmIntrinsics::fcode),
827
828  0, VM_INTRINSICS_DO(VM_INTRINSIC_INFO,
829                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
830    0
831#undef VM_INTRINSIC_INFO
832};
833
834inline jlong intrinsic_info(vmIntrinsics::ID id) {
835  return intrinsic_info_array[vmIntrinsics::ID_from((int)id)];
836}
837
838vmSymbols::SID vmIntrinsics::class_for(vmIntrinsics::ID id) {
839  jlong info = intrinsic_info(id);
840  int shift = 2*vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
841  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1021, "");
842  return vmSymbols::SID( (info >> shift) & mask );
843}
844
845vmSymbols::SID vmIntrinsics::name_for(vmIntrinsics::ID id) {
846  jlong info = intrinsic_info(id);
847  int shift = vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
848  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1022, "");
849  return vmSymbols::SID( (info >> shift) & mask );
850}
851
852vmSymbols::SID vmIntrinsics::signature_for(vmIntrinsics::ID id) {
853  jlong info = intrinsic_info(id);
854  int shift = log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
855  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1023, "");
856  return vmSymbols::SID( (info >> shift) & mask );
857}
858
859vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) {
860  jlong info = intrinsic_info(id);
861  int shift = 0, mask = right_n_bits(log2_FLAG_LIMIT);
862  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 15, "");
863  return Flags( (info >> shift) & mask );
864}
865
866
867#ifndef PRODUCT
868// verify_method performs an extra check on a matched intrinsic method
869
870static bool match_method(Method* m, Symbol* n, Symbol* s) {
871  return (m->name() == n &&
872          m->signature() == s);
873}
874
875static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) {
876#define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
877  { Symbol* k = vmSymbols::klassname(); \
878    if (mk == k) { \
879      Symbol* n = vmSymbols::namepart(); \
880      Symbol* s = vmSymbols::sigpart(); \
881      if (match_method(m, n, s)) \
882        return vmIntrinsics::id; \
883    } }
884  VM_INTRINSICS_DO(VM_INTRINSIC_MATCH,
885                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
886  return vmIntrinsics::_none;
887#undef VM_INTRINSIC_MATCH
888}
889
890void vmIntrinsics::verify_method(ID actual_id, Method* m) {
891  Symbol* mk = m->method_holder()->name();
892  ID declared_id = match_method_with_klass(m, mk);
893
894  if (declared_id == actual_id)  return; // success
895
896  if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {
897    // Here are a few special cases in StrictMath not declared in vmSymbols.hpp.
898    switch (actual_id) {
899    case _min:
900    case _max:
901    case _dsqrt:
902      declared_id = match_method_with_klass(m, vmSymbols::java_lang_Math());
903      if (declared_id == actual_id)  return; // acceptable alias
904      break;
905    }
906  }
907
908  const char* declared_name = name_at(declared_id);
909  const char* actual_name   = name_at(actual_id);
910  methodHandle mh = m;
911  m = NULL;
912  ttyLocker ttyl;
913  if (xtty != NULL) {
914    xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'",
915                     actual_name, declared_name);
916    xtty->method(mh);
917    xtty->end_elem("%s", "");
918  }
919  if (PrintMiscellaneous && (WizardMode || Verbose)) {
920    tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):",
921                  declared_name, declared_id, actual_name, actual_id);
922    mh()->print_short_name(tty);
923    tty->cr();
924  }
925}
926#endif //PRODUCT
927