This commit is contained in:
Andrew John Hughes 2024-04-17 02:29:16 +00:00
commit 0e0b018acb
17 changed files with 242 additions and 173 deletions

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Red Hat Inc. * Copyright (c) 2013, Red Hat Inc.
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. * Copyright (c) 2005, 2024, Oracle and/or its affiliates.
* All rights reserved. * All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -150,8 +150,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
if (index->is_register()) { if (index->is_register()) {
// apply the shift and accumulate the displacement // apply the shift and accumulate the displacement
if (shift > 0) { if (shift > 0) {
LIR_Opr tmp = new_pointer_register(); // Use long register to avoid overflow when shifting large index values left.
__ shift_left(index, shift, tmp); LIR_Opr tmp = new_register(T_LONG);
__ convert(Bytecodes::_i2l, index, tmp);
__ shift_left(tmp, shift, tmp);
index = tmp; index = tmp;
} }
if (disp != 0) { if (disp != 0) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -156,8 +156,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
if (index->is_register()) { if (index->is_register()) {
// apply the shift and accumulate the displacement // apply the shift and accumulate the displacement
if (shift > 0) { if (shift > 0) {
LIR_Opr tmp = new_pointer_register(); // Use long register to avoid overflow when shifting large index values left.
__ shift_left(index, shift, tmp); LIR_Opr tmp = new_register(T_LONG);
__ convert(Bytecodes::_i2l, index, tmp);
__ shift_left(tmp, shift, tmp);
index = tmp; index = tmp;
} }
if (disp != 0) { if (disp != 0) {

View File

@ -1235,14 +1235,13 @@ oop java_lang_Throwable::message(Handle throwable) {
} }
// Return Symbol for detailed_message or NULL const char* java_lang_Throwable::message_as_utf8(oop throwable) {
Symbol* java_lang_Throwable::detail_message(oop throwable) { oop msg = java_lang_Throwable::message(throwable);
PRESERVE_EXCEPTION_MARK; // Keep original exception const char* msg_utf8 = NULL;
oop detailed_message = java_lang_Throwable::message(throwable); if (msg != NULL) {
if (detailed_message != NULL) { msg_utf8 = java_lang_String::as_utf8_string(msg);
return java_lang_String::as_symbol(detailed_message, THREAD);
} }
return NULL; return msg_utf8;
} }
void java_lang_Throwable::set_message(oop throwable, oop value) { void java_lang_Throwable::set_message(oop throwable, oop value) {

View File

@ -523,12 +523,12 @@ class java_lang_Throwable: AllStatic {
static void set_backtrace(oop throwable, oop value); static void set_backtrace(oop throwable, oop value);
// Needed by JVMTI to filter out this internal field. // Needed by JVMTI to filter out this internal field.
static int get_backtrace_offset() { return backtrace_offset;} static int get_backtrace_offset() { return backtrace_offset;}
static int get_detailMessage_offset() { return detailMessage_offset;}
// Message // Message
static int get_detailMessage_offset() { return detailMessage_offset;}
static oop message(oop throwable); static oop message(oop throwable);
static oop message(Handle throwable); static oop message(Handle throwable);
static const char* message_as_utf8(oop throwable);
static void set_message(oop throwable, oop value); static void set_message(oop throwable, oop value);
static Symbol* detail_message(oop throwable);
static void print_stack_element(outputStream *st, Handle mirror, int method, static void print_stack_element(outputStream *st, Handle mirror, int method,
int version, int bci, int cpref); int version, int bci, int cpref);
static void print_stack_element(outputStream *st, methodHandle method, int bci); static void print_stack_element(outputStream *st, methodHandle method, int bci);

View File

@ -33,7 +33,7 @@
// add new entry to the table // add new entry to the table
void ResolutionErrorTable::add_entry(int index, unsigned int hash, void ResolutionErrorTable::add_entry(int index, unsigned int hash,
constantPoolHandle pool, int cp_index, constantPoolHandle pool, int cp_index,
Symbol* error, Symbol* message) Symbol* error, const char* message)
{ {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
assert(!pool.is_null() && error != NULL, "adding NULL obj"); assert(!pool.is_null() && error != NULL, "adding NULL obj");
@ -64,16 +64,14 @@ void ResolutionErrorEntry::set_error(Symbol* e) {
_error->increment_refcount(); _error->increment_refcount();
} }
void ResolutionErrorEntry::set_message(Symbol* c) { void ResolutionErrorEntry::set_message(const char* c) {
assert(c != NULL, "must set a value"); _message = c != NULL ? os::strdup(c) : NULL;
_message = c;
_message->increment_refcount();
} }
// create new error entry // create new error entry
ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool,
int cp_index, Symbol* error, int cp_index, Symbol* error,
Symbol* message) const char* message)
{ {
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool); ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool);
entry->set_cp_index(cp_index); entry->set_cp_index(cp_index);
@ -87,7 +85,9 @@ void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
// decrement error refcount // decrement error refcount
assert(entry->error() != NULL, "error should be set"); assert(entry->error() != NULL, "error should be set");
entry->error()->decrement_refcount(); entry->error()->decrement_refcount();
entry->message()->decrement_refcount(); if (entry->message() != NULL) {
FREE_C_HEAP_ARRAY(char, entry->message(), mtInternal);
}
Hashtable<ConstantPool*, mtClass>::free_entry(entry); Hashtable<ConstantPool*, mtClass>::free_entry(entry);
} }

View File

@ -39,7 +39,7 @@ public:
ResolutionErrorTable(int table_size); ResolutionErrorTable(int table_size);
ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index,
Symbol* error, Symbol* message); Symbol* error, const char* message);
void free_entry(ResolutionErrorEntry *entry); void free_entry(ResolutionErrorEntry *entry);
ResolutionErrorEntry* bucket(int i) { ResolutionErrorEntry* bucket(int i) {
@ -56,7 +56,7 @@ public:
} }
void add_entry(int index, unsigned int hash, void add_entry(int index, unsigned int hash,
constantPoolHandle pool, int which, Symbol* error, Symbol* message); constantPoolHandle pool, int cp_index, Symbol* error, const char* error_msg);
// find error given the constant pool and constant pool index // find error given the constant pool and constant pool index
@ -80,7 +80,7 @@ class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
private: private:
int _cp_index; int _cp_index;
Symbol* _error; Symbol* _error;
Symbol* _message; const char* _message;
public: public:
ConstantPool* pool() const { return literal(); } ConstantPool* pool() const { return literal(); }
@ -91,8 +91,9 @@ class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
Symbol* error() const { return _error; } Symbol* error() const { return _error; }
void set_error(Symbol* e); void set_error(Symbol* e);
Symbol* message() const { return _message; } const char* message() const { return _message; }
void set_message(Symbol* c); // The incoming message is copied to the C-Heap.
void set_message(const char* c);
ResolutionErrorEntry* next() const { ResolutionErrorEntry* next() const {
return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next(); return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next();

View File

@ -2280,7 +2280,7 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name,
// Add entry to resolution error table to record the error when the first // Add entry to resolution error table to record the error when the first
// attempt to resolve a reference to a class has failed. // attempt to resolve a reference to a class has failed.
void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which,
Symbol* error, Symbol* message) { Symbol* error, const char* message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which); unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash); int index = resolution_errors()->hash_to_index(hash);
{ {
@ -2296,7 +2296,7 @@ void SystemDictionary::delete_resolution_error(ConstantPool* pool) {
// Lookup resolution error table. Returns error if found, otherwise NULL. // Lookup resolution error table. Returns error if found, otherwise NULL.
Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which, Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which,
Symbol** message) { const char** message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which); unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash); int index = resolution_errors()->hash_to_index(hash);
{ {

View File

@ -549,10 +549,10 @@ public:
// Record the error when the first attempt to resolve a reference from a constant // Record the error when the first attempt to resolve a reference from a constant
// pool entry to a class fails. // pool entry to a class fails.
static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error, static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error,
Symbol* message); const char* message);
static void delete_resolution_error(ConstantPool* pool); static void delete_resolution_error(ConstantPool* pool);
static Symbol* find_resolution_error(constantPoolHandle pool, int which, static Symbol* find_resolution_error(constantPoolHandle pool, int which,
Symbol** message); const char** message);
protected: protected:

View File

@ -451,11 +451,11 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
// tracing // tracing
if (TraceExceptions) { if (TraceExceptions) {
ResourceMark rm(thread); ResourceMark rm(thread);
Symbol* message = java_lang_Throwable::detail_message(h_exception()); const char* detail_message = java_lang_Throwable::message_as_utf8(h_exception());
ttyLocker ttyl; // Lock after getting the detail message ttyLocker ttyl; // Lock after getting the detail message
if (message != NULL) { if (detail_message != NULL) {
tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")", tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")",
h_exception->print_value_string(), message->as_C_string(), h_exception->print_value_string(), detail_message,
(address)h_exception()); (address)h_exception());
} else { } else {
tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")",

View File

@ -569,13 +569,16 @@ bool ConstantPool::resolve_class_constants(TRAPS) {
return true; return true;
} }
Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { const char* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) {
// Note: caller needs ResourceMark
// Dig out the detailed message to reuse if possible // Dig out the detailed message to reuse if possible
Symbol* message = java_lang_Throwable::detail_message(pending_exception); const char* msg = java_lang_Throwable::message_as_utf8(pending_exception);
if (message != NULL) { if (msg != NULL) {
return message; return msg;
} }
Symbol* message = NULL;
// Return specific message for the tag // Return specific message for the tag
switch (tag.value()) { switch (tag.value()) {
case JVM_CONSTANT_UnresolvedClass: case JVM_CONSTANT_UnresolvedClass:
@ -594,16 +597,16 @@ Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which,
ShouldNotReachHere(); ShouldNotReachHere();
} }
return message; return message != NULL ? message->as_C_string() : NULL;
} }
void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) { void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) {
Symbol* message = NULL; ResourceMark rm(THREAD);
const char* message = NULL;
Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message); Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message);
assert(error != NULL && message != NULL, "checking"); assert(error != NULL && message != NULL, "checking");
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
ResourceMark rm; THROW_MSG(error, message);
THROW_MSG(error, message->as_C_string());
} }
// If resolution for Class, MethodHandle or MethodType fails, save the exception // If resolution for Class, MethodHandle or MethodType fails, save the exception
@ -622,7 +625,9 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int whi
// and OutOfMemoryError, etc, or if the thread was hit by stop() // and OutOfMemoryError, etc, or if the thread was hit by stop()
// Needs clarification to section 5.4.3 of the VM spec (see 6308271) // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
} else if (this_oop->tag_at(which).value() != error_tag) { } else if (this_oop->tag_at(which).value() != error_tag) {
Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); ResourceMark rm(THREAD);
const char* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION);
SystemDictionary::add_resolution_error(this_oop, which, error, message); SystemDictionary::add_resolution_error(this_oop, which, error, message);
this_oop->tag_at_put(which, error_tag); this_oop->tag_at_put(which, error_tag);
} else { } else {

View File

@ -830,7 +830,7 @@ class ConstantPool : public Metadata {
// Exception handling // Exception handling
static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS); static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS);
static Symbol* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); static const char* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception);
static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS); static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS);
public: public:

