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