< prev index next >

src/hotspot/share/cds/classListParser.cpp

Print this page

   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 "cds/archiveUtils.hpp"

  27 #include "cds/classListParser.hpp"
  28 #include "cds/classPrelinker.hpp"
  29 #include "cds/lambdaFormInvokers.hpp"
  30 #include "cds/metaspaceShared.hpp"
  31 #include "cds/unregisteredClasses.hpp"
  32 #include "classfile/classLoaderExt.hpp"
  33 #include "classfile/javaClasses.inline.hpp"
  34 #include "classfile/symbolTable.hpp"
  35 #include "classfile/systemDictionary.hpp"
  36 #include "classfile/systemDictionaryShared.hpp"
  37 #include "classfile/vmClasses.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "interpreter/bytecode.hpp"
  40 #include "interpreter/bytecodeStream.hpp"
  41 #include "interpreter/linkResolver.hpp"
  42 #include "jimage.hpp"
  43 #include "jvm.h"
  44 #include "logging/log.hpp"
  45 #include "logging/logTag.hpp"

  46 #include "memory/resourceArea.hpp"
  47 #include "oops/constantPool.inline.hpp"

  48 #include "runtime/atomic.hpp"

  49 #include "runtime/handles.inline.hpp"
  50 #include "runtime/java.hpp"
  51 #include "runtime/javaCalls.hpp"
  52 #include "utilities/defaultStream.hpp"
  53 #include "utilities/macros.hpp"
  54 #include "utilities/utf8.hpp"
  55 

  56 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";

  57 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
  58 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";


  59 
  60 volatile Thread* ClassListParser::_parsing_thread = nullptr;
  61 ClassListParser* ClassListParser::_instance = nullptr;
  62 
  63 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
  64     _classlist_file(file),
  65     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
  66     _file_input(do_open(file), /* need_close=*/true),
  67     _input_stream(&_file_input),
  68     _parse_mode(parse_mode) {
  69   log_info(cds)("Parsing %s%s", file,
  70                 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
  71   if (!_file_input.is_open()) {
  72     char errmsg[JVM_MAXPATHLEN];
  73     os::lasterror(errmsg, JVM_MAXPATHLEN);
  74     vm_exit_during_initialization("Loading classlist failed", errmsg);




  75   }
  76   _token = _line = nullptr;
  77   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
  78   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
  79 
  80   // _instance should only be accessed by the thread that created _instance.
  81   assert(_instance == nullptr, "must be singleton");
  82   _instance = this;
  83   Atomic::store(&_parsing_thread, Thread::current());
  84 }
  85 
  86 FILE* ClassListParser::do_open(const char* file) {
  87   // Use os::open() because neither fopen() nor os::fopen()
  88   // can handle long path name on Windows. (See JDK-8216184)
  89   int fd = os::open(file, O_RDONLY, S_IREAD);
  90   FILE* fp = nullptr;
  91   if (fd != -1) {
  92     // Obtain a FILE* from the file descriptor so that _input_stream
  93     // can be used in ClassListParser::parse()
  94     fp = os::fdopen(fd, "r");

 290   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
 291     _indy_items->clear();
 292     split_tokens_by_whitespace(offset, _indy_items);
 293     if (_indy_items->length() < 2) {
 294       error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
 295     }
 296     if (!parse_lambda_forms_invokers_only()) {
 297       _class_name = _indy_items->at(0);
 298       check_class_name(_class_name);
 299       TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 300       if (_indy_items->length() > 0) {
 301         // The current line is "@lambda-proxy class_name". Load the proxy class.
 302         resolve_indy(THREAD, class_name_symbol);
 303       }
 304     }
 305   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
 306     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
 307   } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
 308     _token = _line + offset;
 309     parse_constant_pool_tag();












 310   } else {
 311     error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
 312   }
 313 }
 314 
 315 void ClassListParser::skip_whitespaces() {
 316   while (*_token == ' ' || *_token == '\t') {
 317     _token ++;
 318   }
 319 }
 320 
 321 void ClassListParser::skip_non_whitespaces() {
 322   while (*_token && *_token != ' ' && *_token != '\t') {
 323     _token ++;
 324   }
 325 }
 326 
 327 void ClassListParser::parse_int(int* value) {
 328   skip_whitespaces();
 329   if (sscanf(_token, "%i", value) == 1) {

 762 
 763 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
 764   Handle class_loader(current, class_loader_oop);
 765   Handle protection_domain;
 766   return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain);
 767 }
 768 
 769 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
 770   TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
 771   InstanceKlass* ik;
 772 
 773   if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
 774     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
 775     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
 776     return ik;
 777   } else {
 778     return nullptr;
 779   }
 780 }
 781 




































 782 void ClassListParser::parse_constant_pool_tag() {
 783   if (parse_lambda_forms_invokers_only()) {
 784     return;
 785   }
 786 
 787   JavaThread* THREAD = JavaThread::current();
 788   skip_whitespaces();
 789   char* class_name = _token;
 790   skip_non_whitespaces();
 791   *_token = '\0';
 792   _token ++;
 793 
 794   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 795   if (ik == nullptr) {
 796     _token = class_name;
 797     if (strstr(class_name, "/$Proxy") != nullptr ||
 798         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 799       // ignore -- TODO: we should filter these out in classListWriter.cpp
 800     } else {
 801       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);

 817     if (cp_index < 1 || cp_index >= cp->length()) {
 818       constant_pool_resolution_warning("Invalid constant pool index %d", cp_index);
 819       return;
 820     } else {
 821       preresolve_list.at_put(cp_index, true);
 822     }
 823     constantTag cp_tag = cp->tag_at(cp_index);
 824     switch (cp_tag.value()) {
 825     case JVM_CONSTANT_UnresolvedClass:
 826       preresolve_class = true;
 827       break;
 828     case JVM_CONSTANT_UnresolvedClassInError:
 829     case JVM_CONSTANT_Class:
 830       // ignore
 831       break;
 832     case JVM_CONSTANT_Fieldref:
 833     case JVM_CONSTANT_Methodref:
 834     case JVM_CONSTANT_InterfaceMethodref:
 835       preresolve_fmi = true;
 836       break;


 837       break;
 838     default:
 839       constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
 840                                        cp_index, cp_tag.internal_name(), cp_tag.value());
 841       return;
 842     }
 843   }
 844 
 845   if (preresolve_class) {
 846     ClassPrelinker::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
 847   }
 848   if (preresolve_fmi) {
 849     ClassPrelinker::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);





 850   }
 851 }
 852 









































































































































































   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 "cds/aotConstantPoolResolver.hpp"
  27 #include "cds/archiveUtils.hpp"
  28 #include "cds/cdsConfig.hpp"
  29 #include "cds/classListParser.hpp"

  30 #include "cds/lambdaFormInvokers.hpp"
  31 #include "cds/metaspaceShared.hpp"
  32 #include "cds/unregisteredClasses.hpp"

  33 #include "classfile/javaClasses.inline.hpp"
  34 #include "classfile/symbolTable.hpp"
  35 #include "classfile/systemDictionary.hpp"
  36 #include "classfile/systemDictionaryShared.hpp"
  37 #include "classfile/vmClasses.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "interpreter/bytecode.hpp"
  40 #include "interpreter/interpreterRuntime.hpp"
  41 #include "interpreter/linkResolver.hpp"
  42 #include "jimage.hpp"
  43 #include "jvm.h"
  44 #include "logging/log.hpp"
  45 #include "logging/logTag.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "oops/constantPool.inline.hpp"
  49 #include "oops/cpCache.inline.hpp"
  50 #include "runtime/atomic.hpp"
  51 #include "runtime/globals_extension.hpp"
  52 #include "runtime/handles.inline.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/javaCalls.hpp"
  55 #include "utilities/defaultStream.hpp"
  56 #include "utilities/macros.hpp"
  57 #include "utilities/utf8.hpp"
  58 
  59 const char* ClassListParser::CLASS_REFLECTION_DATA_TAG = "@class-reflection-data";
  60 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
  61 const char* ClassListParser::DYNAMIC_PROXY_TAG = "@dynamic-proxy";
  62 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
  63 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
  64 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache";
  65 const char* ClassListParser::ARRAY_TAG = "@array";
  66 
  67 volatile Thread* ClassListParser::_parsing_thread = nullptr;
  68 ClassListParser* ClassListParser::_instance = nullptr;
  69 
  70 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
  71     _classlist_file(file),
  72     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
  73     _file_input(do_open(file), /* need_close=*/true),
  74     _input_stream(&_file_input),
  75     _parse_mode(parse_mode) {
  76   log_info(cds)("Parsing %s%s", file,
  77                 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
  78   if (!_file_input.is_open()) {
  79     char reason[JVM_MAXPATHLEN];
  80     os::lasterror(reason, JVM_MAXPATHLEN);
  81     vm_exit_during_initialization(err_msg("Loading %s %s failed",
  82                                           FLAG_IS_DEFAULT(AOTConfiguration) ?
  83                                           "classlist" : "AOTConfiguration file",
  84                                           file),
  85                                   reason);
  86   }
  87   _token = _line = nullptr;
  88   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
  89   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
  90 
  91   // _instance should only be accessed by the thread that created _instance.
  92   assert(_instance == nullptr, "must be singleton");
  93   _instance = this;
  94   Atomic::store(&_parsing_thread, Thread::current());
  95 }
  96 
  97 FILE* ClassListParser::do_open(const char* file) {
  98   // Use os::open() because neither fopen() nor os::fopen()
  99   // can handle long path name on Windows. (See JDK-8216184)
 100   int fd = os::open(file, O_RDONLY, S_IREAD);
 101   FILE* fp = nullptr;
 102   if (fd != -1) {
 103     // Obtain a FILE* from the file descriptor so that _input_stream
 104     // can be used in ClassListParser::parse()
 105     fp = os::fdopen(fd, "r");

 301   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
 302     _indy_items->clear();
 303     split_tokens_by_whitespace(offset, _indy_items);
 304     if (_indy_items->length() < 2) {
 305       error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
 306     }
 307     if (!parse_lambda_forms_invokers_only()) {
 308       _class_name = _indy_items->at(0);
 309       check_class_name(_class_name);
 310       TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 311       if (_indy_items->length() > 0) {
 312         // The current line is "@lambda-proxy class_name". Load the proxy class.
 313         resolve_indy(THREAD, class_name_symbol);
 314       }
 315     }
 316   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
 317     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
 318   } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
 319     _token = _line + offset;
 320     parse_constant_pool_tag();
 321   } else if (strcmp(_token, ARRAY_TAG) == 0) {
 322     _token = _line + offset;
 323     parse_array_dimension_tag();
 324   } else if (strcmp(_token, CLASS_REFLECTION_DATA_TAG) == 0) {
 325     _token = _line + offset;
 326     parse_class_reflection_data_tag();
 327   } else if (strcmp(_token, DYNAMIC_PROXY_TAG) == 0) {
 328     _token = _line + offset;
 329     parse_dynamic_proxy_tag();
 330   } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) {
 331     _token = _line + offset;
 332     parse_loader_negative_cache_tag();
 333   } else {
 334     error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
 335   }
 336 }
 337 
 338 void ClassListParser::skip_whitespaces() {
 339   while (*_token == ' ' || *_token == '\t') {
 340     _token ++;
 341   }
 342 }
 343 
 344 void ClassListParser::skip_non_whitespaces() {
 345   while (*_token && *_token != ' ' && *_token != '\t') {
 346     _token ++;
 347   }
 348 }
 349 
 350 void ClassListParser::parse_int(int* value) {
 351   skip_whitespaces();
 352   if (sscanf(_token, "%i", value) == 1) {

 785 
 786 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
 787   Handle class_loader(current, class_loader_oop);
 788   Handle protection_domain;
 789   return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain);
 790 }
 791 
 792 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
 793   TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
 794   InstanceKlass* ik;
 795 
 796   if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
 797     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
 798     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
 799     return ik;
 800   } else {
 801     return nullptr;
 802   }
 803 }
 804 
 805 void ClassListParser::parse_array_dimension_tag() {
 806   if (parse_lambda_forms_invokers_only()) {
 807     return;
 808   }
 809 
 810   skip_whitespaces();
 811   char* class_name = _token;
 812   skip_non_whitespaces();
 813   *_token = '\0';
 814   _token ++;
 815 
 816   skip_whitespaces();
 817   int dim;
 818   parse_uint(&dim);
 819 
 820   JavaThread* THREAD = JavaThread::current();
 821   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 822   if (ik == nullptr) {
 823     _token = class_name;
 824     if (strstr(class_name, "/$Proxy") != nullptr ||
 825         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 826       // ignore -- TODO: we should filter these out in classListWriter.cpp
 827     } else {
 828       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
 829     }
 830     return;
 831   }
 832 
 833   if (dim > 0) {
 834     ik->array_klass(dim, THREAD);
 835     if (HAS_PENDING_EXCEPTION) {
 836       error("Array klass allocation failed: %s %d", _class_name, dim);
 837     }
 838   }
 839 }
 840 
 841 void ClassListParser::parse_constant_pool_tag() {
 842   if (parse_lambda_forms_invokers_only()) {
 843     return;
 844   }
 845 
 846   JavaThread* THREAD = JavaThread::current();
 847   skip_whitespaces();
 848   char* class_name = _token;
 849   skip_non_whitespaces();
 850   *_token = '\0';
 851   _token ++;
 852 
 853   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 854   if (ik == nullptr) {
 855     _token = class_name;
 856     if (strstr(class_name, "/$Proxy") != nullptr ||
 857         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 858       // ignore -- TODO: we should filter these out in classListWriter.cpp
 859     } else {
 860       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);

 876     if (cp_index < 1 || cp_index >= cp->length()) {
 877       constant_pool_resolution_warning("Invalid constant pool index %d", cp_index);
 878       return;
 879     } else {
 880       preresolve_list.at_put(cp_index, true);
 881     }
 882     constantTag cp_tag = cp->tag_at(cp_index);
 883     switch (cp_tag.value()) {
 884     case JVM_CONSTANT_UnresolvedClass:
 885       preresolve_class = true;
 886       break;
 887     case JVM_CONSTANT_UnresolvedClassInError:
 888     case JVM_CONSTANT_Class:
 889       // ignore
 890       break;
 891     case JVM_CONSTANT_Fieldref:
 892     case JVM_CONSTANT_Methodref:
 893     case JVM_CONSTANT_InterfaceMethodref:
 894       preresolve_fmi = true;
 895       break;
 896     case JVM_CONSTANT_InvokeDynamic:
 897       preresolve_indy = true;
 898       break;
 899     default:
 900       constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
 901                                        cp_index, cp_tag.internal_name(), cp_tag.value());
 902       return;
 903     }
 904   }
 905 
 906   if (preresolve_class) {
 907     AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
 908   }
 909   if (preresolve_fmi) {
 910 // FIXME: too coarse; doesn't cover resolution of Class entries
 911 //    JavaThread::NoJavaCodeMark no_java_code(THREAD); // ensure no clinits are exectued
 912     AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
 913   }
 914   if (preresolve_indy) {
 915     AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
 916   }
 917 }
 918 
 919 void ClassListParser::parse_class_reflection_data_tag() {
 920   if (parse_lambda_forms_invokers_only()) {
 921     return;
 922   }
 923 
 924   JavaThread* THREAD = JavaThread::current();
 925   skip_whitespaces();
 926   char* class_name = _token;
 927   skip_non_whitespaces();
 928   *_token = '\0';
 929   _token ++;
 930 
 931   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 932   if (ik == nullptr) {
 933     _token = class_name;
 934     if (strstr(class_name, "/$Proxy") != nullptr ||
 935         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 936       // ignore -- TODO: we should filter these out in classListWriter.cpp
 937     } else {
 938       warning("%s: class not found: %s", CLASS_REFLECTION_DATA_TAG, class_name);
 939     }
 940     return;
 941   }
 942 
 943   ResourceMark rm(THREAD);
 944 
 945   int rd_flags = _unspecified;
 946   while (*_token) {
 947     skip_whitespaces();
 948     if (rd_flags != _unspecified) {
 949       error("rd_flags specified twice");
 950       return;
 951     }
 952     parse_uint(&rd_flags);
 953   }
 954   if (rd_flags == _unspecified) {
 955     error("no rd_flags specified");
 956     return;
 957   }
 958 
 959   if (CDSConfig::is_dumping_reflection_data()) {
 960     AOTConstantPoolResolver::generate_reflection_data(THREAD, ik, rd_flags);
 961   }
 962 }
 963 
 964 oop ClassListParser::loader_from_type(const char* loader_type) {
 965   oop loader;
 966   if (!ArchiveUtils::builtin_loader_from_type(loader_type, &loader)) {
 967     error("Unknown loader %s", loader_type);
 968   }
 969   return loader;
 970 }
 971 
 972 void ClassListParser::parse_dynamic_proxy_tag() {
 973   if (parse_lambda_forms_invokers_only()) {
 974     return;
 975   }
 976 
 977   skip_whitespaces();
 978   char* loader_type = _token;
 979   skip_non_whitespaces();
 980   *_token = '\0';
 981   _token ++;
 982 
 983   skip_whitespaces();
 984   char* proxy_name_str = _token;
 985   skip_non_whitespaces();
 986   *_token = '\0';
 987   _token ++;
 988 
 989   skip_whitespaces();
 990   int access_flags;
 991   parse_uint(&access_flags);
 992 
 993   skip_whitespaces();
 994   int num_intfs;
 995   parse_uint(&num_intfs);
 996 
 997   JavaThread* THREAD = JavaThread::current();
 998   Handle loader(THREAD, loader_from_type(loader_type));
 999   Handle proxy_name(THREAD, java_lang_String::create_oop_from_str(proxy_name_str, THREAD));
1000   if (HAS_PENDING_EXCEPTION) {
1001     error("Out of memory");
1002   }
1003 
1004   objArrayHandle interfaces(THREAD, oopFactory::new_objArray(vmClasses::Class_klass(), num_intfs, THREAD));
1005   if (HAS_PENDING_EXCEPTION) {
1006     error("Out of memory");
1007   }
1008 
1009   for (int i = 0; i < num_intfs; i++) {
1010     skip_whitespaces();
1011     char* intf_name = _token;
1012     skip_non_whitespaces();
1013     *_token = '\0';
1014     _token ++;
1015 
1016     InstanceKlass* ik = find_builtin_class(THREAD, intf_name);
1017     if (ik != nullptr) {
1018       interfaces()->obj_at_put(i, ik->java_mirror());
1019     } else {
1020       error("Unknown class %s", intf_name);
1021     }
1022   }
1023 
1024   if (strncmp("jdk.proxy", proxy_name_str, 9) != 0) {
1025     return;
1026   }
1027 
1028   AOTConstantPoolResolver::define_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags, THREAD);
1029   if (HAS_PENDING_EXCEPTION) {
1030     PENDING_EXCEPTION->print_on(tty);
1031     error("defineProxyClassForCDS failed");
1032   }
1033 }
1034 
1035 void ClassListParser::parse_loader_negative_cache_tag() {
1036   skip_whitespaces();
1037   char* loader_type = _token;
1038   skip_non_whitespaces();
1039   *_token = '\0';
1040   _token ++;
1041 
1042   oop loader;
1043   Klass* loader_klass;
1044   if (!strcmp(loader_type, "app")) {
1045     loader = SystemDictionary::java_system_loader();
1046     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
1047   } else if (!strcmp(loader_type, "platform")) {
1048     loader = SystemDictionary::java_platform_loader();
1049     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
1050   } else {
1051     warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type);
1052     return;
1053   }
1054 
1055   char* contents = _token;
1056   skip_non_whitespaces();
1057   *_token = '\0';
1058   _token ++;
1059 
1060   if (ArchiveLoaderLookupCache) {
1061     TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache");
1062     TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V");
1063 
1064     EXCEPTION_MARK;
1065     HandleMark hm(THREAD);
1066     JavaCallArguments args(Handle(THREAD, loader));
1067     Handle contents_h = java_lang_String::create_from_str(contents, THREAD);
1068     args.push_oop(contents_h);
1069     JavaValue result(T_VOID);
1070     JavaCalls::call_virtual(&result,
1071                             loader_klass,
1072                             method,
1073                             signature,
1074                             &args, THREAD);
1075     if (HAS_PENDING_EXCEPTION) {
1076       Handle exc_handle(THREAD, PENDING_EXCEPTION);
1077       CLEAR_PENDING_EXCEPTION;
1078 
1079       log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type);
1080       LogStreamHandle(Debug, cds) log;
1081       if (log.is_enabled()) {
1082         java_lang_Throwable::print_stack_trace(exc_handle, &log);
1083       }
1084     }
1085   }
1086 }
< prev index next >