View File

@ -32,6 +32,8 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.jar.Pack200; import java.util.jar.Pack200;
import java.util.zip.CRC32; import java.util.zip.CRC32;
@ -77,8 +79,13 @@ class NativeUnpack {
private int _estFileLimit; // ditto private int _estFileLimit; // ditto
private int _prevPercent = -1; // for monotonicity private int _prevPercent = -1; // for monotonicity
private final CRC32 _crc32 = new CRC32(); private final CRC32 _crc32 = new CRC32();
private byte[] _buf = new byte[1<<14]; private static final int MAX_BUFFER_SIZE = 1 << 20; // 1 MB byte[]
private byte[] _buf = new byte[1 << 14]; // 16 KB byte[] initially
private List<byte[]> _extra_buf = new LinkedList<>(); // extra buffers
// for large files
private byte[] _current_buf; // buffer being filled
private int _current_buf_pos; // position to fill in more data
private UnpackerImpl _p200; private UnpackerImpl _p200;
private PropMap _props; private PropMap _props;
@ -195,41 +202,44 @@ class NativeUnpack {
updateProgress(); // reset progress bar updateProgress(); // reset progress bar
for (;;) { for (;;) {
// Read the packed bits. // Read the packed bits.
long counts = start(presetInput, 0); long counts = start(presetInput, 0), consumed;
_byteCount = _estByteLimit = 0; // reset partial scan counts try {
++_segCount; // just finished scanning a whole segment... _byteCount = _estByteLimit = 0; // reset partial scan counts
int nextSeg = (int)( counts >>> 32 ); ++_segCount; // just finished scanning a whole segment...
int nextFile = (int)( counts >>> 0 ); int nextSeg = (int) (counts >>> 32);
int nextFile = (int) (counts >>> 0);
// Estimate eventual total number of segments and files. // Estimate eventual total number of segments and files.
_estSegLimit = _segCount + nextSeg; _estSegLimit = _segCount + nextSeg;
double filesAfterThisSeg = _fileCount + nextFile; double filesAfterThisSeg = _fileCount + nextFile;
_estFileLimit = (int)( (filesAfterThisSeg * _estFileLimit = (int) ((filesAfterThisSeg *
_estSegLimit) / _segCount ); _estSegLimit) / _segCount);
// Write the files. // Write the files.
int[] intParts = { 0,0, 0, 0 }; int[] intParts = {0, 0, 0, 0};
// intParts = {size.hi/lo, mod, defl} // intParts = {size.hi/lo, mod, defl}
Object[] parts = { intParts, null, null, null }; Object[] parts = {intParts, null, null, null};
// parts = { {intParts}, name, data0/1 } // parts = { {intParts}, name, data0/1 }
while (getNextFile(parts)) { while (getNextFile(parts)) {
//BandStructure.printArrayTo(System.out, intParts, 0, parts.length); //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
String name = (String) parts[1]; String name = (String) parts[1];
long size = ( (long)intParts[0] << 32) long size = ((long) intParts[0] << 32)
+ (((long)intParts[1] << 32) >>> 32); + (((long) intParts[1] << 32) >>> 32);
long mtime = (modtime != Constants.NO_MODTIME ) ? long mtime = (modtime != Constants.NO_MODTIME) ?
modtime : intParts[2] ; modtime : intParts[2];
boolean deflateHint = (intParts[3] != 0); boolean deflateHint = (intParts[3] != 0);
ByteBuffer data0 = (ByteBuffer) parts[2]; ByteBuffer data0 = (ByteBuffer) parts[2];
ByteBuffer data1 = (ByteBuffer) parts[3]; ByteBuffer data1 = (ByteBuffer) parts[3];
writeEntry(jstream, name, mtime, size, deflateHint, writeEntry(jstream, name, mtime, size, deflateHint,
data0, data1); data0, data1);
++_fileCount; ++_fileCount;
updateProgress(); updateProgress();
}
presetInput = getUnusedInput();
} finally {
consumed = finish();
} }
presetInput = getUnusedInput();
long consumed = finish();
if (_verbose > 0) if (_verbose > 0)
Utils.log.info("bytes consumed = "+consumed); Utils.log.info("bytes consumed = "+consumed);
if (presetInput == null && if (presetInput == null &&
@ -256,76 +266,145 @@ class NativeUnpack {
// Note: caller is responsible to finish with jstream. // Note: caller is responsible to finish with jstream.
} }
private void writeEntry(JarOutputStream j, String name, private void writeEntry(JarOutputStream j, String name, long mtime,
long mtime, long lsize, boolean deflateHint, long lsize, boolean deflateHint, ByteBuffer data0,
ByteBuffer data0, ByteBuffer data1) throws IOException { ByteBuffer data1) throws IOException {
int size = (int)lsize; if (lsize < 0 || lsize > Integer.MAX_VALUE) {
if (size != lsize) throw new IOException("file too large: " + lsize);
throw new IOException("file too large: "+lsize);
CRC32 crc32 = _crc32;
if (_verbose > 1)
Utils.log.fine("Writing entry: "+name+" size="+size
+(deflateHint?" deflated":""));
if (_buf.length < size) {
int newSize = size;
while (newSize < _buf.length) {
newSize <<= 1;
if (newSize <= 0) {
newSize = size;
break;
}
}
_buf = new byte[newSize];
} }
assert(_buf.length >= size); int size = (int) lsize;
int fillp = 0; if (_verbose > 1) {
if (data0 != null) { Utils.log.fine("Writing entry: " + name + " size=" + size +
int size0 = data0.capacity(); (deflateHint ? " deflated" : ""));
data0.get(_buf, fillp, size0);
fillp += size0;
}
if (data1 != null) {
int size1 = data1.capacity();
data1.get(_buf, fillp, size1);
fillp += size1;
}
while (fillp < size) {
// Fill in rest of data from the stream itself.
int nr = in.read(_buf, fillp, size - fillp);
if (nr <= 0) throw new IOException("EOF at end of archive");
fillp += nr;
} }
ZipEntry z = new ZipEntry(name); ZipEntry z = new ZipEntry(name);
z.setTime(mtime * 1000); z.setTime(mtime * 1000);
z.setSize(size);
if (size == 0) { if (size == 0) {
z.setMethod(ZipOutputStream.STORED); z.setMethod(ZipOutputStream.STORED);
z.setSize(0); z.setCompressedSize(size);
z.setCrc(0); z.setCrc(0);
z.setCompressedSize(0); j.putNextEntry(z);
} else if (!deflateHint) { } else if (!deflateHint) {
z.setMethod(ZipOutputStream.STORED); z.setMethod(ZipOutputStream.STORED);
z.setSize(size);
z.setCompressedSize(size); z.setCompressedSize(size);
crc32.reset(); writeEntryData(j, z, data0, data1, size, true);
crc32.update(_buf, 0, size);
z.setCrc(crc32.getValue());
} else { } else {
z.setMethod(Deflater.DEFLATED); z.setMethod(Deflater.DEFLATED);
z.setSize(size); writeEntryData(j, z, data0, data1, size, false);
} }
j.putNextEntry(z);
if (size > 0)
j.write(_buf, 0, size);
j.closeEntry(); j.closeEntry();
if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
} }
private void writeEntryData(JarOutputStream j, ZipEntry z, ByteBuffer data0,
ByteBuffer data1, int size, boolean computeCrc32)
throws IOException {
prepareReadBuffers(size);
try {
int inBytes = size;
inBytes -= readDataByteBuffer(data0);
inBytes -= readDataByteBuffer(data1);
inBytes -= readDataInputStream(inBytes);
if (inBytes != 0L) {
throw new IOException("invalid size: " + size);
}
if (computeCrc32) {
_crc32.reset();
processReadData((byte[] buff, int offset, int len) -> {
_crc32.update(buff, offset, len);
});
z.setCrc(_crc32.getValue());
}
j.putNextEntry(z);
processReadData((byte[] buff, int offset, int len) -> {
j.write(buff, offset, len);
});
} finally {
resetReadBuffers();
}
}
private void prepareReadBuffers(int size) {
if (_buf.length < size && _buf.length < MAX_BUFFER_SIZE) {
// Grow the regular buffer to accomodate lsize up to a limit.
long newIdealSize = _buf.length;
while (newIdealSize < size && newIdealSize < MAX_BUFFER_SIZE) {
// Never overflows: size is [0, 0x7FFFFFFF].
newIdealSize <<= 1;
}
int newSize = (int) Long.min(newIdealSize, MAX_BUFFER_SIZE);
_buf = new byte[newSize];
}
resetReadBuffers();
}
private void resetReadBuffers() {
_extra_buf.clear();
_current_buf = _buf;
_current_buf_pos = 0;
}
private int readDataByteBuffer(ByteBuffer data) throws IOException {
if (data == null) {
return 0;
}
return readData(data.remaining(),
(byte[] buff, int offset, int len) -> {
data.get(buff, offset, len);
return len;
});
}
private int readDataInputStream(int inBytes) throws IOException {
return readData(inBytes, (byte[] buff, int offset, int len) -> {
return in.read(buff, offset, len);
});
}
private static interface ReadDataCB {
public int read(byte[] buff, int offset, int len) throws IOException;
}
private int readData(int bytesToRead, ReadDataCB readDataCb)
throws IOException {
int bytesRemaining = bytesToRead;
while (bytesRemaining > 0) {
if (_current_buf_pos == _current_buf.length) {
byte[] newBuff = new byte[Integer.min(bytesRemaining,
MAX_BUFFER_SIZE)];
_extra_buf.add(newBuff);
_current_buf = newBuff;
_current_buf_pos = 0;
}
int current_buffer_space = _current_buf.length - _current_buf_pos;
int nextRead = Integer.min(current_buffer_space, bytesRemaining);
int bytesRead = readDataCb.read(_current_buf, _current_buf_pos,
nextRead);
if (bytesRead <= 0) {
throw new IOException("EOF at end of archive");
}
_current_buf_pos += bytesRead;
bytesRemaining -= bytesRead;
}
return bytesToRead - bytesRemaining;
}
private static interface ProcessDataCB {
public void apply(byte[] buff, int offset, int len) throws IOException;
}
private void processReadData(ProcessDataCB processDataCB)
throws IOException {
processDataCB.apply(_buf, 0, _buf == _current_buf ? _current_buf_pos :
_buf.length);
for (byte[] buff : _extra_buf) {
// Extra buffers are allocated of a size such that they are always
// full, including the last one.
processDataCB.apply(buff, 0, buff.length);
};
}
} }

View File

@ -247,14 +247,6 @@ public final class RSAPrivateCrtKeyImpl
return keyParams; return keyParams;
} }
// return a string representation of this key for debugging
@Override
public String toString() {
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
/** /**
* Parse the key. Called by PKCS8Key. * Parse the key. Called by PKCS8Key.
*/ */

View File

@ -123,14 +123,6 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
return keyParams; return keyParams;
} }
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
/** /**
* Restores the state of this object from the stream. * Restores the state of this object from the stream.
* <p> * <p>

View File

@ -76,10 +76,14 @@ abstract class CKey implements Key, Length {
protected final String algorithm; protected final String algorithm;
protected CKey(String algorithm, NativeHandles handles, int keyLength) { private final boolean isPublic;
protected CKey(String algorithm, NativeHandles handles, int keyLength,
boolean isPublic) {
this.algorithm = algorithm; this.algorithm = algorithm;
this.handles = handles; this.handles = handles;
this.keyLength = keyLength; this.keyLength = keyLength;
this.isPublic = isPublic;
} }
// Native method to cleanup the key handle. // Native method to cleanup the key handle.
@ -102,6 +106,18 @@ abstract class CKey implements Key, Length {
return algorithm; return algorithm;
} }
public String toString() {
String typeStr;
if (handles.hCryptKey != 0) {
typeStr = getKeyType(handles.hCryptKey) + ", container=" +
getContainerName(handles.hCryptProv);
} else {
typeStr = "CNG";
}
return algorithm + " " + (isPublic ? "PublicKey" : "PrivateKey") +
" [size=" + keyLength + " bits, type=" + typeStr + "]";
}
protected native static String getContainerName(long hCryptProv); protected native static String getContainerName(long hCryptProv);
protected native static String getKeyType(long hCryptKey); protected native static String getKeyType(long hCryptKey);

View File

@ -41,7 +41,7 @@ class CPrivateKey extends CKey implements PrivateKey {
private static final long serialVersionUID = 8113152807912338063L; private static final long serialVersionUID = 8113152807912338063L;
private CPrivateKey(String alg, NativeHandles handles, int keyLength) { private CPrivateKey(String alg, NativeHandles handles, int keyLength) {
super(alg, handles, keyLength); super(alg, handles, keyLength, false);
} }
// Called by native code inside security.cpp // Called by native code inside security.cpp
@ -64,16 +64,6 @@ class CPrivateKey extends CKey implements PrivateKey {
return null; return null;
} }
public String toString() {
if (handles.hCryptKey != 0) {
return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" +
getKeyType(handles.hCryptKey) + ", container=" +
getContainerName(handles.hCryptProv) + "]";
} else {
return algorithm + "PrivateKey [size=" + keyLength + " bits, type=CNG]";
}
}
// This class is not serializable // This class is not serializable
private void writeObject(java.io.ObjectOutputStream out) private void writeObject(java.io.ObjectOutputStream out)
throws java.io.IOException { throws java.io.IOException {

View File

@ -110,9 +110,8 @@ public abstract class CPublicKey extends CKey implements PublicKey {
} }
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer(super.toString());
sb.append(algorithm).append("PublicKey [size=").append(keyLength) sb.append("\n ECPoint: ").append(getW())
.append("]\n ECPoint: ").append(getW())
.append("\n params: ").append(getParams()); .append("\n params: ").append(getParams());
return sb.toString(); return sb.toString();
} }
@ -129,16 +128,8 @@ public abstract class CPublicKey extends CKey implements PublicKey {
} }
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer(super.toString());
sb.append(algorithm).append("PublicKey [size=").append(keyLength) sb.append("\n modulus: ").append(getModulus())
.append(" bits, type=");
if (handles.hCryptKey != 0) {
sb.append(getKeyType(handles.hCryptKey))
.append(", container=").append(getContainerName(handles.hCryptProv));
} else {
sb.append("CNG");
}
sb.append("]\n modulus: ").append(getModulus())
.append("\n public exponent: ").append(getPublicExponent()); .append("\n public exponent: ").append(getPublicExponent());
return sb.toString(); return sb.toString();
} }
@ -209,7 +200,7 @@ public abstract class CPublicKey extends CKey implements PublicKey {
protected CPublicKey( protected CPublicKey(
String alg, NativeHandles handles, int keyLength) { String alg, NativeHandles handles, int keyLength) {
super(alg, handles, keyLength); super(alg, handles, keyLength, true);
} }
@Override @Override