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 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/vmSymbols.hpp" 27 #include "memory/oopFactory.hpp" 28 #include "oops/oop.inline.hpp" 29 #include "runtime/handles.inline.hpp" 30 #include "utilities/xmlstream.hpp" 31 32 33 Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT]; 34 35 Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; 36 37 inline int compare_symbol(Symbol* a, Symbol* b) { 38 if (a == b) return 0; 39 // follow the natural address order: 40 return (address)a > (address)b ? +1 : -1; 41 } 42 43 static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; 44 extern "C" { 45 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { 46 Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); 421 vmIntrinsics::ID id = method->intrinsic_id(); 422 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 423 424 // Check if the intrinsic corresponding to 'method' has been disabled on 425 // the command line by using the DisableIntrinsic flag (either globally 426 // or on a per-method level, see src/share/vm/compiler/abstractCompiler.hpp 427 // for details). 428 // Usually, the compilation context is the caller of the method 'method'. 429 // The only case when for a non-recursive method 'method' the compilation context 430 // is not the caller of the 'method' (but it is the method itself) is 431 // java.lang.ref.Referene::get. 432 // For java.lang.ref.Reference::get, the intrinsic version is used 433 // instead of the compiled version so that the value in the referent 434 // field can be registered by the G1 pre-barrier code. The intrinsified 435 // version of Reference::get also adds a memory barrier to prevent 436 // commoning reads from the referent field across safepoint since GC 437 // can change the referent field's value. See Compile::Compile() 438 // in src/share/vm/opto/compile.cpp or 439 // GraphBuilder::GraphBuilder() in src/share/vm/c1/c1_GraphBuilder.cpp 440 // for more details. 441 ccstr disable_intr = NULL; 442 if ((DisableIntrinsic[0] != '\0' && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || 443 (!compilation_context.is_null() && 444 CompilerOracle::has_option_value(compilation_context, "DisableIntrinsic", disable_intr) && 445 strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL) 446 ) { 447 return true; 448 } 449 450 // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in 451 // the following switch statement. 452 if (!InlineNatives) { 453 switch (id) { 454 case vmIntrinsics::_indexOf: 455 case vmIntrinsics::_compareTo: 456 case vmIntrinsics::_equals: 457 case vmIntrinsics::_equalsC: 458 case vmIntrinsics::_getAndAddInt: 459 case vmIntrinsics::_getAndAddLong: 460 case vmIntrinsics::_getAndSetInt: 461 case vmIntrinsics::_getAndSetLong: 462 case vmIntrinsics::_getAndSetObject: 463 case vmIntrinsics::_loadFence: 464 case vmIntrinsics::_storeFence: 465 case vmIntrinsics::_fullFence: 466 case vmIntrinsics::_Reference_get: 467 break; 468 default: 768 vmSymbols::SID sig, 769 jshort flags) { 770 assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit"); 771 772 // Let the C compiler build the decision tree. 773 774 #define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \ 775 case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \ 776 if (!match_##fcode(flags)) break; \ 777 return id; 778 779 switch (ID3(holder, name, sig)) { 780 VM_INTRINSICS_DO(VM_INTRINSIC_CASE, 781 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); 782 } 783 return vmIntrinsics::_none; 784 785 #undef VM_INTRINSIC_CASE 786 } 787 788 789 const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) { 790 const char* str = name_at(id); 791 #ifndef PRODUCT 792 const char* kname = vmSymbols::name_for(class_for(id)); 793 const char* mname = vmSymbols::name_for(name_for(id)); 794 const char* sname = vmSymbols::name_for(signature_for(id)); 795 const char* fname = ""; 796 switch (flags_for(id)) { 797 case F_Y: fname = "synchronized "; break; 798 case F_RN: fname = "native "; break; 799 case F_SN: fname = "native static "; break; 800 case F_S: fname = "static "; break; 801 case F_RNY:fname = "native synchronized "; break; 802 } 803 const char* kptr = strrchr(kname, '/'); 804 if (kptr != NULL) kname = kptr + 1; 805 int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s", 806 str, fname, kname, mname, sname); 807 if (len < buflen) | 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 */ 24 25 #include <string.h> 26 27 #include "precompiled.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "memory/allocation.hpp" 30 #include "memory/oopFactory.hpp" 31 #include "oops/oop.inline.hpp" 32 #include "runtime/handles.inline.hpp" 33 #include "utilities/xmlstream.hpp" 34 35 36 Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT]; 37 38 Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; 39 40 inline int compare_symbol(Symbol* a, Symbol* b) { 41 if (a == b) return 0; 42 // follow the natural address order: 43 return (address)a > (address)b ? +1 : -1; 44 } 45 46 static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; 47 extern "C" { 48 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { 49 Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); 424 vmIntrinsics::ID id = method->intrinsic_id(); 425 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 426 427 // Check if the intrinsic corresponding to 'method' has been disabled on 428 // the command line by using the DisableIntrinsic flag (either globally 429 // or on a per-method level, see src/share/vm/compiler/abstractCompiler.hpp 430 // for details). 431 // Usually, the compilation context is the caller of the method 'method'. 432 // The only case when for a non-recursive method 'method' the compilation context 433 // is not the caller of the 'method' (but it is the method itself) is 434 // java.lang.ref.Referene::get. 435 // For java.lang.ref.Reference::get, the intrinsic version is used 436 // instead of the compiled version so that the value in the referent 437 // field can be registered by the G1 pre-barrier code. The intrinsified 438 // version of Reference::get also adds a memory barrier to prevent 439 // commoning reads from the referent field across safepoint since GC 440 // can change the referent field's value. See Compile::Compile() 441 // in src/share/vm/opto/compile.cpp or 442 // GraphBuilder::GraphBuilder() in src/share/vm/c1/c1_GraphBuilder.cpp 443 // for more details. 444 445 /* Check if the intrinsic was disabled globally. */ 446 if (DisableIntrinsic[0] != '\0') { 447 if (is_id_in_list(id, DisableIntrinsic)) { 448 return true; 449 } 450 } 451 452 /* Check if the intrinsic was disabled on a per-method level. */ 453 ccstr option_value; 454 if (!compilation_context.is_null() && 455 CompilerOracle::has_option_value(compilation_context, "DisableIntrinsic", option_value)) { 456 if (is_id_in_list(id, option_value)) { 457 return true; 458 } 459 } 460 461 // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in 462 // the following switch statement. 463 if (!InlineNatives) { 464 switch (id) { 465 case vmIntrinsics::_indexOf: 466 case vmIntrinsics::_compareTo: 467 case vmIntrinsics::_equals: 468 case vmIntrinsics::_equalsC: 469 case vmIntrinsics::_getAndAddInt: 470 case vmIntrinsics::_getAndAddLong: 471 case vmIntrinsics::_getAndSetInt: 472 case vmIntrinsics::_getAndSetLong: 473 case vmIntrinsics::_getAndSetObject: 474 case vmIntrinsics::_loadFence: 475 case vmIntrinsics::_storeFence: 476 case vmIntrinsics::_fullFence: 477 case vmIntrinsics::_Reference_get: 478 break; 479 default: 779 vmSymbols::SID sig, 780 jshort flags) { 781 assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit"); 782 783 // Let the C compiler build the decision tree. 784 785 #define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \ 786 case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \ 787 if (!match_##fcode(flags)) break; \ 788 return id; 789 790 switch (ID3(holder, name, sig)) { 791 VM_INTRINSICS_DO(VM_INTRINSIC_CASE, 792 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); 793 } 794 return vmIntrinsics::_none; 795 796 #undef VM_INTRINSIC_CASE 797 } 798 799 bool vmIntrinsics::is_id_in_list(vmIntrinsics::ID id, ccstr list) { 800 ResourceMark rm; 801 size_t length = strlen(list); 802 char* local_list = NEW_RESOURCE_ARRAY(char, length + 1); 803 strncpy(local_list, list, length + 1); 804 805 char* token = strtok(local_list, ","); 806 while (token != NULL) { 807 if (strcmp(token, vmIntrinsics::name_at(id)) == 0) { 808 return true; 809 } else { 810 token = strtok(NULL, ","); 811 } 812 } 813 return false; 814 } 815 816 const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) { 817 const char* str = name_at(id); 818 #ifndef PRODUCT 819 const char* kname = vmSymbols::name_for(class_for(id)); 820 const char* mname = vmSymbols::name_for(name_for(id)); 821 const char* sname = vmSymbols::name_for(signature_for(id)); 822 const char* fname = ""; 823 switch (flags_for(id)) { 824 case F_Y: fname = "synchronized "; break; 825 case F_RN: fname = "native "; break; 826 case F_SN: fname = "native static "; break; 827 case F_S: fname = "static "; break; 828 case F_RNY:fname = "native synchronized "; break; 829 } 830 const char* kptr = strrchr(kname, '/'); 831 if (kptr != NULL) kname = kptr + 1; 832 int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s", 833 str, fname, kname, mname, sname); 834 if (len < buflen) |