Merge
This commit is contained in:
commit
cda0d67617
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2019 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -40,15 +40,17 @@
|
||||
// contain enough detail to gain initial insight while keeping the
|
||||
// internal structure sizes in check.
|
||||
//
|
||||
// The CodeHeap is a living thing. Therefore, the aggregate is collected
|
||||
// under the CodeCache_lock. The subsequent print steps are only locked
|
||||
// against concurrent aggregations. That keeps the impact on
|
||||
// "normal operation" (JIT compiler and sweeper activity) to a minimum.
|
||||
//
|
||||
// The second part, which consists of several, independent steps,
|
||||
// prints the previously collected information with emphasis on
|
||||
// various aspects.
|
||||
//
|
||||
// The CodeHeap is a living thing. Therefore, protection against concurrent
|
||||
// modification (by acquiring the CodeCache_lock) is necessary. It has
|
||||
// to be provided by the caller of the analysis functions.
|
||||
// If the CodeCache_lock is not held, the analysis functions may print
|
||||
// less detailed information or may just do nothing. It is by intention
|
||||
// that an unprotected invocation is not abnormally terminated.
|
||||
//
|
||||
// Data collection and printing is done on an "on request" basis.
|
||||
// While no request is being processed, there is no impact on performance.
|
||||
// The CodeHeap state analytics do have some memory footprint.
|
||||
@ -456,7 +458,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
bool done = false;
|
||||
const int min_granules = 256;
|
||||
const int max_granules = 512*K; // limits analyzable CodeHeap (with segment_granules) to 32M..128M
|
||||
// results in StatArray size of 20M (= max_granules * 40 Bytes per element)
|
||||
// results in StatArray size of 24M (= max_granules * 48 Bytes per element)
|
||||
// For a 1GB CodeHeap, the granule size must be at least 2kB to not violate the max_granles limit.
|
||||
const char* heapName = get_heapName(heap);
|
||||
STRINGSTREAM_DECL(ast, out)
|
||||
@ -495,6 +497,12 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CodeCache_lock->owned_by_self()) {
|
||||
printBox(ast, '-', "aggregate function called without holding the CodeCache_lock for ", heapName);
|
||||
STRINGSTREAM_FLUSH("")
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate granularity of analysis (and output).
|
||||
// The CodeHeap is managed (allocated) in segments (units) of CodeCacheSegmentSize.
|
||||
// The CodeHeap can become fairly large, in particular in productive real-life systems.
|
||||
@ -1028,6 +1036,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
STRINGSTREAM_FLUSH("\n")
|
||||
|
||||
// This loop is intentionally printing directly to "out".
|
||||
// It should not print anything, anyway.
|
||||
out->print("Verifying collected data...");
|
||||
size_t granule_segs = granule_size>>log2_seg_size;
|
||||
for (unsigned int ix = 0; ix < granules; ix++) {
|
||||
@ -1071,6 +1080,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
}
|
||||
|
||||
// This loop is intentionally printing directly to "out".
|
||||
// It should not print anything, anyway.
|
||||
if (used_topSizeBlocks > 0) {
|
||||
unsigned int j = 0;
|
||||
if (TopSizeArray[0].len != currMax) {
|
||||
@ -1166,6 +1176,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
//---< calculate and fill remaining fields >---
|
||||
if (FreeArray != NULL) {
|
||||
// This loop is intentionally printing directly to "out".
|
||||
// It should not print anything, anyway.
|
||||
for (unsigned int ix = 0; ix < alloc_freeBlocks-1; ix++) {
|
||||
size_t lenSum = 0;
|
||||
FreeArray[ix].gap = (unsigned int)((address)FreeArray[ix+1].start - ((address)FreeArray[ix].start + FreeArray[ix].len));
|
||||
@ -1223,6 +1234,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
|
||||
//----------------------------
|
||||
{
|
||||
char* low_bound = heap->low_boundary();
|
||||
bool have_CodeCache_lock = CodeCache_lock->owned_by_self();
|
||||
|
||||
printBox(ast, '-', "Largest Used Blocks in ", heapName);
|
||||
print_blobType_legend(ast);
|
||||
@ -1241,12 +1253,19 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
|
||||
unsigned int printed_topSizeBlocks = 0;
|
||||
for (unsigned int i = 0; i != tsbStopper; i = TopSizeArray[i].index) {
|
||||
printed_topSizeBlocks++;
|
||||
CodeBlob* this_blob = (CodeBlob*)(heap->find_start(TopSizeArray[i].start));
|
||||
nmethod* nm = NULL;
|
||||
const char* blob_name = "unnamed blob";
|
||||
if (this_blob != NULL) {
|
||||
blob_name = this_blob->name();
|
||||
nm = this_blob->as_nmethod_or_null();
|
||||
const char* blob_name = "unnamed blob or blob name unavailable";
|
||||
// heap->find_start() is safe. Only works on _segmap.
|
||||
// Returns NULL or void*. Returned CodeBlob may be uninitialized.
|
||||
HeapBlock* heapBlock = TopSizeArray[i].start;
|
||||
CodeBlob* this_blob = (CodeBlob*)(heap->find_start(heapBlock));
|
||||
bool blob_is_safe = blob_access_is_safe(this_blob, NULL);
|
||||
if (blob_is_safe) {
|
||||
//---< access these fields only if we own the CodeCache_lock >---
|
||||
if (have_CodeCache_lock) {
|
||||
blob_name = this_blob->name();
|
||||
nm = this_blob->as_nmethod_or_null();
|
||||
}
|
||||
//---< blob address >---
|
||||
ast->print(INTPTR_FORMAT, p2i(this_blob));
|
||||
ast->fill_to(19);
|
||||
@ -1262,10 +1281,18 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
|
||||
ast->fill_to(33);
|
||||
}
|
||||
|
||||
|
||||
//---< print size, name, and signature (for nMethods) >---
|
||||
if ((nm != NULL) && (nm->method() != NULL)) {
|
||||
// access nmethod and Method fields only if we own the CodeCache_lock.
|
||||
// This fact is implicitly transported via nm != NULL.
|
||||
if (CompiledMethod::nmethod_access_is_safe(nm)) {
|
||||
ResourceMark rm;
|
||||
Method* method = nm->method();
|
||||
if (nm->is_in_use()) {
|
||||
blob_name = method->name_and_sig_as_C_string();
|
||||
}
|
||||
if (nm->is_not_entrant()) {
|
||||
blob_name = method->name_and_sig_as_C_string();
|
||||
}
|
||||
//---< nMethod size in hex >---
|
||||
unsigned int total_size = nm->total_size();
|
||||
ast->print(PTR32_FORMAT, total_size);
|
||||
@ -1280,10 +1307,12 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
|
||||
ast->print("%5d", nm->hotness_counter());
|
||||
//---< name and signature >---
|
||||
ast->fill_to(67+6);
|
||||
if (nm->is_in_use()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
|
||||
if (nm->is_not_entrant()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
|
||||
if (nm->is_not_installed()) {ast->print("%s", " not (yet) installed method "); }
|
||||
if (nm->is_zombie()) {ast->print("%s", " zombie method "); }
|
||||
if (nm->is_not_installed()) {
|
||||
ast->print(" not (yet) installed method ");
|
||||
}
|
||||
if (nm->is_zombie()) {
|
||||
ast->print(" zombie method ");
|
||||
}
|
||||
ast->print("%s", blob_name);
|
||||
} else {
|
||||
//---< block size in hex >---
|
||||
@ -2083,10 +2112,11 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
}
|
||||
STRINGSTREAM_DECL(ast, out)
|
||||
|
||||
unsigned int granules_per_line = 128;
|
||||
char* low_bound = heap->low_boundary();
|
||||
CodeBlob* last_blob = NULL;
|
||||
bool name_in_addr_range = true;
|
||||
unsigned int granules_per_line = 128;
|
||||
char* low_bound = heap->low_boundary();
|
||||
CodeBlob* last_blob = NULL;
|
||||
bool name_in_addr_range = true;
|
||||
bool have_CodeCache_lock = CodeCache_lock->owned_by_self();
|
||||
|
||||
//---< print at least 128K per block (i.e. between headers) >---
|
||||
if (granules_per_line*granule_size < 128*K) {
|
||||
@ -2121,16 +2151,14 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
StatArray[ix].stub_count + StatArray[ix].dead_count;
|
||||
if (nBlobs > 0 ) {
|
||||
for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
|
||||
// heap->find_start() is safe. Only working with _segmap. Returns NULL or void*. Returned CodeBlob may be uninitialized.
|
||||
CodeBlob* this_blob = (CodeBlob *)(heap->find_start(low_bound+ix*granule_size+is));
|
||||
bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
|
||||
((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
|
||||
((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
|
||||
os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
|
||||
os::is_readable_pointer(this_blob->content_begin());
|
||||
// heap->find_start() is safe. Only works on _segmap.
|
||||
// Returns NULL or void*. Returned CodeBlob may be uninitialized.
|
||||
char* this_seg = low_bound + ix*granule_size + is;
|
||||
CodeBlob* this_blob = (CodeBlob*)(heap->find_start(this_seg));
|
||||
bool blob_is_safe = blob_access_is_safe(this_blob, NULL);
|
||||
// blob could have been flushed, freed, and merged.
|
||||
// this_blob < last_blob is an indicator for that.
|
||||
if (blob_initialized && (this_blob > last_blob)) {
|
||||
if (blob_is_safe && (this_blob > last_blob)) {
|
||||
last_blob = this_blob;
|
||||
|
||||
//---< get type and name >---
|
||||
@ -2138,12 +2166,22 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
if (segment_granules) {
|
||||
cbType = (blobType)StatArray[ix].type;
|
||||
} else {
|
||||
cbType = get_cbType(this_blob);
|
||||
//---< access these fields only if we own the CodeCache_lock >---
|
||||
if (have_CodeCache_lock) {
|
||||
cbType = get_cbType(this_blob);
|
||||
}
|
||||
}
|
||||
// this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
|
||||
const char* blob_name = this_blob->name();
|
||||
if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
|
||||
blob_name = "<unavailable>";
|
||||
|
||||
//---< access these fields only if we own the CodeCache_lock >---
|
||||
const char* blob_name = "<unavailable>";
|
||||
nmethod* nm = NULL;
|
||||
if (have_CodeCache_lock) {
|
||||
blob_name = this_blob->name();
|
||||
nm = this_blob->as_nmethod_or_null();
|
||||
// this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
|
||||
if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
|
||||
blob_name = "<unavailable>";
|
||||
}
|
||||
}
|
||||
|
||||
//---< print table header for new print range >---
|
||||
@ -2163,8 +2201,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
|
||||
ast->fill_to(33);
|
||||
|
||||
// this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
|
||||
nmethod* nm = this_blob->as_nmethod_or_null();
|
||||
// access nmethod and Method fields only if we own the CodeCache_lock.
|
||||
// This fact is implicitly transported via nm != NULL.
|
||||
if (CompiledMethod::nmethod_access_is_safe(nm)) {
|
||||
Method* method = nm->method();
|
||||
ResourceMark rm;
|
||||
@ -2201,14 +2239,17 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
} else {
|
||||
ast->print("%s", blob_name);
|
||||
}
|
||||
} else {
|
||||
} else if (blob_is_safe) {
|
||||
ast->fill_to(62+6);
|
||||
ast->print("%s", blobTypeName[cbType]);
|
||||
ast->fill_to(82+6);
|
||||
ast->print("%s", blob_name);
|
||||
} else {
|
||||
ast->fill_to(62+6);
|
||||
ast->print("<stale blob>");
|
||||
}
|
||||
STRINGSTREAM_FLUSH_LOCKED("\n")
|
||||
} else if (!blob_initialized && (this_blob != last_blob) && (this_blob != NULL)) {
|
||||
} else if (!blob_is_safe && (this_blob != last_blob) && (this_blob != NULL)) {
|
||||
last_blob = this_blob;
|
||||
STRINGSTREAM_FLUSH_LOCKED("\n")
|
||||
}
|
||||
@ -2375,16 +2416,31 @@ CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
|
||||
if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
|
||||
if (cb->is_buffer_blob()) return bufferBlob;
|
||||
|
||||
nmethod* nm = cb->as_nmethod_or_null();
|
||||
if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
|
||||
if (nm->is_not_installed()) return nMethod_inconstruction;
|
||||
if (nm->is_zombie()) return nMethod_dead;
|
||||
if (nm->is_unloaded()) return nMethod_unloaded;
|
||||
if (nm->is_in_use()) return nMethod_inuse;
|
||||
if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
|
||||
if (nm->is_alive()) return nMethod_alive;
|
||||
return nMethod_dead;
|
||||
//---< access these fields only if we own the CodeCache_lock >---
|
||||
// Should be ensured by caller. aggregate() amd print_names() do that.
|
||||
if (CodeCache_lock->owned_by_self()) {
|
||||
nmethod* nm = cb->as_nmethod_or_null();
|
||||
if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
|
||||
if (nm->is_not_installed()) return nMethod_inconstruction;
|
||||
if (nm->is_zombie()) return nMethod_dead;
|
||||
if (nm->is_unloaded()) return nMethod_unloaded;
|
||||
if (nm->is_in_use()) return nMethod_inuse;
|
||||
if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
|
||||
if (nm->is_alive()) return nMethod_alive;
|
||||
return nMethod_dead;
|
||||
}
|
||||
}
|
||||
}
|
||||
return noType;
|
||||
}
|
||||
|
||||
bool CodeHeapState::blob_access_is_safe(CodeBlob* this_blob, CodeBlob* prev_blob) {
|
||||
return (this_blob != NULL) && // a blob must have been found, obviously
|
||||
((this_blob == prev_blob) || (prev_blob == NULL)) && // when re-checking, the same blob must have been found
|
||||
(this_blob->header_size() >= 0) &&
|
||||
(this_blob->relocation_size() >= 0) &&
|
||||
((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
|
||||
((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
|
||||
os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
|
||||
os::is_readable_pointer(this_blob->content_begin());
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -95,6 +95,7 @@ class CodeHeapState : public CHeapObj<mtCode> {
|
||||
static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
|
||||
static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
|
||||
static blobType get_cbType(CodeBlob* cb);
|
||||
static bool blob_access_is_safe(CodeBlob* this_blob, CodeBlob* prev_blob);
|
||||
|
||||
public:
|
||||
static void discard(outputStream* out, CodeHeap* heap);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2672,6 +2672,7 @@ void CompileBroker::print_info(outputStream *out) {
|
||||
// preventing concurrently printing threads from stalling a long time.
|
||||
void CompileBroker::print_heapinfo(outputStream* out, const char* function, const char* granularity) {
|
||||
TimeStamp ts_total;
|
||||
TimeStamp ts_global;
|
||||
TimeStamp ts;
|
||||
|
||||
bool allFun = !strcmp(function, "all");
|
||||
@ -2701,35 +2702,43 @@ void CompileBroker::print_heapinfo(outputStream* out, const char* function, cons
|
||||
}
|
||||
|
||||
// We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
|
||||
// That helps us getting a consistent view on the CodeHeap, at least for the "all" function.
|
||||
// That prevents another thread from destroying our view on the CodeHeap.
|
||||
// When we request individual parts of the analysis via the jcmd interface, it is possible
|
||||
// that in between another thread (another jcmd user or the vm running into CodeCache OOM)
|
||||
// updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
|
||||
// across user interaction.
|
||||
// Acquire this lock before acquiring the CodeCache_lock.
|
||||
// CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
|
||||
// leading to an unnecessarily long hold time of the CodeCache_lock.
|
||||
ts.update(); // record starting point
|
||||
MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
|
||||
out->cr();
|
||||
out->print_cr("__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________", ts.seconds());
|
||||
out->cr();
|
||||
out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());
|
||||
|
||||
// If we serve an "allFun" call, it is beneficial to hold the CodeCache_lock
|
||||
// for the entire duration of aggregation and printing. That makes sure
|
||||
// we see a consistent picture and do not run into issues caused by
|
||||
// the CodeHeap being altered concurrently.
|
||||
Monitor* global_lock = allFun ? CodeCache_lock : NULL;
|
||||
Monitor* function_lock = allFun ? NULL : CodeCache_lock;
|
||||
ts_global.update(); // record starting point
|
||||
MutexLockerEx mu2(global_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (global_lock != NULL) {
|
||||
out->print_cr("\n__ CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
|
||||
ts_global.update(); // record starting point
|
||||
}
|
||||
|
||||
if (aggregate) {
|
||||
// It is sufficient to hold the CodeCache_lock only for the aggregate step.
|
||||
// All other functions operate on aggregated data - except MethodNames, but that should be safe.
|
||||
// The separate CodeHeapStateAnalytics_lock protects the printing functions against
|
||||
// concurrent aggregate steps. Acquire this lock before acquiring the CodeCache_lock.
|
||||
// CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
|
||||
// leading to an unnecessarily long hold time of the CodeCache_lock.
|
||||
ts.update(); // record starting point
|
||||
MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
out->cr();
|
||||
out->print_cr("__ CodeCache lock wait took %10.3f seconds _________", ts.seconds());
|
||||
out->cr();
|
||||
MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (function_lock != NULL) {
|
||||
out->print_cr("\n__ CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
|
||||
}
|
||||
|
||||
ts.update(); // record starting point
|
||||
CodeCache::aggregate(out, granularity);
|
||||
out->cr();
|
||||
out->print_cr("__ CodeCache lock hold took %10.3f seconds _________", ts.seconds());
|
||||
out->cr();
|
||||
if (function_lock != NULL) {
|
||||
out->print_cr("\n__ CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
|
||||
}
|
||||
}
|
||||
|
||||
if (usedSpace) CodeCache::print_usedSpace(out);
|
||||
@ -2737,10 +2746,16 @@ void CompileBroker::print_heapinfo(outputStream* out, const char* function, cons
|
||||
if (methodCount) CodeCache::print_count(out);
|
||||
if (methodSpace) CodeCache::print_space(out);
|
||||
if (methodAge) CodeCache::print_age(out);
|
||||
if (methodNames) CodeCache::print_names(out);
|
||||
if (methodNames) {
|
||||
// print_names() has shown to be sensitive to concurrent CodeHeap modifications.
|
||||
// Therefore, request the CodeCache_lock before calling...
|
||||
MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
|
||||
CodeCache::print_names(out);
|
||||
}
|
||||
if (discard) CodeCache::discard(out);
|
||||
|
||||
out->cr();
|
||||
out->print_cr("__ CodeHeapStateAnalytics total duration %10.3f seconds _________", ts_total.seconds());
|
||||
out->cr();
|
||||
if (global_lock != NULL) {
|
||||
out->print_cr("\n__ CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
|
||||
}
|
||||
out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
|
||||
}
|
||||
|
@ -62,9 +62,8 @@ bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {
|
||||
}
|
||||
|
||||
// Check if enough time has passed since the last GC.
|
||||
uintx time_since_last_gc;
|
||||
if ((G1PeriodicGCInterval == 0) ||
|
||||
((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval)) {
|
||||
uintx time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc();
|
||||
if ((time_since_last_gc < G1PeriodicGCInterval)) {
|
||||
log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.",
|
||||
time_since_last_gc, G1PeriodicGCInterval);
|
||||
return false;
|
||||
@ -83,6 +82,10 @@ bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::check_for_periodic_gc(){
|
||||
// If disabled, just return.
|
||||
if (G1PeriodicGCInterval == 0) {
|
||||
return;
|
||||
}
|
||||
if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
|
||||
log_debug(gc, periodic)("Checking for periodic GC.");
|
||||
if (should_start_periodic_gc()) {
|
||||
@ -95,6 +98,13 @@ void G1YoungRemSetSamplingThread::check_for_periodic_gc(){
|
||||
void G1YoungRemSetSamplingThread::run_service() {
|
||||
double vtime_start = os::elapsedVTime();
|
||||
|
||||
// Print a message about periodic GC configuration.
|
||||
if (G1PeriodicGCInterval != 0) {
|
||||
log_info(gc)("Periodic GC enabled with interval " UINTX_FORMAT "ms", G1PeriodicGCInterval);
|
||||
} else {
|
||||
log_info(gc)("Periodic GC disabled");
|
||||
}
|
||||
|
||||
while (!should_terminate()) {
|
||||
sample_young_list_rs_lengths();
|
||||
|
||||
|
@ -97,7 +97,7 @@ bool ShenandoahBarrierNode::needs_barrier_impl(PhaseGVN* phase, ShenandoahBarrie
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n->is_CallJava() || n->Opcode() == Op_CallLeafNoFP) {
|
||||
if (n->is_Call()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2659,9 +2659,35 @@ void ShenandoahWriteBarrierNode::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
wb->pin_and_expand_helper(phase);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < enqueue_barriers.size(); i++) {
|
||||
Node* barrier = enqueue_barriers.at(i);
|
||||
Node* ctrl = phase->get_ctrl(barrier);
|
||||
IdealLoopTree* loop = phase->get_loop(ctrl);
|
||||
if (loop->_head->is_OuterStripMinedLoop()) {
|
||||
// Expanding a barrier here will break loop strip mining
|
||||
// verification. Transform the loop so the loop nest doesn't
|
||||
// appear as strip mined.
|
||||
OuterStripMinedLoopNode* outer = loop->_head->as_OuterStripMinedLoop();
|
||||
hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count(); i > 0; i--) {
|
||||
int cnt = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count();
|
||||
ShenandoahWriteBarrierNode* wb = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barrier(i-1);
|
||||
Node* ctrl = phase->get_ctrl(wb);
|
||||
IdealLoopTree* loop = phase->get_loop(ctrl);
|
||||
if (loop->_head->is_OuterStripMinedLoop()) {
|
||||
// Expanding a barrier here will break loop strip mining
|
||||
// verification. Transform the loop so the loop nest doesn't
|
||||
// appear as strip mined.
|
||||
OuterStripMinedLoopNode* outer = loop->_head->as_OuterStripMinedLoop();
|
||||
hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase);
|
||||
Unique_Node_List uses_to_ignore;
|
||||
Unique_Node_List outer_lsms;
|
||||
for (uint i = 0; i < enqueue_barriers.size(); i++) {
|
||||
Node* barrier = enqueue_barriers.at(i);
|
||||
Node* pre_val = barrier->in(1);
|
||||
@ -2685,9 +2711,6 @@ void ShenandoahWriteBarrierNode::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
|
||||
Node* init_ctrl = ctrl;
|
||||
IdealLoopTree* loop = phase->get_loop(ctrl);
|
||||
if (loop->_head->is_OuterStripMinedLoop()) {
|
||||
outer_lsms.push(loop->_head);
|
||||
}
|
||||
Node* raw_mem = fixer.find_mem(ctrl, barrier);
|
||||
Node* init_raw_mem = raw_mem;
|
||||
Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
|
||||
@ -2832,9 +2855,6 @@ void ShenandoahWriteBarrierNode::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
Node* val = wb->in(ValueIn);
|
||||
Node* wbproj = wb->find_out_with(Op_ShenandoahWBMemProj);
|
||||
IdealLoopTree *loop = phase->get_loop(ctrl);
|
||||
if (loop->_head->is_OuterStripMinedLoop()) {
|
||||
outer_lsms.push(loop->_head);
|
||||
}
|
||||
|
||||
assert(val->Opcode() != Op_ShenandoahWriteBarrier, "No chain of write barriers");
|
||||
|
||||
@ -3019,14 +3039,6 @@ void ShenandoahWriteBarrierNode::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
}
|
||||
|
||||
assert(ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count() == 0, "all write barrier nodes should have been replaced");
|
||||
|
||||
for (uint i = 0; i < outer_lsms.size(); i++) {
|
||||
// Expanding a barrier here will break loop strip mining
|
||||
// verification. Transform the loop so the loop nest doesn't
|
||||
// appear as strip mined.
|
||||
OuterStripMinedLoopNode* outer = outer_lsms.at(i)->as_OuterStripMinedLoop();
|
||||
hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahWriteBarrierNode::move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) {
|
||||
@ -4274,5 +4286,3 @@ void MemoryGraphFixer::remove(Node* n) {
|
||||
_memory_nodes.map(c->_idx, mem->in(ShenandoahWBMemProjNode::WriteBarrier)->in(ShenandoahBarrierNode::Memory));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -602,6 +602,17 @@ C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_t
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (method->name() == vmSymbols::clone_name() &&
|
||||
resolved == SystemDictionary::Object_klass() &&
|
||||
recv_klass->is_array_klass()) {
|
||||
// Resolution of the clone method on arrays always returns Object.clone even though that method
|
||||
// has protected access. There's some trickery in the access checking to make this all work out
|
||||
// so it's necessary to pass in the array class as the resolved class to properly trigger this.
|
||||
// Otherwise it's impossible to resolve the array clone methods through JVMCI. See
|
||||
// LinkResolver::check_method_accessability for the matching logic.
|
||||
resolved = recv_klass;
|
||||
}
|
||||
|
||||
LinkInfo link_info(resolved, h_name, h_signature, caller_klass);
|
||||
methodHandle m;
|
||||
// Only do exact lookup if receiver klass has been linked. Otherwise,
|
||||
|
@ -160,7 +160,7 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node*
|
||||
// When called from beautify_loops() idom is not constructed yet.
|
||||
if (_idom != NULL) {
|
||||
Node* ridom = idom(rgn);
|
||||
Node* nrdom = dom_lca(ridom, new_iff);
|
||||
Node* nrdom = dom_lca_internal(ridom, new_iff);
|
||||
set_idom(rgn, nrdom, dom_depth(rgn));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,6 @@
|
||||
package java.security.spec;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
|
||||
/**
|
||||
* This class specifies a parameter spec for RSASSA-PSS signature scheme,
|
||||
@ -218,4 +217,14 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
|
||||
public int getTrailerField() {
|
||||
return trailerField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("MD: " + mdName + "\n")
|
||||
.append("MGF: " + mgfSpec + "\n")
|
||||
.append("SaltLength: " + saltLen + "\n")
|
||||
.append("TrailerField: " + trailerField + "\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,6 @@ import java.math.BigInteger;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
@ -237,10 +236,14 @@ public class PKCS10 {
|
||||
*/
|
||||
AlgorithmId algId = null;
|
||||
try {
|
||||
algId = AlgorithmId.get(signature.getAlgorithm());
|
||||
AlgorithmParameters params = signature.getParameters();
|
||||
algId = params == null
|
||||
? AlgorithmId.get(signature.getAlgorithm())
|
||||
: AlgorithmId.get(params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new SignatureException(nsae);
|
||||
}
|
||||
|
||||
algId.encode(scratch); // sig algorithm
|
||||
scratch.putBitString(sig); // sig
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,13 +52,7 @@ import static java.security.spec.PSSParameterSpec.DEFAULT;
|
||||
|
||||
public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
|
||||
private String mdName;
|
||||
private MGF1ParameterSpec mgfSpec;
|
||||
private int saltLength;
|
||||
private int trailerField;
|
||||
|
||||
private static final ObjectIdentifier OID_MGF1 =
|
||||
ObjectIdentifier.newInternal(new int[] {1,2,840,113549,1,1,8});
|
||||
private PSSParameterSpec spec;
|
||||
|
||||
public PSSParameters() {
|
||||
}
|
||||
@ -71,9 +65,9 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
("Inappropriate parameter specification");
|
||||
}
|
||||
PSSParameterSpec spec = (PSSParameterSpec) paramSpec;
|
||||
this.mdName = spec.getDigestAlgorithm();
|
||||
|
||||
String mgfName = spec.getMGFAlgorithm();
|
||||
if (!mgfName.equalsIgnoreCase("MGF1")) {
|
||||
if (!spec.getMGFAlgorithm().equalsIgnoreCase("MGF1")) {
|
||||
throw new InvalidParameterSpecException("Unsupported mgf " +
|
||||
mgfName + "; MGF1 only");
|
||||
}
|
||||
@ -82,31 +76,30 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
throw new InvalidParameterSpecException("Inappropriate mgf " +
|
||||
"parameters; non-null MGF1ParameterSpec only");
|
||||
}
|
||||
this.mgfSpec = (MGF1ParameterSpec) mgfSpec;
|
||||
this.saltLength = spec.getSaltLength();
|
||||
this.trailerField = spec.getTrailerField();
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(byte[] encoded) throws IOException {
|
||||
// first initialize with the DEFAULT values before
|
||||
// retrieving from the encoding bytes
|
||||
this.mdName = DEFAULT.getDigestAlgorithm();
|
||||
this.mgfSpec = (MGF1ParameterSpec) DEFAULT.getMGFParameters();
|
||||
this.saltLength = DEFAULT.getSaltLength();
|
||||
this.trailerField = DEFAULT.getTrailerField();
|
||||
String mdName = DEFAULT.getDigestAlgorithm();
|
||||
MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) DEFAULT.getMGFParameters();
|
||||
int saltLength = DEFAULT.getSaltLength();
|
||||
int trailerField = DEFAULT.getTrailerField();
|
||||
|
||||
DerInputStream der = new DerInputStream(encoded);
|
||||
DerValue[] datum = der.getSequence(4);
|
||||
|
||||
for (DerValue d : datum) {
|
||||
if (d.isContextSpecific((byte) 0x00)) {
|
||||
// hash algid
|
||||
this.mdName = AlgorithmId.parse
|
||||
mdName = AlgorithmId.parse
|
||||
(d.data.getDerValue()).getName();
|
||||
} else if (d.isContextSpecific((byte) 0x01)) {
|
||||
// mgf algid
|
||||
AlgorithmId val = AlgorithmId.parse(d.data.getDerValue());
|
||||
if (!val.getOID().equals(OID_MGF1)) {
|
||||
if (!val.getOID().equals(AlgorithmId.mgf1_oid)) {
|
||||
throw new IOException("Only MGF1 mgf is supported");
|
||||
}
|
||||
AlgorithmId params = AlgorithmId.parse(
|
||||
@ -114,25 +107,25 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
String mgfDigestName = params.getName();
|
||||
switch (mgfDigestName) {
|
||||
case "SHA-1":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA1;
|
||||
mgfSpec = MGF1ParameterSpec.SHA1;
|
||||
break;
|
||||
case "SHA-224":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA224;
|
||||
mgfSpec = MGF1ParameterSpec.SHA224;
|
||||
break;
|
||||
case "SHA-256":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA256;
|
||||
mgfSpec = MGF1ParameterSpec.SHA256;
|
||||
break;
|
||||
case "SHA-384":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA384;
|
||||
mgfSpec = MGF1ParameterSpec.SHA384;
|
||||
break;
|
||||
case "SHA-512":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA512;
|
||||
mgfSpec = MGF1ParameterSpec.SHA512;
|
||||
break;
|
||||
case "SHA-512/224":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA512_224;
|
||||
mgfSpec = MGF1ParameterSpec.SHA512_224;
|
||||
break;
|
||||
case "SHA-512/256":
|
||||
this.mgfSpec = MGF1ParameterSpec.SHA512_256;
|
||||
mgfSpec = MGF1ParameterSpec.SHA512_256;
|
||||
break;
|
||||
default:
|
||||
throw new IOException
|
||||
@ -141,21 +134,24 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
}
|
||||
} else if (d.isContextSpecific((byte) 0x02)) {
|
||||
// salt length
|
||||
this.saltLength = d.data.getDerValue().getInteger();
|
||||
if (this.saltLength < 0) {
|
||||
saltLength = d.data.getDerValue().getInteger();
|
||||
if (saltLength < 0) {
|
||||
throw new IOException("Negative value for saltLength");
|
||||
}
|
||||
} else if (d.isContextSpecific((byte) 0x03)) {
|
||||
// trailer field
|
||||
this.trailerField = d.data.getDerValue().getInteger();
|
||||
if (this.trailerField != 1) {
|
||||
trailerField = d.data.getDerValue().getInteger();
|
||||
if (trailerField != 1) {
|
||||
throw new IOException("Unsupported trailerField value " +
|
||||
this.trailerField);
|
||||
trailerField);
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Invalid encoded PSSParameters");
|
||||
}
|
||||
}
|
||||
|
||||
this.spec = new PSSParameterSpec(mdName, "MGF1", mgfSpec,
|
||||
saltLength, trailerField);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -173,9 +169,7 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
T engineGetParameterSpec(Class<T> paramSpec)
|
||||
throws InvalidParameterSpecException {
|
||||
if (PSSParameterSpec.class.isAssignableFrom(paramSpec)) {
|
||||
return paramSpec.cast(
|
||||
new PSSParameterSpec(mdName, "MGF1", mgfSpec,
|
||||
saltLength, trailerField));
|
||||
return paramSpec.cast(spec);
|
||||
} else {
|
||||
throw new InvalidParameterSpecException
|
||||
("Inappropriate parameter specification");
|
||||
@ -184,54 +178,7 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
|
||||
@Override
|
||||
protected byte[] engineGetEncoded() throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
DerOutputStream tmp2, tmp3;
|
||||
|
||||
// MD
|
||||
AlgorithmId mdAlgId;
|
||||
try {
|
||||
mdAlgId = AlgorithmId.get(mdName);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new IOException("AlgorithmId " + mdName +
|
||||
" impl not found");
|
||||
}
|
||||
tmp2 = new DerOutputStream();
|
||||
mdAlgId.derEncode(tmp2);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0),
|
||||
tmp2);
|
||||
|
||||
// MGF
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putOID(OID_MGF1);
|
||||
AlgorithmId mgfDigestId;
|
||||
try {
|
||||
mgfDigestId = AlgorithmId.get(mgfSpec.getDigestAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nase) {
|
||||
throw new IOException("AlgorithmId " +
|
||||
mgfSpec.getDigestAlgorithm() + " impl not found");
|
||||
}
|
||||
mgfDigestId.encode(tmp2);
|
||||
tmp3 = new DerOutputStream();
|
||||
tmp3.write(DerValue.tag_Sequence, tmp2);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)1),
|
||||
tmp3);
|
||||
|
||||
// SaltLength
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putInteger(saltLength);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)2),
|
||||
tmp2);
|
||||
|
||||
// TrailerField
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putInteger(trailerField);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)3),
|
||||
tmp2);
|
||||
|
||||
// Put all together under a SEQUENCE tag
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
return out.toByteArray();
|
||||
return getEncoded(spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -245,11 +192,83 @@ public final class PSSParameters extends AlgorithmParametersSpi {
|
||||
|
||||
@Override
|
||||
protected String engineToString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("MD: " + mdName + "\n")
|
||||
.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n")
|
||||
.append("SaltLength: " + saltLength + "\n")
|
||||
.append("TrailerField: " + trailerField + "\n");
|
||||
return sb.toString();
|
||||
return spec.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoding of a {@link PSSParameterSpec} object. This method
|
||||
* is used in this class and {@link AlgorithmId}.
|
||||
*
|
||||
* @param spec a {@code PSSParameterSpec} object
|
||||
* @return its DER encoding
|
||||
* @throws IOException if the name of a MessageDigest or MaskGenAlgorithm
|
||||
* is unsupported
|
||||
*/
|
||||
public static byte[] getEncoded(PSSParameterSpec spec) throws IOException {
|
||||
|
||||
AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
|
||||
if (!(mgfSpec instanceof MGF1ParameterSpec)) {
|
||||
throw new IOException("Cannot encode " + mgfSpec);
|
||||
}
|
||||
|
||||
MGF1ParameterSpec mgf1Spec = (MGF1ParameterSpec)mgfSpec;
|
||||
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
DerOutputStream tmp2, tmp3;
|
||||
|
||||
// MD
|
||||
AlgorithmId mdAlgId;
|
||||
try {
|
||||
mdAlgId = AlgorithmId.get(spec.getDigestAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new IOException("AlgorithmId " + spec.getDigestAlgorithm() +
|
||||
" impl not found");
|
||||
}
|
||||
if (!mdAlgId.getOID().equals(AlgorithmId.SHA_oid)) {
|
||||
tmp2 = new DerOutputStream();
|
||||
mdAlgId.derEncode(tmp2);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
|
||||
tmp2);
|
||||
}
|
||||
|
||||
// MGF
|
||||
AlgorithmId mgfDigestId;
|
||||
try {
|
||||
mgfDigestId = AlgorithmId.get(mgf1Spec.getDigestAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nase) {
|
||||
throw new IOException("AlgorithmId " +
|
||||
mgf1Spec.getDigestAlgorithm() + " impl not found");
|
||||
}
|
||||
|
||||
if (!mgfDigestId.getOID().equals(AlgorithmId.SHA_oid)) {
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putOID(AlgorithmId.mgf1_oid);
|
||||
mgfDigestId.encode(tmp2);
|
||||
tmp3 = new DerOutputStream();
|
||||
tmp3.write(DerValue.tag_Sequence, tmp2);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 1),
|
||||
tmp3);
|
||||
}
|
||||
|
||||
// SaltLength
|
||||
if (spec.getSaltLength() != 20) {
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putInteger(spec.getSaltLength());
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 2),
|
||||
tmp2);
|
||||
}
|
||||
|
||||
// TrailerField
|
||||
if (spec.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
|
||||
tmp2 = new DerOutputStream();
|
||||
tmp2.putInteger(spec.getTrailerField());
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 3),
|
||||
tmp2);
|
||||
}
|
||||
|
||||
// Put all together under a SEQUENCE tag
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -220,8 +220,8 @@ final class DHKeyExchange {
|
||||
public byte[] encode() {
|
||||
// Note: the DH public value is encoded as a big-endian integer
|
||||
// and padded to the left with zeros to the size of p in bytes.
|
||||
byte[] encoded = publicKey.getY().toByteArray();
|
||||
int pSize = KeyUtil.getKeySize(publicKey);
|
||||
byte[] encoded = Utilities.toByteArray(publicKey.getY());
|
||||
int pSize = (KeyUtil.getKeySize(publicKey) + 7) >>> 3;
|
||||
if (pSize > 0 && encoded.length < pSize) {
|
||||
byte[] buffer = new byte[pSize];
|
||||
System.arraycopy(encoded, 0,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,6 +30,7 @@ import java.security.cert.X509Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.util.Date;
|
||||
@ -37,7 +38,6 @@ import java.util.Date;
|
||||
import sun.security.pkcs10.PKCS10;
|
||||
import sun.security.x509.*;
|
||||
|
||||
|
||||
/**
|
||||
* Generate a pair of keys, and provide access to them. This class is
|
||||
* provided primarily for ease of use.
|
||||
@ -282,12 +282,14 @@ public final class CertAndKeyGen {
|
||||
new CertificateValidity(firstDate,lastDate);
|
||||
|
||||
X509CertInfo info = new X509CertInfo();
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlg, privateKey);
|
||||
// Add all mandatory attributes
|
||||
info.set(X509CertInfo.VERSION,
|
||||
new CertificateVersion(CertificateVersion.V3));
|
||||
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
|
||||
new java.util.Random().nextInt() & 0x7fffffff));
|
||||
AlgorithmId algID = AlgorithmId.get(sigAlg);
|
||||
AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlg, params);
|
||||
info.set(X509CertInfo.ALGORITHM_ID,
|
||||
new CertificateAlgorithmId(algID));
|
||||
info.set(X509CertInfo.SUBJECT, myname);
|
||||
@ -297,13 +299,19 @@ public final class CertAndKeyGen {
|
||||
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
|
||||
|
||||
cert = new X509CertImpl(info);
|
||||
cert.sign(privateKey, this.sigAlg);
|
||||
cert.sign(privateKey,
|
||||
params,
|
||||
sigAlg,
|
||||
null);
|
||||
|
||||
return (X509Certificate)cert;
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new CertificateEncodingException("getSelfCert: " +
|
||||
e.getMessage());
|
||||
} catch (InvalidAlgorithmParameterException e2) {
|
||||
throw new SignatureException(
|
||||
"Unsupported PSSParameterSpec: " + e2.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,6 +337,7 @@ public final class CertAndKeyGen {
|
||||
* @exception InvalidKeyException on key handling errors.
|
||||
* @exception SignatureException on signature handling errors.
|
||||
*/
|
||||
// This method is not used inside JDK. Will not update it.
|
||||
public PKCS10 getCertRequest (X500Name myname)
|
||||
throws InvalidKeyException, SignatureException
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,6 +52,7 @@ import java.security.cert.URICertStoreParameters;
|
||||
|
||||
|
||||
import java.security.interfaces.ECKey;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.text.Collator;
|
||||
import java.text.MessageFormat;
|
||||
@ -1431,14 +1432,16 @@ public final class Main {
|
||||
signature.initSign(privateKey);
|
||||
|
||||
X509CertInfo info = new X509CertInfo();
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlgName, privateKey);
|
||||
AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlgName, params);
|
||||
info.set(X509CertInfo.VALIDITY, interval);
|
||||
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
|
||||
new java.util.Random().nextInt() & 0x7fffffff));
|
||||
info.set(X509CertInfo.VERSION,
|
||||
new CertificateVersion(CertificateVersion.V3));
|
||||
info.set(X509CertInfo.ALGORITHM_ID,
|
||||
new CertificateAlgorithmId(
|
||||
AlgorithmId.get(sigAlgName)));
|
||||
new CertificateAlgorithmId(algID));
|
||||
info.set(X509CertInfo.ISSUER, issuer);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
@ -1482,7 +1485,7 @@ public final class Main {
|
||||
signerCert.getPublicKey());
|
||||
info.set(X509CertInfo.EXTENSIONS, ext);
|
||||
X509CertImpl cert = new X509CertImpl(info);
|
||||
cert.sign(privateKey, sigAlgName);
|
||||
cert.sign(privateKey, params, sigAlgName, null);
|
||||
dumpCert(cert, out);
|
||||
for (Certificate ca: keyStore.getCertificateChain(alias)) {
|
||||
if (ca instanceof X509Certificate) {
|
||||
@ -1585,6 +1588,12 @@ public final class Main {
|
||||
|
||||
Signature signature = Signature.getInstance(sigAlgName);
|
||||
signature.initSign(privKey);
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlgName, privKey);
|
||||
if (params != null) {
|
||||
signature.setParameter(params);
|
||||
}
|
||||
|
||||
X500Name subject = dname == null?
|
||||
new X500Name(((X509Certificate)cert).getSubjectDN().toString()):
|
||||
new X500Name(dname);
|
||||
@ -2962,7 +2971,9 @@ public final class Main {
|
||||
// other solution: We first sign the cert, then retrieve the
|
||||
// outer sigalg and use it to set the inner sigalg
|
||||
X509CertImpl newCert = new X509CertImpl(certInfo);
|
||||
newCert.sign(privKey, sigAlgName);
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlgName, privKey);
|
||||
newCert.sign(privKey, params, sigAlgName, null);
|
||||
AlgorithmId sigAlgid = (AlgorithmId)newCert.get(X509CertImpl.SIG_ALG);
|
||||
certInfo.set(CertificateAlgorithmId.NAME + "." +
|
||||
CertificateAlgorithmId.ALGORITHM, sigAlgid);
|
||||
@ -2979,7 +2990,7 @@ public final class Main {
|
||||
certInfo.set(X509CertInfo.EXTENSIONS, ext);
|
||||
// Sign the new certificate
|
||||
newCert = new X509CertImpl(certInfo);
|
||||
newCert.sign(privKey, sigAlgName);
|
||||
newCert.sign(privKey, params, sigAlgName, null);
|
||||
|
||||
// Store the new certificate as a single-element certificate chain
|
||||
keyStore.setKeyEntry(alias, privKey,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,9 +26,14 @@
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.security.spec.PSSParameterSpec;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
|
||||
import sun.security.rsa.PSSParameters;
|
||||
import sun.security.util.*;
|
||||
|
||||
|
||||
@ -190,7 +195,12 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
} else {
|
||||
bytes.putNull();
|
||||
}*/
|
||||
bytes.putNull();
|
||||
if (algid.equals(RSASSA_PSS_oid)) {
|
||||
// RFC 4055 3.3: when an RSASSA-PSS key does not require
|
||||
// parameter validation, field is absent.
|
||||
} else {
|
||||
bytes.putNull();
|
||||
}
|
||||
} else {
|
||||
bytes.putDerValue(params);
|
||||
}
|
||||
@ -689,6 +699,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
oid(1, 2, 840, 113549, 1, 1, 1);
|
||||
public static final ObjectIdentifier RSAES_OAEP_oid =
|
||||
oid(1, 2, 840, 113549, 1, 1, 7);
|
||||
public static final ObjectIdentifier mgf1_oid =
|
||||
oid(1, 2, 840, 113549, 1, 1, 8);
|
||||
public static final ObjectIdentifier RSASSA_PSS_oid =
|
||||
oid(1, 2, 840, 113549, 1, 1, 10);
|
||||
|
||||
@ -1063,6 +1075,81 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
// Most commonly used PSSParameterSpec and AlgorithmId
|
||||
private static class PSSParamsHolder {
|
||||
|
||||
final static PSSParameterSpec PSS_256_SPEC = new PSSParameterSpec(
|
||||
"SHA-256", "MGF1",
|
||||
new MGF1ParameterSpec("SHA-256"),
|
||||
32, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
final static PSSParameterSpec PSS_384_SPEC = new PSSParameterSpec(
|
||||
"SHA-384", "MGF1",
|
||||
new MGF1ParameterSpec("SHA-384"),
|
||||
48, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
final static PSSParameterSpec PSS_512_SPEC = new PSSParameterSpec(
|
||||
"SHA-512", "MGF1",
|
||||
new MGF1ParameterSpec("SHA-512"),
|
||||
64, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
final static AlgorithmId PSS_256_ID;
|
||||
final static AlgorithmId PSS_384_ID;
|
||||
final static AlgorithmId PSS_512_ID;
|
||||
|
||||
static {
|
||||
try {
|
||||
PSS_256_ID = new AlgorithmId(RSASSA_PSS_oid,
|
||||
new DerValue(PSSParameters.getEncoded(PSS_256_SPEC)));
|
||||
PSS_384_ID = new AlgorithmId(RSASSA_PSS_oid,
|
||||
new DerValue(PSSParameters.getEncoded(PSS_384_SPEC)));
|
||||
PSS_512_ID = new AlgorithmId(RSASSA_PSS_oid,
|
||||
new DerValue(PSSParameters.getEncoded(PSS_512_SPEC)));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("Should not happen", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static AlgorithmId getWithParameterSpec(String algName,
|
||||
AlgorithmParameterSpec spec) throws NoSuchAlgorithmException {
|
||||
|
||||
if (spec == null) {
|
||||
return AlgorithmId.get(algName);
|
||||
} else if (spec == PSSParamsHolder.PSS_256_SPEC) {
|
||||
return PSSParamsHolder.PSS_256_ID;
|
||||
} else if (spec == PSSParamsHolder.PSS_384_SPEC) {
|
||||
return PSSParamsHolder.PSS_384_ID;
|
||||
} else if (spec == PSSParamsHolder.PSS_512_SPEC) {
|
||||
return PSSParamsHolder.PSS_512_ID;
|
||||
} else {
|
||||
try {
|
||||
AlgorithmParameters result =
|
||||
AlgorithmParameters.getInstance(algName);
|
||||
result.init(spec);
|
||||
return get(result);
|
||||
} catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
|
||||
throw new ProviderException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PSSParameterSpec getDefaultAlgorithmParameterSpec(
|
||||
String sigAlg, PrivateKey k) {
|
||||
if (sigAlg.equalsIgnoreCase("RSASSA-PSS")) {
|
||||
switch (ifcFfcStrength(KeyUtil.getKeySize(k))) {
|
||||
case "SHA256":
|
||||
return PSSParamsHolder.PSS_256_SPEC;
|
||||
case "SHA384":
|
||||
return PSSParamsHolder.PSS_384_SPEC;
|
||||
case "SHA512":
|
||||
return PSSParamsHolder.PSS_512_SPEC;
|
||||
default:
|
||||
throw new AssertionError("Should not happen");
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Values from SP800-57 part 1 rev 4 tables 2 and 3
|
||||
private static String ecStrength (int bitLength) {
|
||||
if (bitLength >= 512) { // 256 bits of strength
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import java.util.Base64;
|
||||
import sun.security.util.*;
|
||||
import sun.security.provider.X509Factory;
|
||||
|
||||
@ -599,14 +598,10 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||
|
||||
sigEngine.initSign(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call, so
|
||||
// the deferred provider selection happens when the key is set
|
||||
try {
|
||||
if (signingParams != null) {
|
||||
// set parameters after Signature.initSign/initVerify call, so
|
||||
// the deferred provider selection happens when the key is set
|
||||
sigEngine.setParameter(signingParams);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// for backward compatibility, only re-throw when
|
||||
// parameters is not null
|
||||
if (signingParams != null) throw e;
|
||||
}
|
||||
|
||||
// in case the name is reset
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -298,8 +298,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
|
||||
private CPlatformResponder responder;
|
||||
private long lastBecomeMainTime; // this is necessary to preserve right siblings order
|
||||
private boolean maximizedBothState = false;
|
||||
private boolean frameResizibilityChanged = false;
|
||||
|
||||
public CPlatformWindow() {
|
||||
super(0, true);
|
||||
@ -402,7 +400,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
// Either java.awt.Frame or java.awt.Dialog can be resizable, however java.awt.Window is never resizable
|
||||
{
|
||||
final boolean resizable = isTargetResizable();
|
||||
final boolean resizable = isFrame ? ((Frame)target).isResizable() : (isDialog ? ((Dialog)target).isResizable() : false);
|
||||
styleBits = SET(styleBits, RESIZABLE, resizable);
|
||||
if (!resizable) {
|
||||
styleBits = SET(styleBits, ZOOMABLE, false);
|
||||
@ -614,8 +612,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
setBounds(maximizedBounds.x, maximizedBounds.y,
|
||||
maximizedBounds.width, maximizedBounds.height);
|
||||
}
|
||||
setFrameResizibilityChanged(true);
|
||||
updateResizableAndMaximizeState(true);
|
||||
}
|
||||
|
||||
private void unmaximize() {
|
||||
@ -712,9 +708,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
// Manage the extended state when showing
|
||||
if (visible) {
|
||||
/* Frame or Dialog should be set property WINDOW_FULLSCREENABLE to true if the
|
||||
Frame resizable and Frame state is not MAXIMIZED_BOTH or Dialog is resizable.
|
||||
Frame or Dialog is resizable.
|
||||
**/
|
||||
if (isTargetResizable()) {
|
||||
final boolean resizable = (target instanceof Frame) ? ((Frame)target).isResizable() :
|
||||
((target instanceof Dialog) ? ((Dialog)target).isResizable() : false);
|
||||
if (resizable) {
|
||||
setCanFullscreen(true);
|
||||
}
|
||||
|
||||
@ -730,11 +728,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
frameState = Frame.ICONIFIED;
|
||||
}
|
||||
|
||||
if (isFrameResizibilityChanged()) {
|
||||
updateResizableAndMaximizeState(false);
|
||||
setFrameResizibilityChanged(false);
|
||||
}
|
||||
|
||||
switch (frameState) {
|
||||
case Frame.ICONIFIED:
|
||||
execute(CWrapper.NSWindow::miniaturize);
|
||||
@ -854,10 +847,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
@Override
|
||||
public void setResizable(final boolean resizable) {
|
||||
boolean windowResizable = resizable && !isMaximizedBoth();
|
||||
setCanFullscreen(windowResizable);
|
||||
setStyleBits(RESIZABLE, windowResizable);
|
||||
setStyleBits(ZOOMABLE, windowResizable);
|
||||
setCanFullscreen(resizable);
|
||||
setStyleBits(RESIZABLE, resizable);
|
||||
setStyleBits(ZOOMABLE, resizable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -966,11 +958,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
windowState = Frame.ICONIFIED;
|
||||
}
|
||||
|
||||
if (isFrameResizibilityChanged()) {
|
||||
updateResizableAndMaximizeState(false);
|
||||
setFrameResizibilityChanged(false);
|
||||
}
|
||||
|
||||
switch (windowState) {
|
||||
case Frame.ICONIFIED:
|
||||
if (prevWindowState == Frame.MAXIMIZED_BOTH) {
|
||||
@ -1173,21 +1160,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Resizibility of frame with state MAXIMIZED_BOTH is set to true to zoom
|
||||
* the frame on double click on title bar and set to false later. This is
|
||||
* required as frame won't zoom if resizibility of frame is false.
|
||||
*/
|
||||
private void deliverDoubleClickOnTitlebar() {
|
||||
if ((peer != null) && (target instanceof Frame)) {
|
||||
if (isMaximizedBoth()) {
|
||||
updateResizableAndMaximizeState(false);
|
||||
execute(CWrapper.NSWindow::zoom);
|
||||
updateResizableAndMaximizeState(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Our focus model is synthetic and only non-simple window
|
||||
* may become natively focusable window.
|
||||
@ -1353,33 +1325,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isTargetResizable() {
|
||||
if (target instanceof Frame) {
|
||||
return ((Frame)target).isResizable() && !isMaximizedBoth();
|
||||
} else if (target instanceof Dialog) {
|
||||
return ((Dialog)target).isResizable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateResizableAndMaximizeState(boolean maximizeState) {
|
||||
maximizedBothState = maximizeState;
|
||||
setResizable(!maximizeState);
|
||||
}
|
||||
|
||||
private boolean isMaximizedBoth() {
|
||||
return maximizedBothState;
|
||||
}
|
||||
|
||||
private void setFrameResizibilityChanged(boolean resize) {
|
||||
frameResizibilityChanged = resize;
|
||||
}
|
||||
|
||||
private boolean isFrameResizibilityChanged() {
|
||||
return frameResizibilityChanged;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// NATIVE CALLBACKS
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -965,11 +965,6 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
// Currently, no need to deliver the whole NSEvent.
|
||||
static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
|
||||
JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
|
||||
// Deliver double click on title bar
|
||||
if ([event clickCount] > 1) {
|
||||
static JNF_MEMBER_CACHE(jm_deliverDoubleClickOnTitlebar, jc_CPlatformWindow, "deliverDoubleClickOnTitlebar", "()V");
|
||||
JNFCallVoidMethod(env, platformWindow, jm_deliverDoubleClickOnTitlebar);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, platformWindow);
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +168,26 @@ public class ResolvedJavaTypeResolveMethodTest {
|
||||
|
||||
}
|
||||
|
||||
static class ClassType {
|
||||
}
|
||||
|
||||
interface InterfaceType {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloneAccessibility() {
|
||||
/*
|
||||
* The resolution machinery for clone on arrays has some hacks in that show up in odd places
|
||||
* so make sure that resolveMethod works as expected.
|
||||
*/
|
||||
ResolvedJavaType interfaceType = getType(InterfaceType.class);
|
||||
ResolvedJavaType classType = getType(ClassType.class);
|
||||
ResolvedJavaType arrayType = getType(double[].class);
|
||||
ResolvedJavaMethod cloneMethod = getMethod(getType(Object.class), "clone");
|
||||
assertEquals("Can't resolve clone for class", cloneMethod, arrayType.resolveMethod(cloneMethod, classType));
|
||||
assertEquals("Can't resolve clone for interface", cloneMethod, arrayType.resolveMethod(cloneMethod, interfaceType));
|
||||
}
|
||||
|
||||
static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
|
||||
for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
|
||||
if (method.getName().equals(methodName)) {
|
||||
|
73
test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java
Normal file
73
test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestPeriodicLogMessages
|
||||
* @bug 8216490
|
||||
* @requires vm.gc.G1
|
||||
* @summary Verify that log messages are printed as expected
|
||||
* @library /test/lib /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @modules java.management/sun.management
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
public class TestPeriodicLogMessages {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
||||
"-XX:G1PeriodicGCInterval=0",
|
||||
"-Xlog:gc,gc+periodic=debug",
|
||||
"-Xmx10M",
|
||||
GCTest.class.getName());
|
||||
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("Periodic GC disabled");
|
||||
output.shouldNotContain("Checking for periodic GC");
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
||||
"-XX:G1PeriodicGCInterval=100",
|
||||
"-Xlog:gc,gc+periodic=debug",
|
||||
"-Xmx10M",
|
||||
GCTest.class.getName());
|
||||
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("Periodic GC enabled with interval 100ms");
|
||||
output.shouldContain("Checking for periodic GC");
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
static class GCTest {
|
||||
public static void main(String [] args) throws Exception {
|
||||
System.out.println("Waiting for messages...");
|
||||
Thread.sleep(1000);
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
@test
|
||||
@key headful
|
||||
@bug 4980161 7158623 8204860 8208125
|
||||
@bug 4980161 7158623 8204860 8208125 8215280
|
||||
@summary Setting focusable window state to false makes the maximized frame resizable
|
||||
@compile UnfocusableMaximizedFrameResizablity.java
|
||||
@run main UnfocusableMaximizedFrameResizablity
|
||||
@ -47,8 +47,15 @@ public class UnfocusableMaximizedFrameResizablity {
|
||||
|
||||
private static void createAndShowFrame() throws Exception {
|
||||
|
||||
//MAXIMIZED_BOTH frame is resizable on Mac OS by default. Nothing to test.
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
//The MAXIMIZED_BOTH state is not supported by the toolkit. Nothing to test.
|
||||
if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -93,7 +100,9 @@ public class UnfocusableMaximizedFrameResizablity {
|
||||
}
|
||||
|
||||
private static void cleanup() {
|
||||
frame.dispose();
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
isProgInterruption = true;
|
||||
mainThread.interrupt();
|
||||
}
|
||||
|
108
test/jdk/sun/security/tools/keytool/PSS.java
Normal file
108
test/jdk/sun/security/tools/keytool/PSS.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8215694
|
||||
* @summary keytool cannot generate RSASSA-PSS certificates
|
||||
* @library /test/lib
|
||||
* @modules java.base/sun.security.util
|
||||
* java.base/sun.security.x509
|
||||
* @run main PSS
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.SecurityTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.security.DerUtils;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public class PSS {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
KeyStore ks = KeyStore.getInstance(
|
||||
new File("ks"), "changeit".toCharArray());
|
||||
|
||||
check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
|
||||
AlgorithmId.SHA256_oid);
|
||||
|
||||
check((X509Certificate)ks.getCertificate("a"), "RSA",
|
||||
AlgorithmId.SHA256_oid);
|
||||
|
||||
check((X509Certificate)ks.getCertificate("b"), "RSA",
|
||||
AlgorithmId.SHA384_oid);
|
||||
|
||||
check((X509Certificate)ks.getCertificate("c"), "RSA",
|
||||
AlgorithmId.SHA512_oid);
|
||||
|
||||
// More commands
|
||||
kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
kt("-importcert -alias p -file p.cert")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
kt("-selfcert -alias p -sigalg RSASSA-PSS")
|
||||
.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
static OutputAnalyzer genkeypair(String alias, String options)
|
||||
throws Exception {
|
||||
return kt("-genkeypair -alias " + alias
|
||||
+ " -dname CN=" + alias + " " + options);
|
||||
}
|
||||
|
||||
static OutputAnalyzer kt(String cmd)
|
||||
throws Exception {
|
||||
return SecurityTools.keytool("-storepass changeit -keypass changeit "
|
||||
+ "-keystore ks " + cmd);
|
||||
}
|
||||
|
||||
static void check(X509Certificate cert, String expectedKeyAlg,
|
||||
ObjectIdentifier expectedMdAlg) throws Exception {
|
||||
Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
|
||||
Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
|
||||
DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user