src/hotspot/share/classfile/classListParser.cpp
author iklam
Mon, 27 Nov 2017 20:21:34 -0800
changeset 48138 78b2ecdd3c4b
parent 47216 71c04702a3d5
child 48155 551de50b4ff7
permissions -rw-r--r--
8188791: Move AppCDS from closed repo to open repo Reviewed-by: dsamersoff, simonis, minqi Contributed-by: jiangli.zhou@oracle.com, mikhailo.seledtsov@oracle.com, calvin.cheung@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     1
/*
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     4
 *
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     7
 * published by the Free Software Foundation.
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     8
 *
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    13
 * accompanied this code).
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    14
 *
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    18
 *
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    21
 * questions.
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    22
 *
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    23
 */
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    24
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    25
#include "precompiled.hpp"
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    26
#include "jvm.h"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    27
#include "jimage.hpp"
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    28
#include "classfile/classListParser.hpp"
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    29
#include "classfile/classLoaderExt.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    30
#include "classfile/sharedClassUtil.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    31
#include "classfile/symbolTable.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    32
#include "classfile/systemDictionary.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    33
#include "classfile/systemDictionaryShared.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    34
#include "memory/metaspaceShared.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    35
#include "memory/resourceArea.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    36
#include "runtime/fieldType.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    37
#include "runtime/javaCalls.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    38
#include "utilities/defaultStream.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    39
#include "utilities/hashtable.inline.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    40
#include "utilities/macros.hpp"
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    41
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    42
ClassListParser* ClassListParser::_instance = NULL;
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    43
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    44
ClassListParser::ClassListParser(const char* file) {
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    45
  assert(_instance == NULL, "must be singleton");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    46
  _instance = this;
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    47
  _classlist_file = file;
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    48
  _file = fopen(file, "r");
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    49
  _line_no = 0;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    50
  _interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, true);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    51
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    52
  if (_file == NULL) {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    53
    char errmsg[JVM_MAXPATHLEN];
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    54
    os::lasterror(errmsg, JVM_MAXPATHLEN);
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    55
    vm_exit_during_initialization("Loading classlist failed", errmsg);
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    56
  }
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    57
}
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    58
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    59
ClassListParser::~ClassListParser() {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    60
  if (_file) {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    61
    fclose(_file);
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    62
  }
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    63
  _instance = NULL;
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    64
}
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    65
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    66
bool ClassListParser::parse_one_line() {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    67
  for (;;) {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    68
    if (fgets(_line, sizeof(_line), _file) == NULL) {
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    69
      return false;
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    70
    }
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    71
    ++ _line_no;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    72
    _line_len = (int)strlen(_line);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    73
    if (_line_len > _max_allowed_line_len) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    74
      error("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    75
    }
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    76
    if (*_line == '#') { // comment
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    77
      continue;
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    78
    }
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    79
    break;
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    80
  }
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
    81
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    82
  _id = _unspecified;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    83
  _super = _unspecified;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    84
  _interfaces->clear();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    85
  _source = NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    86
  _interfaces_specified = false;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    87
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    88
  {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    89
    int len = (int)strlen(_line);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    90
    int i;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    91
    // Replace \t\r\n with ' '
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    92
    for (i=0; i<len; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    93
      if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n') {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    94
        _line[i] = ' ';
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    95
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    96
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    97
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    98
    // Remove trailing newline/space
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
    99
    while (len > 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   100
      if (_line[len-1] == ' ') {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   101
        _line[len-1] = '\0';
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   102
        len --;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   103
      } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   104
        break;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   105
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   106
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   107
    _line_len = len;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   108
    _class_name = _line;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   109
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   110
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   111
  if ((_token = strchr(_line, ' ')) == NULL) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   112
    // No optional arguments are specified.
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   113
    return true;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   114
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   115
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   116
  // Mark the end of the name, and go to the next input char
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   117
  *_token++ = '\0';
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   118
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   119
  while (*_token) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   120
    skip_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   121
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   122
    if (parse_int_option("id:", &_id)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   123
      continue;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   124
    } else if (parse_int_option("super:", &_super)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   125
      check_already_loaded("Super class", _super);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   126
      continue;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   127
    } else if (skip_token("interfaces:")) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   128
      int i;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   129
      while (try_parse_int(&i)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   130
        check_already_loaded("Interface", i);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   131
        _interfaces->append(i);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   132
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   133
    } else if (skip_token("source:")) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   134
      skip_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   135
      _source = _token;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   136
      char* s = strchr(_token, ' ');
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   137
      if (s == NULL) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   138
        break; // end of input line
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   139
      } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   140
        *s = '\0'; // mark the end of _source
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   141
        _token = s+1;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   142
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   143
    } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   144
      error("Unknown input");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   145
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   146
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   147
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   148
  // if src is specified
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   149
  //     id super interfaces must all be specified
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   150
  //     loader may be specified
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   151
  // else
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   152
  //     # the class is loaded from classpath
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   153
  //     id may be specified
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   154
  //     super, interfaces, loader must not be specified
34257
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
   155
  return true;
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
   156
}
4be3504cc03b 8140802: Clean up and refactor of class loading code for CDS
iklam
parents:
diff changeset
   157
48138
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   158
void ClassListParser::skip_whitespaces() {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   159
  while (*_token == ' ' || *_token == '\t') {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   160
    _token ++;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   161
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   162
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   163
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   164
void ClassListParser::skip_non_whitespaces() {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   165
  while (*_token && *_token != ' ' && *_token != '\t') {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   166
    _token ++;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   167
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   168
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   169
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   170
void ClassListParser::parse_int(int* value) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   171
  skip_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   172
  if (sscanf(_token, "%i", value) == 1) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   173
    skip_non_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   174
    if (*value < 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   175
      error("Error: negative integers not allowed (%d)", *value);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   176
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   177
  } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   178
    error("Error: expected integer");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   179
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   180
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   181
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   182
bool ClassListParser::try_parse_int(int* value) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   183
  skip_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   184
  if (sscanf(_token, "%i", value) == 1) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   185
    skip_non_whitespaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   186
    return true;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   187
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   188
  return false;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   189
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   190
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   191
bool ClassListParser::skip_token(const char* option_name) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   192
  size_t len = strlen(option_name);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   193
  if (strncmp(_token, option_name, len) == 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   194
    _token += len;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   195
    return true;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   196
  } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   197
    return false;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   198
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   199
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   200
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   201
bool ClassListParser::parse_int_option(const char* option_name, int* value) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   202
  if (skip_token(option_name)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   203
    if (*value != _unspecified) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   204
      error("%s specified twice", option_name);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   205
    } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   206
      parse_int(value);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   207
      return true;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   208
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   209
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   210
  return false;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   211
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   212
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   213
void ClassListParser::print_specified_interfaces() {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   214
  const int n = _interfaces->length();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   215
  jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   216
  for (int i=0; i<n; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   217
    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   218
    jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   219
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   220
  jio_fprintf(defaultStream::error_stream(), "}\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   221
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   222
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   223
void ClassListParser::print_actual_interfaces(InstanceKlass *ik) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   224
  int n = ik->local_interfaces()->length();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   225
  jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   226
  for (int i = 0; i < n; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   227
    InstanceKlass* e = InstanceKlass::cast(ik->local_interfaces()->at(i));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   228
    jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   229
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   230
  jio_fprintf(defaultStream::error_stream(), "}\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   231
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   232
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   233
void ClassListParser::error(const char *msg, ...) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   234
  va_list ap;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   235
  va_start(ap, msg);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   236
  int error_index = _token - _line;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   237
  if (error_index >= _line_len) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   238
    error_index = _line_len - 1;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   239
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   240
  if (error_index < 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   241
    error_index = 0;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   242
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   243
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   244
  jio_fprintf(defaultStream::error_stream(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   245
              "An error has occurred while processing class list file %s %d:%d.\n",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   246
              _classlist_file, _line_no, (error_index + 1));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   247
  jio_vfprintf(defaultStream::error_stream(), msg, ap);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   248
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   249
  if (_line_len <= 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   250
    jio_fprintf(defaultStream::error_stream(), "\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   251
  } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   252
    jio_fprintf(defaultStream::error_stream(), ":\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   253
    for (int i=0; i<_line_len; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   254
      char c = _line[i];
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   255
      if (c == '\0') {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   256
        jio_fprintf(defaultStream::error_stream(), "%s", " ");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   257
      } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   258
        jio_fprintf(defaultStream::error_stream(), "%c", c);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   259
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   260
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   261
    jio_fprintf(defaultStream::error_stream(), "\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   262
    for (int i=0; i<error_index; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   263
      jio_fprintf(defaultStream::error_stream(), "%s", " ");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   264
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   265
    jio_fprintf(defaultStream::error_stream(), "^\n");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   266
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   267
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   268
  vm_exit_during_initialization("class list format error.", NULL);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   269
  va_end(ap);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   270
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   271
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   272
// This function is used for loading classes for customized class loaders
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   273
// during archive dumping.
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   274
InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   275
#if !((defined(LINUX) && defined(X86) && defined(_LP64)) || \
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   276
      (defined(SOLARIS) && defined(_LP64)))
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   277
  // The only supported platforms are: (1) Linux/AMD64; (2) Solaris/64-bit
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   278
  error("AppCDS custom class loaders not supported on this platform");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   279
#endif
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   280
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   281
  assert(UseAppCDS, "must be");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   282
  if (!is_super_specified()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   283
    error("If source location is specified, super class must be also specified");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   284
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   285
  if (!is_id_specified()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   286
    error("If source location is specified, id must be also specified");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   287
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   288
  InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, THREAD);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   289
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   290
  if (strncmp(_class_name, "java/", 5) == 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   291
    log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   292
          _class_name, _source);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   293
    return NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   294
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   295
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   296
  if (k != NULL) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   297
    if (k->local_interfaces()->length() != _interfaces->length()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   298
      print_specified_interfaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   299
      print_actual_interfaces(k);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   300
      error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   301
            _interfaces->length(), k->local_interfaces()->length());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   302
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   303
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   304
    if (!SystemDictionaryShared::add_non_builtin_klass(class_name, ClassLoaderData::the_null_class_loader_data(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   305
                                                       k, THREAD)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   306
      error("Duplicated class %s", _class_name);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   307
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   308
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   309
    // This tells JVM_FindLoadedClass to not find this class.
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   310
    k->set_shared_classpath_index(UNREGISTERED_INDEX);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   311
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   312
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   313
  return k;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   314
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   315
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   316
InstanceKlass* ClassListParser::load_current_class(TRAPS) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   317
  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name, THREAD);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   318
  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   319
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   320
  InstanceKlass *klass = NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   321
  if (!is_loading_from_source()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   322
    if (is_super_specified()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   323
      error("If source location is not specified, super class must not be specified");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   324
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   325
    if (are_interfaces_specified()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   326
      error("If source location is not specified, interface(s) must not be specified");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   327
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   328
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   329
    bool non_array = !FieldType::is_array(class_name_symbol);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   330
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   331
    Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_0);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   332
    // Translate to external class name format, i.e., convert '/' chars to '.'
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   333
    Handle string = java_lang_String::externalize_classname(s, CHECK_0);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   334
    JavaValue result(T_OBJECT);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   335
    InstanceKlass* spec_klass =  non_array ?
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   336
      SystemDictionary::ClassLoader_klass() : SystemDictionary::Class_klass();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   337
    Symbol* method_name = non_array ?
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   338
      vmSymbols::loadClass_name() : vmSymbols::forName_name();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   339
    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   340
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   341
    if (non_array) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   342
      JavaCalls::call_virtual(&result,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   343
                              loader, //SystemDictionary::java_system_loader(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   344
                              spec_klass,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   345
                              method_name, //vmSymbols::loadClass_name(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   346
                              vmSymbols::string_class_signature(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   347
                              string,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   348
                              THREAD);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   349
    } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   350
      JavaCalls::call_static(&result,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   351
                             spec_klass,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   352
                             method_name,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   353
                             vmSymbols::string_class_signature(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   354
                             string,
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   355
                             CHECK_NULL);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   356
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   357
    assert(result.get_type() == T_OBJECT, "just checking");
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   358
    oop obj = (oop) result.get_jobject();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   359
    if (!HAS_PENDING_EXCEPTION && (obj != NULL)) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   360
      if (non_array) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   361
        klass = InstanceKlass::cast(java_lang_Class::as_Klass(obj));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   362
      } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   363
        klass = static_cast<InstanceKlass*>(java_lang_Class::array_klass_acquire(obj));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   364
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   365
    } else { // load classes in bootclasspath/a
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   366
      if (HAS_PENDING_EXCEPTION) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   367
        CLEAR_PENDING_EXCEPTION;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   368
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   369
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   370
      if (non_array) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   371
        Klass* k = SystemDictionary::resolve_or_null(class_name_symbol, CHECK_NULL);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   372
        if (k != NULL) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   373
          klass = InstanceKlass::cast(k);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   374
        } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   375
          if (!HAS_PENDING_EXCEPTION) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   376
            THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   377
          }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   378
        }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   379
      }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   380
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   381
  } else {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   382
    // If "source:" tag is specified, all super class and super interfaces must be specified in the
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   383
    // class list file.
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   384
    if (UseAppCDS) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   385
      klass = load_class_from_source(class_name_symbol, CHECK_NULL);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   386
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   387
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   388
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   389
  if (klass != NULL && is_id_specified()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   390
    int id = this->id();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   391
    SystemDictionaryShared::update_shared_entry(klass, id);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   392
    InstanceKlass* old = table()->lookup(id);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   393
    if (old != NULL && old != klass) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   394
      error("Duplicated ID %d for class %s", id, _class_name);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   395
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   396
    table()->add(id, klass);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   397
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   398
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   399
  return klass;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   400
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   401
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   402
bool ClassListParser::is_loading_from_source() {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   403
  return (_source != NULL);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   404
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   405
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   406
InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   407
  InstanceKlass* klass = table()->lookup(id);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   408
  if (klass == NULL) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   409
    error("Class ID %d has not been defined", id);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   410
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   411
  return klass;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   412
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   413
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   414
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   415
InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   416
  if (!is_loading_from_source()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   417
    return NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   418
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   419
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   420
  InstanceKlass* k = lookup_class_by_id(super());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   421
  if (super_name != k->name()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   422
    error("The specified super class %s (id %d) does not match actual super class %s",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   423
          k->name()->as_klass_external_name(), super(),
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   424
          super_name->as_klass_external_name());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   425
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   426
  return k;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   427
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   428
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   429
InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   430
  if (!is_loading_from_source()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   431
    return NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   432
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   433
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   434
  const int n = _interfaces->length();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   435
  if (n == 0) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   436
    error("Class %s implements the interface %s, but no interface has been specified in the input line",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   437
          _class_name, interface_name->as_klass_external_name());
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   438
    ShouldNotReachHere();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   439
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   440
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   441
  int i;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   442
  for (i=0; i<n; i++) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   443
    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   444
    if (interface_name == k->name()) {
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   445
      return k;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   446
    }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   447
  }
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   448
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   449
  // interface_name is not specified by the "interfaces:" keyword.
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   450
  print_specified_interfaces();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   451
  error("The interface %s implemented by class %s does not match any of the specified interface IDs",
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   452
        interface_name->as_klass_external_name(), _class_name);
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   453
  ShouldNotReachHere();
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   454
  return NULL;
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   455
}
78b2ecdd3c4b 8188791: Move AppCDS from closed repo to open repo
iklam
parents: 47216
diff changeset
   456