sharedPathsMiscInfo.hpp 5.7 KB
Newer Older
1
/*
2
 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP

#include "runtime/os.hpp"

// During dumping time, when processing class paths, we build up the dump-time
// classpath. The JAR files that exist are stored in the list ClassLoader::_first_entry.
// However, we need to store other "misc" information for run-time checking, such as
//
// + The values of Arguments::get_sysclasspath() used during dumping.
//
// + The meta-index file(s) used during dumping (incl modification time and size)
//
// + The class path elements specified during dumping but did not exist --
//   these elements must also be specified at run time, and they also must not
//   exist at run time.
//
// These misc items are stored in a linear buffer in SharedPathsMiscInfo.
// The storage format is stream oriented to minimize its size.
//
// When writing the information to the archive file, SharedPathsMiscInfo is stored in
// the archive file header. At run-time, this information is used only during initialization
// (accessed using read() instead of mmap()), and is deallocated afterwards to save space.
//
// The SharedPathsMiscInfo class is used for both creating the the information (during
// dumping time) and validation (at run time). Different constructors are used in the
// two situations. See below.

class SharedPathsMiscInfo : public CHeapObj<mtClass> {
protected:
  char* _buf_start;
  char* _cur_ptr;
  char* _end_ptr;
  int   _buf_size;
  bool  _allocated;   // was _buf_start allocated by me?
  void ensure_size(size_t needed_bytes);
  void add_path(const char* path, int type);

  void write(const void* ptr, size_t size);
  bool read(void* ptr, size_t size);

  static void trace_class_path(const char* msg, const char* name = NULL) {
67
    ClassLoader::trace_class_path(tty, msg, name);
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
  }
protected:
  static bool fail(const char* msg, const char* name = NULL);
  virtual bool check(jint type, const char* path);

public:
  enum {
    INITIAL_BUF_SIZE = 128
  };
  // This constructor is used when creating the misc information (during dump)
  SharedPathsMiscInfo() {
    _buf_size = INITIAL_BUF_SIZE;
    _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
    _allocated = true;
  }
  // This constructor is used when validating the misc info (during run time)
  SharedPathsMiscInfo(char *buff, int size) {
    _cur_ptr = _buf_start = buff;
    _end_ptr = _buf_start + size;
    _buf_size = size;
    _allocated = false;
  }
  ~SharedPathsMiscInfo() {
    if (_allocated) {
      FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
    }
  }
  int get_used_bytes() {
    return _cur_ptr - _buf_start;
  }
  void* buffer() {
    return _buf_start;
  }

  // writing --

  // The path must not exist at run-time
  void add_nonexist_path(const char* path) {
    add_path(path, NON_EXIST);
  }

  // The path must exist and have required size and modification time
  void add_required_file(const char* path) {
    add_path(path, REQUIRED);

    struct stat st;
    if (os::stat(path, &st) != 0) {
      assert(0, "sanity");
      ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
    }
    write_time(st.st_mtime);
    write_long(st.st_size);
  }

  // The path must exist, and must contain exactly <num_entries> files/dirs
  void add_boot_classpath(const char* path) {
    add_path(path, BOOT);
  }
  int write_jint(jint num) {
    write(&num, sizeof(num));
    return 0;
  }
  void write_time(time_t t) {
    write(&t, sizeof(t));
  }
  void write_long(long l) {
    write(&l, sizeof(l));
  }

  bool dump_to_file(int fd) {
    int n = get_used_bytes();
    return (os::write(fd, _buf_start, n) == (size_t)n);
  }

  // reading --

  enum {
    BOOT      = 1,
    NON_EXIST = 2,
    REQUIRED  = 3
  };

  virtual const char* type_name(int type) {
    switch (type) {
    case BOOT:      return "BOOT";
    case NON_EXIST: return "NON_EXIST";
    case REQUIRED:  return "REQUIRED";
    default:        ShouldNotReachHere(); return "?";
    }
  }

  virtual void print_path(outputStream* out, int type, const char* path) {
    switch (type) {
    case BOOT:
      out->print("Expecting -Dsun.boot.class.path=%s", path);
      break;
    case NON_EXIST:
      out->print("Expecting that %s does not exist", path);
      break;
    case REQUIRED:
I
iklam 已提交
168
      out->print("Expecting that file %s must exist and is not altered", path);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
      break;
    default:
      ShouldNotReachHere();
    }
  }

  bool check();
  bool read_jint(jint *ptr) {
    return read(ptr, sizeof(jint));
  }
  bool read_long(long *ptr) {
    return read(ptr, sizeof(long));
  }
  bool read_time(time_t *ptr) {
    return read(ptr, sizeof(time_t));
  }
};

#endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP