< 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) {

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




































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

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


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





 852   }
 853 }











































































































































































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

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

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

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