1 /* 2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 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 #ifndef SHARE_CLASSFILE_CLASSLISTPARSER_HPP 26 #define SHARE_CLASSFILE_CLASSLISTPARSER_HPP 27 28 #include "utilities/exceptions.hpp" 29 #include "utilities/globalDefinitions.hpp" 30 #include "utilities/growableArray.hpp" 31 #include "utilities/hashtable.inline.hpp" 32 33 class ID2KlassTable : public KVHashtable<int, InstanceKlass*, mtInternal> { 34 public: ID2KlassTable()35 ID2KlassTable() : KVHashtable<int, InstanceKlass*, mtInternal>(1987) {} 36 }; 37 38 class ClassListParser : public StackObj { 39 enum { 40 _unspecified = -999, 41 42 // Max number of bytes allowed per line in the classlist. 43 // Theoretically Java class names could be 65535 bytes in length. Also, an input line 44 // could have a very long path name up to JVM_MAXPATHLEN bytes in length. In reality, 45 // 4K bytes is more than enough. 46 _max_allowed_line_len = 4096, 47 _line_buf_extra = 10, // for detecting input too long 48 _line_buf_size = _max_allowed_line_len + _line_buf_extra 49 }; 50 51 static ClassListParser* _instance; // the singleton. 52 const char* _classlist_file; 53 FILE* _file; 54 55 ID2KlassTable _id2klass_table; 56 57 // The following field contains information from the *current* line being 58 // parsed. 59 char _line[_line_buf_size]; // The buffer that holds the current line. Some characters in 60 // the buffer may be overwritten by '\0' during parsing. 61 int _line_len; // Original length of the input line. 62 int _line_no; // Line number for current line being parsed 63 const char* _class_name; 64 int _id; 65 int _super; 66 GrowableArray<int>* _interfaces; 67 bool _interfaces_specified; 68 const char* _source; 69 70 bool parse_int_option(const char* option_name, int* value); 71 InstanceKlass* load_class_from_source(Symbol* class_name, TRAPS); table()72 ID2KlassTable *table() { 73 return &_id2klass_table; 74 } 75 InstanceKlass* lookup_class_by_id(int id); 76 void print_specified_interfaces(); 77 void print_actual_interfaces(InstanceKlass *ik); 78 public: 79 ClassListParser(const char* file); 80 ~ClassListParser(); 81 instance()82 static ClassListParser* instance() { 83 return _instance; 84 } 85 bool parse_one_line(); 86 char* _token; 87 void error(const char* msg, ...); 88 void parse_int(int* value); 89 bool try_parse_int(int* value); 90 bool skip_token(const char* option_name); 91 void skip_whitespaces(); 92 void skip_non_whitespaces(); 93 is_id_specified()94 bool is_id_specified() { 95 return _id != _unspecified; 96 } is_super_specified()97 bool is_super_specified() { 98 return _super != _unspecified; 99 } are_interfaces_specified()100 bool are_interfaces_specified() { 101 return _interfaces->length() > 0; 102 } id()103 int id() { 104 assert(is_id_specified(), "do not query unspecified id"); 105 return _id; 106 } super()107 int super() { 108 assert(is_super_specified(), "do not query unspecified super"); 109 return _super; 110 } check_already_loaded(const char * which,int id)111 void check_already_loaded(const char* which, int id) { 112 if (_id2klass_table.lookup(id) == NULL) { 113 error("%s id %d is not yet loaded", which, id); 114 } 115 } 116 current_class_name()117 const char* current_class_name() { 118 return _class_name; 119 } 120 121 Klass* load_current_class(TRAPS); 122 123 bool is_loading_from_source(); 124 125 // Look up the super or interface of the current class being loaded 126 // (in this->load_current_class()). 127 InstanceKlass* lookup_super_for_current_class(Symbol* super_name); 128 InstanceKlass* lookup_interface_for_current_class(Symbol* interface_name); 129 }; 130 #endif // SHARE_CLASSFILE_CLASSLISTPARSER_HPP 131