src/hotspot/share/classfile/classFileStream.cpp
changeset 47216 71c04702a3d5
parent 42650 1f304d0c888b
child 54042 6dd6f988b4e4
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1997, 2016, 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 #include "precompiled.hpp"
       
    26 #include "classfile/classFileStream.hpp"
       
    27 #include "classfile/classLoader.hpp"
       
    28 #include "classfile/dictionary.hpp"
       
    29 #include "classfile/vmSymbols.hpp"
       
    30 #include "memory/resourceArea.hpp"
       
    31 
       
    32 const bool ClassFileStream::verify = true;
       
    33 const bool ClassFileStream::no_verification = false;
       
    34 
       
    35 void ClassFileStream::truncated_file_error(TRAPS) const {
       
    36   THROW_MSG(vmSymbols::java_lang_ClassFormatError(), "Truncated class file");
       
    37 }
       
    38 
       
    39 ClassFileStream::ClassFileStream(const u1* buffer,
       
    40                                  int length,
       
    41                                  const char* source,
       
    42                                  bool verify_stream) :
       
    43   _buffer_start(buffer),
       
    44   _buffer_end(buffer + length),
       
    45   _current(buffer),
       
    46   _source(source),
       
    47   _need_verify(verify_stream) {}
       
    48 
       
    49 const u1* ClassFileStream::clone_buffer() const {
       
    50   u1* const new_buffer_start = NEW_RESOURCE_ARRAY(u1, length());
       
    51   memcpy(new_buffer_start, _buffer_start, length());
       
    52   return new_buffer_start;
       
    53 }
       
    54 
       
    55 const char* const ClassFileStream::clone_source() const {
       
    56   const char* const src = source();
       
    57   char* source_copy = NULL;
       
    58   if (src != NULL) {
       
    59     size_t source_len = strlen(src);
       
    60     source_copy = NEW_RESOURCE_ARRAY(char, source_len + 1);
       
    61     strncpy(source_copy, src, source_len + 1);
       
    62   }
       
    63   return source_copy;
       
    64 }
       
    65 
       
    66 // Caller responsible for ResourceMark
       
    67 // clone stream with a rewound position
       
    68 const ClassFileStream* ClassFileStream::clone() const {
       
    69   const u1* const new_buffer_start = clone_buffer();
       
    70   return new ClassFileStream(new_buffer_start,
       
    71                              length(),
       
    72                              clone_source(),
       
    73                              need_verify());
       
    74 }
       
    75 
       
    76 u1 ClassFileStream::get_u1(TRAPS) const {
       
    77   if (_need_verify) {
       
    78     guarantee_more(1, CHECK_0);
       
    79   } else {
       
    80     assert(1 <= _buffer_end - _current, "buffer overflow");
       
    81   }
       
    82   return *_current++;
       
    83 }
       
    84 
       
    85 u2 ClassFileStream::get_u2(TRAPS) const {
       
    86   if (_need_verify) {
       
    87     guarantee_more(2, CHECK_0);
       
    88   } else {
       
    89     assert(2 <= _buffer_end - _current, "buffer overflow");
       
    90   }
       
    91   const u1* tmp = _current;
       
    92   _current += 2;
       
    93   return Bytes::get_Java_u2((address)tmp);
       
    94 }
       
    95 
       
    96 u4 ClassFileStream::get_u4(TRAPS) const {
       
    97   if (_need_verify) {
       
    98     guarantee_more(4, CHECK_0);
       
    99   } else {
       
   100     assert(4 <= _buffer_end - _current, "buffer overflow");
       
   101   }
       
   102   const u1* tmp = _current;
       
   103   _current += 4;
       
   104   return Bytes::get_Java_u4((address)tmp);
       
   105 }
       
   106 
       
   107 u8 ClassFileStream::get_u8(TRAPS) const {
       
   108   if (_need_verify) {
       
   109     guarantee_more(8, CHECK_0);
       
   110   } else {
       
   111     assert(8 <= _buffer_end - _current, "buffer overflow");
       
   112   }
       
   113   const u1* tmp = _current;
       
   114   _current += 8;
       
   115   return Bytes::get_Java_u8((address)tmp);
       
   116 }
       
   117 
       
   118 void ClassFileStream::skip_u1(int length, TRAPS) const {
       
   119   if (_need_verify) {
       
   120     guarantee_more(length, CHECK);
       
   121   }
       
   122   _current += length;
       
   123 }
       
   124 
       
   125 void ClassFileStream::skip_u2(int length, TRAPS) const {
       
   126   if (_need_verify) {
       
   127     guarantee_more(length * 2, CHECK);
       
   128   }
       
   129   _current += length * 2;
       
   130 }
       
   131 
       
   132 void ClassFileStream::skip_u4(int length, TRAPS) const {
       
   133   if (_need_verify) {
       
   134     guarantee_more(length * 4, CHECK);
       
   135   }
       
   136   _current += length * 4;
       
   137 }
       
   138 
       
   139 uint64_t ClassFileStream::compute_fingerprint() const {
       
   140   int classfile_size = length();
       
   141   int classfile_crc = ClassLoader::crc32(0, (const char*)buffer(), length());
       
   142   uint64_t fingerprint = (uint64_t(classfile_size) << 32) | uint64_t(uint32_t(classfile_crc));
       
   143   assert(fingerprint != 0, "must not be zero");
       
   144 
       
   145   return fingerprint;
       
   146 }