diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 4a5b7897a36..0b2aacac7fc 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -320,3 +320,4 @@ c706ef5ea5da00078dc5e4334660315f7d99c15b jdk9-b71 8fd6eeb878606e39c908f12535f34ebbfd225a4a jdk9-b75 d82072b699b880a1f647a5e2d7c0f86cec958941 jdk9-b76 7972dc8f2a47f0c4cd8f02fa5662af41f028aa14 jdk9-b77 +8c40d4143ee13bdf8170c68cc384c36ab1e9fadb jdk9-b78 diff --git a/common/bin/compare_exceptions.sh.incl b/common/bin/compare_exceptions.sh.incl index 9c23a64222b..79ef2f2c6d9 100644 --- a/common/bin/compare_exceptions.sh.incl +++ b/common/bin/compare_exceptions.sh.incl @@ -42,7 +42,6 @@ STRIP_BEFORE_COMPARE=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -54,7 +53,6 @@ ACCEPTED_BIN_DIFF=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -62,9 +60,7 @@ ACCEPTED_BIN_DIFF=" ./lib/i386/client/libjvm.so ./lib/i386/libattach.so ./lib/i386/libdt_socket.so -./lib/i386/libhprof.so ./lib/i386/libinstrument.so -./lib/i386/libjava_crw_demo.so ./lib/i386/libjsdt.so ./lib/i386/libmanagement.so ./lib/i386/libnpt.so @@ -118,7 +114,6 @@ STRIP_BEFORE_COMPARE=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -130,16 +125,13 @@ ACCEPTED_BIN_DIFF=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so ./demo/jvmti/waiters/lib/libwaiters.so ./lib/amd64/libattach.so ./lib/amd64/libdt_socket.so -./lib/amd64/libhprof.so ./lib/amd64/libinstrument.so -./lib/amd64/libjava_crw_demo.so ./lib/amd64/libjsdt.so ./lib/amd64/libjsig.so ./lib/amd64/libmanagement.so @@ -197,7 +189,6 @@ STRIP_BEFORE_COMPARE=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -217,7 +208,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -232,7 +222,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./lib/amd64/libdcpr.so ./lib/amd64/libdt_socket.so ./lib/amd64/libfontmanager.so -./lib/amd64/libhprof.so ./lib/amd64/libinstrument.so ./lib/amd64/libj2gss.so ./lib/amd64/libj2pcsc.so @@ -240,7 +229,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./lib/amd64/libj2ucrypto.so ./lib/amd64/libjaas_unix.so ./lib/amd64/libjava.so -./lib/amd64/libjava_crw_demo.so ./lib/amd64/libjawt.so ./lib/amd64/libjdwp.so ./lib/amd64/libjfr.so @@ -330,7 +318,6 @@ STRIP_BEFORE_COMPARE=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -353,7 +340,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./demo/jvmti/gctest/lib/libgctest.so ./demo/jvmti/heapTracker/lib/libheapTracker.so ./demo/jvmti/heapViewer/lib/libheapViewer.so -./demo/jvmti/hprof/lib/libhprof.so ./demo/jvmti/minst/lib/libminst.so ./demo/jvmti/mtrace/lib/libmtrace.so ./demo/jvmti/versionCheck/lib/libversionCheck.so @@ -369,7 +355,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./lib/sparcv9/libdcpr.so ./lib/sparcv9/libdt_socket.so ./lib/sparcv9/libfontmanager.so -./lib/sparcv9/libhprof.so ./lib/sparcv9/libinstrument.so ./lib/sparcv9/libj2gss.so ./lib/sparcv9/libj2pcsc.so @@ -377,7 +362,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./lib/sparcv9/libj2ucrypto.so ./lib/sparcv9/libjaas_unix.so ./lib/sparcv9/libjava.so -./lib/sparcv9/libjava_crw_demo.so ./lib/sparcv9/libjawt.so ./lib/sparcv9/libjdwp.so ./lib/sparcv9/libjfr.so @@ -473,7 +457,6 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./demo/jvmti/heapTracker/lib/heapTracker.dll ./demo/jvmti/minst/lib/minst.dll ./bin/attach.dll -./bin/java_crw_demo.dll ./bin/jsoundds.dll ./bin/server/jvm.dll ./bin/appletviewer.exe @@ -611,9 +594,7 @@ ACCEPTED_BIN_DIFF=" ./Contents/Home/lib/libawt_lwawt.dylib ./Contents/Home/lib/libdeploy.dylib ./Contents/Home/lib/libdt_socket.dylib -./Contents/Home/lib/libhprof.dylib ./Contents/Home/lib/libinstrument.dylib -./Contents/Home/lib/libjava_crw_demo.dylib ./Contents/Home/lib/libjdwp.dylib ./Contents/Home/lib/libjsdt.dylib ./Contents/Home/lib/libjsig.dylib @@ -635,9 +616,7 @@ ACCEPTED_BIN_DIFF=" ./lib/libawt_lwawt.dylib ./lib/libdeploy.dylib ./lib/libdt_socket.dylib -./lib/libhprof.dylib ./lib/libinstrument.dylib -./lib/libjava_crw_demo.dylib ./lib/libjdwp.dylib ./lib/libjsdt.dylib ./lib/libjsig.dylib diff --git a/corba/.hgtags b/corba/.hgtags index 3f3d3c4089b..543479a78e1 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -320,3 +320,4 @@ f9f3706bd24c42c07cb260fe05730a749b8e52f4 jdk9-b72 960b56805abd8460598897481820bd6a75f979e7 jdk9-b75 d8126bc88fa5cd1ae4e44d86a4b1280ca1c9e2aa jdk9-b76 8bb2441c0fec8b28f7bf11a0ca3ec1642e7ef457 jdk9-b77 +182bb7accc5253bcfefd8edc1d4997ec8f9f8694 jdk9-b78 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 9662d2a1477..ef5c8bed04e 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -480,3 +480,4 @@ fff6b54e9770ac4c12c2fb4cab5aa7672affa4bd jdk9-b74 2f354281e9915275693c4e519a959b8a6f22d3a3 jdk9-b75 0bc8d1656d6f2b1fdfe803c1305a108bb9939f35 jdk9-b76 e66c3813789debfc06f206afde1bf7a84cb08451 jdk9-b77 +20dc06b04fe5ec373879414d60ef82ac70faef98 jdk9-b78 diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index a3196fe0b6d..8a25fd636b3 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -416,7 +416,8 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { int jmp_off = __ offset(); __ jmp(_patch_site_entry); // Add enough nops so deoptimization can overwrite the jmp above with a call - // and not destroy the world. + // and not destroy the world. We cannot use fat nops here, since the concurrent + // code rewrite may transiently create the illegal instruction sequence. for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) { __ nop(); } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index d8e9f412d79..d43a14be1bf 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -345,9 +345,7 @@ int LIR_Assembler::check_icache() { const bool do_post_padding = VerifyOops || UseCompressedClassPointers; if (!do_post_padding) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment - while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { - __ nop(); - } + __ align(CodeEntryAlignment, __ offset() + ic_cmp_size); } int offset = __ offset(); __ inline_cache_check(receiver, IC_Klass); @@ -2861,9 +2859,7 @@ void LIR_Assembler::align_call(LIR_Code code) { case lir_virtual_call: // currently, sparc-specific for niagara default: ShouldNotReachHere(); } - while (offset++ % BytesPerWord != 0) { - __ nop(); - } + __ align(BytesPerWord, offset); } } @@ -2902,10 +2898,7 @@ void LIR_Assembler::emit_static_call_stub() { int start = __ offset(); if (os::is_MP()) { // make sure that the displacement word of the call ends up word aligned - int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset; - while (offset++ % BytesPerWord != 0) { - __ nop(); - } + __ align(BytesPerWord, __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset); } __ relocate(static_stub_Relocation::spec(call_pc)); __ mov_metadata(rbx, (Metadata*)NULL); diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index c4df8163ead..04c2fe5bde6 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -970,8 +970,12 @@ void MacroAssembler::addss(XMMRegister dst, AddressLiteral src) { } void MacroAssembler::align(int modulus) { - if (offset() % modulus != 0) { - nop(modulus - (offset() % modulus)); + align(modulus, offset()); +} + +void MacroAssembler::align(int modulus, int target) { + if (target % modulus != 0) { + nop(modulus - (target % modulus)); } } diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index 4ad2ba17f94..9a877703126 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -192,6 +192,7 @@ class MacroAssembler: public Assembler { // Alignment void align(int modulus); + void align(int modulus, int target); // A 5 byte nop that is safe for patching (see patch_verified_entry) void fat_nop(); diff --git a/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp b/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp index 8fd9e727b17..6e012a9bee1 100644 --- a/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp +++ b/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp @@ -108,7 +108,7 @@ StubQueue* AbstractInterpreter::_code = NULL; #define GEN_SIZE(Type) \ switch(gen_variant) { \ case GEN_OFFSET: \ - printf("#define SIZE_%-35s %ld\n", \ + printf("#define SIZE_%-35s %ld\n", \ #Type, sizeof(Type)); \ break; \ case GEN_INDEX: \ @@ -134,7 +134,7 @@ StubQueue* AbstractInterpreter::_code = NULL; } void gen_prologue(GEN_variant gen_variant) { - const char *suffix; + const char *suffix = "Undefined-Suffix"; switch(gen_variant) { case GEN_OFFSET: suffix = ".h"; break; @@ -228,10 +228,10 @@ int generateJvmOffsets(GEN_variant gen_variant) { printf("\n"); GEN_OFFS(Method, _constMethod); - GEN_OFFS(Method, _constants); GEN_OFFS(Method, _access_flags); printf("\n"); + GEN_OFFS(ConstMethod, _constants); GEN_OFFS(ConstMethod, _flags); GEN_OFFS(ConstMethod, _code_size); GEN_OFFS(ConstMethod, _name_index); @@ -264,7 +264,7 @@ int generateJvmOffsets(GEN_variant gen_variant) { GEN_OFFS(nmethod, _method); GEN_OFFS(nmethod, _dependencies_offset); - GEN_OFFS(nmethod, _oops_offset); + GEN_OFFS(nmethod, _metadata_offset); GEN_OFFS(nmethod, _scopes_data_offset); GEN_OFFS(nmethod, _scopes_pcs_offset); GEN_OFFS(nmethod, _handler_table_offset); diff --git a/hotspot/src/os/bsd/dtrace/jhelper.d b/hotspot/src/os/bsd/dtrace/jhelper.d index c5fea81b8d8..dbe0a4a42f9 100644 --- a/hotspot/src/os/bsd/dtrace/jhelper.d +++ b/hotspot/src/os/bsd/dtrace/jhelper.d @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, 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 @@ -49,7 +49,7 @@ extern pointer __1cJCodeCacheG_heaps_; extern pointer __1cIUniverseO_collectedHeap_; extern pointer __1cHnmethodG__vtbl_; -extern pointer __1cNMethodG__vtbl_; +extern pointer __1cGMethodG__vtbl_; extern pointer __1cKBufferBlobG__vtbl_; #define copyin_ptr(ADDR) *(pointer*) copyin((pointer) (ADDR), sizeof(pointer)) @@ -164,7 +164,7 @@ dtrace:helper:ustack: this->number_of_heaps = copyin_uint32(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_len); this->Method_vtbl = (pointer) &``__1cGMethodG__vtbl_; - + /* * Get Java heap bounds */ @@ -457,12 +457,15 @@ dtrace:helper:ustack: this->nameSymbol = copyin_ptr(this->constantPool + this->nameIndex * sizeof (pointer) + SIZE_ConstantPool); + /* The symbol is a CPSlot and has lower bit set to indicate metadata */ + this->nameSymbol &= (~1); /* remove metadata lsb */ this->nameSymbolLength = copyin_uint16(this->nameSymbol + OFFSET_Symbol_length); this->signatureSymbol = copyin_ptr(this->constantPool + this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool); + this->signatureSymbol &= (~1); /* remove metadata lsb */ this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + OFFSET_Symbol_length); diff --git a/hotspot/src/os/bsd/dtrace/jvm_dtrace.c b/hotspot/src/os/bsd/dtrace/jvm_dtrace.c index 36d8b61b19f..58fc9197c7e 100644 --- a/hotspot/src/os/bsd/dtrace/jvm_dtrace.c +++ b/hotspot/src/os/bsd/dtrace/jvm_dtrace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2015, 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 @@ -227,7 +227,7 @@ static void delete_attach_file(pid_t pid) { /* attach to given JVM */ jvm_t* jvm_attach(pid_t pid) { jvm_t* jvm; - int door_fd, attach_fd, i; + int door_fd, attach_fd, i = 0; jvm = (jvm_t*) calloc(1, sizeof(jvm_t)); if (jvm == NULL) { @@ -292,14 +292,13 @@ const char* jvm_get_last_error() { /* detach the givenb JVM */ int jvm_detach(jvm_t* jvm) { if (jvm) { - int res; + int res = 0; if (jvm->door_fd != -1) { if (file_close(jvm->door_fd) != 0) { set_jvm_error(JVM_ERR_CANT_CLOSE_DOOR); res = -1; } else { clear_jvm_error(); - res = 0; } } free(jvm); diff --git a/hotspot/src/os/bsd/dtrace/libjvm_db.c b/hotspot/src/os/bsd/dtrace/libjvm_db.c index b483733f9ef..87a9afe24ff 100644 --- a/hotspot/src/os/bsd/dtrace/libjvm_db.c +++ b/hotspot/src/os/bsd/dtrace/libjvm_db.c @@ -882,7 +882,7 @@ get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc) /* Finds a PcDesc with real-pc equal to N->pc */ static int pc_desc_at(Nmethod_t *N) { - uint64_t pc_diff; + uint64_t pc_diff = 999; int32_t offs; int32_t err; diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp index a6fd68ed3db..ab2bcfbfac0 100644 --- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp +++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp @@ -217,9 +217,9 @@ static bool is_statbuf_secure(struct stat *statp) { // return false; } - // See if the uid of the directory matches the effective uid of the process. - // - if (statp->st_uid != geteuid()) { + // If user is not root then see if the uid of the directory matches the effective uid of the process. + uid_t euid = geteuid(); + if ((euid != 0) && (statp->st_uid != euid)) { // The directory was not created by this user, declare it insecure. // return false; diff --git a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp index ac66ccba240..ddd74b16d9e 100644 --- a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp +++ b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp @@ -85,7 +85,7 @@ StubQueue* AbstractInterpreter::_code = NULL; #define GEN_OFFS_NAME(Type,Name,OutputType) \ switch(gen_variant) { \ case GEN_OFFSET: \ - printf("#define OFFSET_%-33s %d\n", \ + printf("#define OFFSET_%-33s %ld\n", \ #OutputType #Name, offset_of(Type, Name)); \ break; \ case GEN_INDEX: \ @@ -103,7 +103,7 @@ StubQueue* AbstractInterpreter::_code = NULL; #define GEN_SIZE(Type) \ switch(gen_variant) { \ case GEN_OFFSET: \ - printf("#define SIZE_%-35s %d\n", \ + printf("#define SIZE_%-35s %ld\n", \ #Type, sizeof(Type)); \ break; \ case GEN_INDEX: \ @@ -129,7 +129,7 @@ StubQueue* AbstractInterpreter::_code = NULL; } void gen_prologue(GEN_variant gen_variant) { - const char *suffix; + const char *suffix = "Undefined-Suffix"; switch(gen_variant) { case GEN_OFFSET: suffix = ".h"; break; @@ -211,7 +211,7 @@ int generateJvmOffsets(GEN_variant gen_variant) { GEN_OFFS(ConstantPool, _pool_holder); printf("\n"); - GEN_VALUE(OFFSET_HeapBlockHeader_used, offset_of(HeapBlock::Header, _used)); + GEN_VALUE(OFFSET_HeapBlockHeader_used, (int) offset_of(HeapBlock::Header, _used)); GEN_OFFS(oopDesc, _metadata); printf("\n"); @@ -275,7 +275,7 @@ int generateJvmOffsets(GEN_variant gen_variant) { GEN_OFFS(NarrowPtrStruct, _shift); printf("\n"); - GEN_VALUE(SIZE_HeapBlockHeader, sizeof(HeapBlock::Header)); + GEN_VALUE(SIZE_HeapBlockHeader, (int) sizeof(HeapBlock::Header)); GEN_SIZE(oopDesc); GEN_SIZE(ConstantPool); printf("\n"); diff --git a/hotspot/src/os/solaris/dtrace/jvm_dtrace.c b/hotspot/src/os/solaris/dtrace/jvm_dtrace.c index 36d8b61b19f..58fc9197c7e 100644 --- a/hotspot/src/os/solaris/dtrace/jvm_dtrace.c +++ b/hotspot/src/os/solaris/dtrace/jvm_dtrace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2015, 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 @@ -227,7 +227,7 @@ static void delete_attach_file(pid_t pid) { /* attach to given JVM */ jvm_t* jvm_attach(pid_t pid) { jvm_t* jvm; - int door_fd, attach_fd, i; + int door_fd, attach_fd, i = 0; jvm = (jvm_t*) calloc(1, sizeof(jvm_t)); if (jvm == NULL) { @@ -292,14 +292,13 @@ const char* jvm_get_last_error() { /* detach the givenb JVM */ int jvm_detach(jvm_t* jvm) { if (jvm) { - int res; + int res = 0; if (jvm->door_fd != -1) { if (file_close(jvm->door_fd) != 0) { set_jvm_error(JVM_ERR_CANT_CLOSE_DOOR); res = -1; } else { clear_jvm_error(); - res = 0; } } free(jvm); diff --git a/hotspot/src/os/solaris/dtrace/libjvm_db.c b/hotspot/src/os/solaris/dtrace/libjvm_db.c index 1f24b8719ad..6bad77b68bb 100644 --- a/hotspot/src/os/solaris/dtrace/libjvm_db.c +++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c @@ -882,7 +882,7 @@ get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc) /* Finds a PcDesc with real-pc equal to N->pc */ static int pc_desc_at(Nmethod_t *N) { - uint64_t pc_diff; + uint64_t pc_diff = 999; int32_t offs; int32_t err; diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 5f060c30a95..e5b68dafb15 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -182,75 +182,6 @@ extern "C" { static void unpackTime(timespec* absTime, bool isAbsolute, jlong time); -// Thread Local Storage -// This is common to all Solaris platforms so it is defined here, -// in this common file. -// The declarations are in the os_cpu threadLS*.hpp files. -// -// Static member initialization for TLS -Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL}; - -#ifndef PRODUCT - #define _PCT(n,d) ((100.0*(double)(n))/(double)(d)) - -int ThreadLocalStorage::_tcacheHit = 0; -int ThreadLocalStorage::_tcacheMiss = 0; - -void ThreadLocalStorage::print_statistics() { - int total = _tcacheMiss+_tcacheHit; - tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n", - _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total)); -} - #undef _PCT -#endif // PRODUCT - -Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id, - int index) { - Thread *thread = get_thread_slow(); - if (thread != NULL) { - address sp = os::current_stack_pointer(); - guarantee(thread->_stack_base == NULL || - (sp <= thread->_stack_base && - sp >= thread->_stack_base - thread->_stack_size) || - is_error_reported(), - "sp must be inside of selected thread stack"); - - thread->set_self_raw_id(raw_id); // mark for quick retrieval - _get_thread_cache[index] = thread; - } - return thread; -} - - -static const double all_zero[sizeof(Thread) / sizeof(double) + 1] = {0}; -#define NO_CACHED_THREAD ((Thread*)all_zero) - -void ThreadLocalStorage::pd_set_thread(Thread* thread) { - - // Store the new value before updating the cache to prevent a race - // between get_thread_via_cache_slowly() and this store operation. - os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); - - // Update thread cache with new thread if setting on thread create, - // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit. - uintptr_t raw = pd_raw_thread_id(); - int ix = pd_cache_index(raw); - _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread; -} - -void ThreadLocalStorage::pd_init() { - for (int i = 0; i < _pd_cache_size; i++) { - _get_thread_cache[i] = NO_CACHED_THREAD; - } -} - -// Invalidate all the caches (happens to be the same as pd_init). -void ThreadLocalStorage::pd_invalidate_all() { pd_init(); } - -#undef NO_CACHED_THREAD - -// END Thread Local Storage - static inline size_t adjust_stack_size(address base, size_t size) { if ((ssize_t)size < 0) { // 4759953: Compensate for ridiculous stack size. @@ -1289,67 +1220,6 @@ int os::current_process_id() { return (int)(_initial_pid ? _initial_pid : getpid()); } -int os::allocate_thread_local_storage() { - // %%% in Win32 this allocates a memory segment pointed to by a - // register. Dan Stein can implement a similar feature in - // Solaris. Alternatively, the VM can do the same thing - // explicitly: malloc some storage and keep the pointer in a - // register (which is part of the thread's context) (or keep it - // in TLS). - // %%% In current versions of Solaris, thr_self and TSD can - // be accessed via short sequences of displaced indirections. - // The value of thr_self is available as %g7(36). - // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4), - // assuming that the current thread already has a value bound to k. - // It may be worth experimenting with such access patterns, - // and later having the parameters formally exported from a Solaris - // interface. I think, however, that it will be faster to - // maintain the invariant that %g2 always contains the - // JavaThread in Java code, and have stubs simply - // treat %g2 as a caller-save register, preserving it in a %lN. - thread_key_t tk; - if (thr_keycreate(&tk, NULL)) { - fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed " - "(%s)", strerror(errno))); - } - return int(tk); -} - -void os::free_thread_local_storage(int index) { - // %%% don't think we need anything here - // if (pthread_key_delete((pthread_key_t) tk)) { - // fatal("os::free_thread_local_storage: pthread_key_delete failed"); - // } -} - -// libthread allocate for tsd_common is a version specific -// small number - point is NO swap space available -#define SMALLINT 32 -void os::thread_local_storage_at_put(int index, void* value) { - // %%% this is used only in threadLocalStorage.cpp - if (thr_setspecific((thread_key_t)index, value)) { - if (errno == ENOMEM) { - vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR, - "thr_setspecific: out of swap space"); - } else { - fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed " - "(%s)", strerror(errno))); - } - } else { - ThreadLocalStorage::set_thread_in_slot((Thread *) value); - } -} - -// This function could be called before TLS is initialized, for example, when -// VM receives an async signal or when VM causes a fatal error during -// initialization. Return NULL if thr_getspecific() fails. -void* os::thread_local_storage_at(int index) { - // %%% this is used only in threadLocalStorage.cpp - void* r = NULL; - return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r; -} - - // gethrtime() should be monotonic according to the documentation, // but some virtualized platforms are known to break this guarantee. // getTimeNanos() must be guaranteed not to move backwards, so we diff --git a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp index 3c941eaeef4..3c9188d3000 100644 --- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp +++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp @@ -219,9 +219,9 @@ static bool is_statbuf_secure(struct stat *statp) { // return false; } - // See if the uid of the directory matches the effective uid of the process. - // - if (statp->st_uid != geteuid()) { + // If user is not root then see if the uid of the directory matches the effective uid of the process. + uid_t euid = geteuid(); + if ((euid != 0) && (statp->st_uid != euid)) { // The directory was not created by this user, declare it insecure. // return false; diff --git a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp index b5355335f39..fdbc553cd22 100644 --- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp +++ b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, 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 @@ -39,19 +39,12 @@ // For SPARC, to avoid excessive register window spill-fill faults, // we aggressively inline these routines. -inline Thread* ThreadLocalStorage::thread() { - // don't use specialized code if +UseMallocOnly -- may confuse Purify et al. - debug_only(if (UseMallocOnly) return get_thread_slow();); +inline void ThreadLocalStorage::set_thread(Thread* thread) { + _thr_current = thread; +} - uintptr_t raw = pd_raw_thread_id(); - int ix = pd_cache_index(raw); - Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix]; - if (candidate->self_raw_id() == raw) { - // hit - return candidate; - } else { - return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix); - } +inline Thread* ThreadLocalStorage::thread() { + return _thr_current; } #endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp index d07db6a5c60..30210a453cc 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, 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,19 +26,26 @@ #include "runtime/thread.inline.hpp" #include "runtime/threadLocalStorage.hpp" -// Provides an entry point we can link against and -// a buffer we can emit code into. The buffer is -// filled by ThreadLocalStorage::generate_code_for_get_thread -// and called from ThreadLocalStorage::thread() +// True thread-local variable +__thread Thread * ThreadLocalStorage::_thr_current = NULL; -#include +// Implementations needed to support the shared API -// The portable TLS mechanism (get_thread_via_cache) is enough on SPARC. -// There is no need for hand-assembling a special function. -void ThreadLocalStorage::generate_code_for_get_thread() { +void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do + +bool ThreadLocalStorage::_initialized = false; + +void ThreadLocalStorage::init() { + _initialized = true; } -void ThreadLocalStorage::set_thread_in_slot (Thread * self) {} +bool ThreadLocalStorage::is_initialized() { + return _initialized; +} + +Thread* ThreadLocalStorage::get_thread_slow() { + return thread(); +} extern "C" Thread* get_thread() { return ThreadLocalStorage::thread(); diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp index 98a8fc58c31..e3d96c87ae7 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, 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 @@ -25,47 +25,15 @@ #ifndef OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP #define OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP -public: - // Java Thread - force inlining - static inline Thread* thread() ; +// Solaris specific implementation involves simple, direct use +// of a compiler-based thread-local variable private: - static Thread* _get_thread_cache[]; // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size] - static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index); + static __thread Thread * _thr_current; - NOT_PRODUCT(static int _tcacheHit;) - NOT_PRODUCT(static int _tcacheMiss;) + static bool _initialized; // needed for shared API public: - - // Print cache hit/miss statistics - static void print_statistics() PRODUCT_RETURN; - - enum Constants { - _pd_cache_size = 256*2 // projected typical # of threads * 2 - }; - - static void set_thread_in_slot (Thread *) ; - - static uintptr_t pd_raw_thread_id() { - return _raw_thread_id(); - } - - static int pd_cache_index(uintptr_t raw_id) { - // Hash function: From email from Dave: - // The hash function deserves an explanation. %g7 points to libthread's - // "thread" structure. On T1 the thread structure is allocated on the - // user's stack (yes, really!) so the ">>20" handles T1 where the JVM's - // stack size is usually >= 1Mb. The ">>9" is for T2 where Roger allocates - // globs of thread blocks contiguously. The "9" has to do with the - // expected size of the T2 thread structure. If these constants are wrong - // the worst thing that'll happen is that the hit rate for heavily threaded - // apps won't be as good as it could be. If you want to burn another - // shift+xor you could mix together _all of the %g7 bits to form the hash, - // but I think that's excessive. Making the change above changed the - // T$ miss rate on SpecJBB (on a 16X system) from about 3% to imperceptible. - uintptr_t ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size); - return ix; - } + static inline Thread* thread(); #endif // OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP diff --git a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp index 203da611c01..d4c0feccaa3 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, 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 @@ -23,11 +23,10 @@ */ #include "precompiled.hpp" -#include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/os.hpp" #include "runtime/threadLocalStorage.hpp" - +#include "runtime/thread.inline.hpp" void MacroAssembler::int3() { push(rax); @@ -39,98 +38,32 @@ void MacroAssembler::int3() { pop(rax); } -#define __ _masm-> -#ifndef _LP64 -static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { - - // slow call to of thr_getspecific - // int thr_getspecific(thread_key_t key, void **value); - // Consider using pthread_getspecific instead. - -__ push(0); // allocate space for return value - if (thread != rax) __ push(rax); // save rax, if caller still wants it -__ push(rcx); // save caller save -__ push(rdx); // save caller save - if (thread != rax) { -__ lea(thread, Address(rsp, 3 * sizeof(int))); // address of return value - } else { -__ lea(thread, Address(rsp, 2 * sizeof(int))); // address of return value - } -__ push(thread); // and pass the address -__ push(ThreadLocalStorage::thread_index()); // the key -__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); -__ increment(rsp, 2 * wordSize); -__ pop(rdx); -__ pop(rcx); - if (thread != rax) __ pop(rax); -__ pop(thread); - -} -#else -static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { - // slow call to of thr_getspecific - // int thr_getspecific(thread_key_t key, void **value); - // Consider using pthread_getspecific instead. - - if (thread != rax) { -__ push(rax); - } -__ push(0); // space for return value -__ push(rdi); -__ push(rsi); -__ lea(rsi, Address(rsp, 16)); // pass return value address -__ push(rdx); -__ push(rcx); -__ push(r8); -__ push(r9); -__ push(r10); - // XXX -__ mov(r10, rsp); -__ andptr(rsp, -16); -__ push(r10); -__ push(r11); - -__ movl(rdi, ThreadLocalStorage::thread_index()); -__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); - -__ pop(r11); -__ pop(rsp); -__ pop(r10); -__ pop(r9); -__ pop(r8); -__ pop(rcx); -__ pop(rdx); -__ pop(rsi); -__ pop(rdi); -__ pop(thread); // load return value - if (thread != rax) { -__ pop(rax); - } -} -#endif //LP64 - +// This is simply a call to ThreadLocalStorage::thread() void MacroAssembler::get_thread(Register thread) { - - int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment); - // Try to emit a Solaris-specific fast TSD/TLS accessor. - ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode (); - if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 - // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset] - emit_int8 (segment); - // ExternalAddress doesn't work because it can't take NULL - AddressLiteral null(0, relocInfo::none); - movptr (thread, null); - movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ; - return ; - } else - if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 - // mov r, gs:[tlsOffset] - emit_int8 (segment); - AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none); - movptr (thread, tls_off); - return ; + if (thread != rax) { + push(rax); } + push(rdi); + push(rsi); + push(rdx); + push(rcx); + push(r8); + push(r9); + push(r10); + push(r11); - slow_call_thr_specific(this, thread); + call(RuntimeAddress(CAST_FROM_FN_PTR(address, ThreadLocalStorage::thread))); + pop(r11); + pop(r10); + pop(r9); + pop(r8); + pop(rcx); + pop(rdx); + pop(rsi); + pop(rdi); + if (thread != rax) { + movl(thread, rax); + pop(rax); + } } diff --git a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp index e2ce144a3c7..30210a453cc 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, 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,167 +26,27 @@ #include "runtime/thread.inline.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef AMD64 -extern "C" Thread* fs_load(ptrdiff_t tlsOffset); -extern "C" intptr_t fs_thread(); -#else -// From solaris_i486.s -extern "C" Thread* gs_load(ptrdiff_t tlsOffset); -extern "C" intptr_t gs_thread(); -#endif // AMD64 +// True thread-local variable +__thread Thread * ThreadLocalStorage::_thr_current = NULL; -// tlsMode encoding: -// -// pd_tlsAccessUndefined : uninitialized -// pd_tlsAccessSlow : not available -// pd_tlsAccessIndirect : -// old-style indirect access - present in "T1" libthread. -// use thr_slot_sync_allocate() to attempt to allocate a slot. -// pd_tlsAccessDirect : -// new-style direct access - present in late-model "T2" libthread. -// Allocate the offset (slot) via _thr_slot_offset() or by -// defining an IE- or LE-mode TLS/TSD slot in the launcher and then passing -// that offset into libjvm.so. -// See http://sac.eng/Archives/CaseLog/arc/PSARC/2003/159/. -// -// Note that we have a capability gap - some early model T2 forms -// (e.g., unpatched S9) have neither _thr_slot_sync_allocate() nor -// _thr_slot_offset(). In that case we revert to the usual -// thr_getspecific accessor. -// +// Implementations needed to support the shared API -static ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_tlsAccessUndefined ; -static ptrdiff_t tlsOffset = 0 ; -static thread_key_t tlsKey ; +void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do -typedef int (*TSSA_Entry) (ptrdiff_t *, int, int) ; -typedef ptrdiff_t (*TSO_Entry) (int) ; +bool ThreadLocalStorage::_initialized = false; -ThreadLocalStorage::pd_tlsAccessMode ThreadLocalStorage::pd_getTlsAccessMode () -{ - guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; - return tlsMode ; +void ThreadLocalStorage::init() { + _initialized = true; } -ptrdiff_t ThreadLocalStorage::pd_getTlsOffset () { - guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; - return tlsOffset ; +bool ThreadLocalStorage::is_initialized() { + return _initialized; } -// TODO: Consider the following improvements: -// -// 1. Convert from thr_*specific* to pthread_*specific*. -// The pthread_ forms are slightly faster. Also, the -// pthread_ forms have a pthread_key_delete() API which -// would aid in clean JVM shutdown and the eventual goal -// of permitting a JVM to reinstantiate itself withing a process. -// -// 2. See ThreadLocalStorage::init(). We end up allocating -// two TLS keys during VM startup. That's benign, but we could collapse -// down to one key without too much trouble. -// -// 3. MacroAssembler::get_thread() currently emits calls to thr_getspecific(). -// Modify get_thread() to call Thread::current() instead. -// -// 4. Thread::current() currently uses a cache keyed by %gs:[0]. -// (The JVM has PSARC permission to use %g7/%gs:[0] -// as an opaque temporally unique thread identifier). -// For C++ access to a thread's reflexive "self" pointer we -// should consider using one of the following: -// a. a radix tree keyed by %esp - as in EVM. -// This requires two loads (the 2nd dependent on the 1st), but -// is easily inlined and doesn't require a "miss" slow path. -// b. a fast TLS/TSD slot allocated by _thr_slot_offset -// or _thr_slot_sync_allocate. -// -// 5. 'generate_code_for_get_thread' is a misnomer. -// We should change it to something more general like -// pd_ThreadSelf_Init(), for instance. -// - -static void AllocateTLSOffset () -{ - int rslt ; - TSSA_Entry tssa ; - TSO_Entry tso ; - ptrdiff_t off ; - - guarantee (tlsMode == ThreadLocalStorage::pd_tlsAccessUndefined, "tlsMode not set") ; - tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; - tlsOffset = 0 ; -#ifndef AMD64 - - tssa = (TSSA_Entry) dlsym (RTLD_DEFAULT, "thr_slot_sync_allocate") ; - if (tssa != NULL) { - off = -1 ; - rslt = (*tssa)(&off, NULL, NULL) ; // (off,dtor,darg) - if (off != -1) { - tlsOffset = off ; - tlsMode = ThreadLocalStorage::pd_tlsAccessIndirect ; - return ; - } - } - - rslt = thr_keycreate (&tlsKey, NULL) ; - if (rslt != 0) { - tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; // revert to slow mode - return ; - } - - tso = (TSO_Entry) dlsym (RTLD_DEFAULT, "_thr_slot_offset") ; - if (tso != NULL) { - off = (*tso)(tlsKey) ; - if (off >= 0) { - tlsOffset = off ; - tlsMode = ThreadLocalStorage::pd_tlsAccessDirect ; - return ; - } - } - - // Failure: Too bad ... we've allocated a TLS slot we don't need and there's - // no provision in the ABI for returning the slot. - // - // If we didn't find a slot then then: - // 1. We might be on liblwp. - // 2. We might be on T2 libthread, but all "fast" slots are already - // consumed - // 3. We might be on T1, and all TSD (thr_slot_sync_allocate) slots are - // consumed. - // 4. We might be on T2 libthread, but it's be re-architected - // so that fast slots are no longer g7-relative. - // - - tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; - return ; -#endif // AMD64 +Thread* ThreadLocalStorage::get_thread_slow() { + return thread(); } -void ThreadLocalStorage::generate_code_for_get_thread() { - AllocateTLSOffset() ; -} - -void ThreadLocalStorage::set_thread_in_slot(Thread *thread) { - guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; - if (tlsMode == pd_tlsAccessIndirect) { -#ifdef AMD64 - intptr_t tbase = fs_thread(); -#else - intptr_t tbase = gs_thread(); -#endif // AMD64 - *((Thread**) (tbase + tlsOffset)) = thread ; - } else - if (tlsMode == pd_tlsAccessDirect) { - thr_setspecific (tlsKey, (void *) thread) ; - // set with thr_setspecific and then readback with gs_load to validate. -#ifdef AMD64 - guarantee (thread == fs_load(tlsOffset), "tls readback failure") ; -#else - guarantee (thread == gs_load(tlsOffset), "tls readback failure") ; -#endif // AMD64 - } -} - - extern "C" Thread* get_thread() { return ThreadLocalStorage::thread(); } diff --git a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp index 05a9e7c25dd..4f8da7bcb65 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, 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 @@ -25,61 +25,15 @@ #ifndef OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP #define OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP -// Processor dependent parts of ThreadLocalStorage +// Solaris specific implementation involves simple, direct use +// of a compiler-based thread-local variable private: - static Thread* _get_thread_cache[]; // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size] - static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index); + static __thread Thread * _thr_current; - NOT_PRODUCT(static int _tcacheHit;) - NOT_PRODUCT(static int _tcacheMiss;) + static bool _initialized; // needed for shared API public: - // Cache hit/miss statistics - static void print_statistics() PRODUCT_RETURN; - - enum Constants { -#ifdef AMD64 - _pd_cache_size = 256*2 // projected typical # of threads * 2 -#else - _pd_cache_size = 128*2 // projected typical # of threads * 2 -#endif // AMD64 - }; - - enum pd_tlsAccessMode { - pd_tlsAccessUndefined = -1, - pd_tlsAccessSlow = 0, - pd_tlsAccessIndirect = 1, - pd_tlsAccessDirect = 2 - } ; - - static void set_thread_in_slot (Thread *) ; - - static pd_tlsAccessMode pd_getTlsAccessMode () ; - static ptrdiff_t pd_getTlsOffset () ; - - static uintptr_t pd_raw_thread_id() { -#ifdef _GNU_SOURCE -#ifdef AMD64 - uintptr_t rv; - __asm__ __volatile__ ("movq %%fs:0, %0" : "=r"(rv)); - return rv; -#else - return gs_thread(); -#endif // AMD64 -#else //_GNU_SOURCE - return _raw_thread_id(); -#endif //_GNU_SOURCE - } - - static int pd_cache_index(uintptr_t raw_id) { - // Copied from the sparc version. Dave said it should also work fine - // for solx86. - int ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size); - return ix; - } - - // Java Thread static inline Thread* thread(); #endif // OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index 2f99452a5a9..94ef3a2bbd6 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -33,7 +33,9 @@ #include "runtime/os.hpp" void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { - // we must have enough patching space so that call can be inserted + // We must have enough patching space so that call can be inserted. + // We cannot use fat nops here, since the concurrent code rewrite may transiently + // create the illegal instruction sequence. while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) { _masm->nop(); } @@ -592,9 +594,7 @@ void LIR_Assembler::emit_op1(LIR_Op1* op) { void LIR_Assembler::emit_op0(LIR_Op0* op) { switch (op->code()) { case lir_word_align: { - while (code_offset() % BytesPerWord != 0) { - _masm->nop(); - } + _masm->align(BytesPerWord); break; } diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp index 831ddf581d7..87242cf495e 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp @@ -620,12 +620,12 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, // Support for parallelizing survivor space rescan if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) { const size_t max_plab_samples = - ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size(); + _young_gen->max_survivor_size() / (ThreadLocalAllocBuffer::min_size() * HeapWordSize); _survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC); - _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC); + _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC); _cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads, mtGC); - _survivor_chunk_capacity = 2*max_plab_samples; + _survivor_chunk_capacity = max_plab_samples; for (uint i = 0; i < ParallelGCThreads; i++) { HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC); ChunkArray* cur = ::new (&_survivor_plab_array[i]) ChunkArray(vec, max_plab_samples); @@ -641,12 +641,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, _inter_sweep_timer.start(); // start of time } -size_t CMSCollector::plab_sample_minimum_size() { - // The default value of MinTLABSize is 2k, but there is - // no way to get the default value if the flag has been overridden. - return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K); -} - const char* ConcurrentMarkSweepGeneration::name() const { return "concurrent mark-sweep generation"; } diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp index ff4c5ea138d..36e2c2f65c9 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp @@ -739,10 +739,6 @@ class CMSCollector: public CHeapObj { size_t* _cursor; ChunkArray* _survivor_plab_array; - // A bounded minimum size of PLABs, should not return too small values since - // this will affect the size of the data structures used for parallel young gen rescan - size_t plab_sample_minimum_size(); - // Support for marking stack overflow handling bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack); bool par_take_from_overflow_list(size_t num, diff --git a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp index 02f948e597f..8633a9d3d23 100644 --- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp @@ -300,5 +300,3 @@ HeapRegion* OldGCAllocRegion::release() { } return G1AllocRegion::release(); } - - diff --git a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp index 9450d728671..a32544f4eb2 100644 --- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp +++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "gc/g1/g1Allocator.hpp" +#include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1MarkSweep.hpp" @@ -67,11 +67,11 @@ void G1Allocator::reuse_retained_old_region(EvacuationInfo& evacuation_info, // retired. We have to remove it now, since we don't allow regions // we allocate to in the region sets. We'll re-add it later, when // it's retired again. - _g1h->_old_set.remove(retained_region); + _g1h->old_set_remove(retained_region); bool during_im = _g1h->collector_state()->during_initial_mark_pause(); retained_region->note_start_of_copying(during_im); old->set(retained_region); - _g1h->_hr_printer.reuse(retained_region); + _g1h->hr_printer()->reuse(retained_region); evacuation_info.set_alloc_regions_used_before(retained_region->used()); } } @@ -116,15 +116,85 @@ void G1DefaultAllocator::abandon_gc_alloc_regions() { G1PLAB::G1PLAB(size_t gclab_word_size) : PLAB(gclab_word_size), _retired(true) { } -HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest, - size_t word_sz, - AllocationContext_t context) { +size_t G1Allocator::unsafe_max_tlab_alloc(AllocationContext_t context) { + // Return the remaining space in the cur alloc region, but not less than + // the min TLAB size. + + // Also, this value can be at most the humongous object threshold, + // since we can't allow tlabs to grow big enough to accommodate + // humongous objects. + + HeapRegion* hr = mutator_alloc_region(context)->get(); + size_t max_tlab = _g1h->max_tlab_size() * wordSize; + if (hr == NULL) { + return max_tlab; + } else { + return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab); + } +} + +HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest, + size_t word_size, + AllocationContext_t context) { + switch (dest.value()) { + case InCSetState::Young: + return survivor_attempt_allocation(word_size, context); + case InCSetState::Old: + return old_attempt_allocation(word_size, context); + default: + ShouldNotReachHere(); + return NULL; // Keep some compilers happy + } +} + +HeapWord* G1Allocator::survivor_attempt_allocation(size_t word_size, + AllocationContext_t context) { + assert(!_g1h->is_humongous(word_size), + "we should not be seeing humongous-size allocations in this path"); + + HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(word_size, + false /* bot_updates */); + if (result == NULL) { + MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); + result = survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size, + false /* bot_updates */); + } + if (result != NULL) { + _g1h->dirty_young_block(result, word_size); + } + return result; +} + +HeapWord* G1Allocator::old_attempt_allocation(size_t word_size, + AllocationContext_t context) { + assert(!_g1h->is_humongous(word_size), + "we should not be seeing humongous-size allocations in this path"); + + HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(word_size, + true /* bot_updates */); + if (result == NULL) { + MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); + result = old_gc_alloc_region(context)->attempt_allocation_locked(word_size, + true /* bot_updates */); + } + return result; +} + +G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : + _g1h(G1CollectedHeap::heap()), + _allocator(allocator), + _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { +} + +HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest, + size_t word_sz, + AllocationContext_t context) { size_t gclab_word_size = _g1h->desired_plab_sz(dest); if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { G1PLAB* alloc_buf = alloc_buffer(dest, context); alloc_buf->retire(); - HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context); + HeapWord* buf = _allocator->par_allocate_during_gc(dest, gclab_word_size, context); if (buf == NULL) { return NULL; // Let caller handle allocation failure. } @@ -136,14 +206,18 @@ HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest, assert(obj != NULL, "buffer was definitely big enough..."); return obj; } else { - return _g1h->par_allocate_during_gc(dest, word_sz, context); + return _allocator->par_allocate_during_gc(dest, word_sz, context); } } -G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) : - G1ParGCAllocator(g1h), - _surviving_alloc_buffer(g1h->desired_plab_sz(InCSetState::Young)), - _tenured_alloc_buffer(g1h->desired_plab_sz(InCSetState::Old)) { +void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) { + alloc_buffer(dest, context)->undo_allocation(obj, word_sz); +} + +G1DefaultPLABAllocator::G1DefaultPLABAllocator(G1Allocator* allocator) : + G1PLABAllocator(allocator), + _surviving_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Young)), + _tenured_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Old)) { for (uint state = 0; state < InCSetState::Num; state++) { _alloc_buffers[state] = NULL; } @@ -151,7 +225,7 @@ G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) : _alloc_buffers[InCSetState::Old] = &_tenured_alloc_buffer; } -void G1DefaultParGCAllocator::retire_alloc_buffers() { +void G1DefaultPLABAllocator::retire_alloc_buffers() { for (uint state = 0; state < InCSetState::Num; state++) { G1PLAB* const buf = _alloc_buffers[state]; if (buf != NULL) { @@ -160,7 +234,7 @@ void G1DefaultParGCAllocator::retire_alloc_buffers() { } } -void G1DefaultParGCAllocator::waste(size_t& wasted, size_t& undo_wasted) { +void G1DefaultPLABAllocator::waste(size_t& wasted, size_t& undo_wasted) { wasted = 0; undo_wasted = 0; for (uint state = 0; state < InCSetState::Num; state++) { @@ -190,8 +264,8 @@ bool G1ArchiveAllocator::alloc_new_region() { } assert(hr->is_empty(), err_msg("expected empty region (index %u)", hr->hrm_index())); hr->set_archive(); - _g1h->_old_set.add(hr); - _g1h->_hr_printer.alloc(hr, G1HRPrinter::Archive); + _g1h->old_set_add(hr); + _g1h->hr_printer()->alloc(hr, G1HRPrinter::Archive); _allocated_regions.append(hr); _allocation_region = hr; diff --git a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp index a5dfebed492..dc9bb16b620 100644 --- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp +++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp @@ -33,17 +33,36 @@ class EvacuationInfo; -// Base class for G1 allocators. +// Interface to keep track of which regions G1 is currently allocating into. Provides +// some accessors (e.g. allocating into them, or getting their occupancy). +// Also keeps track of retained regions across GCs. class G1Allocator : public CHeapObj { friend class VMStructs; protected: G1CollectedHeap* _g1h; + virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0; + + // Accessors to the allocation regions. + virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0; + virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0; + + // Allocation attempt during GC for a survivor object / PLAB. + inline HeapWord* survivor_attempt_allocation(size_t word_size, + AllocationContext_t context); + // Allocation attempt during GC for an old object / PLAB. + inline HeapWord* old_attempt_allocation(size_t word_size, + AllocationContext_t context); public: G1Allocator(G1CollectedHeap* heap) : _g1h(heap) { } + virtual ~G1Allocator() { } static G1Allocator* create_allocator(G1CollectedHeap* g1h); +#ifdef ASSERT + // Do we currently have an active mutator region to allocate into? + bool has_mutator_alloc_region(AllocationContext_t context) { return mutator_alloc_region(context)->get() != NULL; } +#endif virtual void init_mutator_alloc_region() = 0; virtual void release_mutator_alloc_region() = 0; @@ -51,24 +70,35 @@ public: virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0; virtual void abandon_gc_alloc_regions() = 0; - virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0; - virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0; - virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0; - virtual size_t used_in_alloc_regions() = 0; - virtual bool is_retained_old_region(HeapRegion* hr) = 0; + // Management of retained regions. - void reuse_retained_old_region(EvacuationInfo& evacuation_info, - OldGCAllocRegion* old, - HeapRegion** retained); + virtual bool is_retained_old_region(HeapRegion* hr) = 0; + void reuse_retained_old_region(EvacuationInfo& evacuation_info, + OldGCAllocRegion* old, + HeapRegion** retained); - virtual HeapRegion* new_heap_region(uint hrs_index, - G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr) { - return new HeapRegion(hrs_index, sharedOffsetArray, mr); - } + // Allocate blocks of memory during mutator time. + + inline HeapWord* attempt_allocation(size_t word_size, AllocationContext_t context); + inline HeapWord* attempt_allocation_locked(size_t word_size, AllocationContext_t context); + inline HeapWord* attempt_allocation_force(size_t word_size, AllocationContext_t context); + + size_t unsafe_max_tlab_alloc(AllocationContext_t context); + + // Allocate blocks of memory during garbage collection. Will ensure an + // allocation region, either by picking one or expanding the + // heap, and then allocate a block of the given size. The block + // may not be a humongous - it must fit into a single heap region. + HeapWord* par_allocate_during_gc(InCSetState dest, + size_t word_size, + AllocationContext_t context); + + virtual size_t used_in_alloc_regions() = 0; }; -// The default allocator for G1. +// The default allocation region manager for G1. Provides a single mutator, survivor +// and old generation allocation region. +// Can retain the (single) old generation allocation region across GCs. class G1DefaultAllocator : public G1Allocator { protected: // Alloc region used to satisfy mutator allocation requests. @@ -152,10 +182,14 @@ public: } }; -class G1ParGCAllocator : public CHeapObj { +// Manages the PLABs used during garbage collection. Interface for allocation from PLABs. +// Needs to handle multiple contexts, extra alignment in any "survivor" area and some +// statistics. +class G1PLABAllocator : public CHeapObj { friend class G1ParScanThreadState; protected: G1CollectedHeap* _g1h; + G1Allocator* _allocator; // The survivor alignment in effect in bytes. // == 0 : don't align survivors @@ -182,11 +216,10 @@ protected: } public: - G1ParGCAllocator(G1CollectedHeap* g1h) : - _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { } - virtual ~G1ParGCAllocator() { } + G1PLABAllocator(G1Allocator* allocator); + virtual ~G1PLABAllocator() { } - static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h); + static G1PLABAllocator* create_allocator(G1Allocator* allocator); virtual void waste(size_t& wasted, size_t& undo_wasted) = 0; @@ -219,18 +252,18 @@ public: return allocate_direct_or_new_plab(dest, word_sz, context); } - void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) { - alloc_buffer(dest, context)->undo_allocation(obj, word_sz); - } + void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context); }; -class G1DefaultParGCAllocator : public G1ParGCAllocator { +// The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor +// and old generation allocation. +class G1DefaultPLABAllocator : public G1PLABAllocator { G1PLAB _surviving_alloc_buffer; G1PLAB _tenured_alloc_buffer; G1PLAB* _alloc_buffers[InCSetState::Num]; public: - G1DefaultParGCAllocator(G1CollectedHeap* g1h); + G1DefaultPLABAllocator(G1Allocator* _allocator); virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) { assert(dest.is_valid(), diff --git a/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp b/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp new file mode 100644 index 00000000000..f39a4e74877 --- /dev/null +++ b/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, 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. + * + */ + +#ifndef SHARE_VM_GC_G1_G1ALLOCATOR_INLINE_HPP +#define SHARE_VM_GC_G1_G1ALLOCATOR_INLINE_HPP + +#include "gc/g1/g1Allocator.hpp" +#include "gc/g1/g1AllocRegion.inline.hpp" + +HeapWord* G1Allocator::attempt_allocation(size_t word_size, AllocationContext_t context) { + return mutator_alloc_region(context)->attempt_allocation(word_size, false /* bot_updates */); +} + +HeapWord* G1Allocator::attempt_allocation_locked(size_t word_size, AllocationContext_t context) { + HeapWord* result = mutator_alloc_region(context)->attempt_allocation_locked(word_size, false /* bot_updates */); + assert(result != NULL || mutator_alloc_region(context)->get() == NULL, + err_msg("Must not have a mutator alloc region if there is no memory, but is " PTR_FORMAT, p2i(mutator_alloc_region(context)->get()))); + return result; +} + +HeapWord* G1Allocator::attempt_allocation_force(size_t word_size, AllocationContext_t context) { + return mutator_alloc_region(context)->attempt_allocation_force(word_size, false /* bot_updates */); +} + +#endif // SHARE_VM_GC_G1_G1ALLOCATOR_HPP diff --git a/hotspot/src/share/vm/gc/g1/g1Allocator_ext.cpp b/hotspot/src/share/vm/gc/g1/g1Allocator_ext.cpp index 3491ece62ab..35ef20c1045 100644 --- a/hotspot/src/share/vm/gc/g1/g1Allocator_ext.cpp +++ b/hotspot/src/share/vm/gc/g1/g1Allocator_ext.cpp @@ -30,6 +30,6 @@ G1Allocator* G1Allocator::create_allocator(G1CollectedHeap* g1h) { return new G1DefaultAllocator(g1h); } -G1ParGCAllocator* G1ParGCAllocator::create_allocator(G1CollectedHeap* g1h) { - return new G1DefaultParGCAllocator(g1h); +G1PLABAllocator* G1PLABAllocator::create_allocator(G1Allocator* allocator) { + return new G1DefaultPLABAllocator(allocator); } diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index a4f62735a5d..2fec93a7dfe 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -31,7 +31,7 @@ #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" -#include "gc/g1/g1AllocRegion.inline.hpp" +#include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" @@ -815,22 +815,16 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size, { MutexLockerEx x(Heap_lock); - result = _allocator->mutator_alloc_region(context)->attempt_allocation_locked(word_size, - false /* bot_updates */); + result = _allocator->attempt_allocation_locked(word_size, context); if (result != NULL) { return result; } - // If we reach here, attempt_allocation_locked() above failed to - // allocate a new region. So the mutator alloc region should be NULL. - assert(_allocator->mutator_alloc_region(context)->get() == NULL, "only way to get here"); - if (GC_locker::is_active_and_needs_gc()) { if (g1_policy()->can_expand_young_list()) { // No need for an ergo verbose message here, // can_expand_young_list() does this when it returns true. - result = _allocator->mutator_alloc_region(context)->attempt_allocation_force(word_size, - false /* bot_updates */); + result = _allocator->attempt_allocation_force(word_size, context); if (result != NULL) { return result; } @@ -890,8 +884,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size, // first attempt (without holding the Heap_lock) here and the // follow-on attempt will be at the start of the next loop // iteration (after taking the Heap_lock). - result = _allocator->mutator_alloc_region(context)->attempt_allocation(word_size, - false /* bot_updates */); + result = _allocator->attempt_allocation(word_size, context); if (result != NULL) { return result; } @@ -1109,6 +1102,29 @@ void G1CollectedHeap::fill_archive_regions(MemRegion* ranges, size_t count) { } } +inline HeapWord* G1CollectedHeap::attempt_allocation(size_t word_size, + uint* gc_count_before_ret, + uint* gclocker_retry_count_ret) { + assert_heap_not_locked_and_not_at_safepoint(); + assert(!is_humongous(word_size), "attempt_allocation() should not " + "be called for humongous allocation requests"); + + AllocationContext_t context = AllocationContext::current(); + HeapWord* result = _allocator->attempt_allocation(word_size, context); + + if (result == NULL) { + result = attempt_allocation_slow(word_size, + context, + gc_count_before_ret, + gclocker_retry_count_ret); + } + assert_heap_not_locked(); + if (result != NULL) { + dirty_young_block(result, word_size); + } + return result; +} + HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size, uint* gc_count_before_ret, uint* gclocker_retry_count_ret) { @@ -1231,13 +1247,11 @@ HeapWord* G1CollectedHeap::attempt_allocation_at_safepoint(size_t word_size, AllocationContext_t context, bool expect_null_mutator_alloc_region) { assert_at_safepoint(true /* should_be_vm_thread */); - assert(_allocator->mutator_alloc_region(context)->get() == NULL || - !expect_null_mutator_alloc_region, + assert(!_allocator->has_mutator_alloc_region(context) || !expect_null_mutator_alloc_region, "the current alloc region was unexpectedly found to be non-NULL"); if (!is_humongous(word_size)) { - return _allocator->mutator_alloc_region(context)->attempt_allocation_locked(word_size, - false /* bot_updates */); + return _allocator->attempt_allocation_locked(word_size, context); } else { HeapWord* result = humongous_obj_allocate(word_size, context); if (result != NULL && g1_policy()->need_to_start_conc_mark("STW humongous allocation")) { @@ -2373,7 +2387,6 @@ void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!"); } - // Computes the sum of the storage used by the various regions. size_t G1CollectedHeap::used() const { size_t result = _summary_bytes_used + _allocator->used_in_alloc_regions(); @@ -2632,6 +2645,11 @@ bool G1CollectedHeap::is_in_exact(const void* p) const { } #endif +bool G1CollectedHeap::obj_in_cs(oop obj) { + HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj); + return r != NULL && r->in_collection_set(); +} + // Iteration functions. // Applies an ExtendedOopClosure onto all references of objects within a HeapRegion. @@ -2833,20 +2851,8 @@ size_t G1CollectedHeap::max_tlab_size() const { } size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { - // Return the remaining space in the cur alloc region, but not less than - // the min TLAB size. - - // Also, this value can be at most the humongous object threshold, - // since we can't allow tlabs to grow big enough to accommodate - // humongous objects. - - HeapRegion* hr = _allocator->mutator_alloc_region(AllocationContext::current())->get(); - size_t max_tlab = max_tlab_size() * wordSize; - if (hr == NULL) { - return max_tlab; - } else { - return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab); - } + AllocationContext_t context = AllocationContext::current(); + return _allocator->unsafe_max_tlab_alloc(context); } size_t G1CollectedHeap::max_capacity() const { @@ -4279,18 +4285,18 @@ void G1CollectedHeap::remove_self_forwarding_pointers() { g1_policy()->phase_times()->record_evac_fail_remove_self_forwards((os::elapsedTime() - remove_self_forwards_start) * 1000.0); } -void G1CollectedHeap::preserve_mark_during_evac_failure(uint queue_num, oop obj, markOop m) { +void G1CollectedHeap::preserve_mark_during_evac_failure(uint worker_id, oop obj, markOop m) { if (!_evacuation_failed) { _evacuation_failed = true; } - _evacuation_failed_info_array[queue_num].register_copy_failure(obj->size()); + _evacuation_failed_info_array[worker_id].register_copy_failure(obj->size()); // We want to call the "for_promotion_failure" version only in the // case of a promotion failure. if (m->must_be_preserved_for_promotion_failure(obj)) { OopAndMarkOop elem(obj, m); - _preserved_objs[queue_num].push(elem); + _preserved_objs[worker_id].push(elem); } } @@ -4334,7 +4340,7 @@ void G1ParCopyClosure::do_oop_work(T* p) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); - assert(_worker_id == _par_scan_state->queue_num(), "sanity"); + assert(_worker_id == _par_scan_state->worker_id(), "sanity"); const InCSetState state = _g1->in_cset_state(obj); if (state.is_in_cset()) { @@ -4443,9 +4449,6 @@ protected: ParallelTaskTerminator _terminator; uint _n_workers; - Mutex _stats_lock; - Mutex* stats_lock() { return &_stats_lock; } - public: G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor, uint n_workers) : AbstractGangTask("G1 collection"), @@ -4453,8 +4456,7 @@ public: _queues(task_queues), _root_processor(root_processor), _terminator(n_workers, _queues), - _n_workers(n_workers), - _stats_lock(Mutex::leaf, "parallel G1 stats lock", true) + _n_workers(n_workers) {} RefToScanQueueSet* queues() { return _queues; } @@ -4581,8 +4583,8 @@ public: _g1h->update_surviving_young_words(pss.surviving_young_words()+1); if (PrintTerminationStats) { - MutexLocker x(stats_lock()); - pss.print_termination_stats(worker_id); + MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); + pss.print_termination_stats(); } assert(pss.queue_is_empty(), "should be empty"); @@ -5009,7 +5011,7 @@ public: bool G1STWIsAliveClosure::do_object_b(oop p) { // An object is reachable if it is outside the collection set, // or is inside and copied. - return !_g1->obj_in_cs(p) || p->is_forwarded(); + return !_g1->is_in_cset(p) || p->is_forwarded(); } // Non Copying Keep Alive closure @@ -5498,7 +5500,9 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) { } // The individual threads will set their evac-failure closures. - if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr(); + if (PrintTerminationStats) { + G1ParScanThreadState::print_termination_stats_hdr(); + } workers()->run_task(&g1_par_task); end_par_time_sec = os::elapsedTime(); @@ -6491,7 +6495,6 @@ HeapRegion* G1CollectedHeap::alloc_highest_free_region() { return NULL; } - // Heap region set verification class VerifyRegionListsClosure : public HeapRegionClosure { diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp index 7b52c34dc50..e4b4045808d 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp @@ -27,7 +27,6 @@ #include "gc/g1/concurrentMark.hpp" #include "gc/g1/evacuationInfo.hpp" -#include "gc/g1/g1AllocRegion.hpp" #include "gc/g1/g1AllocationContext.hpp" #include "gc/g1/g1Allocator.hpp" #include "gc/g1/g1BiasedArray.hpp" @@ -187,13 +186,11 @@ class G1CollectedHeap : public CollectedHeap { friend class MutatorAllocRegion; friend class SurvivorGCAllocRegion; friend class OldGCAllocRegion; - friend class G1Allocator; - friend class G1ArchiveAllocator; // Closures used in implementation. friend class G1ParScanThreadState; friend class G1ParTask; - friend class G1ParGCAllocator; + friend class G1PLABAllocator; friend class G1PrepareCompactClosure; // Other related classes. @@ -248,7 +245,7 @@ private: // The sequence of all heap regions in the heap. HeapRegionManager _hrm; - // Class that handles the different kinds of allocations. + // Handles non-humongous allocations in the G1CollectedHeap. G1Allocator* _allocator; // Outside of GC pauses, the number of bytes used in all regions other @@ -280,22 +277,6 @@ private: // start of each GC. bool _expand_heap_after_alloc_failure; - // It resets the mutator alloc region before new allocations can take place. - void init_mutator_alloc_region(); - - // It releases the mutator alloc region. - void release_mutator_alloc_region(); - - // It initializes the GC alloc regions at the start of a GC. - void init_gc_alloc_regions(EvacuationInfo& evacuation_info); - - // It releases the GC alloc regions at the end of a GC. - void release_gc_alloc_regions(EvacuationInfo& evacuation_info); - - // It does any cleanup that needs to be done on the GC alloc regions - // before a Full GC. - void abandon_gc_alloc_regions(); - // Helper for monitoring and management support. G1MonitoringSupport* _g1mm; @@ -551,31 +532,6 @@ protected: AllocationContext_t context, bool expect_null_mutator_alloc_region); - // It dirties the cards that cover the block so that so that the post - // write barrier never queues anything when updating objects on this - // block. It is assumed (and in fact we assert) that the block - // belongs to a young region. - inline void dirty_young_block(HeapWord* start, size_t word_size); - - // Allocate blocks during garbage collection. Will ensure an - // allocation region, either by picking one or expanding the - // heap, and then allocate a block of the given size. The block - // may not be a humongous - it must fit into a single heap region. - inline HeapWord* par_allocate_during_gc(InCSetState dest, - size_t word_size, - AllocationContext_t context); - // Ensure that no further allocations can happen in "r", bearing in mind - // that parallel threads might be attempting allocations. - void par_allocate_remaining_space(HeapRegion* r); - - // Allocation attempt during GC for a survivor object / PLAB. - inline HeapWord* survivor_attempt_allocation(size_t word_size, - AllocationContext_t context); - - // Allocation attempt during GC for an old object / PLAB. - inline HeapWord* old_attempt_allocation(size_t word_size, - AllocationContext_t context); - // These methods are the "callbacks" from the G1AllocRegion class. // For mutator alloc regions. @@ -589,10 +545,6 @@ protected: void retire_gc_alloc_region(HeapRegion* alloc_region, size_t allocated_bytes, InCSetState dest); - // Allocate the highest free region in the reserved heap. This will commit - // regions as necessary. - HeapRegion* alloc_highest_free_region(); - // - if explicit_gc is true, the GC is for a System.gc() or a heap // inspection request and should collect the entire heap // - if clear_all_soft_refs is true, all soft references should be @@ -725,6 +677,13 @@ public: G1HRPrinter* hr_printer() { return &_hr_printer; } + // Allocates a new heap region instance. + HeapRegion* new_heap_region(uint hrs_index, MemRegion mr); + + // Allocate the highest free region in the reserved heap. This will commit + // regions as necessary. + HeapRegion* alloc_highest_free_region(); + // Frees a non-humongous region by initializing its contents and // adding it to the free list that's passed as a parameter (this is // usually a local list which will be appended to the master free @@ -738,6 +697,12 @@ public: bool par, bool locked = false); + // It dirties the cards that cover the block so that the post + // write barrier never queues anything when updating objects on this + // block. It is assumed (and in fact we assert) that the block + // belongs to a young region. + inline void dirty_young_block(HeapWord* start, size_t word_size); + // Frees a humongous region by collapsing it into individual regions // and calling free_region() for each of them. The freed regions // will be added to the free list that's passed as a parameter (this @@ -887,7 +852,7 @@ protected: // Preserve the mark of "obj", if necessary, in preparation for its mark // word being overwritten with a self-forwarding-pointer. - void preserve_mark_during_evac_failure(uint queue, oop obj, markOop m); + void preserve_mark_during_evac_failure(uint worker_id, oop obj, markOop m); #ifndef PRODUCT // Support for forcing evacuation failures. Analogous to @@ -1216,6 +1181,7 @@ public: } } + inline void old_set_add(HeapRegion* hr); inline void old_set_remove(HeapRegion* hr); size_t non_young_capacity_bytes() { @@ -1263,7 +1229,7 @@ public: // Return "TRUE" iff the given object address is within the collection // set. Slow implementation. - inline bool obj_in_cs(oop obj); + bool obj_in_cs(oop obj); inline bool is_in_cset(const HeapRegion *hr); inline bool is_in_cset(oop obj); diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp index d35fcac0796..e8d4b8ee160 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_GC_G1_G1COLLECTEDHEAP_INLINE_HPP #include "gc/g1/concurrentMark.hpp" -#include "gc/g1/g1AllocRegion.inline.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" @@ -57,20 +56,6 @@ size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) { return MIN2(_humongous_object_threshold_in_words, gclab_word_size); } -HeapWord* G1CollectedHeap::par_allocate_during_gc(InCSetState dest, - size_t word_size, - AllocationContext_t context) { - switch (dest.value()) { - case InCSetState::Young: - return survivor_attempt_allocation(word_size, context); - case InCSetState::Old: - return old_attempt_allocation(word_size, context); - default: - ShouldNotReachHere(); - return NULL; // Keep some compilers happy - } -} - // Inline functions for G1CollectedHeap inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() { @@ -122,71 +107,14 @@ inline void G1CollectedHeap::increment_gc_time_stamp() { OrderAccess::fence(); } +inline void G1CollectedHeap::old_set_add(HeapRegion* hr) { + _old_set.add(hr); +} + inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) { _old_set.remove(hr); } -inline bool G1CollectedHeap::obj_in_cs(oop obj) { - HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj); - return r != NULL && r->in_collection_set(); -} - -inline HeapWord* G1CollectedHeap::attempt_allocation(size_t word_size, - uint* gc_count_before_ret, - uint* gclocker_retry_count_ret) { - assert_heap_not_locked_and_not_at_safepoint(); - assert(!is_humongous(word_size), "attempt_allocation() should not " - "be called for humongous allocation requests"); - - AllocationContext_t context = AllocationContext::current(); - HeapWord* result = _allocator->mutator_alloc_region(context)->attempt_allocation(word_size, - false /* bot_updates */); - if (result == NULL) { - result = attempt_allocation_slow(word_size, - context, - gc_count_before_ret, - gclocker_retry_count_ret); - } - assert_heap_not_locked(); - if (result != NULL) { - dirty_young_block(result, word_size); - } - return result; -} - -inline HeapWord* G1CollectedHeap::survivor_attempt_allocation(size_t word_size, - AllocationContext_t context) { - assert(!is_humongous(word_size), - "we should not be seeing humongous-size allocations in this path"); - - HeapWord* result = _allocator->survivor_gc_alloc_region(context)->attempt_allocation(word_size, - false /* bot_updates */); - if (result == NULL) { - MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); - result = _allocator->survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size, - false /* bot_updates */); - } - if (result != NULL) { - dirty_young_block(result, word_size); - } - return result; -} - -inline HeapWord* G1CollectedHeap::old_attempt_allocation(size_t word_size, - AllocationContext_t context) { - assert(!is_humongous(word_size), - "we should not be seeing humongous-size allocations in this path"); - - HeapWord* result = _allocator->old_gc_alloc_region(context)->attempt_allocation(word_size, - true /* bot_updates */); - if (result == NULL) { - MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); - result = _allocator->old_gc_alloc_region(context)->attempt_allocation_locked(word_size, - true /* bot_updates */); - } - return result; -} - // It dirties the cards that cover the block so that so that the post // write barrier never queues anything when updating objects on this // block. It is assumed (and in fact we assert) that the block diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp index 5c429bafda2..bb1dfc39893 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" +#include "gc/g1/heapRegion.inline.hpp" bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts, jlong* totals, @@ -31,3 +32,8 @@ bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts, jint len) { return false; } + +HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index, + MemRegion mr) { + return new HeapRegion(hrs_index, bot_shared(), mr); +} diff --git a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp index cec6220d2e3..cae3e54bd3f 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp @@ -31,6 +31,7 @@ #include "gc/g1/g1ErgoVerbose.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1Log.hpp" +#include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/gcPolicyCounters.hpp" #include "runtime/arguments.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp b/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp index b314e45627b..ba41f2c9b70 100644 --- a/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp +++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp @@ -48,7 +48,7 @@ void G1ParClosureSuper::set_par_scan_thread_state(G1ParScanThreadState* par_scan assert(par_scan_state != NULL, "Must set par_scan_state to non-NULL."); _par_scan_state = par_scan_state; - _worker_id = par_scan_state->queue_num(); + _worker_id = par_scan_state->worker_id(); assert(_worker_id < ParallelGCThreads, err_msg("The given worker id %u must be less than the number of threads %u", _worker_id, ParallelGCThreads)); diff --git a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp index e9e996c944b..a6f9ccafc35 100644 --- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp @@ -31,6 +31,7 @@ #include "gc/g1/g1ParScanThreadState.inline.hpp" #include "gc/g1/g1RemSet.hpp" #include "gc/g1/g1RemSet.inline.hpp" +#include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "memory/iterator.inline.hpp" #include "runtime/prefetch.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp index 75a512d0bd2..87471f2ab99 100644 --- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp +++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp @@ -31,13 +31,13 @@ #include "oops/oop.inline.hpp" #include "runtime/prefetch.inline.hpp" -G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp) +G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, ReferenceProcessor* rp) : _g1h(g1h), - _refs(g1h->task_queue(queue_num)), + _refs(g1h->task_queue(worker_id)), _dcq(&g1h->dirty_card_queue_set()), _ct_bs(g1h->g1_barrier_set()), _g1_rem(g1h->g1_rem_set()), - _hash_seed(17), _queue_num(queue_num), + _hash_seed(17), _worker_id(worker_id), _term_attempts(0), _tenuring_threshold(g1h->g1_policy()->tenuring_threshold()), _age_table(false), _scanner(g1h, rp), @@ -59,7 +59,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t)); - _g1_par_allocator = G1ParGCAllocator::create_allocator(_g1h); + _plab_allocator = G1PLABAllocator::create_allocator(_g1h->allocator()); _dest[InCSetState::NotInCSet] = InCSetState::NotInCSet; // The dest for Young is used when the objects are aged enough to @@ -71,37 +71,29 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, } G1ParScanThreadState::~G1ParScanThreadState() { - _g1_par_allocator->retire_alloc_buffers(); - delete _g1_par_allocator; + _plab_allocator->retire_alloc_buffers(); + delete _plab_allocator; FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base); } -void -G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) -{ +void G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) { st->print_raw_cr("GC Termination Stats"); - st->print_raw_cr(" elapsed --strong roots-- -------termination-------" - " ------waste (KiB)------"); - st->print_raw_cr("thr ms ms % ms % attempts" - " total alloc undo"); - st->print_raw_cr("--- --------- --------- ------ --------- ------ --------" - " ------- ------- -------"); + st->print_raw_cr(" elapsed --strong roots-- -------termination------- ------waste (KiB)------"); + st->print_raw_cr("thr ms ms % ms % attempts total alloc undo"); + st->print_raw_cr("--- --------- --------- ------ --------- ------ -------- ------- ------- -------"); } -void -G1ParScanThreadState::print_termination_stats(int i, - outputStream* const st) const -{ +void G1ParScanThreadState::print_termination_stats(outputStream* const st) const { const double elapsed_ms = elapsed_time() * 1000.0; const double s_roots_ms = strong_roots_time() * 1000.0; const double term_ms = term_time() * 1000.0; size_t alloc_buffer_waste = 0; size_t undo_waste = 0; - _g1_par_allocator->waste(alloc_buffer_waste, undo_waste); - st->print_cr("%3d %9.2f %9.2f %6.2f " + _plab_allocator->waste(alloc_buffer_waste, undo_waste); + st->print_cr("%3u %9.2f %9.2f %6.2f " "%9.2f %6.2f " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), - i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, + _worker_id, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, term_ms, term_ms * 100 / elapsed_ms, term_attempts(), (alloc_buffer_waste + undo_waste) * HeapWordSize / K, alloc_buffer_waste * HeapWordSize / K, @@ -167,8 +159,9 @@ HeapWord* G1ParScanThreadState::allocate_in_next_plab(InCSetState const state, // Right now we only have two types of regions (young / old) so // let's keep the logic here simple. We can generalize it when necessary. if (dest->is_young()) { - HeapWord* const obj_ptr = _g1_par_allocator->allocate(InCSetState::Old, - word_sz, context); + HeapWord* const obj_ptr = _plab_allocator->allocate(InCSetState::Old, + word_sz, + context); if (obj_ptr == NULL) { return NULL; } @@ -209,12 +202,12 @@ oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, uint age = 0; InCSetState dest_state = next_state(state, old_mark, age); - HeapWord* obj_ptr = _g1_par_allocator->plab_allocate(dest_state, word_sz, context); + HeapWord* obj_ptr = _plab_allocator->plab_allocate(dest_state, word_sz, context); // PLAB allocations should succeed most of the time, so we'll // normally check against NULL once and that's it. if (obj_ptr == NULL) { - obj_ptr = _g1_par_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context); + obj_ptr = _plab_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context); if (obj_ptr == NULL) { obj_ptr = allocate_in_next_plab(state, &dest_state, word_sz, context); if (obj_ptr == NULL) { @@ -233,7 +226,7 @@ oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, if (_g1h->evacuation_should_fail()) { // Doing this after all the allocation attempts also tests the // undo_allocation() method too. - _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); + _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); return handle_evacuation_failure_par(old, old_mark); } #endif // !PRODUCT @@ -274,7 +267,7 @@ oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, "sanity"); G1StringDedup::enqueue_from_evacuation(is_from_young, is_to_young, - queue_num(), + _worker_id, obj); } @@ -295,7 +288,7 @@ oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, } return obj; } else { - _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); + _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); return forward_ptr; } } @@ -314,7 +307,7 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) { _g1h->hr_printer()->evac_failure(r); } - _g1h->preserve_mark_during_evac_failure(_queue_num, old, m); + _g1h->preserve_mark_during_evac_failure(_worker_id, old, m); _scanner.set_region(r); old->oop_iterate_backwards(&_scanner); diff --git a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp index d01517ff872..2652eda3388 100644 --- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp @@ -46,7 +46,7 @@ class G1ParScanThreadState : public StackObj { G1SATBCardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; - G1ParGCAllocator* _g1_par_allocator; + G1PLABAllocator* _plab_allocator; ageTable _age_table; InCSetState _dest[InCSetState::Num]; @@ -55,7 +55,7 @@ class G1ParScanThreadState : public StackObj { G1ParScanClosure _scanner; int _hash_seed; - uint _queue_num; + uint _worker_id; size_t _term_attempts; @@ -85,7 +85,7 @@ class G1ParScanThreadState : public StackObj { } public: - G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp); + G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, ReferenceProcessor* rp); ~G1ParScanThreadState(); ageTable* age_table() { return &_age_table; } @@ -112,8 +112,7 @@ class G1ParScanThreadState : public StackObj { } } - int* hash_seed() { return &_hash_seed; } - uint queue_num() { return _queue_num; } + uint worker_id() { return _worker_id; } size_t term_attempts() const { return _term_attempts; } void note_term_attempt() { _term_attempts++; } @@ -139,8 +138,11 @@ class G1ParScanThreadState : public StackObj { return os::elapsedTime() - _start; } + // Print the header for the per-thread termination statistics. static void print_termination_stats_hdr(outputStream* const st = gclog_or_tty); - void print_termination_stats(int i, outputStream* const st = gclog_or_tty) const; + + // Print actual per-thread termination statistics. + void print_termination_stats(outputStream* const st = gclog_or_tty) const; size_t* surviving_young_words() { // We add on to hide entry 0 which accumulates surviving words for diff --git a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp index 0a1b3d055c2..c213745be4b 100644 --- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp @@ -56,7 +56,7 @@ template void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from } assert(obj != NULL, "Must be"); - update_rs(from, p, queue_num()); + update_rs(from, p, _worker_id); } template inline void G1ParScanThreadState::push_on_queue(T* ref) { @@ -136,7 +136,7 @@ inline void G1ParScanThreadState::dispatch_reference(StarTask ref) { void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) { StarTask stolen_task; - while (task_queues->steal(queue_num(), hash_seed(), stolen_task)) { + while (task_queues->steal(_worker_id, &_hash_seed, stolen_task)) { assert(verify_task(stolen_task), "sanity"); dispatch_reference(stolen_task); diff --git a/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp b/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp index f48a40da74b..fbe9aa743ff 100644 --- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp +++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp @@ -34,6 +34,7 @@ #include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1RemSet.inline.hpp" #include "gc/g1/g1RootProcessor.hpp" +#include "gc/g1/heapRegion.inline.hpp" #include "memory/allocation.inline.hpp" #include "runtime/fprofiler.hpp" #include "runtime/mutex.hpp" diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.hpp index 2b07a11bf5c..e7bccf0783a 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp @@ -497,20 +497,10 @@ class HeapRegion: public G1OffsetTableContigSpace { return _rem_set; } - bool in_collection_set() const; + inline bool in_collection_set() const; - HeapRegion* next_in_collection_set() { - assert(in_collection_set(), "should only invoke on member of CS."); - assert(_next_in_special_set == NULL || - _next_in_special_set->in_collection_set(), - "Malformed CS."); - return _next_in_special_set; - } - void set_next_in_collection_set(HeapRegion* r) { - assert(in_collection_set(), "should only invoke on member of CS."); - assert(r == NULL || r->in_collection_set(), "Malformed CS."); - _next_in_special_set = r; - } + inline HeapRegion* next_in_collection_set() const; + inline void set_next_in_collection_set(HeapRegion* r); void set_allocation_context(AllocationContext_t context) { _allocation_context = context; diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp index cd963a096d4..24c5b9783fa 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp @@ -26,7 +26,7 @@ #define SHARE_VM_GC_G1_HEAPREGION_INLINE_HPP #include "gc/g1/g1BlockOffsetTable.inline.hpp" -#include "gc/g1/g1CollectedHeap.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/heapRegion.hpp" #include "gc/shared/space.hpp" #include "oops/oop.inline.hpp" @@ -200,4 +200,18 @@ inline bool HeapRegion::in_collection_set() const { return G1CollectedHeap::heap()->is_in_cset(this); } +inline HeapRegion* HeapRegion::next_in_collection_set() const { + assert(in_collection_set(), "should only invoke on member of CS."); + assert(_next_in_special_set == NULL || + _next_in_special_set->in_collection_set(), + "Malformed CS."); + return _next_in_special_set; +} + +void HeapRegion::set_next_in_collection_set(HeapRegion* r) { + assert(in_collection_set(), "should only invoke on member of CS."); + assert(r == NULL || r->in_collection_set(), "Malformed CS."); + _next_in_special_set = r; +} + #endif // SHARE_VM_GC_G1_HEAPREGION_INLINE_HPP diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp index bdb82548871..0501f3237c2 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp @@ -70,7 +70,7 @@ HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) { HeapWord* bottom = g1h->bottom_addr_for_region(hrm_index); MemRegion mr(bottom, bottom + HeapRegion::GrainWords); assert(reserved().contains(mr), "invariant"); - return g1h->allocator()->new_heap_region(hrm_index, g1h->bot_shared(), mr); + return g1h->new_heap_region(hrm_index, mr); } void HeapRegionManager::commit_regions(uint index, size_t num_regions) { diff --git a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp index 90a74d367d5..316a14fbc72 100644 --- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp +++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp @@ -94,8 +94,9 @@ void VM_G1IncCollectionPause::doit() { if (_word_size > 0) { // An allocation has been requested. So, try to do that first. - _result = g1h->attempt_allocation_at_safepoint(_word_size, allocation_context(), - false /* expect_null_cur_alloc_region */); + _result = g1h->attempt_allocation_at_safepoint(_word_size, + allocation_context(), + false /* expect_null_cur_alloc_region */); if (_result != NULL) { // If we can successfully allocate before we actually do the // pause then we will consider this pause successful. @@ -147,8 +148,9 @@ void VM_G1IncCollectionPause::doit() { g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); if (_pause_succeeded && _word_size > 0) { // An allocation had been requested. - _result = g1h->attempt_allocation_at_safepoint(_word_size, allocation_context(), - true /* expect_null_cur_alloc_region */); + _result = g1h->attempt_allocation_at_safepoint(_word_size, + allocation_context(), + true /* expect_null_cur_alloc_region */); } else { assert(_result == NULL, "invariant"); if (!_pause_succeeded) { diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 42ff73ea491..d08c5ce8b78 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -1303,7 +1303,7 @@ void SignatureHandlerLibrary::add(uint64_t fingerprint, address handler) { if (handler_index < 0) { if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) { tty->cr(); - tty->print_cr("argument handler #%d at "PTR_FORMAT" for fingerprint " UINT64_FORMAT, + tty->print_cr("argument handler #%d at " PTR_FORMAT " for fingerprint " UINT64_FORMAT, _handlers->length(), handler, fingerprint); @@ -1313,7 +1313,7 @@ void SignatureHandlerLibrary::add(uint64_t fingerprint, address handler) { } else { if (PrintSignatureHandlers) { tty->cr(); - tty->print_cr("duplicate argument handler #%d for fingerprint " UINT64_FORMAT "(old: "PTR_FORMAT", new : "PTR_FORMAT")", + tty->print_cr("duplicate argument handler #%d for fingerprint " UINT64_FORMAT "(old: " PTR_FORMAT ", new : " PTR_FORMAT ")", _handlers->length(), fingerprint, _handlers->at(handler_index), diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index d3a97225c20..07c63c9b343 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -379,7 +379,8 @@ int LinkResolver::vtable_index_of_interface_method(KlassHandle klass, if (!resolved_method->is_abstract() && (InstanceKlass::cast(klass())->default_methods() != NULL)) { int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), - name, signature, Klass::find_overpass, Klass::find_static); + name, signature, Klass::find_overpass, + Klass::find_static, Klass::find_private); if (index >= 0 ) { vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); } @@ -1189,7 +1190,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, assert(resolved_method->method_holder()->is_linked(), "must be linked"); // do lookup based on receiver klass using the vtable index - if (resolved_method->method_holder()->is_interface()) { // miranda method + if (resolved_method->method_holder()->is_interface()) { // default or miranda method vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); @@ -1198,7 +1199,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); } else { // at this point we are sure that resolved_method is virtual and not - // a miranda method; therefore, it must have a valid vtable index. + // a default or miranda method; therefore, it must have a valid vtable index. assert(!resolved_method->has_itable_index(), ""); vtable_index = resolved_method->vtable_index(); // We could get a negative vtable_index for final methods, diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 63a1b1fa4f3..0aa1c431bbb 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -1381,12 +1381,14 @@ static int binary_search(Array* methods, Symbol* name) { // find_method looks up the name/signature in the local methods array Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { - return find_method_impl(name, signature, find_overpass, find_static); + return find_method_impl(name, signature, find_overpass, find_static, find_private); } Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, - OverpassLookupMode overpass_mode, StaticLookupMode static_mode) const { - return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode); + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode) const { + return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); } // find_instance_method looks up the name/signature in the local methods array @@ -1394,7 +1396,7 @@ Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, Method* InstanceKlass::find_instance_method( Array* methods, Symbol* name, Symbol* signature) { Method* meth = InstanceKlass::find_method_impl(methods, name, signature, - find_overpass, skip_static); + find_overpass, skip_static, find_private); assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); return meth; } @@ -1405,22 +1407,51 @@ Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) { return InstanceKlass::find_instance_method(methods(), name, signature); } +// Find looks up the name/signature in the local methods array +// and filters on the overpass, static and private flags +// This returns the first one found +// note that the local methods array can have up to one overpass, one static +// and one instance (private or not) with the same name/signature +Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode) const { + return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); +} + +// Find looks up the name/signature in the local methods array +// and filters on the overpass, static and private flags +// This returns the first one found +// note that the local methods array can have up to one overpass, one static +// and one instance (private or not) with the same name/signature +Method* InstanceKlass::find_local_method(Array* methods, + Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode) { + return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode); +} + + // find_method looks up the name/signature in the local methods array Method* InstanceKlass::find_method( Array* methods, Symbol* name, Symbol* signature) { - return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static); + return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private); } Method* InstanceKlass::find_method_impl( - Array* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) { - int hit = find_method_index(methods, name, signature, overpass_mode, static_mode); + Array* methods, Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, StaticLookupMode static_mode, + PrivateLookupMode private_mode) { + int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode); return hit >= 0 ? methods->at(hit): NULL; } -bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) { - return (m->signature() == signature) && +bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) { + return ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass()) && - (!skipping_static || !m->is_static()); + (!skipping_static || !m->is_static()) && + (!skipping_private || !m->is_private())); } // Used directly for default_methods to find the index into the @@ -1430,17 +1461,25 @@ bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_o // the search continues to find a potential non-overpass match. This capability // is important during method resolution to prefer a static method, for example, // over an overpass method. +// There is the possibility in any _method's array to have the same name/signature +// for a static method, an overpass method and a local instance method +// To correctly catch a given method, the search criteria may need +// to explicitly skip the other two. For local instance methods, it +// is often necessary to skip private methods int InstanceKlass::find_method_index( - Array* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) { + Array* methods, Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, StaticLookupMode static_mode, + PrivateLookupMode private_mode) { bool skipping_overpass = (overpass_mode == skip_overpass); bool skipping_static = (static_mode == skip_static); + bool skipping_private = (private_mode == skip_private); int hit = binary_search(methods, name); if (hit != -1) { Method* m = methods->at(hit); // Do linear search to find matching signature. First, quick check // for common case, ignoring overpasses if requested. - if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit; + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit; // search downwards through overloaded methods int i; @@ -1448,18 +1487,18 @@ int InstanceKlass::find_method_index( Method* m = methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) break; - if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; } // search upwards for (i = hit + 1; i < methods->length(); ++i) { Method* m = methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) break; - if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; } // not found #ifdef ASSERT - int index = (skipping_overpass || skipping_static) ? -1 : linear_search(methods, name, signature); + int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature); assert(index == -1, err_msg("binary search should have found entry %d", index)); #endif } @@ -1489,7 +1528,7 @@ Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, O OverpassLookupMode overpass_local_mode = overpass_mode; Klass* klass = const_cast(this); while (klass != NULL) { - Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static); + Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static, find_private); if (method != NULL) { return method; } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 141ec1139e6..4529b40d390 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -503,12 +503,28 @@ class InstanceKlass: public Klass { Method* find_instance_method(Symbol* name, Symbol* signature); static Method* find_instance_method(Array* methods, Symbol* name, Symbol* signature); - // true if method matches signature and conforms to skipping_X conditions. - static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static); + // find a local method (returns NULL if not found) + Method* find_local_method(Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode) const; - // find a local method index in default_methods (returns -1 if not found) - static int find_method_index(Array* methods, Symbol* name, Symbol* signature, - OverpassLookupMode overpass_mode, StaticLookupMode static_mode); + // find a local method from given methods array (returns NULL if not found) + static Method* find_local_method(Array* methods, + Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode); + + // true if method matches signature and conforms to skipping_X conditions. + static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private); + + // find a local method index in methods or default_methods (returns -1 if not found) + static int find_method_index(Array* methods, + Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode); // lookup operation (returns NULL if not found) Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const; @@ -1153,9 +1169,14 @@ private: // find a local method (returns NULL if not found) Method* find_method_impl(Symbol* name, Symbol* signature, - OverpassLookupMode overpass_mode, StaticLookupMode static_mode) const; - static Method* find_method_impl(Array* methods, Symbol* name, Symbol* signature, - OverpassLookupMode overpass_mode, StaticLookupMode static_mode); + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode) const; + static Method* find_method_impl(Array* methods, + Symbol* name, Symbol* signature, + OverpassLookupMode overpass_mode, + StaticLookupMode static_mode, + PrivateLookupMode private_mode); // Free CHeap allocated fields. void release_C_heap_structures(); diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 57648b363b6..48267d54ce2 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -161,6 +161,7 @@ protected: enum DefaultsLookupMode { find_defaults, skip_defaults }; enum OverpassLookupMode { find_overpass, skip_overpass }; enum StaticLookupMode { find_static, skip_static }; + enum PrivateLookupMode { find_private, skip_private }; bool is_klass() const volatile { return true; } diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index 54df450637b..545dbd467ae 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -683,7 +683,6 @@ bool klassVtable::is_miranda_entry_at(int i) { if (mhk->is_interface()) { assert(m->is_public(), "should be public"); assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); - // the search could find a miranda or a default method if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super())) { return true; } @@ -691,25 +690,57 @@ bool klassVtable::is_miranda_entry_at(int i) { return false; } -// check if a method is a miranda method, given a class's methods table, -// its default_method table and its super -// Miranda methods are calculated twice: -// first: before vtable size calculation: including abstract and superinterface default +// Check if a method is a miranda method, given a class's methods array, +// its default_method table and its super class. +// "Miranda" means an abstract non-private method that would not be +// overridden for the local class. +// A "miranda" method should only include non-private interface +// instance methods, i.e. not private methods, not static methods, +// not default methods (concrete interface methods), not overpass methods. +// If a given class already has a local (including overpass) method, a +// default method, or any of its superclasses has the same which would have +// overridden an abstract method, then this is not a miranda method. +// +// Miranda methods are checked multiple times. +// Pass 1: during class load/class file parsing: before vtable size calculation: +// include superinterface abstract and default methods (non-private instance). // We include potential default methods to give them space in the vtable. -// During the first run, the default_methods list is empty -// This is seen by default method creation -// Second: recalculated during vtable initialization: only include abstract methods. +// During the first run, the current instanceKlass has not yet been +// created, the superclasses and superinterfaces do have instanceKlasses +// but may not have vtables, the default_methods list is empty, no overpasses. +// This is seen by default method creation. +// +// Pass 2: recalculated during vtable initialization: only include abstract methods. +// The goal of pass 2 is to walk through the superinterfaces to see if any of +// the superinterface methods (which were all abstract pre-default methods) +// need to be added to the vtable. +// With the addition of default methods, we have three new challenges: +// overpasses, static interface methods and private interface methods. +// Static and private interface methods do not get added to the vtable and +// are not seen by the method resolution process, so we skip those. +// Overpass methods are already in the vtable, so vtable lookup will +// find them and we don't need to add a miranda method to the end of +// the vtable. So we look for overpass methods and if they are found we +// return false. Note that we inherit our superclasses vtable, so +// the superclass' search also needs to use find_overpass so that if +// one is found we return false. +// False means - we don't need a miranda method added to the vtable. +// // During the second run, default_methods is set up, so concrete methods from // superinterfaces with matching names/signatures to default_methods are already // in the default_methods list and do not need to be appended to the vtable -// as mirandas -// This is seen by link resolution and selection. -// "miranda" means not static, not defined by this class. -// private methods in interfaces do not belong in the miranda list. -// the caller must make sure that the method belongs to an interface implemented by the class -// Miranda methods only include public interface instance methods -// Not private methods, not static methods, not default == concrete abstract -// Miranda methods also do not include overpass methods in interfaces +// as mirandas. Abstract methods may already have been handled via +// overpasses - either local or superclass overpasses, which may be +// in the vtable already. +// +// Pass 3: They are also checked by link resolution and selection, +// for invocation on a method (not interface method) reference that +// resolves to a method with an interface as its method_holder. +// Used as part of walking from the bottom of the vtable to find +// the vtable index for the miranda method. +// +// Part of the Miranda Rights in the US mean that if you do not have +// an attorney one will be appointed for you. bool klassVtable::is_miranda(Method* m, Array* class_methods, Array* default_methods, Klass* super) { if (m->is_static() || m->is_private() || m->is_overpass()) { @@ -717,44 +748,36 @@ bool klassVtable::is_miranda(Method* m, Array* class_methods, } Symbol* name = m->name(); Symbol* signature = m->signature(); - Method* mo; - if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) { - // did not find it in the method table of the current class - if ((default_methods == NULL) || - InstanceKlass::find_method(default_methods, name, signature) == NULL) { - if (super == NULL) { - // super doesn't exist - return true; - } - - mo = InstanceKlass::cast(super)->lookup_method(name, signature); - while (mo != NULL && mo->access_flags().is_static() - && mo->method_holder() != NULL - && mo->method_holder()->super() != NULL) - { - mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::find_overpass); - } - if (mo == NULL || mo->access_flags().is_private() ) { - // super class hierarchy does not implement it or protection is different - return true; - } - } - } else { - // if the local class has a private method, the miranda will not - // override it, so a vtable slot is needed - if (mo->access_flags().is_private()) { - - // Second round, weed out any superinterface methods that turned - // into default methods, i.e. were concrete not abstract in the end - if ((default_methods == NULL) || - InstanceKlass::find_method(default_methods, name, signature) == NULL) { - return true; - } - } + // First look in local methods to see if already covered + if (InstanceKlass::find_local_method(class_methods, name, signature, + Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) + { + return false; } - return false; + // Check local default methods + if ((default_methods != NULL) && + (InstanceKlass::find_method(default_methods, name, signature) != NULL)) + { + return false; + } + + InstanceKlass* cursuper; + // Iterate on all superclasses, which should have instanceKlasses + // Note that we explicitly look for overpasses at each level. + // Overpasses may or may not exist for supers for pass 1, + // they should have been created for pass 2 and later. + + for (cursuper = InstanceKlass::cast(super); cursuper != NULL; cursuper = (InstanceKlass*)cursuper->super()) + { + if (cursuper->find_local_method(name, signature, + Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) { + return false; + } + } + + return true; } // Scans current_interface_methods for miranda methods that do not diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 7c32b68d015..ded60f22583 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -393,7 +393,7 @@ uint PhaseCFG::build_cfg() { VectorSet visited(a); // Allocate stack with enough space to avoid frequent realloc - Node_Stack nstack(a, C->unique() >> 1); + Node_Stack nstack(a, C->live_nodes() >> 1); nstack.push(_root, 0); uint sum = 0; // Counter for blocks diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 9014eb6df4a..8cb6488a535 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -802,7 +802,7 @@ PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) cons Compile *C = igvn->C; Arena *a = Thread::current()->resource_area(); Node_Array node_map = new Node_Array(a); - Node_Stack stack(a, C->unique() >> 4); + Node_Stack stack(a, C->live_nodes() >> 4); PhiNode *nphi = slice_memory(at); igvn->register_new_node_with_optimizer( nphi ); node_map.map(_idx, nphi); diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 3cf18d16ceb..9f1aedc735c 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -3315,7 +3315,7 @@ bool Compile::final_graph_reshaping() { // Visit everybody reachable! // Allocate stack of size C->unique()/2 to avoid frequent realloc - Node_Stack nstack(unique() >> 1); + Node_Stack nstack(live_nodes() >> 1); final_graph_reshaping_walk(nstack, root(), frc); // Check for unreachable (from below) code (i.e., infinite loops). diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp index 0be96ad7f71..3b21df0ce1d 100644 --- a/hotspot/src/share/vm/opto/domgraph.cpp +++ b/hotspot/src/share/vm/opto/domgraph.cpp @@ -507,7 +507,7 @@ void PhaseIdealLoop::Dominators() { // 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent. int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) { // Allocate stack of size C->unique()/8 to avoid frequent realloc - GrowableArray dfstack(pil->C->unique() >> 3); + GrowableArray dfstack(pil->C->live_nodes() >> 3); Node *b = pil->C->root(); int dfsnum = 1; dfsorder[b->_idx] = dfsnum; // Cache parent's dfsnum for a later use diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index d3a579a1064..744ecc77737 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -107,8 +107,8 @@ static bool is_dominator(Block* d, Block* n) { //------------------------------schedule_pinned_nodes-------------------------- // Set the basic block for Nodes pinned into blocks void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) { - // Allocate node stack of size C->unique()+8 to avoid frequent realloc - GrowableArray spstack(C->unique() + 8); + // Allocate node stack of size C->live_nodes()+8 to avoid frequent realloc + GrowableArray spstack(C->live_nodes() + 8); spstack.push(_root); while (spstack.is_nonempty()) { Node* node = spstack.pop(); @@ -1310,7 +1310,7 @@ void PhaseCFG::global_code_motion() { visited.Clear(); Node_List stack(arena); // Pre-grow the list - stack.map((C->unique() >> 1) + 16, NULL); + stack.map((C->live_nodes() >> 1) + 16, NULL); if (!schedule_early(visited, stack)) { // Bailout without retry C->record_method_not_compilable("early schedule failed"); diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index 155216105e3..02153bf31e6 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -1282,7 +1282,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad if (C->do_vector_loop() && (PrintOpto && VerifyLoopOptimizations || TraceLoopOpts)) { Arena* arena = Thread::current()->resource_area(); - Node_Stack stack(arena, C->unique() >> 2); + Node_Stack stack(arena, C->live_nodes() >> 2); Node_List rpo_list; VectorSet visited(arena); visited.set(loop_head->_idx); diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index a50afb59316..c55cb111bd6 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -2231,7 +2231,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts) // _nodes array holds the earliest legal controlling CFG node. // Allocate stack with enough space to avoid frequent realloc - int stack_size = (C->unique() >> 1) + 16; // (unique>>1)+16 from Java2D stats + int stack_size = (C->live_nodes() >> 1) + 16; // (live_nodes>>1)+16 from Java2D stats Node_Stack nstack( a, stack_size ); visited.Clear(); @@ -2691,7 +2691,7 @@ void PhaseIdealLoop::recompute_dom_depth() { } } if (_dom_stk == NULL) { - uint init_size = C->unique() / 100; // Guess that 1/100 is a reasonable initial size. + uint init_size = C->live_nodes() / 100; // Guess that 1/100 is a reasonable initial size. if (init_size < 10) init_size = 10; _dom_stk = new GrowableArray(init_size); } @@ -2781,8 +2781,8 @@ IdealLoopTree *PhaseIdealLoop::sort( IdealLoopTree *loop, IdealLoopTree *innermo // The sort is of size number-of-control-children, which generally limits // it to size 2 (i.e., I just choose between my 2 target loops). void PhaseIdealLoop::build_loop_tree() { - // Allocate stack of size C->unique()/2 to avoid frequent realloc - GrowableArray bltstack(C->unique() >> 1); + // Allocate stack of size C->live_nodes()/2 to avoid frequent realloc + GrowableArray bltstack(C->live_nodes() >> 1); Node *n = C->root(); bltstack.push(n); int pre_order = 1; @@ -3672,7 +3672,7 @@ void PhaseIdealLoop::dump_bad_graph(const char* msg, Node* n, Node* early, Node* void PhaseIdealLoop::dump( ) const { ResourceMark rm; Arena* arena = Thread::current()->resource_area(); - Node_Stack stack(arena, C->unique() >> 2); + Node_Stack stack(arena, C->live_nodes() >> 2); Node_List rpo_list; VectorSet visited(arena); visited.set(C->top()->_idx); diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index ee66e1aac4b..2c07c458859 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -2050,7 +2050,7 @@ bool Matcher::is_bmi_pattern(Node *n, Node *m) { // Set bits if Node is shared or otherwise a root void Matcher::find_shared( Node *n ) { // Allocate stack of size C->unique() * 2 to avoid frequent realloc - MStack mstack(C->unique() * 2); + MStack mstack(C->live_nodes() * 2); // Mark nodes as address_visited if they are inputs to an address expression VectorSet address_visited(Thread::current()->resource_area()); mstack.push(n, Visit); // Don't need to pre-visit root node diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index a331ac637cf..0a049163d3a 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1799,7 +1799,7 @@ static void collect_nodes_i(GrowableArray *nstack, const Node* start, int static void dump_nodes(const Node* start, int d, bool only_ctrl) { if (NotANode(start)) return; - GrowableArray nstack(Compile::current()->unique()); + GrowableArray nstack(Compile::current()->live_nodes()); collect_nodes_i(&nstack, start, d, (uint) ABS(d), true, only_ctrl, false); int end = nstack.length(); diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 1426a31c9c5..9d2b11e26a7 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -791,7 +791,7 @@ void PhaseGVN::dead_loop_check( Node *n ) { //------------------------------PhaseIterGVN----------------------------------- // Initialize hash table to fresh and clean for +VerifyOpto PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ), - _stack(C->unique() >> 1), + _stack(C->live_nodes() >> 1), _delay_transform(false) { } @@ -808,7 +808,11 @@ PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn), // Initialize with previous PhaseGVN info from Parser PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn), _worklist(*C->for_igvn()), - _stack(C->unique() >> 1), +// TODO: Before incremental inlining it was allocated only once and it was fine. Now that +// the constructor is used in incremental inlining, this consumes too much memory: +// _stack(C->live_nodes() >> 1), +// So, as a band-aid, we replace this by: + _stack(C->comp_arena(), 32), _delay_transform(false) { uint max; @@ -1638,7 +1642,7 @@ Node *PhaseCCP::transform( Node *n ) { _nodes.map( n->_idx, new_node ); // Flag as having been cloned // Allocate stack of size _nodes.Size()/2 to avoid frequent realloc - GrowableArray trstack(C->unique() >> 1); + GrowableArray trstack(C->live_nodes() >> 1); trstack.push(new_node); // Process children of cloned node while ( trstack.is_nonempty() ) { diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 45043cc7371..de5af848735 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2295,13 +2295,13 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, } // Checks if name in command-line argument -agent{lib,path}:name[=options] -// represents a valid HPROF of JDWP agent. is_path==true denotes that we +// represents a valid JDWP agent. is_path==true denotes that we // are dealing with -agentpath (case where name is a path), otherwise with // -agentlib -bool valid_hprof_or_jdwp_agent(char *name, bool is_path) { +bool valid_jdwp_agent(char *name, bool is_path) { char *_name; - const char *_hprof = "hprof", *_jdwp = "jdwp"; - size_t _len_hprof, _len_jdwp, _len_prefix; + const char *_jdwp = "jdwp"; + size_t _len_jdwp, _len_prefix; if (is_path) { if ((_name = strrchr(name, (int) *os::file_separator())) == NULL) { @@ -2316,13 +2316,9 @@ bool valid_hprof_or_jdwp_agent(char *name, bool is_path) { } _name += _len_prefix; - _len_hprof = strlen(_hprof); _len_jdwp = strlen(_jdwp); - if (strncmp(_name, _hprof, _len_hprof) == 0) { - _name += _len_hprof; - } - else if (strncmp(_name, _jdwp, _len_jdwp) == 0) { + if (strncmp(_name, _jdwp, _len_jdwp) == 0) { _name += _len_jdwp; } else { @@ -2336,7 +2332,7 @@ bool valid_hprof_or_jdwp_agent(char *name, bool is_path) { return true; } - if (strcmp(name, _hprof) == 0 || strcmp(name, _jdwp) == 0) { + if (strcmp(name, _jdwp) == 0) { return true; } @@ -2427,9 +2423,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2); } #if !INCLUDE_JVMTI - if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { + if (strcmp(name, "jdwp") == 0) { jio_fprintf(defaultStream::error_stream(), - "Profiling and debugging agents are not supported in this VM\n"); + "Debugging agents are not supported in this VM\n"); return JNI_ERR; } #endif // !INCLUDE_JVMTI @@ -2449,9 +2445,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, options = os::strdup_check_oom(pos + 1, mtInternal); } #if !INCLUDE_JVMTI - if (valid_hprof_or_jdwp_agent(name, is_absolute_path)) { + if (valid_jdwp_agent(name, is_absolute_path)) { jio_fprintf(defaultStream::error_stream(), - "Profiling and debugging agents are not supported in this VM\n"); + "Debugging agents are not supported in this VM\n"); return JNI_ERR; } #endif // !INCLUDE_JVMTI @@ -3305,7 +3301,9 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req if (scp_assembly_required) { // Assemble the bootclasspath elements into the final path. - Arguments::set_sysclasspath(scp_p->combined_path()); + char *combined_path = scp_p->combined_path(); + Arguments::set_sysclasspath(combined_path); + FREE_C_HEAP_ARRAY(char, combined_path); } // This must be done after all arguments have been processed. diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index bf10f5ab3c2..068bcacdc12 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1271,6 +1271,7 @@ bool os::set_boot_path(char fileSep, char pathSep) { bool has_jimage = (os::stat(jimage, &st) == 0); if (has_jimage) { Arguments::set_sysclasspath(jimage); + FREE_C_HEAP_ARRAY(char, jimage); return true; } FREE_C_HEAP_ARRAY(char, jimage); @@ -1282,6 +1283,7 @@ bool os::set_boot_path(char fileSep, char pathSep) { sysclasspath = expand_entries_to_path(modules_dir, fileSep, pathSep); } } + FREE_C_HEAP_ARRAY(char, modules_dir); // fallback to classes if (sysclasspath == NULL) @@ -1289,6 +1291,7 @@ bool os::set_boot_path(char fileSep, char pathSep) { if (sysclasspath == NULL) return false; Arguments::set_sysclasspath(sysclasspath); + FREE_C_HEAP_ARRAY(char, sysclasspath); return true; } diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp index e5271b6d7e3..61d40889615 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -27,6 +27,11 @@ #include "runtime/thread.inline.hpp" #include "runtime/threadLocalStorage.hpp" +// Solaris no longer has this kind of ThreadLocalStorage implementation. +// This will be removed from all platforms in the near future. + +#ifndef SOLARIS + // static member initialization int ThreadLocalStorage::_thread_index = -1; @@ -54,3 +59,5 @@ void ThreadLocalStorage::init() { bool ThreadLocalStorage::is_initialized() { return (thread_index() != -1); } + +#endif // SOLARIS diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp index 9d6d9f6f8c2..128dd98067f 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp @@ -38,10 +38,14 @@ extern "C" Thread* get_thread(); extern "C" uintptr_t _raw_thread_id(); class ThreadLocalStorage : AllStatic { + + // Exported API public: static void set_thread(Thread* thread); static Thread* get_thread_slow(); static void invalidate_all() { pd_invalidate_all(); } + static void init(); + static bool is_initialized(); // Machine dependent stuff #ifdef TARGET_OS_ARCH_linux_x86 @@ -81,17 +85,12 @@ class ThreadLocalStorage : AllStatic { # include "threadLS_bsd_zero.hpp" #endif - +#ifndef SOLARIS public: // Accessor static inline int thread_index() { return _thread_index; } static inline void set_thread_index(int index) { _thread_index = index; } - // Initialization - // Called explicitly from VMThread::activate_system instead of init_globals. - static void init(); - static bool is_initialized(); - private: static int _thread_index; @@ -100,6 +99,9 @@ class ThreadLocalStorage : AllStatic { // Processor dependent parts of set_thread and initialization static void pd_set_thread(Thread* thread); static void pd_init(); + +#endif // SOLARIS + // Invalidate any thread cacheing or optimization schemes. static void pd_invalidate_all(); diff --git a/hotspot/test/runtime/SharedArchiveFile/BasicJarBuilder.java b/hotspot/test/runtime/SharedArchiveFile/BasicJarBuilder.java new file mode 100644 index 00000000000..0bb499590c5 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/BasicJarBuilder.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 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. + */ + +/* + * @summary Simple jar builder + * Input: jarName className1 className2 ... + * do not specify extensions, just the names + * E.g. prot_domain ProtDomainA ProtDomainB + * Output: A jar containing compiled classes, placed in a test classes folder + */ + +import jdk.test.lib.*; + +import java.io.File; +import java.util.ArrayList; +import sun.tools.jar.Main; + +public class BasicJarBuilder { + private static final String classDir = System.getProperty("test.classes"); + + public static void build(String jarName, String ...classNames) + throws Exception { + + createSimpleJar(classDir, classDir + File.separator + jarName + + ".jar", classNames); + } + + private static void createSimpleJar(String jarclassDir, String jarName, + String[] classNames) throws Exception { + ArrayList args = new ArrayList(); + args.add("cf"); + args.add(jarName); + addClassArgs(args, jarclassDir, classNames); + createJar(args); + } + + private static void addClassArgs(ArrayList args, String jarclassDir, + String[] classNames) { + + for (String name : classNames) { + args.add("-C"); + args.add(jarclassDir); + args.add(name + ".class"); + } + } + + private static void createJar(ArrayList args) { + Main jarTool = new Main(System.out, System.err, "jar"); + if (!jarTool.run(args.toArray(new String[1]))) { + throw new RuntimeException("jar operation failed"); + } + } + + // helpers + public static String getTestJar(String jar) { + File dir = new File(System.getProperty("test.classes", ".")); + File jarFile = new File(dir, jar); + if (!jarFile.exists()) { + throw new RuntimeException("Cannot find " + jarFile.getPath()); + } + if (!jarFile.isFile()) { + throw new RuntimeException("Not a regular file: " + jarFile.getPath()); + } + return jarFile.getPath(); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java b/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java new file mode 100644 index 00000000000..2078949d659 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/SharedStrings.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015, 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 + * @summary Check to make sure that shared strings in the bootstrap CDS archive + * are actually shared + * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows + * @requires (sun.arch.data.model != "32") & (os.family != "windows") + * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) + * @requires (vm.gc=="G1" | vm.gc=="null") + * @library /testlibrary /../../test/lib + * @modules java.base/sun.misc + * java.management + * @ignore - 8133180 + * @build SharedStringsWb SharedStrings BasicJarBuilder + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main SharedStrings + */ + +import jdk.test.lib.*; + +public class SharedStrings { + public static void main(String[] args) throws Exception { + BasicJarBuilder.build("whitebox", "sun/hotspot/WhiteBox"); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./SharedStrings.jsa", + "-XX:+PrintSharedSpaces", + // Needed for bootclasspath match, for CDS to work with WhiteBox API + "-Xbootclasspath/a:" + BasicJarBuilder.getTestJar("whitebox.jar"), + "-Xshare:dump"); + + new OutputAnalyzer(pb.start()) + .shouldContain("Loading classes to share") + .shouldContain("Shared string table stats") + .shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./SharedStrings.jsa", + // these are required modes for shared strings + "-XX:+UseCompressedOops", "-XX:+UseG1GC", + // needed for access to white box test API + "-Xbootclasspath/a:" + BasicJarBuilder.getTestJar("whitebox.jar"), + "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", + "-Xshare:on", "-showversion", "SharedStringsWb"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + try { + output.shouldContain("sharing"); + output.shouldHaveExitValue(0); + } catch (RuntimeException e) { + output.shouldContain("Unable to use shared archive"); + output.shouldHaveExitValue(1); + } + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedStringsWb.java b/hotspot/test/runtime/SharedArchiveFile/SharedStringsWb.java new file mode 100644 index 00000000000..be5aeab412c --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/SharedStringsWb.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, 2015, 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. + */ + +import sun.hotspot.WhiteBox; + +// This class is used by the test SharedStrings.java +// It should be launched in CDS mode +public class SharedStringsWb { + public static void main(String[] args) throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + + if (wb.areSharedStringsIgnored()) { + System.out.println("Shared strings are ignored, assuming PASS"); + return; + } + + // The string "java" is known to be interened and added to CDS archive + String s = "java"; + String internedS = s.intern(); + + if (wb.isShared(internedS)) { + System.out.println("Found shared string, result: PASS"); + } else { + throw new RuntimeException("String is not shared, result: FAIL"); + } + } +} + + diff --git a/hotspot/test/runtime/lambda-features/TestStaticandInstance.java b/hotspot/test/runtime/lambda-features/TestStaticandInstance.java new file mode 100644 index 00000000000..021ac48bf8a --- /dev/null +++ b/hotspot/test/runtime/lambda-features/TestStaticandInstance.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2015, 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 8087342 + * @summary Test linkresolver search static, instance and overpass duplicates + * @run main/othervm -Xverify:none TestStaticandInstance + */ + + +import java.util.*; +import jdk.internal.org.objectweb.asm.*; +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +public class TestStaticandInstance { + static final String stringC = "C"; + static final String stringD = "D"; + static final String stringI = "I"; + + public static void main(String args[]) throws Throwable { + ClassLoader cl = new ClassLoader() { + public Class loadClass(String name) throws ClassNotFoundException { + Class retClass; + if ((retClass = findLoadedClass(name)) != null) { + return retClass; + } + if (stringC.equals(name)) { + byte[] classFile=dumpC(); + return defineClass(stringC, classFile, 0, classFile.length); + } + if (stringD.equals(name)) { + byte[] classFile=dumpD(); + return defineClass(stringD, classFile, 0, classFile.length); + } + if (stringI.equals(name)) { + byte[] classFile=dumpI(); + return defineClass(stringI, classFile, 0, classFile.length); + } + return super.loadClass(name); + } + }; + + Class classC = cl.loadClass(stringC); + Class classI = cl.loadClass(stringI); + + try { + int staticret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallStatic").invoke(null); + if (staticret != 1) { + throw new RuntimeException("invokestatic failed to call correct method"); + } + System.out.println("staticret: " + staticret); // should be 1 + + int invokeinterfaceret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallInterface").invoke(null); + if (invokeinterfaceret != 0) { + throw new RuntimeException(String.format("Expected java.lang.AbstractMethodError, got %d", invokeinterfaceret)); + } + System.out.println("invokeinterfaceret: AbstractMethodError"); + + int invokevirtualret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallVirtual").invoke(null); + if (invokevirtualret != 0) { + throw new RuntimeException(String.format("Expected java.lang.IncompatibleClassChangeError, got %d", invokevirtualret)); + } + System.out.println("invokevirtualret: IncompatibleClassChangeError"); + } catch (java.lang.Throwable e) { + throw new RuntimeException("Unexpected exception: " + e.getMessage()); + } + } + +/* +interface I { + public int m(); // abstract + default int q() { return 3; } // trigger defmeth processing: C gets AME overpass +} + +// C gets static, private and AME overpass m()I with -Xverify:none +class C implements I { + static int m() { return 1;} // javac with "n()" and patch to "m()" + private int m() { return 2;} // javac with public and patch to private +} + +public class D { + public static int CallStatic() { + int staticret = C.m(); // javac with "C.n" and patch to "C.m" + return staticret; + } + public static int CallInterface() throws AbstractMethodError{ + try { + I myI = new C(); + return myI.m(); + } catch (java.lang.AbstractMethodError e) { + return 0; // for success + } + } + public static int CallVirtual() { + try { + C myC = new C(); + return myC.m(); + } catch (java.lang.IncompatibleClassChangeError e) { + return 0; // for success + } + } +} +*/ + + public static byte[] dumpC() { + + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(52, ACC_SUPER, "C", null, "java/lang/Object", new String[] { "I" }); + + { + mv = cw.visitMethod(0, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_STATIC, "m", "()I", null, null); + mv.visitCode(); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 0); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PRIVATE, "m", "()I", null, null); + mv.visitCode(); + mv.visitInsn(ICONST_2); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } + + public static byte[] dumpD () { + + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(52, ACC_PUBLIC + ACC_SUPER, "D", null, "java/lang/Object", null); + + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallStatic", "()I", null, null); + mv.visitCode(); + mv.visitMethodInsn(INVOKESTATIC, "C", "m", "()I", false); + mv.visitVarInsn(ISTORE, 0); + mv.visitVarInsn(ILOAD, 0); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallInterface", "()I", null, new String[] { "java/lang/AbstractMethodError" }); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/AbstractMethodError"); + mv.visitLabel(l0); + mv.visitTypeInsn(NEW, "C"); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, "C", "", "()V", false); + mv.visitVarInsn(ASTORE, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "I", "m", "()I", true); + mv.visitLabel(l1); + mv.visitInsn(IRETURN); + mv.visitLabel(l2); + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/AbstractMethodError"}); + mv.visitVarInsn(ASTORE, 0); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + mv.visitMaxs(2, 1); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallVirtual", "()I", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IncompatibleClassChangeError"); + mv.visitLabel(l0); + mv.visitTypeInsn(NEW, "C"); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, "C", "", "()V", false); + mv.visitVarInsn(ASTORE, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()I", false); + mv.visitLabel(l1); + mv.visitInsn(IRETURN); + mv.visitLabel(l2); + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/IncompatibleClassChangeError"}); + mv.visitVarInsn(ASTORE, 0); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + mv.visitMaxs(2, 1); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } + + public static byte[] dumpI() { + + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(52, ACC_ABSTRACT + ACC_INTERFACE, "I", null, "java/lang/Object", null); + + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()I", null, null); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "q", "()I", null, null); + mv.visitCode(); + mv.visitInsn(ICONST_3); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } +} diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e3b3c6177a6..de30885c88b 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -320,3 +320,4 @@ eadcb2b55cd1daf77625813aad0f6f3967b1528a jdk9-b74 16b5e696f948cd8aa9b3afdb686ddffd48bd17a8 jdk9-b75 36801a89a04201b59874ec776ffe85d6253c9ab5 jdk9-b76 be357705874c4ba1a69c38fb211e5e31e35bf9cb jdk9-b77 +5b1899c9822db4a80a29cac82af492afea9f8f41 jdk9-b78 diff --git a/jdk/.hgtags b/jdk/.hgtags index 46783012104..cd552d722c6 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -320,3 +320,4 @@ f376824d4940f45719d91838f3f6249f873440db jdk9-b72 4dd09cb5f7c2a2a23a9958ea7a602dd74d5709b2 jdk9-b75 4526c0da8fb362eebd7e88f4d44e86858cf9b80b jdk9-b76 7fd081100f48828431e7c1bff65c906ee759069b jdk9-b77 +0940ce86c614458f5bdd72278b190abbf36b7b45 jdk9-b78 diff --git a/jdk/make/copy/Copy-jdk.hprof.agent.gmk b/jdk/make/copy/Copy-jdk.hprof.agent.gmk deleted file mode 100644 index f738867240c..00000000000 --- a/jdk/make/copy/Copy-jdk.hprof.agent.gmk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2014, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -include CopyCommon.gmk - -################################################################################ - -HPROF_SRC := $(JDK_TOPDIR)/src/jdk.hprof.agent/share/native/libhprof/jvm.hprof.txt - -$(LIB_DST_DIR)/jvm.hprof.txt: $(HPROF_SRC) - $(call install-file) - -TARGETS := $(LIB_DST_DIR)/jvm.hprof.txt - -################################################################################ diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION index d6f6f158d1d..4bb2351d627 100644 --- a/jdk/make/data/tzdata/VERSION +++ b/jdk/make/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2015e +tzdata2015f diff --git a/jdk/make/data/tzdata/africa b/jdk/make/data/tzdata/africa index 049861192cc..00150c68ef0 100644 --- a/jdk/make/data/tzdata/africa +++ b/jdk/make/data/tzdata/africa @@ -561,7 +561,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 # From Alex Krivenyshev (2008-07-11): # Seems that English language article "The revival of daylight saving -# time: Energy conservation?"-# No. 16578 (07/11/2008) was originally +# time: Energy conservation?"- No. 16578 (07/11/2008) was originally # published on Monday, June 30, 2008... # # I guess that article in French "Le gouvernement avance l'introduction @@ -693,7 +693,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # Here is a link to official document from Royaume du Maroc Premier Ministre, # Ministère de la Modernisation des Secteurs Publics # -# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967) +# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 June 1967) # concerning the amendment of the legal time, the Ministry of Modernization of # Public Sectors announced that the official time in the Kingdom will be # advanced 60 minutes from Sunday 31 May 2009 at midnight. diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia index fa4f2461cbb..8a1f75fe7c0 100644 --- a/jdk/make/data/tzdata/asia +++ b/jdk/make/data/tzdata/asia @@ -29,7 +29,7 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2014-10-31): +# From Paul Eggert (2015-08-08): # # Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), @@ -66,7 +66,7 @@ # 2:00 EET EEST Eastern European Time # 2:00 IST IDT Israel # 3:00 AST ADT Arabia* -# 3:30 IRST IRDT Iran +# 3:30 IRST IRDT Iran* # 4:00 GST Gulf* # 5:30 IST India # 7:00 ICT Indochina, most times and locations* @@ -75,10 +75,11 @@ # 8:00 CST China # 8:00 IDT Indochina, 1943-45, 1947-55, 1960-75 (some locations)* # 8:00 JWST Western Standard Time (Japan, 1896/1937)* +# 8:30 KST KDT Korea when at +0830* # 9:00 JCST Central Standard Time (Japan, 1896/1937) # 9:00 WIT east Indonesia (Waktu Indonesia Timur) # 9:00 JST JDT Japan -# 9:00 KST KDT Korea +# 9:00 KST KDT Korea when at +09 # 9:30 ACST Australian Central Standard Time # # See the 'europe' file for Russia and Turkey in Asia. @@ -1050,7 +1051,7 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov # # From Roozbeh Pournader (2007-11-05): # This is quoted from Official Gazette of the Islamic Republic of -# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24 +# Iran, Volume 63, No. 18242, dated Tuesday 1386/6/24 # [2007-10-16]. I am doing the best translation I can:... # The official time of the country will be moved forward for one hour # on the 24 hours of the first day of the month of Farvardin and will @@ -1580,7 +1581,7 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00. # - Oral switched from +5:00 to +4:00 in spring 1989. -# From Kazakhstan Embassy's News Bulletin #11 +# From Kazakhstan Embassy's News Bulletin No. 11 # (2005-03-21): # The Government of Kazakhstan passed a resolution March 15 abolishing # daylight saving time citing lack of economic benefits and health @@ -1734,6 +1735,17 @@ Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S # # For Pyongyang we have no information; guess no changes since World War II. +# From Steffen Thorsen (2015-08-07): +# According to many news sources, North Korea is going to change to +# the 8:30 time zone on August 15, one example: +# http://www.bbc.com/news/world-asia-33815049 +# +# From Paul Eggert (2015-08-07): +# No transition time is specified; assume 00:00. +# There is no common English-language abbreviation for this time zone. +# Use %z rather than invent one. We can't assume %z works everywhere yet, +# so for now substitute its output manually. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1 8:30 - KST 1912 Jan 1 @@ -1746,7 +1758,8 @@ Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1 8:30 - KST 1912 Jan 1 9:00 - JCST 1937 Oct 1 9:00 - JST 1945 Aug 24 - 9:00 - KST + 9:00 - KST 2015 Aug 15 + 8:30 - KST ############################################################################### diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe index 7cee9a81527..b3a9854fc4f 100644 --- a/jdk/make/data/tzdata/europe +++ b/jdk/make/data/tzdata/europe @@ -216,11 +216,14 @@ # republished in Finest Hour (Spring 2002) 1(114):26 # http://www.winstonchurchill.org/images/finesthour/Vol.01%20No.114.pdf -# From Paul Eggert (1996-09-03): +# From Paul Eggert (2015-08-08): # The OED Supplement says that the English originally said "Daylight Saving" # when they were debating the adoption of DST in 1908; but by 1916 this # term appears only in quotes taken from DST's opponents, whereas the # proponents (who eventually won the argument) are quoted as using "Summer". +# The term "Summer Time" was introduced by Herbert Samuel, Home Secretary; see: +# Viscount Samuel. Leisure in a Democracy. Cambridge University Press +# ISBN 978-1-107-49471-8 (1949, reissued 2015), p 8. # From Arthur David Olson (1989-01-19): # A source at the British Information Office in New York avers that it's @@ -366,7 +369,7 @@ # From an anonymous contributor (1996-06-02): # The law governing time in Ireland is under Statutory Instrument SI 395/94, -# which gives force to European Union 7th Council Directive # 94/21/EC. +# which gives force to European Union 7th Council Directive No. 94/21/EC. # Under this directive, the Minister for Justice in Ireland makes appropriate # regulations. I spoke this morning with the Secretary of the Department of # Justice (tel +353 1 678 9711) who confirmed to me that the correct name is @@ -615,11 +618,11 @@ Rule Russia 1921 only - Feb 14 23:00 1:00 MSD Rule Russia 1921 only - Mar 20 23:00 2:00 MSM # Midsummer Rule Russia 1921 only - Sep 1 0:00 1:00 MSD Rule Russia 1921 only - Oct 1 0:00 0 - -# Act No.925 of the Council of Ministers of the USSR (1980-10-24): +# Act No. 925 of the Council of Ministers of the USSR (1980-10-24): Rule Russia 1981 1984 - Apr 1 0:00 1:00 S Rule Russia 1981 1983 - Oct 1 0:00 0 - -# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in -# Act No.227 of the Council of Ministers of the USSR (1989-03-14): +# Act No. 967 of the Council of Ministers of the USSR (1984-09-13), repeated in +# Act No. 227 of the Council of Ministers of the USSR (1989-03-14): Rule Russia 1984 1991 - Sep lastSun 2:00s 0 - Rule Russia 1985 1991 - Mar lastSun 2:00s 1:00 S # @@ -851,7 +854,7 @@ Zone Europe/Brussels 0:17:30 - LMT 1880 # Bulgaria # # From Plamen Simenov via Steffen Thorsen (1999-09-09): -# A document of Government of Bulgaria (No.94/1997) says: +# A document of Government of Bulgaria (No. 94/1997) says: # EET -> EETDST is in 03:00 Local time in last Sunday of March ... # EETDST -> EET is in 04:00 Local time in last Sunday of October # @@ -868,7 +871,7 @@ Zone Europe/Sofia 1:33:16 - LMT 1880 1:00 C-Eur CE%sT 1945 1:00 - CET 1945 Apr 2 3:00 2:00 - EET 1979 Mar 31 23:00 - 2:00 Bulg EE%sT 1982 Sep 26 2:00 + 2:00 Bulg EE%sT 1982 Sep 26 3:00 2:00 C-Eur EE%sT 1991 2:00 E-Eur EE%sT 1997 2:00 EU EE%sT @@ -1085,8 +1088,8 @@ Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base # after that. # From Mart Oruaas (2000-01-29): -# Regulation no. 301 (1999-10-12) obsoletes previous regulation -# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all +# Regulation No. 301 (1999-10-12) obsoletes previous regulation +# No. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all # the year round. The regulation is effective 1999-11-01. # From Toomas Soome (2002-02-21): @@ -1107,7 +1110,7 @@ Zone Europe/Tallinn 1:39:00 - LMT 1880 3:00 Russia MSK/MSD 1989 Mar 26 2:00s 2:00 1:00 EEST 1989 Sep 24 2:00s 2:00 C-Eur EE%sT 1998 Sep 22 - 2:00 EU EE%sT 1999 Nov 1 + 2:00 EU EE%sT 1999 Oct 31 4:00 2:00 - EET 2002 Feb 21 2:00 EU EE%sT @@ -1550,21 +1553,21 @@ Link Europe/Rome Europe/San_Marino # correct data in juridical acts and I found some juridical documents about # changes in the counting of time in Latvia from 1981.... # -# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ... -# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24 +# Act No. 35 of the Council of Ministers of Latvian SSR of 1981-01-22 ... +# according to the Act No. 925 of the Council of Ministers of USSR of 1980-10-24 # ...: all year round the time of 2nd time zone + 1 hour, in addition turning # the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00) # and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00). # -# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ... -# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13 +# Act No. 592 of the Council of Ministers of Latvian SSR of 1984-09-24 ... +# according to the Act No. 967 of the Council of Ministers of USSR of 1984-09-13 # ...: all year round the time of 2nd time zone + 1 hour, in addition turning # the hands of the clock 1 hour forward on the last Sunday of March at 02:00 # (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of # September at 03:00 (GMT 23:00 on the previous day). # -# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ... -# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14 +# Act No. 81 of the Council of Ministers of Latvian SSR of 1989-03-22 ... +# according to the Act No. 227 of the Council of Ministers of USSR of 1989-03-14 # ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR, # Estonian SSR and Kaliningrad region of Russian Federation all year round the # time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia @@ -1581,7 +1584,7 @@ Link Europe/Rome Europe/San_Marino # From Andrei Ivanov (2000-03-06): # This year Latvia will not switch to Daylight Savings Time (as specified in # The Regulations of the Cabinet of Ministers of the Rep. of Latvia of -# 29-Feb-2000 (#79) , +# 29-Feb-2000 (No. 79) , # in Latvian for subscribers only). # From RFE/RL Newsline @@ -1786,6 +1789,18 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta # News from Moldova (in russian): # http://ru.publika.md/link_317061.html +# From Roman Tudos (2015-07-02): +# http://lex.justice.md/index.php?action=view&view=doc&lang=1&id=355077 +# From Paul Eggert (2015-07-01): +# The abovementioned official link to IGO1445-868/2014 states that +# 2014-10-26's fallback transition occurred at 03:00 local time. Also, +# http://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara +# says the 2014-03-30 spring-forward transition was at 02:00 local time. +# Guess that since 1997 Moldova has switched one hour before the EU. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Moldova 1997 max - Mar lastSun 2:00 1:00 S +Rule Moldova 1997 max - Oct lastSun 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Chisinau 1:55:20 - LMT 1880 @@ -1800,7 +1815,7 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880 2:00 Russia EE%sT 1992 2:00 E-Eur EE%sT 1997 # See Romania commentary for the guessed 1997 transition to EU rules. - 2:00 EU EE%sT + 2:00 Moldova EE%sT # Monaco # Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's @@ -2146,7 +2161,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # Russia # From Alexander Krivenyshev (2011-09-15): -# Based on last Russian Government Decree # 725 on August 31, 2011 +# Based on last Russian Government Decree No. 725 on August 31, 2011 # (Government document # http://www.government.ru/gov/results/16355/print/ # in Russian) @@ -2156,7 +2171,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # http://www.worldtimezone.com/dst_news/dst_news_russia36.htm # From Sanjeev Gupta (2011-09-27): -# Scans of [Decree #23 of January 8, 1992] are available at: +# Scans of [Decree No. 23 of January 8, 1992] are available at: # http://government.consultant.ru/page.aspx?1223966 # They are in Cyrillic letters (presumably Russian). @@ -2167,19 +2182,19 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # One source is # http://government.ru/gov/results/16355/ # which, according to translate.google.com, begins "Decree of August 31, -# 2011 No 725" and contains no other dates or "effective date" information. +# 2011 No. 725" and contains no other dates or "effective date" information. # # Another source is # http://www.rg.ru/2011/09/06/chas-zona-dok.html # which, according to translate.google.com, begins "Resolution of the # Government of the Russian Federation on August 31, 2011 N 725" and also # contains "Date first official publication: September 6, 2011 Posted on: -# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which +# in the 'RG' - Federal Issue No. 5573 September 6, 2011" but which # does not contain any "effective date" information. # # Another source is # http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7 -# which, in note 8, contains "Resolution #725 of August 31, 2011... +# which, in note 8, contains "Resolution No. 725 of August 31, 2011... # Effective as of after 7 days following the day of the official publication" # but which does not contain any reference to September 6, 2011. # @@ -2387,7 +2402,7 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880 # changed in May. 2:00 E-Eur EE%sT 1994 May # From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev. - 3:00 E-Eur MSK/MSD 1996 Mar 31 3:00s + 3:00 E-Eur MSK/MSD 1996 Mar 31 0:00s 3:00 1:00 MSD 1996 Oct 27 3:00s # IATA SSIM (1997-09) says Crimea switched to EET/EEST. # Assume it happened in March by not changing the clocks. @@ -2522,7 +2537,7 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 # from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700 # to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600 # -# This is according to Government of Russia decree # 740, on September +# This is according to Government of Russia decree No. 740, on September # 14, 2009 "Application in the territory of the Kemerovo region the Fifth # time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600) # @@ -2945,7 +2960,7 @@ Zone Africa/Ceuta -0:21:16 - LMT 1901 Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. -1:00 - CANT 1946 Sep 30 1:00 # Canaries T 0:00 - WET 1980 Apr 6 0:00s - 0:00 1:00 WEST 1980 Sep 28 0:00s + 0:00 1:00 WEST 1980 Sep 28 1:00u 0:00 EU WE%sT # IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u. # Ignore this for now, as the Canaries are part of the EU. @@ -3235,7 +3250,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # From Igor Karpov, who works for the Ukrainian Ministry of Justice, # via Garrett Wollman (2003-01-27): # BTW, I've found the official document on this matter. It's government -# regulations number 509, May 13, 1996. In my poor translation it says: +# regulations No. 509, May 13, 1996. In my poor translation it says: # "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday # of March at 3am the time is changing to 4am and each last Sunday of # October the time at 4am is changing to 3am" @@ -3244,7 +3259,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # On September 20, 2011 the deputies of the Verkhovna Rada agreed to # abolish the transfer clock to winter time. # -# Bill number 8330 of MP from the Party of Regions Oleg Nadoshi got +# Bill No. 8330 of MP from the Party of Regions Oleg Nadoshi got # approval from 266 deputies. # # Ukraine abolishes transfer back to the winter time (in Russian) diff --git a/jdk/make/data/tzdata/leapseconds b/jdk/make/data/tzdata/leapseconds index 9b0a2278433..de698eaa562 100644 --- a/jdk/make/data/tzdata/leapseconds +++ b/jdk/make/data/tzdata/leapseconds @@ -79,5 +79,5 @@ Leap 2008 Dec 31 23:59:60 + S Leap 2012 Jun 30 23:59:60 + S Leap 2015 Jun 30 23:59:60 + S -# Updated through IERS Bulletin C49 -# File expires on: 28 December 2015 +# Updated through IERS Bulletin C50 +# File expires on: 28 June 2016 diff --git a/jdk/make/data/tzdata/northamerica b/jdk/make/data/tzdata/northamerica index 09b1b7fad9f..f8197462426 100644 --- a/jdk/make/data/tzdata/northamerica +++ b/jdk/make/data/tzdata/northamerica @@ -1258,10 +1258,19 @@ Zone America/Goose_Bay -4:01:40 - LMT 1884 # Happy Valley-Goose Bay # west Labrador, Nova Scotia, Prince Edward I -# From Paul Eggert (2006-03-22): +# From Brian Inglis (2015-07-20): +# From the historical weather station records available at: +# https://weatherspark.com/history/28351/1971/Sydney-Nova-Scotia-Canada +# Sydney shares the same time history as Glace Bay, so was +# likely to be the same across the island.... +# Sydney, as the capital and most populous location, or Cape Breton, would +# have been better names for the zone had we known this in 1996. + +# From Paul Eggert (2015-07-20): # Shanks & Pottenger write that since 1970 most of this region has been like # Halifax. Many locales did not observe peacetime DST until 1972; -# Glace Bay, NS is the largest that we know of. +# the Cape Breton area, represented by Glace Bay, is the largest we know of +# (Glace Bay was perhaps not the best name choice but no point changing now). # Shanks & Pottenger also write that Liverpool, NS was the only town # in Canada to observe DST in 1971 but not 1970; for now we'll assume # this is a typo. @@ -1819,13 +1828,13 @@ Zone America/Edmonton -7:33:52 - LMT 1906 Sep # Exact date in October unknown; Sunday October 1 is a reasonable guess. # 3. June 1918: switch to Pacific Daylight Time (GMT-7) # Exact date in June unknown; Sunday June 2 is a reasonable guess. -# note#1: +# note 1: # On Oct 27/1918 when daylight saving ended in the rest of Canada, # Creston did not change its clocks. -# note#2: +# note 2: # During WWII when the Federal Government legislated a mandatory clock change, # Creston did not oblige. -# note#3: +# note 3: # There is no guarantee that Creston will remain on Mountain Standard Time # (UTC-7) forever. # The subject was debated at least once this year by the town Council. diff --git a/jdk/make/data/tzdata/southamerica b/jdk/make/data/tzdata/southamerica index 6cf0b2bff37..082018691d6 100644 --- a/jdk/make/data/tzdata/southamerica +++ b/jdk/make/data/tzdata/southamerica @@ -154,7 +154,7 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # Timezone Law (which never was effectively applied) will (would?) be # in effect.... The article is at # http://ar.clarin.com/diario/2001-06-06/e-01701.htm -# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted +# ... The Law itself is "Ley No. 25155", sanctioned on 1999-08-25, enacted # 1999-09-17, and published 1999-09-21. The official publication is at: # http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF # Regretfully, you have to subscribe (and pay) for the on-line version.... @@ -198,15 +198,11 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # http://www.worldtimezone.com/dst_news/dst_news_argentina03.html # http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish) -# From Rodrigo Severo (2008-10-06): -# Here is some info available at a Gentoo bug related to TZ on Argentina's DST: -# ... -# ------- Comment #1 from [jmdocile] 2008-10-06 16:28 0000 ------- -# Hi, there is a problem with timezone-data-2008e and maybe with -# timezone-data-2008f -# Argentinian law [Number] 25.155 is no longer valid. +# From Juan Manuel Docile in https://bugs.gentoo.org/240339 (2008-10-07) +# via Rodrigo Severo: +# Argentinian law No. 25.155 is no longer valid. # http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm -# The new one is law [Number] 26.350 +# The new one is law No. 26.350 # http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm # So there is no summer time in Argentina for now. @@ -794,7 +790,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # [ and in a second message (same day): ] # I found the decree. # -# DECRETO No- 7.584, DE 13 DE OUTUBRO DE 2011 +# DECRETO No. 7.584, DE 13 DE OUTUBRO DE 2011 # Link : # http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6 @@ -1148,7 +1144,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # Conflicts between [1] and [2] were resolved as follows: # # - [1] says the 1910 transition was Jan 1, [2] says Jan 10 and cites -# Boletín Nº 1, Aviso Nº 1 (1910). Go with [2]. +# Boletín No. 1, Aviso No. 1 (1910). Go with [2]. # # - [1] says SMT was -4:42:45, [2] says Chile's official time from # 1916 to 1919 was -4:42:46.3, the meridian of Chile's National @@ -1156,7 +1152,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # Quinta Normal in Santiago. Go with [2], rounding it to -4:42:46. # # - [1] says the 1918 transition was Sep 1, [2] says Sep 10 and cites -# Boletín Nº 22, Aviso Nº 129/1918 (1918-08-23). Go with [2]. +# Boletín No. 22, Aviso No. 129/1918 (1918-08-23). Go with [2]. # # - [1] does not give times for transitions; assume they occur # at midnight mainland time, the current common practice. However, @@ -1556,7 +1552,7 @@ Rule Para 1997 only - Feb lastSun 0:00 0 - # (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27). Rule Para 1998 2001 - Mar Sun>=1 0:00 0 - # From Rives McDow (2002-02-28): -# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the +# A decree was issued in Paraguay (No. 16350) on 2002-02-26 that changed the # dst method to be from the first Sunday in September to the first Sunday in # April. Rule Para 2002 2004 - Apr Sun>=1 0:00 0 - @@ -1736,8 +1732,19 @@ Rule Uruguay 2005 only - Oct 9 2:00 1:00 S Rule Uruguay 2006 only - Mar 12 2:00 0 - # From Jesper Nørgaard Welen (2006-09-06): # http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF -Rule Uruguay 2006 max - Oct Sun>=1 2:00 1:00 S -Rule Uruguay 2007 max - Mar Sun>=8 2:00 0 - +# +# From Steffen Thorsen (2015-06-30): +# ... it looks like they will not be using DST the coming summer: +# http://www.elobservador.com.uy/gobierno-resolvio-que-no-habra-cambio-horario-verano-n656787 +# http://www.republica.com.uy/este-ano-no-se-modificara-el-huso-horario-en-uruguay/523760/ +# From Paul Eggert (2015-06-30): +# Apparently restaurateurs complained that DST caused people to go to the beach +# instead of out to dinner. +# From Pablo Camargo (2015-07-13): +# http://archivo.presidencia.gub.uy/sci/decretos/2015/06/cons_min_201.pdf +# [dated 2015-06-29; repeals Decree 311/006 dated 2006-09-04] +Rule Uruguay 2006 2014 - Oct Sun>=1 2:00 1:00 S +Rule Uruguay 2007 2015 - Mar Sun>=8 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 -3:44:44 - MMT 1920 May 1 # Montevideo MT @@ -1746,6 +1753,10 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # Venezuela # +# From Paul Eggert (2015-07-28): +# For the 1965 transition see Gaceta Oficial No. 27.619 (1964-12-15), p 205.533 +# http://www.pgr.gob.ve/dmdocuments/1964/27619.pdf +# # From John Stainforth (2007-11-28): # ... the change for Venezuela originally expected for 2007-12-31 has # been brought forward to 2007-12-09. The official announcement was @@ -1757,6 +1768,6 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time? - -4:30 - VET 1965 # Venezuela Time + -4:30 - VET 1965 Jan 1 0:00 # Venezuela T. -4:00 - VET 2007 Dec 9 3:00 -4:30 - VET diff --git a/jdk/make/data/tzdata/zone.tab b/jdk/make/data/tzdata/zone.tab index ffb6469676e..3fe4a3f2b57 100644 --- a/jdk/make/data/tzdata/zone.tab +++ b/jdk/make/data/tzdata/zone.tab @@ -129,8 +129,8 @@ BW -2439+02555 Africa/Gaborone BY +5354+02734 Europe/Minsk BZ +1730-08812 America/Belize CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador -CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI -CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971 +CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (peninsula), PEI +CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia (Cape Breton) CA +4606-06447 America/Moncton Atlantic Time - New Brunswick CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore diff --git a/jdk/make/lib/Lib-java.base.gmk b/jdk/make/lib/Lib-java.base.gmk index ef5f64aea09..c5949d57138 100644 --- a/jdk/make/lib/Lib-java.base.gmk +++ b/jdk/make/lib/Lib-java.base.gmk @@ -32,3 +32,4 @@ $(eval $(call FillCacheFind, $(wildcard $(JDK_TOPDIR)/src/java.base/*/native \ include CoreLibraries.gmk include NetworkingLibraries.gmk include NioLibraries.gmk +include SecurityLibraries.gmk diff --git a/jdk/make/lib/Lib-jdk.deploy.osx.gmk b/jdk/make/lib/Lib-jdk.deploy.osx.gmk index 51c56355b5b..7ed6f9eb0a8 100644 --- a/jdk/make/lib/Lib-jdk.deploy.osx.gmk +++ b/jdk/make/lib/Lib-jdk.deploy.osx.gmk @@ -80,7 +80,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx) -framework ApplicationServices \ -framework JavaNativeFoundation \ -framework JavaRuntimeSupport \ - -framework Security \ -framework SystemConfiguration \ $(LDFLAGS_JDKLIB_SUFFIX), \ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosx, \ diff --git a/jdk/make/lib/Lib-jdk.hprof.agent.gmk b/jdk/make/lib/Lib-jdk.hprof.agent.gmk deleted file mode 100644 index c6d1bbd1d04..00000000000 --- a/jdk/make/lib/Lib-jdk.hprof.agent.gmk +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright (c) 2011, 2015, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -include LibCommon.gmk - -################################################################################ - -BUILD_LIBHPROF_SRC := $(call FindSrcDirsForLib, jdk.hprof.agent, hprof) - -BUILD_LIBHPROF_CFLAGS := $(addprefix -I, $(BUILD_LIBHPROF_SRC)) \ - -I$(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo - -BUILD_LIBHPROF_LDFLAGS := - -LIBHPROF_OPTIMIZATION := HIGHEST -ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) - ifeq ($(ENABLE_DEBUG_SYMBOLS), true) - LIBHPROF_OPTIMIZATION := LOW - endif -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBHPROF, \ - LIBRARY := hprof, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBHPROF_SRC), \ - OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBHPROF_CFLAGS), \ - CFLAGS_debug := -DHPROF_LOGGING, \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libhprof/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := wsock32.lib winmm.lib advapi32.lib, \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_macosx := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lsocket -lnsl $(LIBDL) -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=hprof.dll" \ - -D "JDK_INTERNAL_NAME=hprof" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libhprof_jvmti, \ - DEBUG_SYMBOLS := true)) - -TARGETS += $(BUILD_LIBHPROF) - -################################################################################ - -LIBJAVA_CRW_DEMO_SRC := $(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo - -$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA_CRW_DEMO, \ - LIBRARY := java_crw_demo, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJAVA_CRW_DEMO_SRC), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(addprefix -I, $(LIBJAVA_CRW_DEMO_SRC)), \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjava_crw_demo/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=java_crw_demo.dll" \ - -D "JDK_INTERNAL_NAME=java_crw_demo" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava_crw_demo, \ - DEBUG_SYMBOLS := true)) - -TARGETS += $(BUILD_LIBJAVA_CRW_DEMO) - -################################################################################ diff --git a/jdk/make/lib/NioLibraries.gmk b/jdk/make/lib/NioLibraries.gmk index d78f4a7db97..b34818325f5 100644 --- a/jdk/make/lib/NioLibraries.gmk +++ b/jdk/make/lib/NioLibraries.gmk @@ -69,9 +69,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB) \ $(BUILD_LIBNIO_CFLAGS), \ - DISABLED_WARNINGS_gcc := type-limits, \ - DISABLED_WARNINGS_clang := tautological-compare, \ - DISABLED_WARNINGS_microsoft := 4244 4996, \ MAPFILE := $(BUILD_LIBNIO_MAPFILE), \ LDFLAGS := $(LDFLAGS_JDKLIB) $(BUILD_LIBNIO_LDFLAGS) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff --git a/jdk/make/lib/SecurityLibraries.gmk b/jdk/make/lib/SecurityLibraries.gmk new file mode 100644 index 00000000000..9778137ae1f --- /dev/null +++ b/jdk/make/lib/SecurityLibraries.gmk @@ -0,0 +1,63 @@ +# +# Copyright (c) 2015, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +include LibCommon.gmk + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + ################################################################################ + + LIBOSXSECURITY_DIRS := $(JDK_TOPDIR)/src/java.base/macosx/native/libosxsecurity + LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \ + $(LIBJAVA_HEADER_FLAGS) \ + -I$(SUPPORT_OUTPUTDIR)/headers/java.base \ + + $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \ + LIBRARY := osxsecurity, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBOSXSECURITY_DIRS), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBOSXSECURITY_CFLAGS), \ + DISABLED_WARNINGS_clang := deprecated-declarations, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_macosx := \ + -fobjc-link-runtime \ + -framework JavaNativeFoundation \ + -framework CoreServices \ + -framework Security \ + $(LDFLAGS_JDKLIB_SUFFIX), \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA) + + TARGETS += $(BUILD_LIBOSXSECURITY) + + ################################################################################ + +endif diff --git a/jdk/make/mapfiles/libhprof/mapfile-vers b/jdk/make/mapfiles/libhprof/mapfile-vers deleted file mode 100644 index 1873c4f210a..00000000000 --- a/jdk/make/mapfiles/libhprof/mapfile-vers +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2003, 2013, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -# Define public interface. - -SUNWprivate_1.1 { - global: - Agent_OnLoad; - Agent_OnUnload; - local: - *; -}; diff --git a/jdk/make/mapfiles/libjava_crw_demo/mapfile-vers b/jdk/make/mapfiles/libjava_crw_demo/mapfile-vers deleted file mode 100644 index b9b31f7b106..00000000000 --- a/jdk/make/mapfiles/libjava_crw_demo/mapfile-vers +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2004, 2013, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -# Define public interface. - -SUNWprivate_1.1 { - global: - java_crw_demo; - java_crw_demo_classname; - local: - *; -}; diff --git a/jdk/make/src/classes/build/tools/module/boot.modules b/jdk/make/src/classes/build/tools/module/boot.modules index b77e400e4ed..6830c6c8335 100644 --- a/jdk/make/src/classes/build/tools/module/boot.modules +++ b/jdk/make/src/classes/build/tools/module/boot.modules @@ -19,7 +19,6 @@ java.xml.crypto jdk.charsets jdk.deploy jdk.deploy.osx -jdk.hprof.agent jdk.httpserver jdk.jfr jdk.management diff --git a/jdk/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c b/jdk/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c new file mode 100644 index 00000000000..93347bd8c20 --- /dev/null +++ b/jdk/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include "jni.h" + +#include "ProcessHandleImpl_unix.h" + +#include + +/* + * Implementation of native ProcessHandleImpl functions for AIX. + * See ProcessHandleImpl_unix.c for more details. + */ + +void os_initNative(JNIEnv *env, jclass clazz) {} + +jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, + jlongArray jparentArray, jlongArray jstimesArray) { + return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray); +} + +pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { + return unix_getParentPidAndTimings(env, pid, total, start); +} + +void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { + unix_getCmdlineAndUserInfo(env, jinfo, pid); +} diff --git a/jdk/src/java.base/linux/native/libjava/ProcessHandleImpl_linux.c b/jdk/src/java.base/linux/native/libjava/ProcessHandleImpl_linux.c new file mode 100644 index 00000000000..dcd6db86865 --- /dev/null +++ b/jdk/src/java.base/linux/native/libjava/ProcessHandleImpl_linux.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include "jni.h" +#include "jni_util.h" +#include "java_lang_ProcessHandleImpl.h" +#include "java_lang_ProcessHandleImpl_Info.h" + +#include "ProcessHandleImpl_unix.h" + + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * Implementation of native ProcessHandleImpl functions for Linux. + * See ProcessHandleImpl_unix.c for more details. + */ + +/* Signatures for internal OS specific functions. */ +static long long getBoottime(JNIEnv *env); + +/* A static offset in milliseconds since boot. */ +static long long bootTime_ms; +static long clock_ticks_per_second; +static int pageSize; + +void os_initNative(JNIEnv *env, jclass clazz) { + bootTime_ms = getBoottime(env); + clock_ticks_per_second = sysconf(_SC_CLK_TCK); + pageSize = sysconf(_SC_PAGESIZE); +} + +jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, + jlongArray jparentArray, jlongArray jstimesArray) { + return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray); +} + +/** + * Read /proc//stat and return the ppid, total cputime and start time. + * -1 is fail; >= 0 is parent pid + * 'total' will contain the running time of 'pid' in nanoseconds. + * 'start' will contain the start time of 'pid' in milliseconds since epoch. + */ +pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, + jlong *totalTime, jlong* startTime) { + FILE* fp; + char buffer[2048]; + int statlen; + char fn[32]; + char* s; + int parentPid; + long unsigned int utime = 0; // clock tics + long unsigned int stime = 0; // clock tics + long long unsigned int start = 0; // microseconds + + /* + * Try to stat and then open /proc/%d/stat + */ + snprintf(fn, sizeof fn, "/proc/%d/stat", pid); + + fp = fopen(fn, "r"); + if (fp == NULL) { + return -1; // fail, no such /proc/pid/stat + } + + /* + * The format is: pid (command) state ppid ... + * As the command could be anything we must find the right most + * ")" and then skip the white spaces that follow it. + */ + statlen = fread(buffer, 1, (sizeof buffer - 1), fp); + fclose(fp); + if (statlen < 0) { + return -1; // parent pid is not available + } + + buffer[statlen] = '\0'; + s = strchr(buffer, '('); + if (s == NULL) { + return -1; // parent pid is not available + } + // Found start of command, skip to end + s++; + s = strrchr(s, ')'); + if (s == NULL) { + return -1; // parent pid is not available + } + s++; + + // Scan the needed fields from status, retaining only ppid(4), + // utime (14), stime(15), starttime(22) + if (4 != sscanf(s, " %*c %d %*d %*d %*d %*d %*d %*u %*u %*u %*u %lu %lu %*d %*d %*d %*d %*d %*d %llu", + &parentPid, &utime, &stime, &start)) { + return 0; // not all values parsed; return error + } + + *totalTime = (utime + stime) * (jlong)(1000000000 / clock_ticks_per_second); + + *startTime = bootTime_ms + ((start * 1000) / clock_ticks_per_second); + + return parentPid; +} + +void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { + int fd; + int cmdlen = 0; + char *cmdline = NULL, *cmdEnd = NULL; // used for command line args and exe + char *args = NULL; + jstring cmdexe = NULL; + char fn[32]; + struct stat stat_buf; + + /* + * Try to open /proc//cmdline + */ + snprintf(fn, sizeof fn, "/proc/%d/cmdline", pid); + if ((fd = open(fn, O_RDONLY)) < 0) { + return; + } + + if (fstat(fd, &stat_buf) == 0) { + unix_getUserInfo(env, jinfo, stat_buf.st_uid); + } + + do { // Block to break out of on errors + int i, truncated = 0; + int count; + char *s; + + /* + * The path name read by readlink() is limited to PATH_MAX characters. + * The content of /proc//cmdline is limited to PAGE_SIZE characters. + */ + cmdline = (char*)malloc((PATH_MAX > pageSize ? PATH_MAX : pageSize) + 1); + if (cmdline == NULL) { + break; + } + + /* + * On Linux, the full path to the executable command is the link in + * /proc//exe. But it is only readable for processes we own. + */ + snprintf(fn, sizeof fn, "/proc/%d/exe", pid); + if ((cmdlen = readlink(fn, cmdline, PATH_MAX)) > 0) { + // null terminate and create String to store for command + cmdline[cmdlen] = '\0'; + cmdexe = JNU_NewStringPlatform(env, cmdline); + (*env)->ExceptionClear(env); // unconditionally clear any exception + } + + /* + * The command-line arguments appear as a set of strings separated by + * null bytes ('\0'), with a further null byte after the last + * string. The last string is only null terminated if the whole command + * line is not exceeding (PAGE_SIZE - 1) characters. + */ + cmdlen = 0; + s = cmdline; + while ((count = read(fd, s, pageSize - cmdlen)) > 0) { + cmdlen += count; + s += count; + } + if (count < 0) { + break; + } + // We have to null-terminate because the process may have changed argv[] + // or because the content in /proc//cmdline is truncated. + cmdline[cmdlen] = '\0'; + if (cmdlen == pageSize && cmdline[pageSize - 1] != '\0') { + truncated = 1; + } else if (cmdlen == 0) { + // /proc//cmdline was empty. This usually happens for kernel processes + // like '[kthreadd]'. We could try to read /proc//comm in the future. + } + if (cmdlen > 0 && (cmdexe == NULL || truncated)) { + // We have no exact command or the arguments are truncated. + // In this case we save the command line from /proc//cmdline. + args = (char*)malloc(pageSize + 1); + if (args != NULL) { + memcpy(args, cmdline, cmdlen + 1); + for (i = 0; i < cmdlen; i++) { + if (args[i] == '\0') { + args[i] = ' '; + } + } + } + } + i = 0; + if (!truncated) { + // Count the arguments + cmdEnd = &cmdline[cmdlen]; + for (s = cmdline; *s != '\0' && (s < cmdEnd); i++) { + s += strnlen(s, (cmdEnd - s)) + 1; + } + } + unix_fillArgArray(env, jinfo, i, cmdline, cmdEnd, cmdexe, args); + } while (0); + + if (cmdline != NULL) { + free(cmdline); + } + if (args != NULL) { + free(args); + } + if (fd >= 0) { + close(fd); + } +} + +/** + * Read the boottime from /proc/stat. + */ +static long long getBoottime(JNIEnv *env) { + FILE *fp; + char *line = NULL; + size_t len = 0; + long long bootTime = 0; + + fp = fopen("/proc/stat", "r"); + if (fp == NULL) { + return -1; + } + + while (getline(&line, &len, fp) != -1) { + if (sscanf(line, "btime %llu", &bootTime) == 1) { + break; + } + } + free(line); + + if (fp != 0) { + fclose(fp); + } + + return bootTime * 1000; +} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/AppleProvider.java b/jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java similarity index 100% rename from jdk/src/jdk.deploy.osx/macosx/classes/apple/security/AppleProvider.java rename to jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java b/jdk/src/java.base/macosx/classes/apple/security/KeychainStore.java similarity index 99% rename from jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java rename to jdk/src/java.base/macosx/classes/apple/security/KeychainStore.java index 36f146b9ba7..42b312196cd 100644 --- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java +++ b/jdk/src/java.base/macosx/classes/apple/security/KeychainStore.java @@ -106,7 +106,7 @@ public final class KeychainStore extends KeyStoreSpi { AccessController.doPrivileged( new PrivilegedAction() { public Void run() { - System.loadLibrary("osx"); + System.loadLibrary("osxsecurity"); return null; } }); diff --git a/jdk/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c b/jdk/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c index 98f62b3e8f1..bc64cd1ae62 100644 --- a/jdk/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c +++ b/jdk/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c @@ -28,6 +28,8 @@ #include "java_lang_ProcessHandleImpl.h" #include "java_lang_ProcessHandleImpl_Info.h" +#include "ProcessHandleImpl_unix.h" + #include #include #include @@ -38,144 +40,15 @@ #include /** - * Implementations of ProcessHandleImpl functions for MAC OS X; - * are NOT common to all Unix variants. + * Implementation of native ProcessHandleImpl functions for MAC OS X. + * See ProcessHandleImpl_unix.c for more details. */ -static void getStatInfo(JNIEnv *env, jobject jinfo, pid_t pid); -static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid); - -/* - * Common Unix function to lookup the uid and return the user name. - */ -extern jstring uidToUser(JNIEnv* env, uid_t uid); - -/* Field id for jString 'command' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_commandID; - -/* Field id for jString[] 'arguments' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_argumentsID; - -/* Field id for jlong 'totalTime' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_totalTimeID; - -/* Field id for jlong 'startTime' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_startTimeID; - -/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_userID; - -/* static value for clock ticks per second. */ -static long clock_ticks_per_second; - -/************************************************************** - * Static method to initialize field IDs and the ticks per second rate. - * - * Class: java_lang_ProcessHandleImpl_Info - * Method: initIDs - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) { - CHECK_NULL(ProcessHandleImpl_Info_commandID = - (*env)->GetFieldID(env, clazz, "command", "Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_argumentsID = - (*env)->GetFieldID(env, clazz, "arguments", "[Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = - (*env)->GetFieldID(env, clazz, "totalTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_startTimeID = - (*env)->GetFieldID(env, clazz, "startTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_userID = - (*env)->GetFieldID(env, clazz, "user", "Ljava/lang/String;")); -} -/************************************************************** - * Static method to initialize the ticks per second rate. - * - * Class: java_lang_ProcessHandleImpl - * Method: initNative - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) { - clock_ticks_per_second = sysconf(_SC_CLK_TCK); -} - -/* - * Check if a process is alive. - * Return the start time (ms since 1970) if it is available. - * If the start time is not available return 0. - * If the pid is invalid, return -1. - * - * Class: java_lang_ProcessHandleImpl - * Method: isAlive0 - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jobject obj, jlong jpid) { - pid_t pid = (pid_t) jpid; - struct kinfo_proc kp; - size_t bufSize = sizeof kp; - - // Read the process info for the specific pid - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - - if (sysctl(mib, 4, &kp, &bufSize, NULL, 0) < 0) { - return (errno == EINVAL) ? -1 : 0; - } else { - return (bufSize == 0) ? -1 : - (jlong) (kp.kp_proc.p_starttime.tv_sec * 1000 - + kp.kp_proc.p_starttime.tv_usec / 1000); - } -} - -/* - * Returns the parent pid of the requested pid. - * - * Class: java_lang_ProcessHandleImpl - * Method: parent0 - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, - jobject obj, - jlong jpid, - jlong startTime) { - pid_t pid = (pid_t) jpid; - pid_t ppid = -1; - - if (pid == getpid()) { - ppid = getppid(); - } else { - const pid_t pid = (pid_t) jpid; - struct kinfo_proc kp; - size_t bufSize = sizeof kp; - - // Read the process info for the specific pid - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - if (sysctl(mib, 4, &kp, &bufSize, NULL, 0) < 0) { - JNU_ThrowByNameWithLastError(env, - "java/lang/RuntimeException", "sysctl failed"); - return -1; - } - // If the buffer is full and for the pid requested then check the start - if (bufSize > 0 && kp.kp_proc.p_pid == pid) { - jlong start = (jlong) (kp.kp_proc.p_starttime.tv_sec * 1000 - + kp.kp_proc.p_starttime.tv_usec / 1000); - if (start == startTime || start == 0 || startTime == 0) { - ppid = kp.kp_eproc.e_ppid; - } - } - } - return (jlong) ppid; -} +void os_initNative(JNIEnv *env, jclass clazz) {} /* * Returns the children of the requested pid and optionally each parent. * - * Class: java_lang_ProcessHandleImpl - * Method: getProcessPids0 - * Signature: (J[J[J)I - * * Use sysctl to accumulate any process whose parent pid is zero or matches. * The resulting pids are stored into the array of longs. * The number of pids is returned if they all fit. @@ -183,13 +56,8 @@ Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, * If the array is too short, excess pids are not stored and * the desired length is returned. */ -JNIEXPORT jint JNICALL -Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, - jclass clazz, - jlong jpid, - jlongArray jarray, - jlongArray jparentArray, - jlongArray jstimesArray) { +jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, + jlongArray jparentArray, jlongArray jstimesArray) { jlong* pids = NULL; jlong* ppids = NULL; jlong* stimes = NULL; @@ -303,35 +171,17 @@ Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, return count; } -/************************************************************** - * Implementation of ProcessHandleImpl_Info native methods. - */ - -/* - * Fill in the Info object from the OS information about the process. - * - * Class: java_lang_ProcessHandleImpl - * Method: info0 - * Signature: (J)I - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env, - jobject jinfo, - jlong jpid) { - pid_t pid = (pid_t) jpid; - getStatInfo(env, jinfo, pid); - getCmdlineInfo(env, jinfo, pid); -} - /** - * Read /proc//stat and fill in the fields of the Info object. - * The executable name, plus the user, system, and start times are gathered. + * Use sysctl and return the ppid, total cputime and start time. + * Return: -1 is fail; >= 0 is parent pid + * 'total' will contain the running time of 'pid' in nanoseconds. + * 'start' will contain the start time of 'pid' in milliseconds since epoch. */ -static void getStatInfo(JNIEnv *env, jobject jinfo, pid_t jpid) { - jlong totalTime; // nanoseconds - unsigned long long startTime; // milliseconds +pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t jpid, + jlong *totalTime, jlong *startTime) { const pid_t pid = (pid_t) jpid; + pid_t ppid = -1; struct kinfo_proc kp; size_t bufSize = sizeof kp; @@ -339,92 +189,70 @@ static void getStatInfo(JNIEnv *env, jobject jinfo, pid_t jpid) { int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; if (sysctl(mib, 4, &kp, &bufSize, NULL, 0) < 0) { - if (errno == EINVAL) { - return; - } else { - JNU_ThrowByNameWithLastError(env, - "java/lang/RuntimeException", "sysctl failed"); - } - return; + JNU_ThrowByNameWithLastError(env, + "java/lang/RuntimeException", "sysctl failed"); + return -1; + } + if (bufSize > 0 && kp.kp_proc.p_pid == pid) { + *startTime = (jlong) (kp.kp_proc.p_starttime.tv_sec * 1000 + + kp.kp_proc.p_starttime.tv_usec / 1000); + ppid = kp.kp_eproc.e_ppid; } - - // Convert the UID to the username - jstring name = NULL; - CHECK_NULL((name = uidToUser(env, kp.kp_eproc.e_ucred.cr_uid))); - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, name); - JNU_CHECK_EXCEPTION(env); - - startTime = kp.kp_proc.p_starttime.tv_sec * 1000 + - kp.kp_proc.p_starttime.tv_usec / 1000; - - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime); - JNU_CHECK_EXCEPTION(env); // Get cputime if for current process if (pid == getpid()) { struct rusage usage; - if (getrusage(RUSAGE_SELF, &usage) != 0) { - return; + if (getrusage(RUSAGE_SELF, &usage) == 0) { + jlong microsecs = + usage.ru_utime.tv_sec * 1000 * 1000 + usage.ru_utime.tv_usec + + usage.ru_stime.tv_sec * 1000 * 1000 + usage.ru_stime.tv_usec; + *totalTime = microsecs * 1000; } - jlong microsecs = - usage.ru_utime.tv_sec * 1000 * 1000 + usage.ru_utime.tv_usec + - usage.ru_stime.tv_sec * 1000 * 1000 + usage.ru_stime.tv_usec; - totalTime = microsecs * 1000; - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime); - JNU_CHECK_EXCEPTION(env); } + + return ppid; + } /** - * Construct the argument array by parsing the arguments from the sequence of arguments. + * Return the uid of a process or -1 on error */ -static int fillArgArray(JNIEnv *env, jobject jinfo, int nargs, - const char *cp, const char *argsEnd) { - jstring str = NULL; - jobject argsArray; - int i; +static uid_t getUID(pid_t pid) { + struct kinfo_proc kp; + size_t bufSize = sizeof kp; - if (nargs < 1) { - return 0; - } - // Create a String array for nargs-1 elements - CHECK_NULL_RETURN((argsArray = (*env)->NewObjectArray(env, - nargs - 1, JNU_ClassString(env), NULL)), -1); + // Read the process info for the specific pid + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - for (i = 0; i < nargs - 1; i++) { - // skip to the next argument; omits arg[0] - cp += strnlen(cp, (argsEnd - cp)) + 1; - - if (cp > argsEnd || *cp == '\0') { - return -2; // Off the end pointer or an empty argument is an error + if (sysctl(mib, 4, &kp, &bufSize, NULL, 0) == 0) { + if (bufSize > 0 && kp.kp_proc.p_pid == pid) { + return kp.kp_eproc.e_ucred.cr_uid; } - - CHECK_NULL_RETURN((str = JNU_NewStringPlatform(env, cp)), -1); - - (*env)->SetObjectArrayElement(env, argsArray, i, str); - JNU_CHECK_EXCEPTION_RETURN(env, -3); } - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_argumentsID, argsArray); - JNU_CHECK_EXCEPTION_RETURN(env, -4); - return 0; + return (uid_t)-1; } /** * Retrieve the command and arguments for the process and store them * into the Info object. */ -static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { +void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { int mib[3], maxargs, nargs, i; size_t size; char *args, *cp, *sp, *np; + // Get the UID first. This is done here because it is cheap to do it here + // on other platforms like Linux/Solaris/AIX where the uid comes from the + // same source like the command line info. + unix_getUserInfo(env, jinfo, getUID(pid)); + // Get the maximum size of the arguments mib[0] = CTL_KERN; mib[1] = KERN_ARGMAX; size = sizeof(maxargs); if (sysctl(mib, 2, &maxargs, &size, NULL, 0) == -1) { JNU_ThrowByNameWithLastError(env, - "java/lang/RuntimeException", "sysctl failed"); + "java/lang/RuntimeException", "sysctl failed"); return; } @@ -437,7 +265,7 @@ static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { do { // a block to break out of on error char *argsEnd; - jstring str = NULL; + jstring cmdexe = NULL; mib[0] = CTL_KERN; mib[1] = KERN_PROCARGS2; @@ -445,7 +273,7 @@ static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { size = (size_t) maxargs; if (sysctl(mib, 3, args, &size, NULL, 0) == -1) { if (errno != EINVAL) { - JNU_ThrowByNameWithLastError(env, + JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", "sysctl failed"); } break; @@ -456,11 +284,7 @@ static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { argsEnd = &args[size]; // Store the command executable path - if ((str = JNU_NewStringPlatform(env, cp)) == NULL) { - break; - } - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, str); - if ((*env)->ExceptionCheck(env)) { + if ((cmdexe = JNU_NewStringPlatform(env, cp)) == NULL) { break; } @@ -471,7 +295,7 @@ static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { } } - fillArgArray(env, jinfo, nargs, cp, argsEnd); + unix_fillArgArray(env, jinfo, nargs, cp, argsEnd, cmdexe, NULL); } while (0); // Free the arg buffer free(args); diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m b/jdk/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m similarity index 100% rename from jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m rename to jdk/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m diff --git a/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java b/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java index 983d855cfda..980870c5bb7 100644 --- a/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java @@ -224,9 +224,35 @@ public interface ProcessHandle extends Comparable { */ public Optional command(); + /** + * Returns the command line of the process. + *

+ * If {@link #command command()} and {@link #arguments arguments()} return + * non-empty optionals, this is simply a convenience method which concatenates + * the values of the two functions separated by spaces. Otherwise it will return a + * best-effort, platform dependent representation of the command line. + * + * @apiNote Note that the returned executable pathname and the + * arguments may be truncated on some platforms due to system + * limitations. + *

+ * The executable pathname may contain only the + * name of the executable without the full path information. + * It is undecideable whether white space separates different + * arguments or is part of a single argument. + * + * @return an {@code Optional} of the command line + * of the process + */ + public Optional commandLine(); + /** * Returns an array of Strings of the arguments of the process. * + * @apiNote On some platforms, native applications are free to change + * the arguments array after startup and this method may only + * show the changed values. + * * @return an {@code Optional} of the arguments of the process */ public Optional arguments(); diff --git a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java index b7295bc5971..b3d03683e4a 100644 --- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java @@ -472,7 +472,7 @@ final class ProcessHandleImpl implements ProcessHandle { /** * Implementation of ProcessHandle.Info. * Information snapshot about a process. - * The attributes of a process vary by operating system and not available + * The attributes of a process vary by operating system and are not available * in all implementations. Additionally, information about other processes * is limited by the operating system privileges of the process making the request. * If a value is not available, either a {@code null} or {@code -1} is stored. @@ -496,6 +496,7 @@ final class ProcessHandleImpl implements ProcessHandle { private native void info0(long pid); String command; + String commandLine; String[] arguments; long startTime; long totalTime; @@ -503,6 +504,7 @@ final class ProcessHandleImpl implements ProcessHandle { Info() { command = null; + commandLine = null; arguments = null; startTime = -1L; totalTime = -1L; @@ -538,6 +540,15 @@ final class ProcessHandleImpl implements ProcessHandle { return Optional.ofNullable(command); } + @Override + public Optional commandLine() { + if (command != null && arguments != null) { + return Optional.of(command + " " + String.join(" ", arguments)); + } else { + return Optional.ofNullable(commandLine); + } + } + @Override public Optional arguments() { return Optional.ofNullable(arguments); @@ -580,6 +591,11 @@ final class ProcessHandleImpl implements ProcessHandle { sb.append("args: "); sb.append(Arrays.toString(arguments)); } + if (commandLine != null) { + if (sb.length() != 0) sb.append(", "); + sb.append("cmdLine: "); + sb.append(commandLine); + } if (startTime > 0) { if (sb.length() != 0) sb.append(", "); sb.append("startTime: "); diff --git a/jdk/src/java.base/share/classes/java/lang/Shutdown.java b/jdk/src/java.base/share/classes/java/lang/Shutdown.java index 7ce64ffae18..e13a7c40f0e 100644 --- a/jdk/src/java.base/share/classes/java/lang/Shutdown.java +++ b/jdk/src/java.base/share/classes/java/lang/Shutdown.java @@ -86,10 +86,10 @@ class Shutdown { * to be registered even if the shutdown is in progress. * @params hook the hook to be registered * - * @throw IllegalStateException - * if registerShutdownInProgress is false and shutdown is in progress; or - * if registerShutdownInProgress is true and the shutdown process - * already passes the given slot + * @throws IllegalStateException + * if registerShutdownInProgress is false and shutdown is in progress; or + * if registerShutdownInProgress is true and the shutdown process + * already passes the given slot */ static void add(int slot, boolean registerShutdownInProgress, Runnable hook) { synchronized (lock) { diff --git a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java index 9d1df2de21e..bf68b61b36f 100644 --- a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java +++ b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java @@ -65,10 +65,13 @@ public class ReferenceQueue { return false; } assert queue == this; - r.queue = ENQUEUED; r.next = (head == null) ? r : head; head = r; queueLength++; + // Update r.queue *after* adding to list, to avoid race + // with concurrent enqueued checks and fast-path poll(). + // Volatiles ensure ordering. + r.queue = ENQUEUED; if (r instanceof FinalReference) { sun.misc.VM.addFinalRefCount(1); } @@ -80,10 +83,13 @@ public class ReferenceQueue { private Reference reallyPoll() { /* Must hold lock */ Reference r = head; if (r != null) { + r.queue = NULL; + // Update r.queue *before* removing from list, to avoid + // race with concurrent enqueued checks and fast-path + // poll(). Volatiles ensure ordering. @SuppressWarnings("unchecked") Reference rn = r.next; head = (rn == r) ? null : rn; - r.queue = NULL; r.next = r; queueLength--; if (r instanceof FinalReference) { diff --git a/jdk/src/java.base/share/classes/java/net/ContentHandler.java b/jdk/src/java.base/share/classes/java/net/ContentHandler.java index 47bc21699f5..690cbd9b2bd 100644 --- a/jdk/src/java.base/share/classes/java/net/ContentHandler.java +++ b/jdk/src/java.base/share/classes/java/net/ContentHandler.java @@ -47,7 +47,7 @@ import java.io.IOException; * If no content handler could be {@linkplain URLConnection#getContent() found}, * URLConnection will look for a content handler in a user-definable set of places. * Users can define a vertical-bar delimited set of class prefixes - * to search through by defining the {@value java.net.URLConnection#contentPathProp} + * to search through by defining the {@link java.net.URLConnection#contentPathProp} * property. The class name must be of the form: *

* {package-prefix}.{major}.{minor} diff --git a/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java b/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java index 87fce160fb2..2bdfdc25102 100644 --- a/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java +++ b/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java @@ -206,7 +206,7 @@ public class InetSocketAddress * @param hostname the Host name * @param port The port number * @throws IllegalArgumentException if the port parameter is outside the range - * of valid port values, or if the hostname parameter is null. + * of valid port values, or if the hostname parameter is {@code null}. * @throws SecurityException if a security manager is present and * permission to resolve the host name is * denied. @@ -244,7 +244,7 @@ public class InetSocketAddress * @param port The port number * @throws IllegalArgumentException if the port parameter is outside * the range of valid port values, or if the hostname - * parameter is null. + * parameter is {@code null}. * @see #isUnresolved() * @return a {@code InetSocketAddress} representing the unresolved * socket address diff --git a/jdk/src/java.base/share/classes/java/net/spi/package-info.java b/jdk/src/java.base/share/classes/java/net/spi/package-info.java index 3be4ac8231f..06ddeccb00d 100644 --- a/jdk/src/java.base/share/classes/java/net/spi/package-info.java +++ b/jdk/src/java.base/share/classes/java/net/spi/package-info.java @@ -24,7 +24,7 @@ */ /** - * Service-provider classes for the {@link java.net} package. + * Service-provider classes for the {@link java.net} package. * *

Only developers who are defining new URL stream handler providers * should need to make direct use of this package. diff --git a/jdk/src/java.base/share/classes/java/nio/Buffer.java b/jdk/src/java.base/share/classes/java/nio/Buffer.java index 8669242c195..51436dc2f1b 100644 --- a/jdk/src/java.base/share/classes/java/nio/Buffer.java +++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java @@ -215,8 +215,8 @@ public abstract class Buffer { * {@code put(src)} when the parameter is the {@code Buffer} on which the * method is being invoked. * - * @returns IllegalArgumentException - * With a message indicating equal source and target buffers + * @return IllegalArgumentException + * With a message indicating equal source and target buffers */ static IllegalArgumentException createSameBufferException() { return new IllegalArgumentException("The source buffer is this buffer"); diff --git a/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java b/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java index 1e5072af48a..65ede7a2a83 100644 --- a/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java +++ b/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java @@ -618,9 +618,12 @@ public abstract class KeyStoreSpi { * @throws IOException if there is an I/O problem with the keystore data. * @throws NullPointerException if stream is {@code null}. * - * @since 1.9 + * @since 9 */ public boolean engineProbe(InputStream stream) throws IOException { + if (stream == null) { + throw new NullPointerException("input stream must not be null"); + } return false; } } diff --git a/jdk/src/java.base/share/classes/java/util/Formatter.java b/jdk/src/java.base/share/classes/java/util/Formatter.java index 14909eca9ad..d8fc7e60ecd 100644 --- a/jdk/src/java.base/share/classes/java/util/Formatter.java +++ b/jdk/src/java.base/share/classes/java/util/Formatter.java @@ -273,6 +273,10 @@ import sun.misc.FormattedFloatingDecimal; * * * + *

For category General, Character, Numberic, + * Integral and Date/Time conversion, unless otherwise specified, + * if the argument arg is {@code null}, then the result is "{@code null}". + * *

The following table summarizes the supported conversions. Conversions * denoted by an upper-case character (i.e. {@code 'B'}, {@code 'H'}, * {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'}, {@code 'G'}, @@ -301,14 +305,12 @@ import sun.misc.FormattedFloatingDecimal; * * {@code 'h'}, {@code 'H'} * general - * If the argument arg is {@code null}, then the result is - * "{@code null}". Otherwise, the result is obtained by invoking + * The result is obtained by invoking * {@code Integer.toHexString(arg.hashCode())}. * * {@code 's'}, {@code 'S'} * general - * If the argument arg is {@code null}, then the result is - * "{@code null}". If arg implements {@link Formattable}, then + * If arg implements {@link Formattable}, then * {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the * result is obtained by invoking {@code arg.toString()}. * @@ -683,6 +685,10 @@ import sun.misc.FormattedFloatingDecimal; * methods such as {@link String#format(String,Object...) String.format} and * {@link java.io.PrintStream#printf(String,Object...) PrintStream.printf}. * + *

For category General, Character, Numberic, + * Integral and Date/Time conversion, unless otherwise specified, + * if the argument arg is {@code null}, then the result is "{@code null}". + * *

Conversions denoted by an upper-case character (i.e. {@code 'B'}, * {@code 'H'}, {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'}, * {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the @@ -722,9 +728,8 @@ import sun.misc.FormattedFloatingDecimal; * '\u0068' * Produces a string representing the hash code value of the object. * - *

If the argument, arg is {@code null}, then the - * result is "{@code null}". Otherwise, the result is obtained - * by invoking {@code Integer.toHexString(arg.hashCode())}. + *

The result is obtained by invoking + * {@code Integer.toHexString(arg.hashCode())}. * *

If the {@code '#'} flag is given, then a {@link * FormatFlagsConversionMismatchException} will be thrown. @@ -737,8 +742,7 @@ import sun.misc.FormattedFloatingDecimal; * '\u0073' * Produces a string. * - *

If the argument is {@code null}, then the result is - * "{@code null}". If the argument implements {@link Formattable}, then + *

If the argument implements {@link Formattable}, then * its {@link Formattable#formatTo formatTo} method is invoked. * Otherwise, the result is obtained by invoking the argument's * {@code toString()} method. diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java index ebdae178fd8..e5bd2b78259 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java @@ -39,7 +39,7 @@ import sun.security.jca.GetInstance; *

Every implementation of the Java platform is required to support the * following standard {@code SSLContext} protocol: *

    - *
  • TLSv1
  • + *
  • {@code TLSv1}
  • *
* This protocol is described in the diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLException.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLException.java index 98d8bd3cbf6..f5a1a87423f 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLException.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLException.java @@ -53,13 +53,13 @@ class SSLException extends IOException } /** - * Creates a SSLException with the specified + * Creates a {@code SSLException} with the specified * detail message and cause. * * @param message the detail message (which is saved for later retrieval * by the {@link #getMessage()} method). * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is + * {@link #getCause()} method). (A {@code null} value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.5 @@ -70,13 +70,13 @@ class SSLException extends IOException } /** - * Creates a SSLException with the specified cause - * and a detail message of (cause==null ? null : cause.toString()) + * Creates a {@code SSLException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} * (which typically contains the class and detail message of - * cause). + * {@code cause}). * * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is + * {@link #getCause()} method). (A {@code null} value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.5 diff --git a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageFileCreator.java b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageFileCreator.java index 6bb482a208f..cbdc93fdde9 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageFileCreator.java +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageFileCreator.java @@ -139,6 +139,7 @@ public final class ImageFileCreator { } public static void recreateJimage(Path jimageFile, + String jdataName, Set archives, Map> modulePackages) throws IOException { @@ -159,12 +160,7 @@ public final class ImageFileCreator { throw new UnsupportedOperationException("Not supported, no external file " + "in a jimage file"); }, entriesForModule, order); - String fileName = jimageFile.getFileName().toString(); - if (fileName.endsWith(IMAGE_EXT)) { - fileName = fileName.substring(0, fileName.length() - - BasicImageWriter.IMAGE_EXT.length()); - } - generateJImage(jimageFile, fileName, resources, order); + generateJImage(jimageFile, jdataName, resources, order); } private void writeImage(String fileName, diff --git a/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java b/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java index 06deae65817..bbdb1cde5bd 100644 --- a/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java +++ b/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java @@ -52,7 +52,7 @@ public abstract class FtpClientProvider { * Initializes a new instance of this class. * * @throws SecurityException if a security manager is installed and it denies - * {@link RuntimePermission}("ftpClientProvider") + * {@link RuntimePermission}{@code ("ftpClientProvider")} */ protected FtpClientProvider() { SecurityManager sm = System.getSecurityManager(); @@ -108,7 +108,7 @@ public abstract class FtpClientProvider { *
    * *
  1. If the system property - * java.net.FtpClientProvider is defined then it is + * {@code java.net.FtpClientProvider} is defined then it is * taken to be the fully-qualified name of a concrete provider class. * The class is loaded and instantiated; if this process fails then an * unspecified unchecked error or exception is thrown.

  2. @@ -116,8 +116,8 @@ public abstract class FtpClientProvider { *
  3. If a provider class has been installed in a jar file that is * visible to the system class loader, and that jar file contains a * provider-configuration file named - * java.net.FtpClientProvider in the resource - * directory META-INF/services, then the first class name + * {@code java.net.FtpClientProvider} in the resource + * directory {@code META-INF/services}, then the first class name * specified in that file is taken. The class is loaded and * instantiated; if this process fails then an unspecified unchecked error or exception is * thrown.

  4. diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 9e2a49a0380..74326af85e0 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -191,7 +191,7 @@ class NegotiateAuthentication extends AuthenticationInfo { /** * return the first token. - * @returns the token + * @return the token * @throws IOException if Negotiator.getNegotiator() or * Negotiator.firstToken() failed. */ @@ -219,7 +219,7 @@ class NegotiateAuthentication extends AuthenticationInfo { /** * return more tokens * @param token the token to be fed into negotiator.nextToken() - * @returns the token + * @return the token * @throws IOException if negotiator.nextToken() throws Exception. * May happen if the input token is invalid. */ diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java index 598b4849e5b..846fcf9f2ea 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, 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 @@ -391,8 +391,7 @@ public class Net { private static native boolean isIPv6Available0(); /* - * Returns 1 for Windows versions that support exclusive binding by default, 0 - * for those that do not, and -1 for Solaris/Linux/Mac OS + * Returns 1 for Windows and -1 for Solaris/Linux/Mac OS */ private static native int isExclusiveBindAvailable(); diff --git a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java index b8967c14626..12ee34e6099 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java +++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java @@ -98,8 +98,8 @@ public class AnnotationType { * Sole constructor. * * @param annotationClass the class object for the annotation type - * @throw IllegalArgumentException if the specified class object for - * does not represent a valid annotation type + * @throws IllegalArgumentException if the specified class object for + * does not represent a valid annotation type */ private AnnotationType(final Class annotationClass) { if (!annotationClass.isAnnotation()) diff --git a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java index f0ed2fb19bb..ea542fe213c 100644 --- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java +++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java @@ -178,6 +178,26 @@ final class ProviderConfig { p = new com.sun.crypto.provider.SunJCE(); } else if (provName.equals("SunJSSE") || provName.equals("com.sun.net.ssl.internal.ssl.Provider")) { p = new com.sun.net.ssl.internal.ssl.Provider(); + } else if (provName.equals("Apple") || provName.equals("apple.security.AppleProvider")) { + // need to use reflection since this class only exists on MacOsx + p = AccessController.doPrivileged(new PrivilegedAction() { + public Provider run() { + try { + Class c = Class.forName("apple.security.AppleProvider"); + if (Provider.class.isAssignableFrom(c)) { + return (Provider) c.newInstance(); + } else { + return null; + } + } catch (Exception ex) { + if (debug != null) { + debug.println("Error loading provider Apple"); + ex.printStackTrace(); + } + return null; + } + } + }); } else { if (isLoading) { // because this method is synchronized, this can only diff --git a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java index 35b0b64d4a2..8bc31826c67 100644 --- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java +++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java @@ -319,18 +319,17 @@ public final class RSAPadding { } // generate non-zero padding bytes // use a buffer to reduce calls to SecureRandom - byte[] r = new byte[64]; - int i = -1; - while (psSize-- > 0) { - int b; - do { - if (i < 0) { - random.nextBytes(r); - i = r.length - 1; + while (psSize > 0) { + // extra bytes to avoid zero bytes, + // number of zero bytes <= 4 in 98% cases + byte[] r = new byte[psSize + 4]; + random.nextBytes(r); + for (int i = 0; i < r.length && psSize > 0; i++) { + if (r[i] != 0) { + padded[k++] = r[i]; + psSize--; } - b = r[i--] & 0xff; - } while (b == 0); - padded[k++] = (byte)b; + } } } return padded; diff --git a/jdk/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template b/jdk/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template index 0d7e2e0a1bd..0f34122e68b 100644 --- a/jdk/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template +++ b/jdk/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template @@ -92,7 +92,7 @@ public class CoreResourceBundleControl extends ResourceBundle.Control { } /** - * @returns a list of candidate locales to search from. + * @return a list of candidate locales to search from. * @exception NullPointerException if baseName or locale is null. */ @Override diff --git a/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java b/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java index 1bb05705c04..724af5412ef 100644 --- a/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java +++ b/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java @@ -56,7 +56,7 @@ import java.util.NoSuchElementException; * * }
* - *

The init method is invoked by the PreHashedMap + *

The {@code init} method is invoked by the {@code PreHashedMap} * constructor with an object array long enough for the map's rows. The method * must construct the hash chain for each row and store it in the appropriate * element of the array. @@ -73,7 +73,7 @@ import java.util.NoSuchElementException; * methods in the {@link java.util.Collections} utility class. * *

In the JDK build, subclasses of this class are typically created via the - * Hasher program in the make/tools/Hasher directory. + * {@code Hasher} program in the {@code make/tools/Hasher} directory. * * @author Mark Reinhold * @since 1.5 @@ -95,7 +95,7 @@ public abstract class PreHashedMap * Creates a new map. * *

This constructor invokes the {@link #init init} method, passing it a - * newly-constructed row array that is rows elements long. + * newly-constructed row array that is {@code rows} elements long. * * @param rows * The number of rows in the map diff --git a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java index e2ba1853f2d..867a62253e4 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java @@ -201,7 +201,7 @@ public class LocaleData { * * @param baseName the resource bundle base name. * locale the requested locale for the resource bundle. - * @returns a list of candidate locales to search from. + * @return a list of candidate locales to search from. * @exception NullPointerException if baseName or locale is null. */ @Override diff --git a/jdk/src/java.base/share/native/libjli/java.c b/jdk/src/java.base/share/native/libjli/java.c index 64deecadec4..313f26b7c84 100644 --- a/jdk/src/java.base/share/native/libjli/java.c +++ b/jdk/src/java.base/share/native/libjli/java.c @@ -1082,15 +1082,6 @@ ParseArguments(int *pargc, char ***pargv, AddOption("-Xverify:remote", NULL); } else if (JLI_StrCmp(arg, "-noverify") == 0) { AddOption("-Xverify:none", NULL); - } else if (JLI_StrCCmp(arg, "-prof") == 0) { - char *p = arg + 5; - char *tmp = JLI_MemAlloc(JLI_StrLen(arg) + 50); - if (*p) { - sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1); - } else { - sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof"); - } - AddOption(tmp, NULL); } else if (JLI_StrCCmp(arg, "-ss") == 0 || JLI_StrCCmp(arg, "-oss") == 0 || JLI_StrCCmp(arg, "-ms") == 0 || diff --git a/jdk/src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c b/jdk/src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c index baf22f9f2b3..f63653cd120 100644 --- a/jdk/src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c +++ b/jdk/src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c @@ -24,368 +24,28 @@ */ #include "jni.h" -#include "jni_util.h" -#include "java_lang_ProcessHandleImpl.h" -#include "java_lang_ProcessHandleImpl_Info.h" +#include "ProcessHandleImpl_unix.h" -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include - -/** - * Implementations of ProcessHandleImpl functions that are - * NOT common to all Unix variants: - * - getProcessPids0(pid, pidArray) - * - * Implementations of ProcessHandleImpl_Info - * - totalTime, startTime - * - Command - * - Arguments - */ /* - * Signatures for internal OS specific functions. + * Implementation of native ProcessHandleImpl functions for Solaris. + * See ProcessHandleImpl_unix.c for more details. */ -static pid_t getStatInfo(JNIEnv *env, pid_t pid, - jlong *totalTime, jlong* startTime, - uid_t *uid); -static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid); -extern jstring uidToUser(JNIEnv* env, uid_t uid); +void os_initNative(JNIEnv *env, jclass clazz) {} -/* Field id for jString 'command' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_commandID; - -/* Field id for jString[] 'arguments' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_argumentsID; - -/* Field id for jlong 'totalTime' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_totalTimeID; - -/* Field id for jlong 'startTime' in java.lang.ProcessHandle.Info */ -static jfieldID ProcessHandleImpl_Info_startTimeID; - -/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_userID; - -/* static value for clock ticks per second. */ -static long clock_ticks_per_second; - -/************************************************************** - * Static method to initialize field IDs and the ticks per second rate. - * - * Class: java_lang_ProcessHandleImpl_Info - * Method: initIDs - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) { - CHECK_NULL(ProcessHandleImpl_Info_commandID = (*env)->GetFieldID(env, - clazz, "command", "Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_argumentsID = (*env)->GetFieldID(env, - clazz, "arguments", "[Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = (*env)->GetFieldID(env, - clazz, "totalTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_startTimeID = (*env)->GetFieldID(env, - clazz, "startTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_userID = (*env)->GetFieldID(env, - clazz, "user", "Ljava/lang/String;")); +jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, + jlongArray jparentArray, jlongArray jstimesArray) { + return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray); } -/************************************************************** - * Static method to initialize the ticks per second rate. - * - * Class: java_lang_ProcessHandleImpl - * Method: initNative - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) { - clock_ticks_per_second = sysconf(_SC_CLK_TCK); +pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { + return unix_getParentPidAndTimings(env, pid, total, start); } -/* - * Check if a process is alive. - * Return the start time (ms since 1970) if it is available. - * If the start time is not available return 0. - * If the pid is invalid, return -1. - * - * Class: java_lang_ProcessHandleImpl - * Method: isAlive0 - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jobject obj, jlong jpid) { - pid_t pid = (pid_t) jpid; - jlong startTime = 0L; - jlong totalTime = 0L; - uid_t uid = -1; - pid_t ppid = getStatInfo(env, pid, &totalTime, &startTime, &uid); - return (ppid < 0) ? -1 : startTime; -} - -/* - * Returns the parent pid of the requested pid. - * - * Class: java_lang_ProcessHandleImpl - * Method: parent0 - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, - jobject obj, - jlong jpid, - jlong startTime) { - pid_t pid = (pid_t) jpid; - pid_t ppid = -1; - - if (pid == getpid()) { - ppid = getppid(); - } else { - jlong start = 0L; - jlong total = 0L; - uid_t uid = -1; - - pid_t ppid = getStatInfo(env, pid, &total, &start, &uid); - if (start != startTime - && start != 0 - && startTime != 0) { - ppid = -1; - } - } - return (jlong) ppid; -} - -/* - * Returns the children of the requested pid and optionally each parent. - * - * Class: java_lang_ProcessHandleImpl - * Method: getChildPids - * Signature: (J[J)I - * - * Reads /proc and accumulates any process who parent pid matches. - * The resulting pids are stored into the array of longs. - * The number of pids is returned if they all fit. - * If the array is too short, the desired length is returned. - */ -JNIEXPORT jint JNICALL -Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, - jclass clazz, - jlong jpid, - jlongArray jarray, - jlongArray jparentArray, - jlongArray jstimesArray) { - DIR* dir; - struct dirent* ptr; - pid_t pid = (pid_t) jpid; - jlong* pids = NULL; - jlong* ppids = NULL; - jlong* stimes = NULL; - jsize parentArraySize = 0; - jsize arraySize = 0; - jsize stimesSize = 0; - jsize count = 0; - char procname[32]; - - arraySize = (*env)->GetArrayLength(env, jarray); - JNU_CHECK_EXCEPTION_RETURN(env, 0); - if (jparentArray != NULL) { - parentArraySize = (*env)->GetArrayLength(env, jparentArray); - JNU_CHECK_EXCEPTION_RETURN(env, 0); - - if (arraySize != parentArraySize) { - JNU_ThrowIllegalArgumentException(env, "array sizes not equal"); - return 0; - } - } - if (jstimesArray != NULL) { - stimesSize = (*env)->GetArrayLength(env, jstimesArray); - JNU_CHECK_EXCEPTION_RETURN(env, -1); - - if (arraySize != stimesSize) { - JNU_ThrowIllegalArgumentException(env, "array sizes not equal"); - return 0; - } - } - - /* - * To locate the children we scan /proc looking for files that have a - * positive integer as a filename. - */ - if ((dir = opendir("/proc")) == NULL) { - JNU_ThrowByNameWithLastError(env, - "java/lang/Runtime", "Unable to open /proc"); - return 0; - } - - do { // Block to break out of on Exception - pids = (*env)->GetLongArrayElements(env, jarray, NULL); - if (pids == NULL) { - break; - } - if (jparentArray != NULL) { - ppids = (*env)->GetLongArrayElements(env, jparentArray, NULL); - if (ppids == NULL) { - break; - } - } - if (jstimesArray != NULL) { - stimes = (*env)->GetLongArrayElements(env, jstimesArray, NULL); - if (stimes == NULL) { - break; - } - } - - while ((ptr = readdir(dir)) != NULL) { - pid_t ppid = 0; - jlong totalTime = 0L; - jlong startTime = 0L; - uid_t uid; // value unused - - /* skip files that aren't numbers */ - pid_t childpid = (pid_t) atoi(ptr->d_name); - if ((int) childpid <= 0) { - continue; - } - - // Read /proc/pid/stat and get the parent pid, and start time - ppid = getStatInfo(env, childpid, &totalTime, &startTime, &uid); - if (ppid >= 0 && (pid == 0 || ppid == pid)) { - if (count < arraySize) { - // Only store if it fits - pids[count] = (jlong) childpid; - - if (ppids != NULL) { - // Store the parent Pid - ppids[count] = (jlong) ppid; - } - if (stimes != NULL) { - // Store the process start time - stimes[count] = startTime; - } - } - count++; // Count to tabulate size needed - } - } - } while (0); - - if (pids != NULL) { - (*env)->ReleaseLongArrayElements(env, jarray, pids, 0); - } - if (ppids != NULL) { - (*env)->ReleaseLongArrayElements(env, jparentArray, ppids, 0); - } - if (stimes != NULL) { - (*env)->ReleaseLongArrayElements(env, jstimesArray, stimes, 0); - } - - closedir(dir); - // If more pids than array had size for; count will be greater than array size - return count; -} - -/************************************************************** - * Implementation of ProcessHandleImpl_Info native methods. - */ - -/* - * Fill in the Info object from the OS information about the process. - * - * Class: java_lang_ProcessHandleImpl_Info - * Method: info0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env, - jobject jinfo, - jlong jpid) { - pid_t pid = (pid_t) jpid; - jlong startTime = 0L; - jlong totalTime = 0L; - uid_t uid = -1; - pid_t ppid = getStatInfo(env, pid, &totalTime, &startTime, &uid); - - getCmdlineInfo(env, jinfo, pid); - - if (ppid > 0) { - jstring str; - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime); - JNU_CHECK_EXCEPTION(env); - - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime); - JNU_CHECK_EXCEPTION(env); - - CHECK_NULL((str = uidToUser(env, uid))); - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, str); - JNU_CHECK_EXCEPTION(env); - } -} - -/** - * Read /proc//status and return the ppid, total cputime and start time. - * Return: -1 is fail; zero is unknown; > 0 is parent pid - */ -static pid_t getStatInfo(JNIEnv *env, pid_t pid, - jlong *totalTime, jlong* startTime, - uid_t* uid) { - FILE* fp; - psinfo_t psinfo; - char fn[32]; - int ret; - - /* - * Try to open /proc/%d/status - */ - snprintf(fn, sizeof fn, "/proc/%d/psinfo", pid); - fp = fopen(fn, "r"); - if (fp == NULL) { - return -1; - } - - ret = fread(&psinfo, 1, (sizeof psinfo), fp); - fclose(fp); - if (ret < (sizeof psinfo)) { - return -1; - } - - *totalTime = psinfo.pr_time.tv_sec * 1000000000L + psinfo.pr_time.tv_nsec; - - *startTime = psinfo.pr_start.tv_sec * (jlong)1000 + - psinfo.pr_start.tv_nsec / 1000000; - - *uid = psinfo.pr_uid; - - return (pid_t) psinfo.pr_ppid; -} - -static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) { - char fn[32]; - char exePath[PATH_MAX]; - jstring str = NULL; - int ret; - - /* - * The path to the executable command is the link in /proc//paths/a.out. - */ - snprintf(fn, sizeof fn, "/proc/%d/path/a.out", pid); - if ((ret = readlink(fn, exePath, PATH_MAX - 1)) < 0) { - return; - } - - // null terminate and create String to store for command - exePath[ret] = '\0'; - CHECK_NULL(str = JNU_NewStringPlatform(env, exePath)); - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, str); - JNU_CHECK_EXCEPTION(env); +void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { + unix_getCmdlineAndUserInfo(env, jinfo, pid); } diff --git a/jdk/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java b/jdk/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java index 4fa76ae6df4..ce280dc455a 100644 --- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java +++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java @@ -116,8 +116,8 @@ public class Handler extends URLStreamHandler { * Compares the host components of two URLs. * @param u1 the URL of the first host to compare * @param u2 the URL of the second host to compare - * @return true if and only if they - * are equal, false otherwise. + * @return {@code true} if and only if they + * are equal, {@code false} otherwise. */ protected boolean hostsEqual(URL u1, URL u2) { /* diff --git a/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c b/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c index 9e772366477..afbe1e275ee 100644 --- a/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c +++ b/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c @@ -28,31 +28,87 @@ #include "java_lang_ProcessHandleImpl.h" #include "java_lang_ProcessHandleImpl_Info.h" +#include "ProcessHandleImpl_unix.h" + #include - #include #include #include #include #include #include +#include +#include +#include +#include #include #include #include -#include -#include -#include +#ifdef _AIX +#include +#endif +#ifdef __solaris__ +#include +#endif /** - * Implementations of ProcessHandleImpl functions that are common to all - * Unix variants: - * - waitForProcessExit0(pid, reap) - * - getCurrentPid0() - * - destroy0(pid, force) + * This file contains the implementation of the native ProcessHandleImpl + * functions which are common to all Unix variants. + * + * The currently supported Unix variants are Solaris, Linux, MaxOS X and AIX. + * The various similarities and differences between these systems make it hard + * to find a clear boundary between platform specific and shared code. + * + * In order to ease code sharing between the platforms while still keeping the + * code as clean as possible (i.e. free of preprocessor macros) we use the + * following source code layout (remember that ProcessHandleImpl_unix.c will + * be compiled on EVERY Unix platform while ProcessHandleImpl_.c will be + * only compiled on the specific OS): + * + * - all the JNI wrappers for the ProcessHandleImpl functions go into this file + * - if their implementation is common on ALL the supported Unix platforms it + * goes right into the JNI wrappers + * - if the whole function or substantial parts of it are platform dependent, + * the implementation goes into os_ functions in + * ProcessHandleImpl_.c + * - if at least two platforms implement an os_ function in the + * same way, this implementation is factored out into unix_, + * placed into this file and called from the corresponding os_ + * function. + * - For convenience, all the os_ and unix_ functions are declared in + * ProcessHandleImpl_unix.h which is included into every + * ProcessHandleImpl_.c file. + * + * Example 1: + * ---------- + * The implementation of Java_java_lang_ProcessHandleImpl_initNative() + * is the same on all platforms except on Linux where it initilizes one + * additional field. So we place the implementation right into + * Java_java_lang_ProcessHandleImpl_initNative() but add call to + * os_init() at the end of the function which is empty on all platforms + * except Linux where it performs the additionally initializations. + * + * Example 2: + * ---------- + * The implementation of Java_java_lang_ProcessHandleImpl_00024Info_info0 is the + * same on Solaris and AIX but different on Linux and MacOSX. We therefore simply + * call the helpers os_getParentPidAndTimings() and os_getCmdlineAndUserInfo(). + * The Linux and MaxOS X versions of these functions (in the corresponding files + * ProcessHandleImpl_linux.c and ProcessHandleImpl_macosx.c) directly contain + * the platform specific implementations while the Solaris and AIX + * implementations simply call back to unix_getParentPidAndTimings() and + * unix_getCmdlineAndUserInfo() which are implemented right in this file. + * + * The term "same implementation" is still a question of interpretation. It my + * be acceptable to have a few ifdef'ed lines if that allows the sharing of a + * huge function. On the other hand, if the platform specific code in a shared + * function grows over a certain limit, it may be better to refactor that + * functionality into corresponding, platform-specific os_ functions. */ + #ifndef WIFEXITED #define WIFEXITED(status) (((status)&0xFF) == 0) #endif @@ -69,6 +125,19 @@ #define WTERMSIG(status) ((status)&0x7F) #endif +#ifdef __solaris__ +/* The child exited because of a signal. + * The best value to return is 0x80 + signal number, + * because that is what all Unix shells do, and because + * it allows callers to distinguish between process exit and + * process death by signal. + * Unfortunately, the historical behavior on Solaris is to return + * the signal number, and we preserve this for compatibility. */ +#define WTERMSIG_RETURN(status) WTERMSIG(status) +#else +#define WTERMSIG_RETURN(status) (WTERMSIG(status) + 0x80) +#endif + #define RESTARTABLE(_cmd, _result) do { \ do { \ _result = _cmd; \ @@ -81,21 +150,83 @@ } while((_result == NULL) && (errno == EINTR)); \ } while(0) -#ifdef __solaris__ - #define STAT_FILE "/proc/%d/status" -#else - #define STAT_FILE "/proc/%d/stat" -#endif + +/* Field id for jString 'command' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_commandID; + +/* Field id for jString 'commandLine' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_commandLineID; + +/* Field id for jString[] 'arguments' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_argumentsID; + +/* Field id for jlong 'totalTime' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_totalTimeID; + +/* Field id for jlong 'startTime' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_startTimeID; + +/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */ +jfieldID ProcessHandleImpl_Info_userID; + +/* Size of password or group entry when not available via sysconf */ +#define ENT_BUF_SIZE 1024 +/* The value for the size of the buffer used by getpwuid_r(). The result of */ +/* sysconf(_SC_GETPW_R_SIZE_MAX) if available or ENT_BUF_SIZE otherwise. */ +static long getpw_buf_size; + +/************************************************************** + * Static method to initialize field IDs and the ticks per second rate. + * + * Class: java_lang_ProcessHandleImpl_Info + * Method: initIDs + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) { + + CHECK_NULL(ProcessHandleImpl_Info_commandID = + (*env)->GetFieldID(env, clazz, "command", "Ljava/lang/String;")); + CHECK_NULL(ProcessHandleImpl_Info_commandLineID = + (*env)->GetFieldID(env, clazz, "commandLine", "Ljava/lang/String;")); + CHECK_NULL(ProcessHandleImpl_Info_argumentsID = + (*env)->GetFieldID(env, clazz, "arguments", "[Ljava/lang/String;")); + CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = + (*env)->GetFieldID(env, clazz, "totalTime", "J")); + CHECK_NULL(ProcessHandleImpl_Info_startTimeID = + (*env)->GetFieldID(env, clazz, "startTime", "J")); + CHECK_NULL(ProcessHandleImpl_Info_userID = + (*env)->GetFieldID(env, clazz, "user", "Ljava/lang/String;")); +} + +/*********************************************************** + * Static method to initialize platform dependent constants. + * + * Class: java_lang_ProcessHandleImpl + * Method: initNative + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) { + getpw_buf_size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (getpw_buf_size == -1) { + getpw_buf_size = ENT_BUF_SIZE; + } + os_initNative(env, clazz); +} /* Block until a child process exits and return its exit code. * Note, can only be called once for any given pid if reapStatus = true. + * + * Class: java_lang_ProcessHandleImpl + * Method: waitForProcessExit0 + * Signature: (JZ)I */ JNIEXPORT jint JNICALL Java_java_lang_ProcessHandleImpl_waitForProcessExit0(JNIEnv* env, jclass junk, jlong jpid, - jboolean reapStatus) -{ + jboolean reapStatus) { pid_t pid = (pid_t)jpid; errno = 0; @@ -117,18 +248,7 @@ Java_java_lang_ProcessHandleImpl_waitForProcessExit0(JNIEnv* env, if (WIFEXITED(status)) { return WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { - /* The child exited because of a signal. - * The best value to return is 0x80 + signal number, - * because that is what all Unix shells do, and because - * it allows callers to distinguish between process exit and - * process death by signal. - * Unfortunately, the historical behavior on Solaris is to return - * the signal number, and we preserve this for compatibility. */ -#ifdef __solaris__ - return WTERMSIG(status); -#else - return 0x80 + WTERMSIG(status); -#endif + return WTERMSIG_RETURN(status); } else { return status; } @@ -156,18 +276,7 @@ Java_java_lang_ProcessHandleImpl_waitForProcessExit0(JNIEnv* env, */ return siginfo.si_status; } else if (siginfo.si_code == CLD_KILLED || siginfo.si_code == CLD_DUMPED) { - /* The child exited because of a signal. - * The best value to return is 0x80 + signal number, - * because that is what all Unix shells do, and because - * it allows callers to distinguish between process exit and - * process death by signal. - * Unfortunately, the historical behavior on Solaris is to return - * the signal number, and we preserve this for compatibility. */ - #ifdef __solaris__ - return WTERMSIG(siginfo.si_status); - #else - return 0x80 + WTERMSIG(siginfo.si_status); - #endif + return WTERMSIG_RETURN(siginfo.si_status); } else { /* * Unknown exit code; pass it through. @@ -191,7 +300,7 @@ Java_java_lang_ProcessHandleImpl_getCurrentPid0(JNIEnv *env, jclass clazz) { /* * Class: java_lang_ProcessHandleImpl * Method: destroy0 - * Signature: (Z)Z + * Signature: (JJZ)Z */ JNIEXPORT jboolean JNICALL Java_java_lang_ProcessHandleImpl_destroy0(JNIEnv *env, @@ -210,119 +319,52 @@ Java_java_lang_ProcessHandleImpl_destroy0(JNIEnv *env, } } -/** - * Size of password or group entry when not available via sysconf +/* + * Returns the children of the requested pid and optionally each parent and + * start time. + * Accumulates any process who parent pid matches. + * The resulting pids are stored into the array of longs. + * The number of pids is returned if they all fit. + * If the array is too short, the negative of the desired length is returned. + * Class: java_lang_ProcessHandleImpl + * Method: getProcessPids0 + * Signature: (J[J[J[J)I */ -#define ENT_BUF_SIZE 1024 - -/** - * Return a strong username for the uid_t or null. - */ -jstring uidToUser(JNIEnv* env, uid_t uid) { - int result = 0; - int buflen; - char* pwbuf; - jstring name = NULL; - - /* allocate buffer for password record */ - buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX); - if (buflen == -1) - buflen = ENT_BUF_SIZE; - pwbuf = (char*)malloc(buflen); - if (pwbuf == NULL) { - JNU_ThrowOutOfMemoryError(env, "Unable to open getpwent"); - } else { - struct passwd pwent; - struct passwd* p = NULL; - -#ifdef __solaris__ - RESTARTABLE_RETURN_PTR(getpwuid_r(uid, &pwent, pwbuf, (size_t)buflen), p); -#else - RESTARTABLE(getpwuid_r(uid, &pwent, pwbuf, (size_t)buflen, &p), result); -#endif - - // Return the Java String if a name was found - if (result == 0 && p != NULL && - p->pw_name != NULL && *(p->pw_name) != '\0') { - name = JNU_NewStringPlatform(env, p->pw_name); - } - free(pwbuf); - } - return name; +JNIEXPORT jint JNICALL +Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, + jclass clazz, + jlong jpid, + jlongArray jarray, + jlongArray jparentArray, + jlongArray jstimesArray) { + return os_getChildren(env, jpid, jarray, jparentArray, jstimesArray); } -/** - * Implementations of ProcessHandleImpl functions that are common to - * (some) Unix variants: - * - getProcessPids0(pid, pidArray, parentArray) - */ - -#if defined(__linux__) || defined(__AIX__) - /* - * Signatures for internal OS specific functions. - */ -static pid_t getStatInfo(JNIEnv *env, pid_t pid, - jlong *totalTime, jlong* startTime); -static void getCmdlineInfo(JNIEnv *env, pid_t pid, jobject jinfo); -static long long getBoottime(JNIEnv *env); - -jstring uidToUser(JNIEnv* env, uid_t uid); - -/* Field id for jString 'command' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_commandID; - -/* Field id for jString[] 'arguments' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_argumentsID; - -/* Field id for jlong 'totalTime' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_totalTimeID; - -/* Field id for jlong 'startTime' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_startTimeID; - -/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */ -static jfieldID ProcessHandleImpl_Info_userID; - -/* static value for clock ticks per second. */ -static long clock_ticks_per_second; - -/* A static offset in milliseconds since boot. */ -static long long bootTime_ms; - -/************************************************************** - * Static method to initialize field IDs and the ticks per second rate. + * Fill in the Info object from the OS information about the process. * * Class: java_lang_ProcessHandleImpl_Info - * Method: initIDs - * Signature: ()V + * Method: info0 + * Signature: (Ljava/lang/ProcessHandle/Info;J)I */ JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) { +Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env, + jobject jinfo, + jlong jpid) { + pid_t pid = (pid_t) jpid; + pid_t ppid; + jlong totalTime = -1L; + jlong startTime = -1L; - CHECK_NULL(ProcessHandleImpl_Info_commandID = (*env)->GetFieldID(env, - clazz, "command", "Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_argumentsID = (*env)->GetFieldID(env, - clazz, "arguments", "[Ljava/lang/String;")); - CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = (*env)->GetFieldID(env, - clazz, "totalTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_startTimeID = (*env)->GetFieldID(env, - clazz, "startTime", "J")); - CHECK_NULL(ProcessHandleImpl_Info_userID = (*env)->GetFieldID(env, - clazz, "user", "Ljava/lang/String;")); -} + ppid = os_getParentPidAndTimings(env, pid, &totalTime, &startTime); + if (ppid >= 0) { + (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime); + JNU_CHECK_EXCEPTION(env); -/************************************************************** - * Static method to initialize the ticks per second rate. - * - * Class: java_lang_ProcessHandleImpl - * Method: initNative - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) { - clock_ticks_per_second = sysconf(_SC_CLK_TCK); - bootTime_ms = getBoottime(env); + (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime); + JNU_CHECK_EXCEPTION(env); + } + os_getCmdlineAndUserInfo(env, jinfo, pid); } /* @@ -340,8 +382,8 @@ Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jobject obj, jlong jpid) pid_t pid = (pid_t) jpid; jlong startTime = 0L; jlong totalTime = 0L; - pid_t ppid = getStatInfo(env, pid, &totalTime, &startTime); - return (ppid <= 0) ? -1 : startTime; + pid_t ppid = os_getParentPidAndTimings(env, pid, &totalTime, &startTime); + return (ppid < 0) ? -1 : startTime; } /* @@ -350,7 +392,7 @@ Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jobject obj, jlong jpid) * * Class: java_lang_ProcessHandleImpl * Method: parent0 - * Signature: (J)J + * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, @@ -360,13 +402,12 @@ Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, pid_t pid = (pid_t) jpid; pid_t ppid; - pid_t mypid = getpid(); - if (pid == mypid) { + if (pid == getpid()) { ppid = getppid(); } else { - jlong start = 0L;; + jlong start = 0L; jlong total = 0L; // unused - ppid = getStatInfo(env, pid, &total, &start); + ppid = os_getParentPidAndTimings(env, pid, &total, &start); if (start != startTime && start != 0 && startTime != 0) { ppid = -1; } @@ -374,24 +415,94 @@ Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env, return (jlong) ppid; } +/** + * Construct the argument array by parsing the arguments from the sequence + * of arguments. + */ +void unix_fillArgArray(JNIEnv *env, jobject jinfo, int nargs, char *cp, + char *argsEnd, jstring cmdexe, char *cmdline) { + jobject argsArray; + int i; + + (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, cmdexe); + JNU_CHECK_EXCEPTION(env); + + if (nargs >= 1) { + // Create a String array for nargs-1 elements + argsArray = (*env)->NewObjectArray(env, nargs - 1, JNU_ClassString(env), NULL); + CHECK_NULL(argsArray); + + for (i = 0; i < nargs - 1; i++) { + jstring str = NULL; + + cp += strlen(cp) + 1; + if (cp > argsEnd || *cp == '\0') { + return; // Off the end pointer or an empty argument is an error + } + + CHECK_NULL((str = JNU_NewStringPlatform(env, cp))); + + (*env)->SetObjectArrayElement(env, argsArray, i, str); + JNU_CHECK_EXCEPTION(env); + } + (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_argumentsID, argsArray); + JNU_CHECK_EXCEPTION(env); + } + if (cmdline != NULL) { + jstring commandLine = NULL; + CHECK_NULL((commandLine = JNU_NewStringPlatform(env, cmdline))); + (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandLineID, commandLine); + JNU_CHECK_EXCEPTION(env); + } +} + +void unix_getUserInfo(JNIEnv* env, jobject jinfo, uid_t uid) { + int result = 0; + char* pwbuf; + jstring name = NULL; + + /* allocate buffer for password record */ + pwbuf = (char*)malloc(getpw_buf_size); + if (pwbuf == NULL) { + JNU_ThrowOutOfMemoryError(env, "Unable to open getpwent"); + } else { + struct passwd pwent; + struct passwd* p = NULL; + +#ifdef __solaris__ + RESTARTABLE_RETURN_PTR(getpwuid_r(uid, &pwent, pwbuf, (size_t)getpw_buf_size), p); +#else + RESTARTABLE(getpwuid_r(uid, &pwent, pwbuf, (size_t)getpw_buf_size, &p), result); +#endif + + // Create the Java String if a name was found + if (result == 0 && p != NULL && + p->pw_name != NULL && *(p->pw_name) != '\0') { + name = JNU_NewStringPlatform(env, p->pw_name); + } + free(pwbuf); + } + if (name != NULL) { + (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, name); + } +} + /* - * Returns the children of the requested pid and optionally each parent. + * The following functions are common on Solaris, Linux and AIX. + */ + +#if defined(__solaris__) || defined (__linux__) || defined(_AIX) + +/* + * Returns the children of the requested pid and optionally each parent and + * start time. * Reads /proc and accumulates any process who parent pid matches. * The resulting pids are stored into the array of longs. * The number of pids is returned if they all fit. - * If the array is too short, the negative of the desired length is returned. * - * Class: java_lang_ProcessHandleImpl - * Method: getChildPids - * Signature: (J[J[J)I + * If the array is too short, the negative of the desired length is returned. */ -JNIEXPORT jint JNICALL -Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, - jclass clazz, - jlong jpid, - jlongArray jarray, - jlongArray jparentArray, - jlongArray jstimesArray) { - +jint unix_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, + jlongArray jparentArray, jlongArray jstimesArray) { DIR* dir; struct dirent* ptr; pid_t pid = (pid_t) jpid; @@ -462,9 +573,10 @@ Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, if ((int) childpid <= 0) { continue; } - // Read /proc/pid/stat and get the parent pid, and start time - ppid = getStatInfo(env, childpid, &totalTime, &startTime); - if (ppid > 0 && (pid == 0 || ppid == pid)) { + + // Get the parent pid, and start time + ppid = os_getParentPidAndTimings(env, childpid, &totalTime, &startTime); + if (ppid >= 0 && (pid == 0 || ppid == pid)) { if (count < arraySize) { // Only store if it fits pids[count] = (jlong) childpid; @@ -498,293 +610,110 @@ Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env, return count; } - -/************************************************************** - * Implementation of ProcessHandleImpl_Info native methods. - */ +#endif // defined(__solaris__) || defined (__linux__) || defined(_AIX) /* - * Fill in the Info object from the OS information about the process. - * - * Class: java_lang_ProcessHandleImpl_Info - * Method: info0 - * Signature: (JLjava/lang/ProcessHandle/Info;)I + * The following functions are common on Solaris and AIX. */ -JNIEXPORT void JNICALL -Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env, - jobject jinfo, - jlong jpid) { - pid_t pid = (pid_t) jpid; - pid_t ppid; - jlong totalTime = 0L; - jlong startTime = -1L; - ppid = getStatInfo(env, pid, &totalTime, &startTime); - if (ppid > 0) { - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime); - JNU_CHECK_EXCEPTION(env); - - (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime); - JNU_CHECK_EXCEPTION(env); - - getCmdlineInfo(env, pid, jinfo); - } -} +#if defined(__solaris__) || defined(_AIX) /** - * Read /proc//stat and return the ppid, total cputime and start time. - * -1 is fail; zero is unknown; > 0 is parent pid + * Helper function to get the 'psinfo_t' data from "/proc/%d/psinfo". + * Returns 0 on success and -1 on error. */ -static pid_t getStatInfo(JNIEnv *env, pid_t pid, - jlong *totalTime, jlong* startTime) { +static int getPsinfo(pid_t pid, psinfo_t *psinfo) { FILE* fp; - char buffer[2048]; - int statlen; char fn[32]; - char* s; - int parentPid; - long unsigned int utime = 0; // clock tics - long unsigned int stime = 0; // clock tics - long long unsigned int start = 0; // microseconds + int ret; /* - * Try to stat and then open /proc/%d/stat + * Try to open /proc/%d/psinfo */ - snprintf(fn, sizeof fn, STAT_FILE, pid); - + snprintf(fn, sizeof fn, "/proc/%d/psinfo", pid); fp = fopen(fn, "r"); - if (fp == NULL) { - return -1; // fail, no such /proc/pid/stat - } - - /* - * The format is: pid (command) state ppid ... - * As the command could be anything we must find the right most - * ")" and then skip the white spaces that follow it. - */ - statlen = fread(buffer, 1, (sizeof buffer - 1), fp); - fclose(fp); - if (statlen < 0) { - return 0; // parent pid is not available - } - - buffer[statlen] = '\0'; - s = strchr(buffer, '('); - if (s == NULL) { - return 0; // parent pid is not available - } - // Found start of command, skip to end - s++; - s = strrchr(s, ')'); - if (s == NULL) { - return 0; // parent pid is not available - } - s++; - - // Scan the needed fields from status, retaining only ppid(4), - // utime (14), stime(15), starttime(22) - if (4 != sscanf(s, " %*c %d %*d %*d %*d %*d %*d %*u %*u %*u %*u %lu %lu %*d %*d %*d %*d %*d %*d %llu", - &parentPid, &utime, &stime, &start)) { - return 0; // not all values parsed; return error - } - - *totalTime = (utime + stime) * (jlong)(1000000000 / clock_ticks_per_second); - - *startTime = bootTime_ms + ((start * 1000) / clock_ticks_per_second); - - return parentPid; -} - -/** - * Construct the argument array by parsing the arguments from the sequence - * of arguments. The zero'th arg is the command executable - */ -static int fillArgArray(JNIEnv *env, jobject jinfo, - int nargs, char *cp, char *argsEnd, jstring cmdexe) { - jobject argsArray; - int i; - - if (nargs < 1) { - return 0; - } - - if (cmdexe == NULL) { - // Create a string from arg[0] - CHECK_NULL_RETURN((cmdexe = JNU_NewStringPlatform(env, cp)), -1); - } - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, cmdexe); - JNU_CHECK_EXCEPTION_RETURN(env, -3); - - // Create a String array for nargs-1 elements - argsArray = (*env)->NewObjectArray(env, nargs - 1, JNU_ClassString(env), NULL); - CHECK_NULL_RETURN(argsArray, -1); - - for (i = 0; i < nargs - 1; i++) { - jstring str = NULL; - - cp += strnlen(cp, (argsEnd - cp)) + 1; - if (cp > argsEnd || *cp == '\0') { - return -2; // Off the end pointer or an empty argument is an error - } - - CHECK_NULL_RETURN((str = JNU_NewStringPlatform(env, cp)), -1); - - (*env)->SetObjectArrayElement(env, argsArray, i, str); - JNU_CHECK_EXCEPTION_RETURN(env, -3); - } - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_argumentsID, argsArray); - JNU_CHECK_EXCEPTION_RETURN(env, -4); - return 0; -} - - -static void getCmdlineInfo(JNIEnv *env, pid_t pid, jobject jinfo) { - int fd; - int cmdlen = 0; - char *cmdline = NULL, *cmdEnd; // used for command line args and exe - jstring cmdexe = NULL; - char fn[32]; - struct stat stat_buf; - - /* - * Try to open /proc/%d/cmdline - */ - snprintf(fn, sizeof fn, "/proc/%d/cmdline", pid); - if ((fd = open(fn, O_RDONLY)) < 0) { - return; - } - - do { // Block to break out of on errors - int i; - char *s; - - cmdline = (char*)malloc(PATH_MAX); - if (cmdline == NULL) { - break; - } - - /* - * The path to the executable command is the link in /proc//exe. - */ - snprintf(fn, sizeof fn, "/proc/%d/exe", pid); - if ((cmdlen = readlink(fn, cmdline, PATH_MAX - 1)) > 0) { - // null terminate and create String to store for command - cmdline[cmdlen] = '\0'; - cmdexe = JNU_NewStringPlatform(env, cmdline); - (*env)->ExceptionClear(env); // unconditionally clear any exception - } - - /* - * The buffer format is the arguments nul terminated with an extra nul. - */ - cmdlen = read(fd, cmdline, PATH_MAX-1); - if (cmdlen < 0) { - break; - } - - // Terminate the buffer and count the arguments - cmdline[cmdlen] = '\0'; - cmdEnd = &cmdline[cmdlen + 1]; - for (s = cmdline,i = 0; *s != '\0' && (s < cmdEnd); i++) { - s += strnlen(s, (cmdEnd - s)) + 1; - } - - if (fillArgArray(env, jinfo, i, cmdline, cmdEnd, cmdexe) < 0) { - break; - } - - // Get and store the user name - if (fstat(fd, &stat_buf) == 0) { - jstring name = uidToUser(env, stat_buf.st_uid); - if (name != NULL) { - (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, name); - } - } - } while (0); - - if (cmdline != NULL) { - free(cmdline); - } - if (fd >= 0) { - close(fd); - } -} - -/** - * Read the boottime from /proc/stat. - */ -static long long getBoottime(JNIEnv *env) { - FILE *fp; - char *line = NULL; - size_t len = 0; - long long bootTime = 0; - - fp = fopen("/proc/stat", "r"); if (fp == NULL) { return -1; } - while (getline(&line, &len, fp) != -1) { - if (sscanf(line, "btime %llu", &bootTime) == 1) { - break; - } + ret = fread(psinfo, 1, sizeof(psinfo_t), fp); + fclose(fp); + if (ret < sizeof(psinfo_t)) { + return -1; } - free(line); - - if (fp != 0) { - fclose(fp); - } - - return bootTime * 1000; + return 0; } -#endif // defined(__linux__) || defined(__AIX__) +/** + * Read /proc//psinfo and return the ppid, total cputime and start time. + * Return: -1 is fail; >= 0 is parent pid + * 'total' will contain the running time of 'pid' in nanoseconds. + * 'start' will contain the start time of 'pid' in milliseconds since epoch. + */ +pid_t unix_getParentPidAndTimings(JNIEnv *env, pid_t pid, + jlong *totalTime, jlong* startTime) { + psinfo_t psinfo; - -/* Block until a child process exits and return its exit code. - Note, can only be called once for any given pid. */ -JNIEXPORT jint JNICALL -Java_java_lang_ProcessImpl_waitForProcessExit(JNIEnv* env, - jobject junk, - jint pid) -{ - /* We used to use waitid() on Solaris, waitpid() on Linux, but - * waitpid() is more standard, so use it on all POSIX platforms. */ - int status; - /* Wait for the child process to exit. This returns immediately if - the child has already exited. */ - while (waitpid(pid, &status, 0) < 0) { - switch (errno) { - case ECHILD: return 0; - case EINTR: break; - default: return -1; - } + if (getPsinfo(pid, &psinfo) < 0) { + return -1; } - if (WIFEXITED(status)) { - /* - * The child exited normally; get its exit code. - */ - return WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) { - /* The child exited because of a signal. - * The best value to return is 0x80 + signal number, - * because that is what all Unix shells do, and because - * it allows callers to distinguish between process exit and - * process death by signal. - * Unfortunately, the historical behavior on Solaris is to return - * the signal number, and we preserve this for compatibility. */ -#ifdef __solaris__ - return WTERMSIG(status); -#else - return 0x80 + WTERMSIG(status); + *totalTime = psinfo.pr_time.tv_sec * 1000000000L + psinfo.pr_time.tv_nsec; + + *startTime = psinfo.pr_start.tv_sec * (jlong)1000 + + psinfo.pr_start.tv_nsec / 1000000; + + return (pid_t) psinfo.pr_ppid; +} + +void unix_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { + psinfo_t psinfo; + char fn[32]; + char exePath[PATH_MAX]; + char prargs[PRARGSZ + 1]; + jstring cmdexe = NULL; + int ret; + + /* + * On Solaris, the full path to the executable command is the link in + * /proc//paths/a.out. But it is only readable for processes we own. + */ +#if defined(__solaris__) + snprintf(fn, sizeof fn, "/proc/%d/path/a.out", pid); + if ((ret = readlink(fn, exePath, PATH_MAX - 1)) > 0) { + // null terminate and create String to store for command + exePath[ret] = '\0'; + CHECK_NULL(cmdexe = JNU_NewStringPlatform(env, exePath)); + } #endif - } else { - /* - * Unknown exit code; pass it through. - */ - return status; + + /* + * Now try to open /proc/%d/psinfo + */ + if (getPsinfo(pid, &psinfo) < 0) { + unix_fillArgArray(env, jinfo, 0, NULL, NULL, cmdexe, NULL); + return; } + + unix_getUserInfo(env, jinfo, psinfo.pr_uid); + + /* + * Now read psinfo.pr_psargs which contains the first PRARGSZ characters of the + * argument list (i.e. arg[0] arg[1] ...). Unfortunately, PRARGSZ is usually set + * to 80 characters only. Nevertheless it's better than nothing :) + */ + strncpy(prargs, psinfo.pr_psargs, PRARGSZ); + prargs[PRARGSZ] = '\0'; + if (prargs[0] == '\0') { + /* If psinfo.pr_psargs didn't contain any strings, use psinfo.pr_fname + * (which only contains the last component of exec()ed pathname) as a + * last resort. This is true for AIX kernel processes for example. + */ + strncpy(prargs, psinfo.pr_fname, PRARGSZ); + prargs[PRARGSZ] = '\0'; + } + unix_fillArgArray(env, jinfo, 0, NULL, NULL, cmdexe, + prargs[0] == '\0' ? NULL : prargs); } - +#endif // defined(__solaris__) || defined(_AIX) diff --git a/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.h b/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.h new file mode 100644 index 00000000000..a77f8ab5fc7 --- /dev/null +++ b/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include + +/* + * Declaration of ProcessHandleImpl functions common on all Unix platforms. + * 'unix_' functions have a single implementation in ProcessHandleImpl_unix.c + * 'os_' prefixed functions have different, os-specific implementations in the + * various ProcessHandleImpl_{linux,macosx,solaris,aix}.c files. + * See ProcessHandleImpl_unix.c for more details. + */ + +/* Field id for jString 'command' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_commandID; + +/* Field id for jString 'commandLine' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_commandLineID; + +/* Field id for jString[] 'arguments' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_argumentsID; + +/* Field id for jlong 'totalTime' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_totalTimeID; + +/* Field id for jlong 'startTime' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_startTimeID; + +/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */ +extern jfieldID ProcessHandleImpl_Info_userID; + +/** + * Return: -1 is fail; >= 0 is parent pid + * 'total' will contain the running time of 'pid' in nanoseconds. + * 'start' will contain the start time of 'pid' in milliseconds since epoch. + */ +extern pid_t unix_getParentPidAndTimings(JNIEnv *env, pid_t pid, + jlong *total, jlong *start); +extern pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, + jlong *total, jlong *start); + +extern void unix_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid); +extern void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid); + +extern jint unix_getChildren(JNIEnv *env, jlong jpid, jlongArray array, + jlongArray jparentArray, jlongArray jstimesArray); +extern jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray array, + jlongArray jparentArray, jlongArray jstimesArray); + +extern void unix_getUserInfo(JNIEnv* env, jobject jinfo, uid_t uid); +extern void unix_fillArgArray(JNIEnv *env, jobject jinfo, int nargs, char *cp, + char *argsEnd, jstring cmdexe, char *cmdline); + +extern void os_initNative(JNIEnv *env, jclass clazz); diff --git a/jdk/src/java.base/unix/native/libnio/ch/IOUtil.c b/jdk/src/java.base/unix/native/libnio/ch/IOUtil.c index 438bf41ddea..2a5ff23c6b9 100644 --- a/jdk/src/java.base/unix/native/libnio/ch/IOUtil.c +++ b/jdk/src/java.base/unix/native/libnio/ch/IOUtil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, 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 @@ -129,7 +129,8 @@ Java_sun_nio_ch_IOUtil_fdLimit(JNIEnv *env, jclass this) JNU_ThrowIOExceptionWithLastError(env, "getrlimit failed"); return -1; } - if (rlp.rlim_max < 0 || rlp.rlim_max > java_lang_Integer_MAX_VALUE) { + if (rlp.rlim_max == RLIM_INFINITY || + rlp.rlim_max > (rlim_t)java_lang_Integer_MAX_VALUE) { return java_lang_Integer_MAX_VALUE; } else { return (jint)rlp.rlim_max; diff --git a/jdk/src/java.base/windows/classes/sun/io/Win32ErrorMode.java b/jdk/src/java.base/windows/classes/sun/io/Win32ErrorMode.java index 8ec417fd6e2..18626a76462 100644 --- a/jdk/src/java.base/windows/classes/sun/io/Win32ErrorMode.java +++ b/jdk/src/java.base/windows/classes/sun/io/Win32ErrorMode.java @@ -59,8 +59,8 @@ public class Win32ErrorMode { * Invoke at VM initialization time to disable the critical error message box. *

* The critial error message box is disabled unless the system property - * sun.io.allowCriticalErrorMessageBox is set to something other than - * false. This includes the empty string. + * {@code sun.io.allowCriticalErrorMessageBox} is set to something other than + * {@code false}. This includes the empty string. *

* This method does nothing if invoked after VM and class library initialization * has completed. diff --git a/jdk/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java b/jdk/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java index 8a5531268de..c2cb1d17f5d 100644 --- a/jdk/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java +++ b/jdk/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java @@ -134,8 +134,8 @@ public class Handler extends URLStreamHandler { * Compares the host components of two URLs. * @param u1 the URL of the first host to compare * @param u2 the URL of the second host to compare - * @return true if and only if they - * are equal, false otherwise. + * @return {@code true} if and only if they + * are equal, {@code false} otherwise. */ protected boolean hostsEqual(URL u1, URL u2) { /* diff --git a/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c b/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c index 028a0565172..4885ddbc9db 100644 --- a/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c +++ b/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c @@ -45,6 +45,9 @@ static void procToUser(JNIEnv *env, HANDLE handle, jobject jinfo); /* Field id for jString 'command' in java.lang.ProcessHandle.Info */ static jfieldID ProcessHandleImpl_Info_commandID; +/* Field id for jString 'commandLine' in java.lang.ProcessHandleImpl.Info */ +static jfieldID ProcessHandleImpl_Info_commandLineID; + /* Field id for jString[] 'arguments' in java.lang.ProcessHandle.Info */ static jfieldID ProcessHandleImpl_Info_argumentsID; @@ -69,6 +72,8 @@ Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) { CHECK_NULL(ProcessHandleImpl_Info_commandID = (*env)->GetFieldID(env, clazz, "command", "Ljava/lang/String;")); + CHECK_NULL(ProcessHandleImpl_Info_commandLineID = (*env)->GetFieldID(env, + clazz, "commandLine", "Ljava/lang/String;")); CHECK_NULL(ProcessHandleImpl_Info_argumentsID = (*env)->GetFieldID(env, clazz, "arguments", "[Ljava/lang/String;")); CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = (*env)->GetFieldID(env, diff --git a/jdk/src/java.base/windows/native/libnio/ch/Iocp.c b/jdk/src/java.base/windows/native/libnio/ch/Iocp.c index f9556234075..8b7bde92c9b 100644 --- a/jdk/src/java.base/windows/native/libnio/ch/Iocp.c +++ b/jdk/src/java.base/windows/native/libnio/ch/Iocp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, 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 @@ -57,16 +57,6 @@ Java_sun_nio_ch_Iocp_initIDs(JNIEnv* env, jclass this) CHECK_NULL(completionStatus_overlapped); } -JNIEXPORT jint JNICALL -Java_sun_nio_ch_Iocp_osMajorVersion(JNIEnv* env, jclass this) -{ - OSVERSIONINFOEX ver; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx((OSVERSIONINFO *) &ver); - return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) ? - (jint)(ver.dwMajorVersion) : (jint)0; -} - JNIEXPORT jlong JNICALL Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this, jlong handle, jlong existingPort, jint completionKey, jint concurrency) diff --git a/jdk/src/java.base/windows/native/libnio/ch/Net.c b/jdk/src/java.base/windows/native/libnio/ch/Net.c index be3d0f99677..12f3c190c49 100644 --- a/jdk/src/java.base/windows/native/libnio/ch/Net.c +++ b/jdk/src/java.base/windows/native/libnio/ch/Net.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015, 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 @@ -88,28 +88,14 @@ JNIEXPORT jboolean JNICALL Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl) { /* - * Return true if Windows Vista or newer, and IPv6 is configured + * Return true if IPv6 is configured */ - OSVERSIONINFO ver; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - if ((ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && - (ver.dwMajorVersion >= 6) && ipv6_available()) - { - return JNI_TRUE; - } - return JNI_FALSE; + return ipv6_available() ? JNI_TRUE : JNI_FALSE; } JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) { - OSVERSIONINFO ver; - int version; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - version = ver.dwMajorVersion * 10 + ver.dwMinorVersion; - //if os <= xp exclusive binding is off by default - return version >= 60 ? 1 : 0; + return 1; } @@ -567,7 +553,7 @@ Java_sun_nio_ch_Net_poll(JNIEnv* env, jclass this, jobject fdo, jint events, jlo fd_set rd, wr, ex; jint fd = fdval(env, fdo); - t.tv_sec = timeout / 1000; + t.tv_sec = (long)(timeout / 1000); t.tv_usec = (timeout % 1000) * 1000; FD_ZERO(&rd); diff --git a/jdk/src/java.corba/share/classes/com/sun/jndi/cosnaming/RemoteToCorba.java b/jdk/src/java.corba/share/classes/com/sun/jndi/cosnaming/RemoteToCorba.java index 69cc7b45523..9f8414a9573 100644 --- a/jdk/src/java.corba/share/classes/com/sun/jndi/cosnaming/RemoteToCorba.java +++ b/jdk/src/java.corba/share/classes/com/sun/jndi/cosnaming/RemoteToCorba.java @@ -56,7 +56,7 @@ public class RemoteToCorba implements StateFactory { * @param name Ignored * @param ctx The non-null CNCtx whose ORB to use. * @param env Ignored - * @return The CORBA object for orig or null. + * @return The CORBA object for {@code orig} or null. * @exception ConfigurationException If the CORBA object cannot be obtained * due to configuration problems, for instance, if RMI-IIOP not available. * @exception NamingException If some other problem prevented a CORBA diff --git a/jdk/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java b/jdk/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java index 2fa43bca79e..122c9df57f5 100644 --- a/jdk/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java +++ b/jdk/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java @@ -76,7 +76,7 @@ public class CorbaUtils { * * @param remoteObj The non-null remote object for * @param orb The non-null ORB to connect the remote object to - * @return The CORBA Object for remoteObj; null if remoteObj + * @return The CORBA Object for remoteObj; null if {@code remoteObj} * is a JRMP implementation or JRMP stub. * @exception ConfigurationException The CORBA Object cannot be obtained * because of configuration problems. diff --git a/jdk/src/java.management/share/classes/javax/management/InstanceOfQueryExp.java b/jdk/src/java.management/share/classes/javax/management/InstanceOfQueryExp.java index 17bc39b61d2..6496f019e21 100644 --- a/jdk/src/java.management/share/classes/javax/management/InstanceOfQueryExp.java +++ b/jdk/src/java.management/share/classes/javax/management/InstanceOfQueryExp.java @@ -65,7 +65,7 @@ class InstanceOfQueryExp extends QueryEval implements QueryExp { /** * Returns the class name. - * @returns The {@link StringValueExp} returning the name of + * @return The {@link StringValueExp} returning the name of * the class of which selected MBeans should be instances. */ public StringValueExp getClassNameValue() { diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java index f89faab4138..0e44f735a97 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -909,7 +909,7 @@ final public class LdapCtx extends ComponentDirContext * @param dn The non-null DN of the entry to add * @param attrs The non-null attributes of entry to add * @param directUpdate Whether attrs can be updated directly - * @returns Non-null attributes with attributes from the RDN added + * @return Non-null attributes with attributes from the RDN added */ private static Attributes addRdnAttributes(String dn, Attributes attrs, boolean directUpdate) throws NamingException { diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ServiceLocator.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ServiceLocator.java index a7bf61d9494..b33a7792f8f 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ServiceLocator.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ServiceLocator.java @@ -62,7 +62,7 @@ class ServiceLocator { * * @param dn A string distinguished name (RFC 2253). * @return A domain name or null if none can be derived. - * @throw InvalidNameException If the distinguished name is invalid. + * @throws InvalidNameException If the distinguished name is invalid. */ static String mapDnToDomainName(String dn) throws InvalidNameException { if (dn == null) { diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java index c7f73337cc8..5b560eb8313 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java @@ -297,7 +297,7 @@ final public class StartTlsResponseImpl extends StartTlsResponse { * Returns the default SSL socket factory. * * @return The default SSL socket factory. - * @throw IOException If TLS is not supported. + * @throws IOException If TLS is not supported. */ private SSLSocketFactory getDefaultFactory() throws IOException { @@ -314,7 +314,7 @@ final public class StartTlsResponseImpl extends StartTlsResponse { * * @param factory The SSL socket factory to use. * @return The SSL socket. - * @throw IOException If an exception occurred while performing the + * @throws IOException If an exception occurred while performing the * TLS handshake. */ private SSLSocket startHandshake(SSLSocketFactory factory) diff --git a/jdk/src/java.prefs/share/classes/java/util/prefs/Base64.java b/jdk/src/java.prefs/share/classes/java/util/prefs/Base64.java index 523379c4612..5125e07d194 100644 --- a/jdk/src/java.prefs/share/classes/java/util/prefs/Base64.java +++ b/jdk/src/java.prefs/share/classes/java/util/prefs/Base64.java @@ -124,8 +124,8 @@ class Base64 { * Translates the specified Base64 string (as per Preferences.get(byte[])) * into a byte array. * - * @throw IllegalArgumentException if {@code s} is not a valid Base64 - * string. + * @throws IllegalArgumentException if {@code s} is not a valid Base64 + * string. */ static byte[] base64ToByteArray(String s) { return base64ToByteArray(s, false); @@ -135,9 +135,9 @@ class Base64 { * Translates the specified "alternate representation" Base64 string * into a byte array. * - * @throw IllegalArgumentException or ArrayOutOfBoundsException - * if {@code s} is not a valid alternate representation - * Base64 string. + * @throws IllegalArgumentException or ArrayOutOfBoundsException + * if {@code s} is not a valid alternate representation + * Base64 string. */ static byte[] altBase64ToByteArray(String s) { return base64ToByteArray(s, true); @@ -194,8 +194,8 @@ class Base64 { * Translates the specified character, which is assumed to be in the * "Base 64 Alphabet" into its equivalent 6-bit positive integer. * - * @throw IllegalArgumentException or ArrayOutOfBoundsException if - * c is not in the Base64 Alphabet. + * @throws IllegalArgumentException or ArrayOutOfBoundsException if + * c is not in the Base64 Alphabet. */ private static int base64toInt(char c, byte[] alphaToInt) { int result = alphaToInt[c]; diff --git a/jdk/src/java.rmi/share/classes/java/rmi/RemoteException.java b/jdk/src/java.rmi/share/classes/java/rmi/RemoteException.java index b125932c41e..b32558bc05f 100644 --- a/jdk/src/java.rmi/share/classes/java/rmi/RemoteException.java +++ b/jdk/src/java.rmi/share/classes/java/rmi/RemoteException.java @@ -26,11 +26,11 @@ package java.rmi; /** - * A RemoteException is the common superclass for a number of + * A {@code RemoteException} is the common superclass for a number of * communication-related exceptions that may occur during the execution of a * remote method call. Each method of a remote interface, an interface that - * extends java.rmi.Remote, must list - * RemoteException in its throws clause. + * extends {@code java.rmi.Remote}, must list + * {@code RemoteException} in its throws clause. * *

As of release 1.4, this exception has been retrofitted to conform to * the general purpose exception-chaining mechanism. The "wrapped remote @@ -40,7 +40,7 @@ package java.rmi; * the aforementioned "legacy field." * *

Invoking the method {@link Throwable#initCause(Throwable)} on an - * instance of RemoteException always throws {@link + * instance of {@code RemoteException} always throws {@link * IllegalStateException}. * * @author Ann Wollrath @@ -63,14 +63,14 @@ public class RemoteException extends java.io.IOException { public Throwable detail; /** - * Constructs a RemoteException. + * Constructs a {@code RemoteException}. */ public RemoteException() { initCause(null); // Disallow subsequent initCause } /** - * Constructs a RemoteException with the specified + * Constructs a {@code RemoteException} with the specified * detail message. * * @param s the detail message @@ -81,9 +81,9 @@ public class RemoteException extends java.io.IOException { } /** - * Constructs a RemoteException with the specified detail + * Constructs a {@code RemoteException} with the specified detail * message and cause. This constructor sets the {@link #detail} - * field to the specified Throwable. + * field to the specified {@code Throwable}. * * @param s the detail message * @param cause the cause @@ -113,7 +113,7 @@ public class RemoteException extends java.io.IOException { * Returns the cause of this exception. This method returns the value * of the {@link #detail} field. * - * @return the cause, which may be null. + * @return the cause, which may be {@code null}. * @since 1.4 */ public Throwable getCause() { diff --git a/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationException.java b/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationException.java index 7ac8bf7994d..5fc7323f529 100644 --- a/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationException.java +++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationException.java @@ -36,7 +36,7 @@ package java.rmi.activation; * the aforementioned "legacy field." * *

Invoking the method {@link Throwable#initCause(Throwable)} on an - * instance of ActivationException always throws {@link + * instance of {@code ActivationException} always throws {@link * IllegalStateException}. * * @author Ann Wollrath @@ -59,14 +59,14 @@ public class ActivationException extends Exception { private static final long serialVersionUID = -4320118837291406071L; /** - * Constructs an ActivationException. + * Constructs an {@code ActivationException}. */ public ActivationException() { initCause(null); // Disallow subsequent initCause } /** - * Constructs an ActivationException with the specified + * Constructs an {@code ActivationException} with the specified * detail message. * * @param s the detail message @@ -77,9 +77,9 @@ public class ActivationException extends Exception { } /** - * Constructs an ActivationException with the specified + * Constructs an {@code ActivationException} with the specified * detail message and cause. This constructor sets the {@link #detail} - * field to the specified Throwable. + * field to the specified {@code Throwable}. * * @param s the detail message * @param cause the cause @@ -109,7 +109,7 @@ public class ActivationException extends Exception { * Returns the cause of this exception. This method returns the value * of the {@link #detail} field. * - * @return the cause, which may be null. + * @return the cause, which may be {@code null}. * @since 1.4 */ public Throwable getCause() { diff --git a/jdk/src/java.rmi/share/classes/java/rmi/server/ServerCloneException.java b/jdk/src/java.rmi/share/classes/java/rmi/server/ServerCloneException.java index b93c56588ad..f48bd0d092f 100644 --- a/jdk/src/java.rmi/share/classes/java/rmi/server/ServerCloneException.java +++ b/jdk/src/java.rmi/share/classes/java/rmi/server/ServerCloneException.java @@ -26,8 +26,8 @@ package java.rmi.server; /** - * A ServerCloneException is thrown if a remote exception occurs - * during the cloning of a UnicastRemoteObject. + * A {@code ServerCloneException} is thrown if a remote exception occurs + * during the cloning of a {@code UnicastRemoteObject}. * *

As of release 1.4, this exception has been retrofitted to conform to * the general purpose exception-chaining mechanism. The "nested exception" @@ -37,7 +37,7 @@ package java.rmi.server; * the aforementioned "legacy field." * *

Invoking the method {@link Throwable#initCause(Throwable)} on an - * instance of ServerCloneException always throws {@link + * instance of {@code ServerCloneException} always throws {@link * IllegalStateException}. * * @author Ann Wollrath @@ -61,7 +61,7 @@ public class ServerCloneException extends CloneNotSupportedException { private static final long serialVersionUID = 6617456357664815945L; /** - * Constructs a ServerCloneException with the specified + * Constructs a {@code ServerCloneException} with the specified * detail message. * * @param s the detail message. @@ -72,7 +72,7 @@ public class ServerCloneException extends CloneNotSupportedException { } /** - * Constructs a ServerCloneException with the specified + * Constructs a {@code ServerCloneException} with the specified * detail message and cause. * * @param s the detail message. @@ -103,7 +103,7 @@ public class ServerCloneException extends CloneNotSupportedException { * Returns the cause of this exception. This method returns the value * of the {@link #detail} field. * - * @return the cause, which may be null. + * @return the cause, which may be {@code null}. * @since 1.4 */ public Throwable getCause() { diff --git a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/package.html b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/package.html index 00096524051..5945c539e56 100644 --- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/package.html +++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/package.html @@ -26,51 +26,51 @@ - + com.sun.rowset Package -Provides five standard implementations of the standard JDBC RowSet implementation -interface definitions. These reference implementations are included with the J2SE version -1.5 platform and represent the benchmark standard RowSet implementations as verified +Provides five standard implementations of the standard JDBC RowSet implementation +interface definitions. These reference implementations are included with the J2SE version +1.5 platform and represent the benchmark standard RowSet implementations as verified by the Test Compatibility Kit (TCK) as mandated by the Java Community Process. -
- +
+

1.0 Available JDBC RowSet Reference Implementations

- The following implementations are provided:
- -
JdbcRowSetImpl - The javax.sql.rowset.JdbcRowSet +The following implementations are provided:
+ +
JdbcRowSetImpl - The javax.sql.rowset.JdbcRowSet interface reference implementation.

-CachedRowSetImpl - The javax.sql.rowset.CachedRowSet interface +CachedRowSetImpl - The javax.sql.rowset.CachedRowSet interface reference implementation.

-WebRowSetImpl - The javax.sql.rowset.WebRowSet interface +WebRowSetImpl - The javax.sql.rowset.WebRowSet interface reference implementation.

-FilteredRowSetImpl - The javax.sql.rowset.FilteredRowSet +FilteredRowSetImpl - The javax.sql.rowset.FilteredRowSet interface reference implementation.

-JoinRowSetImpl - The javax.sql.rowset.JoinRowSet interface +JoinRowSetImpl - The javax.sql.rowset.JoinRowSet interface reference implementation.
-All details on their expected behavior, including their interactions with the SyncProvider -SPI and helper classes are provided in the interface definitions in the javax.sql.rowset +All details on their expected behavior, including their interactions with the SyncProvider +SPI and helper classes are provided in the interface definitions in the javax.sql.rowset package specification.
- +

2.0 Usage

The reference implementations represent robust implementations of the standard -RowSet interfaces defined in the javax.sql.rowset package. -All disconnected RowSet implementations, such as the CachedRowSetImpl -and WebRowSetImpl, are flexible enough to use the SyncFactory SPIs to -leverage non-reference implementation SyncProvider implementations to obtain -differing synchronization semantics. Furthermore, developers and vendors alike are free +RowSet interfaces defined in the javax.sql.rowset package. +All disconnected RowSet implementations, such as the CachedRowSetImpl +and WebRowSetImpl, are flexible enough to use the SyncFactory SPIs to +leverage non-reference implementation SyncProvider implementations to obtain +differing synchronization semantics. Furthermore, developers and vendors alike are free to use these implementations and integrate them into their products just as they can with to other components of the Java platform.
- +

3.0 Extending the JDBC RowSet Implementations

The JDBC RowSet reference implementations are provided as non-final @@ -81,6 +81,6 @@ set to their their particular needs. The website for JDBC Technology will provider a portal where implementations can be listed, similar to the way it provides a site for JDBC drivers.
-
+
diff --git a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/providers/package.html b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/providers/package.html index 7e7ff315b52..1910541538d 100644 --- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/providers/package.html +++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/providers/package.html @@ -1,10 +1,10 @@ - + - + contains -size requested by user - * ----------------- - * User gets --->| user space | - * | | - * | | left_over | ---> left_over bytes will be <= 7 - * ----------------- - * | clobber Word | ---> contains -size requested by user - * ----------------- - * | Warrant | ---> Optional (malloc_watch!=0) - * | | Contains filename and line number - * | | where allocation happened - * | | - * ----------------- - ***************************************************************************/ - -/* - * Flag that tells debug_malloc/debug_free/debug_realloc to police - * heap space usage. (This is a dynamic flag that can be turned on/off) - */ -static int malloc_watch = 1; - -/* Character to stuff into freed space */ -#define FREED_CHAR 'F' - -/* Character to stuff into allocated space */ -#define ALLOC_CHAR 'A' - -/* Character to stuff into left over trailing bytes */ -#define LEFT_OVER_CHAR 'Z' - -/* Number of 'free' calls that will be delayed until the end */ -#define MAX_FREE_DELAY_COUNT 1 -#undef MAX_FREE_DELAY_COUNT - -/* Maximum name of __FILE_ stored in each malloc'd area */ -#define WARRANT_NAME_MAX (32-1) /* 1 less than multiple of 8 is best */ - -/* Macro to convert a user pointer to the malloc pointer */ -#define user2malloc_(uptr) (((char*)(void*)uptr)-sizeof(Word)) - -/* Macro to convert a macro pointer to the user pointer */ -#define malloc2user_(mptr) (((char*)(void*)(mptr))+sizeof(Word)) - -/* Size of the warrant record (this is dynamic) */ -#define warrant_space ( malloc_watch?sizeof(Warrant_Record):0 ) - -/* Macro to round up a number of bytes to a multiple of sizeof(Word) bytes */ -#define round_up_(n) \ - ((n)==0?0:(sizeof(Word)+(((n)-1)/sizeof(Word))*sizeof(Word))) - -/* Macro to calculate the needed malloc bytes from the user's request. */ -#define rbytes_(nbytes) \ - (size_t)( sizeof(Word) + round_up_(nbytes) + sizeof(Word) + warrant_space ) - -/* Macro to get the -size stored in space through the malloc pointer */ -#define nsize1_(mptr) (((Word*)(void*)(mptr))->nsize1) -#define nsize2_(mptr) (((Word*)(void*)(mptr))->nsize2) - -/* Macro to get the -size stored in the tail of the space through */ -/* the malloc pointer */ -#define tail_nsize1_(mptr) \ - nsize1_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)) -#define tail_nsize2_(mptr) \ - nsize2_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)) - -/* Macro to get the -size stored in space through the user pointer */ -#define user_nsize1_(uptr) nsize1_(user2malloc_(uptr)) -#define user_nsize2_(uptr) nsize2_(user2malloc_(uptr)) - -/* Macro to get the -size stored in the tail of the space through */ -/* the user pointer */ -#define user_tail_nsize1_(uptr) tail_nsize1_(user2malloc_(uptr)) -#define user_tail_nsize2_(uptr) tail_nsize2_(user2malloc_(uptr)) - -/* Macro to get the int* of the last 32bit word of user space */ -#define last_user_word_(mptr) \ - ((int*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr)))) - -/* Macros to get at the warrant contents from the malloc pointer */ -#define warrant_(mptr) \ - (*((Warrant_Record*)(void*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)*2))) - -/* This struct is allocated after the tail clobber word if malloc_watch */ -/* is true. */ -typedef struct { - void *link; /* Next mptr in list */ - char name[WARRANT_NAME_MAX + 1]; /* Name of allocator */ - int line; /* Line number where allocated */ - int id; /* Nth allocation */ -} Warrant_Record; -#define warrant_link_(mptr) warrant_(mptr).link -#define warrant_name_(mptr) warrant_(mptr).name -#define warrant_line_(mptr) warrant_(mptr).line -#define warrant_id_(mptr) warrant_(mptr).id -#define MFILE(mptr) (malloc_watch?warrant_name_(mptr):"?") -#define MLINE(mptr) (malloc_watch?warrant_line_(mptr):0) -#define MID(mptr) (malloc_watch?warrant_id_(mptr):0) - -/* This should be one machine word and is also the clobber word struct */ -typedef struct { - int nsize1; - int nsize2; -} Word; /* Largest basic type , sizeof(double)? */ - -/* The first malloc pointer for the warrants */ -static void *first_warrant_mptr = NULL; - -/* Counter of allocations */ -static int id_counter = 0; -static int largest_size = 0; -static void * largest_addr = NULL; -static void * smallest_addr = NULL; - -/* Used to isolate what the error is */ -static char *debug_check; -static void *clobbered_ptr; - -/* Minimum macro */ -#define minimum(a,b) ((a)<(b)?(a):(b)) - -/* Message routine */ -static void -error_message(const char * format, ...) -{ - FILE *error_fp = stderr; /* All debug_malloc.c messages */ - va_list ap; - va_start(ap, format); - (void)fprintf(error_fp, "debug_malloc: "); - (void)vfprintf(error_fp, format, ap); - (void)fprintf(error_fp, "\n"); - (void)fflush(error_fp); - va_end(ap); -} - -/* This function prints out a memory error for the memory function - * 'name' which was called in file 'file' at line number 'line'. The malloc - * pointer with the error is in 'mptr'. - */ -static void -memory_error(void *mptr, const char *name, int mid, const char *mfile, int mline, const char *file, int line) -{ - char nice_words[512]; - char temp[256]; - int len; - void *mptr_walk; - - if (name == NULL) - name = "UNKNOWN_NAME"; - if (file == NULL) - file = "UNKNOWN_FILE"; - md_system_error(temp, (int)sizeof(temp)); - (void)strcpy(nice_words, temp); - if ( debug_check!=NULL ) { - (void)md_snprintf(nice_words, sizeof(nice_words), - "%s The %s at %p appears to have been hit.", - temp, debug_check, clobbered_ptr); - } - len = -nsize1_(mptr); - error_message("Error: " - "%s The malloc space #%d is at %p [user size=%d(0x%x)]," - " and was allocated from file \"%s\" at line %d." - " [The debug function %s() detected this error " - "in file \"%s\" at line %d.]", - nice_words, mid, mptr, len, len, mfile, mline, - name, file, line); - - /* Print out contents of this allocation */ - { - int i; - void *uptr = malloc2user_(mptr); - char *pmess; - pmess = temp; - for(i=0;i<(int)sizeof(temp);i++) { - int ch = ((unsigned char*)uptr)[i]; - if ( isprint(ch) ) { - *pmess++ = ch; - } else { - *pmess++ = '\\'; - *pmess++ = 'x'; - (void)sprintf(pmess,"%02x",ch); - pmess+=2; - } - } - *pmess = 0; - error_message("Error: %p contains user data: %s", uptr, temp); - } - - /* Try and print out table */ - if (!malloc_watch) { - return; - } - mptr_walk = first_warrant_mptr; - if (mptr_walk != NULL) { - error_message("Active allocations: " - "count=%d, largest_size=%d, address range (%p,%p)", - id_counter, largest_size, smallest_addr, largest_addr); - do { - int size1; - int size2; - char *mfile_walk; - - if ( mptr_walk > largest_addr || mptr_walk < smallest_addr ) { - error_message("Terminating list due to pointer corruption"); - break; - } - size1 = -nsize1_(mptr_walk); - size2 = -nsize2_(mptr_walk); - mfile_walk = MFILE(mptr_walk); - error_message("#%d: addr=%p size1=%d size2=%d file=\"%.*s\" line=%d", - MID(mptr_walk), mptr_walk, size1, size2, - WARRANT_NAME_MAX, mfile_walk, MLINE(mptr_walk)); - if ( size1 != size2 || size1 > largest_size || size1 < 0 ) { - error_message("Terminating list due to size corruption"); - break; - } - mptr_walk = warrant_link_(mptr_walk); - } while (mptr_walk != NULL); - } - abort(); -} - -/* This function sets the clobber word and sets up the warrant for the input - * malloc pointer "mptr". - */ -static void -setup_space_and_issue_warrant(void *mptr, size_t size, const char *file, int line) -{ - register int nbytes; - - /*LINTED*/ - nbytes = (int)size; - if ( nbytes > largest_size || largest_addr == NULL ) largest_size = nbytes; - /*LINTED*/ - if ( mptr > largest_addr ) largest_addr = mptr; - /*LINTED*/ - if ( mptr < smallest_addr || smallest_addr == NULL ) smallest_addr = mptr; - - /* Must be done first: */ - nsize1_(mptr) = -nbytes; - nsize2_(mptr) = -nbytes; - tail_nsize1_(mptr) = -nbytes; - tail_nsize2_(mptr) = -nbytes; - -#ifdef LEFT_OVER_CHAR - /* Fill in those few extra bytes just before the tail Word structure */ - { - register int trailing_extra_bytes; - /* LINTED */ - trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes); - if ( trailing_extra_bytes > 0 ) { - register char *p; - register int i; - p = ((char *) mptr) + sizeof(Word) + nbytes; - for (i = 0; i < trailing_extra_bytes; i++) - p[i] = LEFT_OVER_CHAR; - } - } -#endif - - /* Fill out warrant */ - if (malloc_watch) { - static Warrant_Record zero_warrant; - register void *p1, - *p2; - size_t len; - int start_pos = 0; - warrant_(mptr) = zero_warrant; - p1 = warrant_name_(mptr); - len = strlen(file); - if ( len > WARRANT_NAME_MAX ) { - /*LINTED*/ - start_pos = (int)len - WARRANT_NAME_MAX; - } - p2 = ((char*)file) + start_pos; - /*LINTED*/ - (void) memcpy(p1, p2, minimum(((int)len), WARRANT_NAME_MAX)); - warrant_line_(mptr) = line; - warrant_id_(mptr) = ++id_counter; - warrant_link_(mptr) = first_warrant_mptr; - first_warrant_mptr = mptr; - } -} - -/* This function checks the clobber words at the beginning and end of the - * allocated space. - */ -static void -memory_check(void *uptr, int mid, const char *mfile, int mline, const char *file, int line) -{ - int neg_nbytes; - int nbytes; - - debug_check = "pointer value itself"; - clobbered_ptr = uptr; - if (uptr == NULL) - memory_error((void *) NULL, "memory_check", mid, mfile, mline, file, line); - - /* Check both Word structures */ - - debug_check = "first beginning clobber word"; - clobbered_ptr = (char*)&user_nsize1_(uptr); - neg_nbytes = user_nsize1_(uptr); - if (neg_nbytes >= 0) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "second beginning clobber word"; - clobbered_ptr = (char*)&user_nsize2_(uptr); - if (neg_nbytes != user_nsize2_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "first ending clobber word"; - clobbered_ptr = (char*)&user_tail_nsize1_(uptr); - if (neg_nbytes != user_tail_nsize1_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "second ending clobber word"; - clobbered_ptr = (char*)&user_tail_nsize2_(uptr); - if (neg_nbytes != user_tail_nsize2_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - /* Get a positive count of bytes */ - nbytes = -neg_nbytes; - -#ifdef LEFT_OVER_CHAR - { - /* Check those few extra bytes just before the tail Word structure */ - register int trailing_extra_bytes; - register int i; - register char *p; - /* LINTED */ - trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes); - p = ((char *) (uptr)) + nbytes; - debug_check = "trailing left over area"; - for (i = 0; i < trailing_extra_bytes; i++) { - clobbered_ptr = p+1; - if (p[i] != LEFT_OVER_CHAR) { - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - } - } - } -#endif - - /* Make sure debug_check is cleared */ - debug_check = NULL; -} - -/* This function looks for the given malloc pointer in the police line up - * and removes it from the warrant list. - * mptr The pointer to the malloc space being removed - */ -static int -remove_warrant(void *mptr) -{ - void *mptr1, - *last_mptr1; - - /* Free it up from the list */ - if (malloc_watch && mptr != NULL) { - int found; - - found = 0; - last_mptr1 = NULL; - mptr1 = first_warrant_mptr; - while (mptr1 != NULL) { - if (mptr1 == mptr) { - if (last_mptr1 == NULL) - first_warrant_mptr = warrant_link_(mptr1); - else - warrant_link_(last_mptr1) = warrant_link_(mptr1); - found = 1; - break; - } - last_mptr1 = mptr1; - mptr1 = warrant_link_(mptr1); - } - return found; - } - return 1; -} - -static void -actual_free(void *uptr, const char *file, int line) -{ - void *mptr; - const char *mfile; - int mline; - int mid; - if ( uptr == NULL ) - return; - mptr = user2malloc_(uptr); - memory_check(uptr, (mid=MID(mptr)), (mfile=MFILE(mptr)), (mline=MLINE(mptr)), file, line); - if (malloc_watch && remove_warrant(mptr)==0 ) - memory_check(uptr, mid, mfile, mline, file, line); -#ifdef FREED_CHAR - if ( mptr!=NULL ) { - size_t nbytes = -nsize1_(mptr); - /* LINTED */ - (void)memset(mptr, FREED_CHAR, rbytes_(nbytes)); - } -#endif - free(mptr); -} - -#ifdef MAX_FREE_DELAY_COUNT - -static void *free_delay[MAX_FREE_DELAY_COUNT]; -static int free_delay_pos = 0; - -static void -delayed_free(void *uptr, const char* file, int line) -{ - void *mptr; - void *olduptr = free_delay[free_delay_pos]; - size_t nbytes; - if ( uptr==NULL ) - return; - mptr = user2malloc_(uptr); - memory_check(uptr, MID(mptr), MFILE(mptr), MLINE(mptr), file, line); - if ( olduptr!=NULL ) { - actual_free(olduptr, file, line); - } - free_delay[free_delay_pos] = uptr; - free_delay_pos++; - free_delay_pos = free_delay_pos % MAX_FREE_DELAY_COUNT; - nbytes = -user_nsize1_(uptr); -#ifdef FREED_CHAR - (void)memset(uptr, FREED_CHAR, (size_t)nbytes); -#endif -} - -static void -delayed_free_all(const char *file, int line) -{ - int i; - for ( i=0; i< MAX_FREE_DELAY_COUNT; i++) { - void *olduptr = free_delay[i]; - free_delay[i] = NULL; - if ( olduptr!=NULL ) { - actual_free(olduptr, file, line); - } - } -} - -#endif - -void -debug_free(void *uptr, const char *file, int line) -{ - int mid = 0; - - if (uptr == NULL) - memory_error((void *) NULL, "debug_free", mid, file, line, file, line); -#ifdef MAX_FREE_DELAY_COUNT - delayed_free(uptr, file, line); -#else - actual_free(uptr, file, line); -#endif -} - -/* This function calls malloc(). */ -void * -debug_malloc(size_t nbytes, const char *file, int line) -{ - void *mptr; - void *uptr; - int mid = id_counter; - - /*LINTED*/ - if ((int)nbytes <= 0) - memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line); - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - if (mptr == NULL) - memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - uptr = malloc2user_(mptr); -#ifdef ALLOC_CHAR - (void)memset(uptr, ALLOC_CHAR, (size_t)nbytes); -#endif - return uptr; -} - -void * -debug_realloc(void *uptr, size_t nbytes, const char *file, int line) -{ - void *mptr; - void *oldmptr; - void *newuptr; - size_t oldnbytes; - int mid = id_counter; - - oldmptr = user2malloc_(uptr); - oldnbytes = 0; - if ((int)nbytes <= 0) - memory_error(oldmptr, "debug_realloc", mid, file, line, file, line); - if (uptr != NULL) { - memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line); - oldnbytes = -user_nsize1_(uptr); - if ( malloc_watch && remove_warrant(oldmptr)==0 ) - memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line); - } - if (uptr == NULL) { - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - } else { - /* LINTED */ - mptr = realloc(oldmptr, rbytes_(nbytes)); - } - if (mptr == NULL) - memory_error(oldmptr, "debug_realloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - newuptr = malloc2user_(mptr); -#ifdef ALLOC_CHAR - if (uptr == NULL) - (void)memset(newuptr, ALLOC_CHAR, (size_t)nbytes); - else if ( nbytes > oldnbytes ) - (void)memset(((char*)newuptr)+oldnbytes, ALLOC_CHAR, (size_t)nbytes-oldnbytes); -#endif - return newuptr; -} - -/* This function calls calloc(). */ -void * -debug_calloc(size_t nelem, size_t elsize, const char *file, int line) -{ - void *mptr; - size_t nbytes; - int mid = id_counter; - - nbytes = nelem*elsize; - /*LINTED*/ - if ((int)nbytes <= 0) - memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line); - /* LINTED */ - mptr = calloc(rbytes_(nbytes),1); - if (mptr == NULL) - memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - return malloc2user_(mptr); -} - -/* This function replaces strdup(). */ -char * -debug_strdup(const char *s1, const char *file, int line) -{ - void *mptr; - void *uptr; - size_t nbytes; - int mid = id_counter; - - if (s1 == NULL) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - nbytes = strlen(s1)+1; - /*LINTED*/ - if ((int)nbytes < 0) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - if (mptr == NULL) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - uptr = malloc2user_(mptr); - (void)strcpy((char*)uptr, s1); - return (char*)uptr; -} - -void -debug_malloc_verify(const char *file, int line) -{ - void *mptr; - -#ifdef MAX_FREE_DELAY_COUNT - delayed_free_all(file,line); -#endif - - if (!malloc_watch) { - return; - } - mptr = first_warrant_mptr; - if (mptr != NULL) { - /* Check all this memory first */ - do { - memory_check(malloc2user_(mptr), MID(mptr), MFILE(mptr), MLINE(mptr), file, line); - mptr = warrant_link_(mptr); - } while (mptr != NULL); - } -} - -/* Report outstanding space warrants to console. */ -void -debug_malloc_police(const char *file, int line) -{ - void *mptr; - -#ifdef MAX_FREE_DELAY_COUNT - delayed_free_all(file,line); -#endif - - if (!malloc_watch) { - return; - } - - mptr = first_warrant_mptr; - if (mptr != NULL) { - debug_malloc_verify(file, line); - /* Now issue warrants */ - mptr = first_warrant_mptr; - do { - error_message("Outstanding space warrant: %p (%d bytes) allocated by %s at line %d, allocation #%d", - mptr, -nsize1_(mptr), warrant_name_(mptr), - warrant_line_(mptr), warrant_id_(mptr)); - - mptr = warrant_link_(mptr); - } while (mptr != NULL); - } -} - -#else - -void -debug_malloc_verify(const char *file, int line) -{ - file = file; - line = line; -} - -void -debug_malloc_police(const char *file, int line) -{ - file = file; - line = line; -} - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.h deleted file mode 100644 index 2b854770ff4..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* *********************************************************************** - * - * The source file debug_malloc.c should be included with your sources. - * - * The object file debug_malloc.o should be included with your object files. - * - * WARNING: Any memory allocattion from things like memalign(), valloc(), - * or any memory not coming from these macros (malloc, realloc, - * calloc, and strdup) will fail miserably. - * - * *********************************************************************** - */ - -#ifndef _DEBUG_MALLOC_H -#define _DEBUG_MALLOC_H - -#ifdef DEBUG - -#include -#include - -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - -/* The real functions behind the macro curtains. */ - -void *debug_malloc(size_t, const char *, int); -void *debug_realloc(void *, size_t, const char *, int); -void *debug_calloc(size_t, size_t, const char *, int); -char *debug_strdup(const char *, const char *, int); -void debug_free(void *, const char *, int); - -#endif - -void debug_malloc_verify(const char*, int); -#undef malloc_verify -#define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__) - -void debug_malloc_police(const char*, int); -#undef malloc_police -#define malloc_police() debug_malloc_police(THIS_FILE, __LINE__) - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof.h deleted file mode 100644 index 696de3d3a26..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Primary hprof #include file, should be included by most if not - * all hprof source files. Gives access to the global data structure - * and all global macros, and everything declared in the #include - * files of each of the source files. - */ - -#ifndef HPROF_H -#define HPROF_H - -/* Standard C functions used throughout. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* General JVM/Java functions, types and macros. */ - -#include -#include "jni.h" -#include "jvmti.h" -#include "classfile_constants.h" -#include "jvm_md.h" - -/* Macros to extract the upper and lower 32 bits of a jlong */ - -#define jlong_high(a) ((jint)((a)>>32)) -#define jlong_low(a) ((jint)(a)) -#define jlong_to_jint(a) ((jint)(a)) -#define jint_to_jlong(a) ((jlong)(a)) - -#define jlong_add(a, b) ((a) + (b)) - - -/* The type used to contain a generic 32bit "serial number". */ - -typedef unsigned SerialNumber; - -/* How the options get to OnLoad: */ - -#define AGENTNAME "hprof" -#define XRUN "-Xrun" AGENTNAME -#define AGENTLIB "-agentlib:" AGENTNAME - -/* Name of prelude file, found at runtime relative to java binary location */ - -#define PRELUDE_FILE "jvm.hprof.txt" - -/* File I/O buffer size to be used with any file i/o operation */ - -#define FILE_IO_BUFFER_SIZE (1024*64) - -/* Machine dependent functions. */ - -#include "hprof_md.h" - -/* Table index types */ - -typedef unsigned TableIndex; -typedef TableIndex ClassIndex; -typedef TableIndex FrameIndex; -typedef TableIndex IoNameIndex; -typedef TableIndex MonitorIndex; -typedef TableIndex ObjectIndex; -typedef TableIndex LoaderIndex; -typedef TableIndex RefIndex; -typedef TableIndex SiteIndex; -typedef TableIndex StringIndex; -typedef TableIndex TlsIndex; -typedef TableIndex TraceIndex; - -/* Index for method tables in classes */ - -typedef int MethodIndex; - -/* The different kinds of class status bits. */ - -enum ClassStatus { - CLASS_PREPARED = 0x00000001, - CLASS_LOADED = 0x00000002, - CLASS_UNLOADED = 0x00000004, - CLASS_SPECIAL = 0x00000008, - CLASS_IN_LOAD_LIST = 0x00000010, - CLASS_SYSTEM = 0x00000020, - CLASS_DUMPED = 0x00000040 -}; -typedef jint ClassStatus; - -/* The different kind of objects we track with heap=dump */ - -typedef unsigned char ObjectKind; -enum { - OBJECT_NORMAL = 1, - OBJECT_CLASS = 2, - OBJECT_SYSTEM = 3, - OBJECT_HPROF = 4, - OBJECT_LOADER = 5 -}; - -/* Used by site_write() when writing out the heap=sites data. */ - -enum { - SITE_DUMP_INCREMENTAL = 0x01, - SITE_SORT_BY_ALLOC = 0x02, - SITE_FORCE_GC = 0x04 -}; - -/* Used to hold information about a field, and potentially a value too. */ - -typedef struct FieldInfo { - ClassIndex cnum; - StringIndex name_index; - StringIndex sig_index; - unsigned short modifiers; - unsigned char primType; - unsigned char primSize; -} FieldInfo; - -/* Used to hold information about a constant pool entry value for a class. */ - -typedef struct ConstantPoolValue { - unsigned constant_pool_index; - StringIndex sig_index; - jvalue value; -} ConstantPoolValue; - -/* All machine independent functions */ - -#include "hprof_error.h" -#include "hprof_util.h" -#include "hprof_blocks.h" -#include "hprof_stack.h" -#include "hprof_init.h" -#include "hprof_table.h" -#include "hprof_string.h" -#include "hprof_class.h" -#include "hprof_tracker.h" -#include "hprof_frame.h" -#include "hprof_monitor.h" -#include "hprof_trace.h" -#include "hprof_site.h" -#include "hprof_event.h" -#include "hprof_reference.h" -#include "hprof_object.h" -#include "hprof_loader.h" -#include "hprof_tls.h" -#include "hprof_check.h" -#include "hprof_io.h" -#include "hprof_listener.h" -#include "hprof_cpu.h" -#include "hprof_tag.h" - -/* Global data structure */ - -struct LineTable; - -typedef struct { - - jvmtiEnv *jvmti; /* JVMTI env for this session */ - JavaVM *jvm; /* JavaVM* for this session */ - jint cachedJvmtiVersion; /* JVMTI version number */ - - char *header; /* "JAVA PROFILE 1.0.[12]" */ - jboolean segmented; /* JNI_TRUE if 1.0.2 */ - jlong maxHeapSegment; - jlong maxMemory; - - /* Option settings */ - char * options; /* option string copy */ - char * utf8_output_filename;/* file=filename */ - int net_port; /* net=hostname:port */ - char * net_hostname; /* net=hostname:port */ - char output_format; /* format=a|b */ - int max_trace_depth; /* depth=max_trace_depth */ - int prof_trace_depth; /* max_trace_depth or 2 (old) */ - int sample_interval; /* interval=sample_interval (ms) */ - double cutoff_point; /* cutoff=cutoff_point */ - jboolean cpu_sampling; /* cpu=samples|y */ - jboolean cpu_timing; /* cpu=times */ - jboolean old_timing_format; /* cpu=old (old) output format */ - jboolean heap_dump; /* heap=dump|all */ - jboolean alloc_sites; /* heap=sites|all */ - jboolean thread_in_traces; /* thread=y|n */ - jboolean lineno_in_traces; /* lineno=y|n */ - jboolean dump_on_exit; /* doe=y|n */ - jboolean micro_state_accounting; /* msa=y|n */ - jboolean force_output; /* force=y|n */ - jboolean monitor_tracing; /* monitor=y|n */ - jboolean gc_okay; /* gc_okay=y|n (Not used) */ - - unsigned logflags; /* logflags=bitmask */ - - #define DEBUGFLAG_UNPREPARED_CLASSES 0x001 - unsigned debugflags; /* debugflags=bitmask */ - - jboolean coredump; /* coredump=y|n */ - jboolean errorexit; /* errorexit=y|n */ - jboolean pause; /* pause=y|n */ - jboolean debug; /* debug=y|n */ - jboolean verbose; /* verbose=y|n */ - jboolean primfields; /* primfields=y|n */ - jboolean primarrays; /* primarrays=y|n */ - jint experiment; /* X=NUMBER */ - - int fd; /* file or socket (net=addr). */ - jboolean socket; /* True if fd is a socket (net=addr). */ - jboolean bci; /* True if any kind of BCI being done */ - jboolean obj_watch; /* True if bci and watching allocs */ - - int bci_counter; /* Class BCI counter */ - - int heap_fd; - char *output_filename; /* file=filename */ - char *heapfilename; - - int check_fd; - char *checkfilename; - - volatile jboolean dump_in_process; /* Dump in process */ - volatile jboolean jvm_initializing; /* VMInit happening */ - volatile jboolean jvm_initialized; /* VMInit happened */ - volatile jboolean jvm_shut_down; /* VMDeath happened */ - jboolean vm_death_callback_active; /* VMDeath happening */ - - /* Stack of objects freed during GC */ - Stack * object_free_stack; - jrawMonitorID object_free_lock; - - /* Lock for debug_malloc() */ - jrawMonitorID debug_malloc_lock; - - /* Count of classes that JVMTI thinks are active */ - jint class_count; - - /* Used to track callbacks for VM_DEATH */ - jrawMonitorID callbackBlock; - jrawMonitorID callbackLock; - jint active_callbacks; - - /* Running totals on all bytes allocated */ - jlong total_alloced_bytes; - jlong total_alloced_instances; - jint total_live_bytes; - jint total_live_instances; - - /* Running total on all time spent in GC (very rough estimate) */ - jlong gc_start_time; - jlong time_in_gc; - - /* Global Data access Lock */ - jrawMonitorID data_access_lock; - - /* Global Dump lock */ - jrawMonitorID dump_lock; - - /* Milli-second clock when hprof onload started */ - jlong micro_sec_ticks; - - /* Thread class (for starting agent threads) */ - ClassIndex thread_cnum; - - /* Agent threads started information */ - jboolean listener_loop_running; - jrawMonitorID listener_loop_lock; - jboolean cpu_loop_running; - jrawMonitorID cpu_loop_lock; - jrawMonitorID cpu_sample_lock; /* cpu=samples loop */ - jint gc_finish; /* Count of GC finish events */ - jboolean gc_finish_active; /* True if thread active */ - jboolean gc_finish_stop_request; /* True if we want it to stop */ - jrawMonitorID gc_finish_lock; - - jboolean pause_cpu_sampling; /* temp pause in cpu sampling */ - - /* Output buffer, position, size, and position in dump if reading */ - char * write_buffer; - int write_buffer_index; - int write_buffer_size; - char * heap_buffer; - int heap_buffer_index; - int heap_buffer_size; - jlong heap_last_tag_position; - jlong heap_write_count; - char * check_buffer; - int check_buffer_index; - int check_buffer_size; - - /* Serial number counters for tables (see hprof_table.c), classes, - * tls (thread local storage), and traces. - */ - SerialNumber table_serial_number_start; - SerialNumber class_serial_number_start; - SerialNumber thread_serial_number_start; - SerialNumber trace_serial_number_start; - SerialNumber object_serial_number_start; - SerialNumber frame_serial_number_start; - SerialNumber gref_serial_number_start; - - SerialNumber table_serial_number_counter; - SerialNumber class_serial_number_counter; - SerialNumber thread_serial_number_counter; - SerialNumber trace_serial_number_counter; - SerialNumber object_serial_number_counter; - SerialNumber frame_serial_number_counter; - SerialNumber gref_serial_number_counter; - - /* The methodID for the Object method. */ - jmethodID object_init_method; - - /* Keeping track of the tracker class and it's methods */ - volatile jint tracking_engaged; /* !=0 means it's on */ - ClassIndex tracker_cnum; - int tracker_method_count; - struct { - StringIndex name; /* String index for name */ - StringIndex sig; /* String index for signature */ - jmethodID method; /* Method ID */ - } tracker_methods[12]; /* MAX 12 Tracker class methods */ - - /* Index to some common items */ - LoaderIndex system_loader; - SerialNumber unknown_thread_serial_num; - TraceIndex system_trace_index; - SiteIndex system_object_site_index; - jint system_class_size; - TraceIndex hprof_trace_index; - SiteIndex hprof_site_index; - - /* Tables for strings, classes, sites, etc. */ - struct LookupTable * string_table; - struct LookupTable * ioname_table; - struct LookupTable * class_table; - struct LookupTable * site_table; - struct LookupTable * object_table; - struct LookupTable * reference_table; - struct LookupTable * frame_table; - struct LookupTable * trace_table; - struct LookupTable * monitor_table; - struct LookupTable * tls_table; - struct LookupTable * loader_table; - - /* Handles to java_crw_demo library */ - void * java_crw_demo_library; - void * java_crw_demo_function; - void * java_crw_demo_classname_function; - - /* Indication that the agent has been loaded */ - jboolean isLoaded; - -} GlobalData; - -/* This should be the only 'extern' in the library (not exported). */ - -extern GlobalData * gdata; - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_b_spec.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_b_spec.h deleted file mode 100644 index c9a2c346f4d..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_b_spec.h +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef HPROF_B_SPEC_H -#define HPROF_B_SPEC_H - -/* Hprof binary format enums and spec. */ - -/* Need to #define or typedef HprofId before including this file. - * hprof used ObjectIndex or 4 bytes, but it can be 4 or 8 byte type. - */ - -/* -------------------------------------------------------------------- */ -/* -------------------------------------------------------------------- */ -/* -------------------------------------------------------------------- */ - -/* - * hprof binary format: (result either written to a file or sent over - * the network). - * - * WARNING: This format is still under development, and is subject to - * change without notice. - * - * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2" (0-terminated) - * u4 size of identifiers. Identifiers are used to represent - * UTF8 strings, objects, stack traces, etc. They usually - * have the same size as host pointers. For example, on - * Solaris and Win32, the size is 4. - * u4 high word - * u4 low word number of milliseconds since 0:00 GMT, 1/1/70 - * [record]* a sequence of records. - */ - -/* - * Record format: - * - * u1 a TAG denoting the type of the record - * u4 number of *microseconds* since the time stamp in the - * header. (wraps around in a little more than an hour) - * u4 number of bytes *remaining* in the record. Note that - * this number excludes the tag and the length field itself. - * [u1]* BODY of the record (a sequence of bytes) - */ - -/* - * The following TAGs are supported: - * - * TAG BODY notes - *---------------------------------------------------------- - * HPROF_UTF8 a UTF8-encoded name - * - * id name ID - * [u1]* UTF8 characters (no trailing zero) - * - * HPROF_LOAD_CLASS a newly loaded class - * - * u4 class serial number (> 0) - * id class object ID - * u4 stack trace serial number - * id class name ID - * - * HPROF_UNLOAD_CLASS an unloading class - * - * u4 class serial_number - * - * HPROF_FRAME a Java stack frame - * - * id stack frame ID - * id method name ID - * id method signature ID - * id source file name ID - * u4 class serial number - * i4 line number. >0: normal - * -1: unknown - * -2: compiled method - * -3: native method - * - * HPROF_TRACE a Java stack trace - * - * u4 stack trace serial number - * u4 thread serial number - * u4 number of frames - * [id]* stack frame IDs - * - * - * HPROF_ALLOC_SITES a set of heap allocation sites, obtained after GC - * - * u2 flags 0x0001: incremental vs. complete - * 0x0002: sorted by allocation vs. live - * 0x0004: whether to force a GC - * u4 cutoff ratio - * u4 total live bytes - * u4 total live instances - * u8 total bytes allocated - * u8 total instances allocated - * u4 number of sites that follow - * [u1 is_array: 0: normal object - * 2: object array - * 4: boolean array - * 5: char array - * 6: float array - * 7: double array - * 8: byte array - * 9: short array - * 10: int array - * 11: long array - * u4 class serial number (may be zero during startup) - * u4 stack trace serial number - * u4 number of bytes alive - * u4 number of instances alive - * u4 number of bytes allocated - * u4]* number of instance allocated - * - * HPROF_START_THREAD a newly started thread. - * - * u4 thread serial number (> 0) - * id thread object ID - * u4 stack trace serial number - * id thread name ID - * id thread group name ID - * id thread group parent name ID - * - * HPROF_END_THREAD a terminating thread. - * - * u4 thread serial number - * - * HPROF_HEAP_SUMMARY heap summary - * - * u4 total live bytes - * u4 total live instances - * u8 total bytes allocated - * u8 total instances allocated - * - * HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT denote a heap dump - * - * [heap dump sub-records]* - * - * There are four kinds of heap dump sub-records: - * - * u1 sub-record type - * - * HPROF_GC_ROOT_UNKNOWN unknown root - * - * id object ID - * - * HPROF_GC_ROOT_THREAD_OBJ thread object - * - * id thread object ID (may be 0 for a - * thread newly attached through JNI) - * u4 thread sequence number - * u4 stack trace sequence number - * - * HPROF_GC_ROOT_JNI_GLOBAL JNI global ref root - * - * id object ID - * id JNI global ref ID - * - * HPROF_GC_ROOT_JNI_LOCAL JNI local ref - * - * id object ID - * u4 thread serial number - * u4 frame # in stack trace (-1 for empty) - * - * HPROF_GC_ROOT_JAVA_FRAME Java stack frame - * - * id object ID - * u4 thread serial number - * u4 frame # in stack trace (-1 for empty) - * - * HPROF_GC_ROOT_NATIVE_STACK Native stack - * - * id object ID - * u4 thread serial number - * - * HPROF_GC_ROOT_STICKY_CLASS System class - * - * id object ID - * - * HPROF_GC_ROOT_THREAD_BLOCK Reference from thread block - * - * id object ID - * u4 thread serial number - * - * HPROF_GC_ROOT_MONITOR_USED Busy monitor - * - * id object ID - * - * HPROF_GC_CLASS_DUMP dump of a class object - * - * id class object ID - * u4 stack trace serial number - * id super class object ID - * id class loader object ID - * id signers object ID - * id protection domain object ID - * id reserved - * id reserved - * - * u4 instance size (in bytes) - * - * u2 size of constant pool - * [u2, constant pool index, - * ty, type - * 2: object - * 4: boolean - * 5: char - * 6: float - * 7: double - * 8: byte - * 9: short - * 10: int - * 11: long - * vl]* and value - * - * u2 number of static fields - * [id, static field name, - * ty, type, - * vl]* and value - * - * u2 number of inst. fields (not inc. super) - * [id, instance field name, - * ty]* type - * - * HPROF_GC_INSTANCE_DUMP dump of a normal object - * - * id object ID - * u4 stack trace serial number - * id class object ID - * u4 number of bytes that follow - * [vl]* instance field values (class, followed - * by super, super's super ...) - * - * HPROF_GC_OBJ_ARRAY_DUMP dump of an object array - * - * id array object ID - * u4 stack trace serial number - * u4 number of elements - * id array class ID - * [id]* elements - * - * HPROF_GC_PRIM_ARRAY_DUMP dump of a primitive array - * - * id array object ID - * u4 stack trace serial number - * u4 number of elements - * u1 element type - * 4: boolean array - * 5: char array - * 6: float array - * 7: double array - * 8: byte array - * 9: short array - * 10: int array - * 11: long array - * [u1]* elements - * - * HPROF_HEAP_DUMP_END terminates series of heap dump segments - * - * HPROF_CPU_SAMPLES a set of sample traces of running threads - * - * u4 total number of samples - * u4 # of traces - * [u4 # of samples - * u4]* stack trace serial number - * - * HPROF_CONTROL_SETTINGS the settings of on/off switches - * - * u4 0x00000001: alloc traces on/off - * 0x00000002: cpu sampling on/off - * u2 stack trace depth - * - */ - -typedef enum HprofTag { - HPROF_UTF8 = 0x01, - HPROF_LOAD_CLASS = 0x02, - HPROF_UNLOAD_CLASS = 0x03, - HPROF_FRAME = 0x04, - HPROF_TRACE = 0x05, - HPROF_ALLOC_SITES = 0x06, - HPROF_HEAP_SUMMARY = 0x07, - HPROF_START_THREAD = 0x0A, - HPROF_END_THREAD = 0x0B, - HPROF_HEAP_DUMP = 0x0C, - HPROF_HEAP_DUMP_SEGMENT = 0x1C, /* 1.0.2 only */ - HPROF_HEAP_DUMP_END = 0x2C, /* 1.0.2 only */ - HPROF_CPU_SAMPLES = 0x0D, - HPROF_CONTROL_SETTINGS = 0x0E -} HprofTag; - -/* - * Heap dump constants - */ - -typedef enum HprofGcTag { - HPROF_GC_ROOT_UNKNOWN = 0xFF, - HPROF_GC_ROOT_JNI_GLOBAL = 0x01, - HPROF_GC_ROOT_JNI_LOCAL = 0x02, - HPROF_GC_ROOT_JAVA_FRAME = 0x03, - HPROF_GC_ROOT_NATIVE_STACK = 0x04, - HPROF_GC_ROOT_STICKY_CLASS = 0x05, - HPROF_GC_ROOT_THREAD_BLOCK = 0x06, - HPROF_GC_ROOT_MONITOR_USED = 0x07, - HPROF_GC_ROOT_THREAD_OBJ = 0x08, - HPROF_GC_CLASS_DUMP = 0x20, - HPROF_GC_INSTANCE_DUMP = 0x21, - HPROF_GC_OBJ_ARRAY_DUMP = 0x22, - HPROF_GC_PRIM_ARRAY_DUMP = 0x23 -} HprofGcTag; - -enum HprofType { - HPROF_ARRAY_OBJECT = 1, - HPROF_NORMAL_OBJECT = 2, - HPROF_BOOLEAN = 4, - HPROF_CHAR = 5, - HPROF_FLOAT = 6, - HPROF_DOUBLE = 7, - HPROF_BYTE = 8, - HPROF_SHORT = 9, - HPROF_INT = 10, - HPROF_LONG = 11 -}; -typedef unsigned char HprofType; - -#define HPROF_TYPE_SIZES \ - { \ - /*Object?*/ sizeof(HprofId), \ - /*Object?*/ sizeof(HprofId), \ - /*Array*/ sizeof(HprofId), \ - /*Object?*/ sizeof(HprofId), \ - /*jboolean*/ 1, \ - /*jchar*/ 2, \ - /*jfloat*/ 4, \ - /*jdouble*/ 8, \ - /*jbyte*/ 1, \ - /*jshort*/ 2, \ - /*jint*/ 4, \ - /*jlong*/ 8 \ - } - -#define HPROF_TYPE_IS_PRIMITIVE(ty) ((ty)>=HPROF_BOOLEAN) - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c deleted file mode 100644 index ce205bf2ce6..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Allocations from large blocks, no individual free's */ - -#include "hprof.h" - -/* - * This file contains some allocation code that allows you - * to have space allocated via larger blocks of space. - * The only free allowed is of all the blocks and all the elements. - * Elements can be of different alignments and fixed or variable sized. - * The space allocated never moves. - * - */ - -/* Get the real size allocated based on alignment and bytes needed */ -static int -real_size(int alignment, int nbytes) -{ - if ( alignment > 1 ) { - int wasted; - - wasted = alignment - ( nbytes % alignment ); - if ( wasted != alignment ) { - nbytes += wasted; - } - } - return nbytes; -} - -/* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */ -static void -add_block(Blocks *blocks, int nbytes) -{ - int header_size; - int block_size; - BlockHeader *block_header; - - HPROF_ASSERT(blocks!=NULL); - HPROF_ASSERT(nbytes>0); - - header_size = real_size(blocks->alignment, sizeof(BlockHeader)); - block_size = blocks->elem_size*blocks->population; - if ( nbytes > block_size ) { - block_size = real_size(blocks->alignment, nbytes); - } - block_header = (BlockHeader*)HPROF_MALLOC(block_size+header_size); - block_header->next = NULL; - block_header->bytes_left = block_size; - block_header->next_pos = header_size; - - /* Link in new block */ - if ( blocks->current_block != NULL ) { - blocks->current_block->next = block_header; - } - blocks->current_block = block_header; - if ( blocks->first_block == NULL ) { - blocks->first_block = block_header; - } -} - -/* Initialize a new Blocks */ -Blocks * -blocks_init(int alignment, int elem_size, int population) -{ - Blocks *blocks; - - HPROF_ASSERT(alignment>0); - HPROF_ASSERT(elem_size>0); - HPROF_ASSERT(population>0); - - blocks = (Blocks*)HPROF_MALLOC(sizeof(Blocks)); - blocks->alignment = alignment; - blocks->elem_size = elem_size; - blocks->population = population; - blocks->first_block = NULL; - blocks->current_block = NULL; - return blocks; -} - -/* Allocate bytes from a Blocks area. */ -void * -blocks_alloc(Blocks *blocks, int nbytes) -{ - BlockHeader *block; - int pos; - void *ptr; - - HPROF_ASSERT(blocks!=NULL); - HPROF_ASSERT(nbytes>=0); - if ( nbytes == 0 ) { - return NULL; - } - - block = blocks->current_block; - nbytes = real_size(blocks->alignment, nbytes); - if ( block == NULL || block->bytes_left < nbytes ) { - add_block(blocks, nbytes); - block = blocks->current_block; - } - pos = block->next_pos; - ptr = (void*)(((char*)block)+pos); - block->next_pos += nbytes; - block->bytes_left -= nbytes; - return ptr; -} - -/* Terminate the Blocks */ -void -blocks_term(Blocks *blocks) -{ - BlockHeader *block; - - HPROF_ASSERT(blocks!=NULL); - - block = blocks->first_block; - while ( block != NULL ) { - BlockHeader *next_block; - - next_block = block->next; - HPROF_FREE(block); - block = next_block; - } - HPROF_FREE(blocks); -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.h deleted file mode 100644 index d6dd6d38091..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_BLOCKS_H -#define HPROF_BLOCKS_H - -typedef struct BlockHeader { - struct BlockHeader *next; - int bytes_left; - int next_pos; -} BlockHeader; - -typedef struct Blocks { - BlockHeader *first_block; /* Pointer to first BlockHeader */ - BlockHeader *current_block; /* Pointer to current BlockHeader */ - int alignment; /* Data alignment, 1, 2, 4, 8, 16 */ - int elem_size; /* Size in bytes, ==1 means variable sizes */ - int population; /* Number of elements to allow for per Block */ -} Blocks; - -Blocks * blocks_init(int alignment, int elem_size, int population); -void * blocks_alloc(Blocks *blocks, int nbytes); -void blocks_term(Blocks *blocks); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.c deleted file mode 100644 index aef1eb90ef2..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.c +++ /dev/null @@ -1,1152 +0,0 @@ -/* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Functionality for checking hprof format=b output. */ - -/* ONLY used with logflags=4. */ - -/* Verifies and write a verbose textual version of a format=b file. - * Textual output file is gdata->checkfilename, fd is gdata->check_fd. - * Buffer is in gdata too, see gdata->check* variables. - * Could probably be isolated to a separate library or utility. - */ - -#include "hprof.h" - -typedef TableIndex HprofId; - -#include "hprof_b_spec.h" - -static int type_size[ /*HprofType*/ ] = HPROF_TYPE_SIZES; - -/* For map from HPROF_UTF8 to a string */ -typedef struct UmapInfo { - char *str; -} UmapInfo; - -/* Field information */ -typedef struct Finfo { - HprofId id; - HprofType ty; -} Finfo; - -/* Class information map from class ID (ClassIndex) to class information */ -typedef struct CmapInfo { - int max_finfo; - int n_finfo; - Finfo *finfo; - int inst_size; - HprofId sup; -} CmapInfo; - -/* Read raw bytes from the file image, update the pointer */ -static void -read_raw(unsigned char **pp, unsigned char *buf, int len) -{ - while ( len > 0 ) { - *buf = **pp; - buf++; - (*pp)++; - len--; - } -} - -/* Read various sized elements, properly converted from big to right endian. - * File will contain big endian format. - */ -static unsigned -read_u1(unsigned char **pp) -{ - unsigned char b; - - read_raw(pp, &b, 1); - return b; -} -static unsigned -read_u2(unsigned char **pp) -{ - unsigned short s; - - read_raw(pp, (void*)&s, 2); - return md_htons(s); -} -static unsigned -read_u4(unsigned char **pp) -{ - unsigned int u; - - read_raw(pp, (void*)&u, 4); - return md_htonl(u); -} -static jlong -read_u8(unsigned char **pp) -{ - unsigned int high; - unsigned int low; - jlong x; - - high = read_u4(pp); - low = read_u4(pp); - x = high; - x = (x << 32) | low; - return x; -} -static HprofId -read_id(unsigned char **pp) -{ - return (HprofId)read_u4(pp); -} - -/* System error routine */ -static void -system_error(const char *system_call, int rc, int errnum) -{ - char buf[256]; - char details[256]; - - details[0] = 0; - if ( errnum != 0 ) { - md_system_error(details, (int)sizeof(details)); - } else if ( rc >= 0 ) { - (void)strcpy(details,"Only part of buffer processed"); - } - if ( details[0] == 0 ) { - (void)strcpy(details,"Unknown system error condition"); - } - (void)md_snprintf(buf, sizeof(buf), "System %s failed: %s\n", - system_call, details); - HPROF_ERROR(JNI_TRUE, buf); -} - -/* Write to a fd */ -static void -system_write(int fd, void *buf, int len) -{ - int res; - - HPROF_ASSERT(fd>=0); - res = md_write(fd, buf, len); - if (res < 0 || res!=len) { - system_error("write", res, errno); - } -} - -/* Flush check buffer */ -static void -check_flush(void) -{ - if ( gdata->check_fd < 0 ) { - return; - } - if (gdata->check_buffer_index) { - system_write(gdata->check_fd, gdata->check_buffer, gdata->check_buffer_index); - gdata->check_buffer_index = 0; - } -} - -/* Read out a given typed element */ -static jvalue -read_val(unsigned char **pp, HprofType ty) -{ - jvalue val; - static jvalue empty_val; - - val = empty_val; - switch ( ty ) { - case 0: - case HPROF_ARRAY_OBJECT: - case HPROF_NORMAL_OBJECT: - val.i = read_id(pp); - break; - case HPROF_BYTE: - case HPROF_BOOLEAN: - val.b = read_u1(pp); - break; - case HPROF_CHAR: - case HPROF_SHORT: - val.s = read_u2(pp); - break; - case HPROF_FLOAT: - case HPROF_INT: - val.i = read_u4(pp); - break; - case HPROF_DOUBLE: - case HPROF_LONG: - val.j = read_u8(pp); - break; - default: - HPROF_ERROR(JNI_TRUE, "bad type number"); - break; - } - return val; -} - -/* Move arbitrary byte stream into gdata->check_fd */ -static void -check_raw(void *buf, int len) -{ - if ( gdata->check_fd < 0 ) { - return; - } - - if ( len <= 0 ) { - return; - } - - if (gdata->check_buffer_index + len > gdata->check_buffer_size) { - check_flush(); - if (len > gdata->check_buffer_size) { - system_write(gdata->check_fd, buf, len); - return; - } - } - (void)memcpy(gdata->check_buffer + gdata->check_buffer_index, buf, len); - gdata->check_buffer_index += len; -} - -/* Printf for gdata->check_fd */ -static void -check_printf(char *fmt, ...) -{ - char buf[1024]; - va_list args; - - if ( gdata->check_fd < 0 ) { - return; - } - - va_start(args, fmt); - (void)md_vsnprintf(buf, sizeof(buf), fmt, args); - buf[sizeof(buf)-1] = 0; - check_raw(buf, (int)strlen(buf)); - va_end(args); -} - -/* Printf of an element for gdata->check_fd */ -static void -check_printf_val(HprofType ty, jvalue val, int long_form) -{ - jint low; - jint high; - - switch ( ty ) { - case HPROF_ARRAY_OBJECT: - check_printf("0x%08x", val.i); - break; - case HPROF_NORMAL_OBJECT: - check_printf("0x%08x", val.i); - break; - case HPROF_BOOLEAN: - check_printf("0x%02x", val.b); - break; - case HPROF_CHAR: - if ( long_form ) { - if ( val.s < 0 || val.s > 0x7f || !isprint(val.s) ) { - check_printf("0x%04x", val.s); - } else { - check_printf("0x%04x(%c)", val.s, val.s); - } - } else { - if ( val.s < 0 || val.s > 0x7f || !isprint(val.s) ) { - check_printf("\\u%04x", val.s); - } else { - check_printf("%c", val.s); - } - } - break; - case HPROF_FLOAT: - low = jlong_low(val.j); - check_printf("0x%08x(%f)", low, (double)val.f); - break; - case HPROF_DOUBLE: - high = jlong_high(val.j); - low = jlong_low(val.j); - check_printf("0x%08x%08x(%f)", high, low, val.d); - break; - case HPROF_BYTE: - check_printf("0x%02x", val.b); - break; - case HPROF_SHORT: - check_printf("0x%04x", val.s); - break; - case HPROF_INT: - check_printf("0x%08x", val.i); - break; - case HPROF_LONG: - high = jlong_high(val.j); - low = jlong_low(val.j); - check_printf("0x%08x%08x", high, low); - break; - } -} - -/* Printf of a string for gdata->check_fd */ -static void -check_printf_str(char *str) -{ - int len; - int i; - - if ( str == NULL ) { - check_printf(""); - } - check_printf("\""); - len = (int)strlen(str); - for (i = 0; i < len; i++) { - unsigned char c; - c = str[i]; - if ( isprint(c) ) { - check_printf("%c", c); - } else { - check_printf("\\x%02x", c); - } - } - check_printf("\""); -} - -/* Printf of a utf8 id for gdata->check_fd */ -static void -check_print_utf8(struct LookupTable *utab, char *prefix, HprofId id) -{ - TableIndex uindex; - - if ( id == 0 ) { - check_printf("%s0x%x", prefix, id); - } else { - uindex = table_find_entry(utab, &id, sizeof(id)); - if ( uindex == 0 ) { - check_printf("%s0x%x", prefix, id); - } else { - UmapInfo *umap; - - umap = (UmapInfo*)table_get_info(utab, uindex); - HPROF_ASSERT(umap!=NULL); - HPROF_ASSERT(umap->str!=NULL); - check_printf("%s0x%x->", prefix, id); - check_printf_str(umap->str); - } - } -} - -/* Add a instance field information to this cmap. */ -static void -add_inst_field_to_cmap(CmapInfo *cmap, HprofId id, HprofType ty) -{ - int i; - - HPROF_ASSERT(cmap!=NULL); - i = cmap->n_finfo++; - if ( i+1 >= cmap->max_finfo ) { - int osize; - Finfo *new_finfo; - - osize = cmap->max_finfo; - cmap->max_finfo += 12; - new_finfo = (Finfo*)HPROF_MALLOC(cmap->max_finfo*(int)sizeof(Finfo)); - (void)memset(new_finfo,0,cmap->max_finfo*(int)sizeof(Finfo)); - if ( i == 0 ) { - cmap->finfo = new_finfo; - } else { - (void)memcpy(new_finfo,cmap->finfo,osize*(int)sizeof(Finfo)); - HPROF_FREE(cmap->finfo); - cmap->finfo = new_finfo; - } - } - cmap->finfo[i].id = id; - cmap->finfo[i].ty = ty; -} - -/* LookupTable callback for cmap entry cleanup */ -static void -cmap_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data) -{ - CmapInfo *cmap = info; - - if ( cmap == NULL ) { - return; - } - if ( cmap->finfo != NULL ) { - HPROF_FREE(cmap->finfo); - cmap->finfo = NULL; - } -} - -/* Case label for a switch on hprof heap dump elements */ -#define CASE_HEAP(name) case name: label = #name; - -/* Given the heap dump data and the utf8 map, check/write the heap dump. */ -static int -check_heap_tags(struct LookupTable *utab, unsigned char *pstart, int nbytes) -{ - int nrecords; - unsigned char *p; - unsigned char *psave; - struct LookupTable *ctab; - CmapInfo cmap; - char *label; - unsigned tag; - HprofType ty; - HprofId id, id2, fr, sup; - int num_elements; - int num_bytes; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - int npos; - int i; - int inst_size; - - ctab = table_initialize("temp ctab", 64, 64, 512, sizeof(CmapInfo)); - - /* First pass over heap records just fills in the CmapInfo table */ - nrecords = 0; - p = pstart; - while ( p < (pstart+nbytes) ) { - nrecords++; - /*LINTED*/ - npos = (int)(p - pstart); - tag = read_u1(&p); - switch ( tag ) { - CASE_HEAP(HPROF_GC_ROOT_UNKNOWN) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JNI_GLOBAL) - id = read_id(&p); - id2 = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JNI_LOCAL) - id = read_id(&p); - thread_serial_num = read_u4(&p); - fr = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JAVA_FRAME) - id = read_id(&p); - thread_serial_num = read_u4(&p); - fr = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_NATIVE_STACK) - id = read_id(&p); - thread_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_STICKY_CLASS) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_THREAD_BLOCK) - id = read_id(&p); - thread_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_MONITOR_USED) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_THREAD_OBJ) - id = read_id(&p); - thread_serial_num = read_u4(&p); - trace_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_CLASS_DUMP) - (void)memset((void*)&cmap, 0, sizeof(cmap)); - id = read_id(&p); - trace_serial_num = read_u4(&p); - { - HprofId ld, si, pr, re1, re2; - - sup = read_id(&p); - ld = read_id(&p); - si = read_id(&p); - pr = read_id(&p); - re1 = read_id(&p); - re2 = read_id(&p); - cmap.sup = sup; - } - inst_size = read_u4(&p); - cmap.inst_size = inst_size; - num_elements = read_u2(&p); - for(i=0; i 0 ) { - TableIndex cindex; - int ifield; - CmapInfo *map; - - cindex = table_find_entry(ctab, &id2, sizeof(id2)); - HPROF_ASSERT(cindex!=0); - map = (CmapInfo*)table_get_info(ctab, cindex); - HPROF_ASSERT(map!=NULL); - HPROF_ASSERT(num_bytes==map->inst_size); - - psave = p; - ifield = 0; - - do { - for(i=0;in_finfo;i++) { - HprofType ty; - HprofId id; - jvalue val; - - ty = map->finfo[i].ty; - id = map->finfo[i].id; - HPROF_ASSERT(ty!=0); - HPROF_ASSERT(id!=0); - val = read_val(&p, ty); - check_printf(" field %d: ", ifield); - check_print_utf8(utab, "id=", id); - check_printf(", ty=%d, val=", ty); - check_printf_val(ty, val, 1); - check_printf("\n"); - ifield++; - } - id2 = map->sup; - map = NULL; - cindex = 0; - if ( id2 != 0 ) { - cindex = table_find_entry(ctab, &id2, sizeof(id2)); - HPROF_ASSERT(cindex!=0); - map = (CmapInfo*)table_get_info(ctab, cindex); - HPROF_ASSERT(map!=NULL); - } - } while ( map != NULL ); - HPROF_ASSERT(num_bytes==(p-psave)); - } - break; - CASE_HEAP(HPROF_GC_OBJ_ARRAY_DUMP) - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - num_elements = read_u4(&p); - id2 = read_id(&p); - check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u, nelems=%d, eid=0x%x\n", - nrecords, npos, label, id, trace_serial_num, num_elements, id2); - for(i=0; i 0 ) { - int count; - int long_form; - int max_count; - char *quote; - - quote = ""; - long_form = 1; - max_count = 8; - count = 0; - switch ( ty ) { - case HPROF_CHAR: - long_form = 0; - max_count = 72; - quote = "\""; - /*FALLTHRU*/ - case HPROF_INT: - case HPROF_DOUBLE: - case HPROF_LONG: - case HPROF_BYTE: - case HPROF_BOOLEAN: - case HPROF_SHORT: - case HPROF_FLOAT: - check_printf(" val=%s", quote); - for(i=0; i 0 && count == 0 ) { - check_printf(" %s", quote); - } - val = read_val(&p, ty); - check_printf_val(ty, val, long_form); - count += 1; - if ( count >= max_count ) { - check_printf("\"\n"); - count = 0; - } - } - if ( count != 0 ) { - check_printf("%s\n", quote); - } - break; - } - } - HPROF_ASSERT(type_size[ty]*num_elements==(p-psave)); - break; - default: - label = "UNKNOWN"; - check_printf("H#%d@%d %s: ERROR!\n", - nrecords, npos, label); - HPROF_ERROR(JNI_TRUE, "unknown heap record type"); - break; - } - } - CHECK_FOR_ERROR(p==pstart+nbytes); - - table_cleanup(ctab, &cmap_cleanup, NULL); - - return nrecords; -} - -/* LookupTable cleanup callback for utab */ -static void -utab_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data) -{ - UmapInfo *umap = info; - - if ( umap == NULL ) { - return; - } - if ( umap->str != NULL ) { - HPROF_FREE(umap->str); - umap->str = NULL; - } -} - -/* Check all the heap tags in a heap dump */ -static int -check_tags(unsigned char *pstart, int nbytes) -{ - unsigned char *p; - int nrecord; - struct LookupTable *utab; - UmapInfo umap; - - check_printf("\nCHECK TAGS: starting\n"); - - utab = table_initialize("temp utf8 map", 64, 64, 512, sizeof(UmapInfo)); - - /* Walk the tags, assumes UTF8 tags are defined before used */ - p = pstart; - nrecord = 0; - while ( p < (pstart+nbytes) ) { - unsigned tag; - unsigned size; - int nheap_records; - int npos; - char *label; - HprofId id, nm, sg, so, gr, gn; - int i, li, num_elements; - HprofType ty; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - SerialNumber class_serial_num; - unsigned flags; - unsigned depth; - float cutoff; - unsigned temp; - jint nblive; - jint nilive; - jlong tbytes; - jlong tinsts; - jint total_samples; - jint trace_count; - - nrecord++; - /*LINTED*/ - npos = (int)(p - pstart); - tag = read_u1(&p); - (void)read_u4(&p); /* microsecs */ - size = read_u4(&p); - #define CASE_TAG(name) case name: label = #name; - switch ( tag ) { - CASE_TAG(HPROF_UTF8) - CHECK_FOR_ERROR(size>=(int)sizeof(HprofId)); - id = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, name_id=0x%x, \"", - nrecord, npos, label, size, id); - num_elements = size-(int)sizeof(HprofId); - check_raw(p, num_elements); - check_printf("\"\n"); - /* Create entry in umap */ - umap.str = HPROF_MALLOC(num_elements+1); - (void)strncpy(umap.str, (char*)p, (size_t)num_elements); - umap.str[num_elements] = 0; - (void)table_create_entry(utab, &id, sizeof(id), &umap); - p += num_elements; - break; - CASE_TAG(HPROF_LOAD_CLASS) - CHECK_FOR_ERROR(size==2*4+2*(int)sizeof(HprofId)); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nm = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u," - " id=0x%x, trace_serial_num=%u, name_id=0x%x\n", - nrecord, npos, label, size, class_serial_num, - id, trace_serial_num, nm); - break; - CASE_TAG(HPROF_UNLOAD_CLASS) - CHECK_FOR_ERROR(size==4); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u\n", - nrecord, npos, label, size, class_serial_num); - break; - CASE_TAG(HPROF_FRAME) - CHECK_FOR_ERROR(size==2*4+4*(int)sizeof(HprofId)); - id = read_id(&p); - nm = read_id(&p); - sg = read_id(&p); - so = read_id(&p); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - li = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, ", nrecord, npos, label, size); - check_print_utf8(utab, "id=", id); - check_printf(" name_id=0x%x, sig_id=0x%x, source_id=0x%x," - " class_serial_num=%u, lineno=%d\n", - nm, sg, so, class_serial_num, li); - break; - CASE_TAG(HPROF_TRACE) - CHECK_FOR_ERROR(size>=3*4); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - thread_serial_num = read_u4(&p); /* Can be 0 */ - num_elements = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, trace_serial_num=%u," - " thread_serial_num=%u, nelems=%d [", - nrecord, npos, label, size, - trace_serial_num, thread_serial_num, num_elements); - for(i=0; i< num_elements; i++) { - check_printf("0x%x,", read_id(&p)); - } - check_printf("]\n"); - break; - CASE_TAG(HPROF_ALLOC_SITES) - CHECK_FOR_ERROR(size>=2+4*4+2*8); - flags = read_u2(&p); - temp = read_u4(&p); - cutoff = *((float*)&temp); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u8(&p); - tinsts = read_u8(&p); - num_elements = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, flags=0x%x, cutoff=%g," - " nblive=%d, nilive=%d, tbytes=(%d,%d)," - " tinsts=(%d,%d), num_elements=%d\n", - nrecord, npos, label, size, - flags, cutoff, nblive, nilive, - jlong_high(tbytes), jlong_low(tbytes), - jlong_high(tinsts), jlong_low(tinsts), - num_elements); - for(i=0; i< num_elements; i++) { - ty = read_u1(&p); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u4(&p); - tinsts = read_u4(&p); - check_printf("\t %d: ty=%d, class_serial_num=%u," - " trace_serial_num=%u, nblive=%d, nilive=%d," - " tbytes=%d, tinsts=%d\n", - i, ty, class_serial_num, trace_serial_num, - nblive, nilive, (jint)tbytes, (jint)tinsts); - } - break; - CASE_TAG(HPROF_HEAP_SUMMARY) - CHECK_FOR_ERROR(size==2*4+2*8); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u8(&p); - tinsts = read_u8(&p); - check_printf("#%d@%d: %s, sz=%d," - " nblive=%d, nilive=%d, tbytes=(%d,%d)," - " tinsts=(%d,%d)\n", - nrecord, npos, label, size, - nblive, nilive, - jlong_high(tbytes), jlong_low(tbytes), - jlong_high(tinsts), jlong_low(tinsts)); - break; - CASE_TAG(HPROF_START_THREAD) - CHECK_FOR_ERROR(size==2*4+4*(int)sizeof(HprofId)); - thread_serial_num = read_u4(&p); - CHECK_THREAD_SERIAL_NO(thread_serial_num); - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nm = read_id(&p); - gr = read_id(&p); - gn = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u," - " id=0x%x, trace_serial_num=%u, ", - nrecord, npos, label, size, - thread_serial_num, id, trace_serial_num); - check_print_utf8(utab, "nm=", id); - check_printf(" trace_serial_num=%u, nm=0x%x," - " gr=0x%x, gn=0x%x\n", - trace_serial_num, nm, gr, gn); - break; - CASE_TAG(HPROF_END_THREAD) - CHECK_FOR_ERROR(size==4); - thread_serial_num = read_u4(&p); - CHECK_THREAD_SERIAL_NO(thread_serial_num); - check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u\n", - nrecord, npos, label, size, thread_serial_num); - break; - CASE_TAG(HPROF_HEAP_DUMP) - check_printf("#%d@%d: BEGIN: %s, sz=%d\n", - nrecord, npos, label, size); - nheap_records = check_heap_tags(utab, p, size); - check_printf("#%d@%d: END: %s, sz=%d, nheap_recs=%d\n", - nrecord, npos, label, size, nheap_records); - p += size; - break; - CASE_TAG(HPROF_HEAP_DUMP_SEGMENT) /* 1.0.2 */ - check_printf("#%d@%d: BEGIN SEGMENT: %s, sz=%d\n", - nrecord, npos, label, size); - nheap_records = check_heap_tags(utab, p, size); - check_printf("#%d@%d: END SEGMENT: %s, sz=%d, nheap_recs=%d\n", - nrecord, npos, label, size, nheap_records); - p += size; - break; - CASE_TAG(HPROF_HEAP_DUMP_END) /* 1.0.2 */ - check_printf("#%d@%d: SEGMENT END: %s, sz=%d\n", - nrecord, npos, label, size); - break; - CASE_TAG(HPROF_CPU_SAMPLES) - CHECK_FOR_ERROR(size>=2*4); - total_samples = read_u4(&p); - trace_count = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, total_samples=%d," - " trace_count=%d\n", - nrecord, npos, label, size, - total_samples, trace_count); - for(i=0; i< trace_count; i++) { - num_elements = read_u4(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - check_printf("\t %d: samples=%d, trace_serial_num=%u\n", - trace_serial_num, num_elements); - } - break; - CASE_TAG(HPROF_CONTROL_SETTINGS) - CHECK_FOR_ERROR(size==4+2); - flags = read_u4(&p); - depth = read_u2(&p); - check_printf("#%d@%d: %s, sz=%d, flags=0x%x, depth=%d\n", - nrecord, npos, label, size, flags, depth); - break; - default: - label = "UNKNOWN"; - check_printf("#%d@%d: %s, sz=%d\n", - nrecord, npos, label, size); - HPROF_ERROR(JNI_TRUE, "unknown record type"); - p += size; - break; - } - CHECK_FOR_ERROR(p<=(pstart+nbytes)); - } - check_flush(); - CHECK_FOR_ERROR(p==(pstart+nbytes)); - table_cleanup(utab, &utab_cleanup, NULL); - return nrecord; -} - -/* Read the entire file into memory */ -static void * -get_binary_file_image(char *filename, int *pnbytes) -{ - unsigned char *image; - int fd; - jlong nbytes; - int nread; - - *pnbytes = 0; - fd = md_open_binary(filename); - CHECK_FOR_ERROR(fd>=0); - if ( (nbytes = md_seek(fd, (jlong)-1)) == (jlong)-1 ) { - HPROF_ERROR(JNI_TRUE, "Cannot md_seek() to end of file"); - } - CHECK_FOR_ERROR(((jint)nbytes)>512); - if ( md_seek(fd, (jlong)0) != (jlong)0 ) { - HPROF_ERROR(JNI_TRUE, "Cannot md_seek() to start of file"); - } - image = HPROF_MALLOC(((jint)nbytes)+1); - CHECK_FOR_ERROR(image!=NULL); - - /* Read the entire file image into memory */ - nread = md_read(fd, image, (jint)nbytes); - if ( nread <= 0 ) { - HPROF_ERROR(JNI_TRUE, "System read failed."); - } - CHECK_FOR_ERROR(((jint)nbytes)==nread); - md_close(fd); - *pnbytes = (jint)nbytes; - return image; -} - -/* ------------------------------------------------------------------ */ - -void -check_binary_file(char *filename) -{ - unsigned char *image; - unsigned char *p; - unsigned idsize; - int nbytes; - int nrecords; - - image = get_binary_file_image(filename, &nbytes); - if ( image == NULL ) { - check_printf("No file image: %s\n", filename); - return; - } - p = image; - CHECK_FOR_ERROR(strcmp((char*)p, gdata->header)==0); - check_printf("Filename=%s, nbytes=%d, header=\"%s\"\n", - filename, nbytes, p); - p+=((int)strlen((char*)p)+1); - idsize = read_u4(&p); - CHECK_FOR_ERROR(idsize==sizeof(HprofId)); - (void)read_u4(&p); - (void)read_u4(&p); - /* LINTED */ - nrecords = check_tags(p, nbytes - (int)( p - image ) ); - check_printf("#%d total records found in %d bytes\n", nrecords, nbytes); - HPROF_FREE(image); -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.h deleted file mode 100644 index 02f470773bf..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_CHECK_H -#define HPROF_CHECK_H - -#define CHECK_FOR_ERROR(condition) \ - ( (condition) ? \ - (void)0 : \ - HPROF_ERROR(JNI_TRUE, #condition) ) -#define CHECK_SERIAL_NO(name, sno) \ - CHECK_FOR_ERROR( (sno) >= gdata->name##_serial_number_start && \ - (sno) < gdata->name##_serial_number_counter) -#define CHECK_CLASS_SERIAL_NO(sno) CHECK_SERIAL_NO(class,sno) -#define CHECK_THREAD_SERIAL_NO(sno) CHECK_SERIAL_NO(thread,sno) -#define CHECK_TRACE_SERIAL_NO(sno) CHECK_SERIAL_NO(trace,sno) -#define CHECK_OBJECT_SERIAL_NO(sno) CHECK_SERIAL_NO(object,sno) - -void check_binary_file(char *filename); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.c deleted file mode 100644 index 3ebe0086685..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Table of class information. - * - * Each element in this table is identified with a ClassIndex. - * Each element is uniquely identified by it's signature and loader. - * Every class load has a unique class serial number. - * While loaded, each element will have a cache of a global reference - * to it's jclass object, plus jmethodID's as needed. - * Method signatures and names are obtained via BCI. - * Methods can be identified with a ClassIndex and MethodIndex pair, - * where the MethodIndex matches the index of the method name and - * signature arrays obtained from the BCI pass. - * Strings are stored in the string table and a StringIndex is used. - * Class Loaders are stored in the loader table and a LoaderIndex is used. - * Since the jclass object is an object, at some point an object table - * entry may be allocated for the jclass as an ObjectIndex. - */ - -#include "hprof.h" - -/* Effectively represents a jclass object. */ - -/* These table elements are made unique by and sorted by signature name. */ - -typedef struct ClassKey { - StringIndex sig_string_index; /* Signature of class */ - LoaderIndex loader_index; /* Index for class loader */ -} ClassKey; - -/* Each class could contain method information, gotten from BCI callback */ - -typedef struct MethodInfo { - StringIndex name_index; /* Method name, index into string table */ - StringIndex sig_index; /* Method signature, index into string table */ - jmethodID method_id; /* Method ID, possibly NULL at first */ -} MethodInfo; - -/* The basic class information we save */ - -typedef struct ClassInfo { - jclass classref; /* Global ref to jclass */ - MethodInfo *method; /* Array of method data */ - int method_count; /* Count of methods */ - ObjectIndex object_index; /* Optional object index for jclass */ - SerialNumber serial_num; /* Unique to the actual class load */ - ClassStatus status; /* Current class status (bit mask) */ - ClassIndex super; /* Super class in this table */ - StringIndex name; /* Name of class */ - jint inst_size; /* #bytes needed for instance fields */ - jint field_count; /* Number of all fields */ - FieldInfo *field; /* Pointer to all FieldInfo's */ -} ClassInfo; - -/* Private interfaces */ - -static ClassKey* -get_pkey(ClassIndex index) -{ - void *key_ptr; - int key_len; - - table_get_key(gdata->class_table, index, (void*)&key_ptr, &key_len); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(key_ptr!=NULL); - return (ClassKey*)key_ptr; -} - -static void -fillin_pkey(const char *sig, LoaderIndex loader_index, ClassKey *pkey) -{ - static ClassKey empty_key; - - HPROF_ASSERT(loader_index!=0); - *pkey = empty_key; - pkey->sig_string_index = string_find_or_create(sig); - pkey->loader_index = loader_index; -} - -static ClassInfo * -get_info(ClassIndex index) -{ - ClassInfo *info; - - info = (ClassInfo*)table_get_info(gdata->class_table, index); - return info; -} - -static void -fill_info(TableIndex index, ClassKey *pkey) -{ - ClassInfo *info; - char *sig; - - info = get_info(index); - info->serial_num = gdata->class_serial_number_counter++; - info->method_count = 0; - info->inst_size = -1; - info->field_count = -1; - info->field = NULL; - sig = string_get(pkey->sig_string_index); - if ( sig[0] != JVM_SIGNATURE_CLASS ) { - info->name = pkey->sig_string_index; - } else { - int len; - - len = string_get_len(pkey->sig_string_index); - if ( len > 2 ) { - char *name; - - /* Class signature looks like "Lname;", we want "name" here. */ - name = HPROF_MALLOC(len-1); - (void)memcpy(name, sig+1, len-2); - name[len-2] = 0; - info->name = string_find_or_create(name); - HPROF_FREE(name); - } else { - /* This would be strange, a class signature not in "Lname;" form? */ - info->name = pkey->sig_string_index; - } - } -} - -static ClassIndex -find_entry(ClassKey *pkey) -{ - ClassIndex index; - - index = table_find_entry(gdata->class_table, - (void*)pkey, (int)sizeof(ClassKey)); - return index; -} - -static ClassIndex -create_entry(ClassKey *pkey) -{ - ClassIndex index; - - index = table_create_entry(gdata->class_table, - (void*)pkey, (int)sizeof(ClassKey), NULL); - fill_info(index, pkey); - return index; -} - -static ClassIndex -find_or_create_entry(ClassKey *pkey) -{ - ClassIndex index; - - HPROF_ASSERT(pkey!=NULL); - HPROF_ASSERT(pkey->loader_index!=0); - index = find_entry(pkey); - if ( index == 0 ) { - index = create_entry(pkey); - } - return index; -} - -static void -delete_classref(JNIEnv *env, ClassInfo *info, jclass klass) -{ - jclass ref; - int i; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(info!=NULL); - - for ( i = 0 ; i < info->method_count ; i++ ) { - info->method[i].method_id = NULL; - } - ref = info->classref; - if ( klass != NULL ) { - info->classref = newGlobalReference(env, klass); - } else { - info->classref = NULL; - } - if ( ref != NULL ) { - deleteGlobalReference(env, ref); - } -} - -static void -cleanup_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - - /* Cleanup any information in this ClassInfo structure. */ - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(info_ptr!=NULL); - info = (ClassInfo *)info_ptr; - if ( info->method_count > 0 ) { - HPROF_FREE((void*)info->method); - info->method_count = 0; - info->method = NULL; - } - if ( info->field != NULL ) { - HPROF_FREE((void*)info->field); - info->field_count = 0; - info->field = NULL; - } -} - -static void -delete_ref_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - delete_classref((JNIEnv*)arg, (ClassInfo*)info_ptr, NULL); -} - -static void -list_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - ClassKey key; - char *sig; - int i; - - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(info_ptr!=NULL); - key = *((ClassKey*)key_ptr); - sig = string_get(key.sig_string_index); - info = (ClassInfo *)info_ptr; - debug_message( - "0x%08x: Class %s, SN=%u, status=0x%08x, ref=%p," - " method_count=%d\n", - index, - (const char *)sig, - info->serial_num, - info->status, - (void*)info->classref, - info->method_count); - if ( info->method_count > 0 ) { - for ( i = 0 ; i < info->method_count ; i++ ) { - debug_message( - " Method %d: \"%s\", sig=\"%s\", method=%p\n", - i, - string_get(info->method[i].name_index), - string_get(info->method[i].sig_index), - (void*)info->method[i].method_id); - } - } -} - -static void -all_status_remove(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - ClassStatus status; - - HPROF_ASSERT(info_ptr!=NULL); - /*LINTED*/ - status = (ClassStatus)(long)(ptrdiff_t)arg; - info = (ClassInfo *)info_ptr; - info->status &= (~status); -} - -static void -unload_walker(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - - HPROF_ASSERT(info_ptr!=NULL); - info = (ClassInfo *)info_ptr; - if ( ! ( info->status & CLASS_IN_LOAD_LIST ) ) { - if ( ! (info->status & (CLASS_SPECIAL|CLASS_SYSTEM|CLASS_UNLOADED)) ) { - io_write_class_unload(info->serial_num, info->object_index); - info->status |= CLASS_UNLOADED; - delete_classref((JNIEnv*)arg, info, NULL); - } - } -} - -/* External interfaces */ - -void -class_init(void) -{ - HPROF_ASSERT(gdata->class_table==NULL); - gdata->class_table = table_initialize("Class", 512, 512, 511, - (int)sizeof(ClassInfo)); -} - -ClassIndex -class_find_or_create(const char *sig, LoaderIndex loader_index) -{ - ClassKey key; - - fillin_pkey(sig, loader_index, &key); - return find_or_create_entry(&key); -} - -ClassIndex -class_create(const char *sig, LoaderIndex loader_index) -{ - ClassKey key; - - fillin_pkey(sig, loader_index, &key); - return create_entry(&key); -} - -void -class_prime_system_classes(void) -{ - /* Prime System classes? Anything before VM_START is System class. - * Or classes loaded before env arg is non-NULL. - * Or any of the classes listed below. - */ - static const char * signatures[] = - { - "Ljava/lang/Object;", - "Ljava/io/Serializable;", - "Ljava/lang/String;", - "Ljava/lang/Class;", - "Ljava/lang/ClassLoader;", - "Ljava/lang/System;", - "Ljava/lang/Thread;", - "Ljava/lang/ThreadGroup;", - }; - int n_signatures; - int i; - LoaderIndex loader_index; - - n_signatures = (int)sizeof(signatures)/(int)sizeof(signatures[0]); - loader_index = loader_find_or_create(NULL, NULL); - for ( i = 0 ; i < n_signatures ; i++ ) { - ClassInfo *info; - ClassIndex index; - ClassKey key; - - fillin_pkey(signatures[i], loader_index, &key); - index = find_or_create_entry(&key); - info = get_info(index); - info->status |= CLASS_SYSTEM; - } -} - -void -class_add_status(ClassIndex index, ClassStatus status) -{ - ClassInfo *info; - - info = get_info(index); - info->status |= status; -} - -ClassStatus -class_get_status(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->status; -} - -StringIndex -class_get_signature(ClassIndex index) -{ - ClassKey *pkey; - - pkey = get_pkey(index); - return pkey->sig_string_index; -} - -SerialNumber -class_get_serial_number(ClassIndex index) -{ - ClassInfo *info; - - if ( index == 0 ) { - return 0; - } - info = get_info(index); - return info->serial_num; -} - -void -class_all_status_remove(ClassStatus status) -{ - table_walk_items(gdata->class_table, &all_status_remove, - (void*)(ptrdiff_t)(long)status); -} - -void -class_do_unloads(JNIEnv *env) -{ - table_walk_items(gdata->class_table, &unload_walker, (void*)env); -} - -void -class_list(void) -{ - debug_message( - "--------------------- Class Table ------------------------\n"); - table_walk_items(gdata->class_table, &list_item, NULL); - debug_message( - "----------------------------------------------------------\n"); -} - -void -class_cleanup(void) -{ - table_cleanup(gdata->class_table, &cleanup_item, NULL); - gdata->class_table = NULL; -} - -void -class_delete_global_references(JNIEnv* env) -{ - table_walk_items(gdata->class_table, &delete_ref_item, (void*)env); -} - -void -class_set_methods(ClassIndex index, const char **name, const char **sig, - int count) -{ - ClassInfo *info; - int i; - - info = get_info(index); - if ( info->method_count > 0 ) { - HPROF_FREE((void*)info->method); - info->method_count = 0; - info->method = NULL; - } - info->method_count = count; - if ( count > 0 ) { - info->method = (MethodInfo *)HPROF_MALLOC(count*(int)sizeof(MethodInfo)); - for ( i = 0 ; i < count ; i++ ) { - info->method[i].name_index = string_find_or_create(name[i]); - info->method[i].sig_index = string_find_or_create(sig[i]); - info->method[i].method_id = NULL; - } - } -} - -jclass -class_new_classref(JNIEnv *env, ClassIndex index, jclass classref) -{ - ClassInfo *info; - - HPROF_ASSERT(classref!=NULL); - info = get_info(index); - if ( ! isSameObject(env, classref, info->classref) ) { - delete_classref(env, info, classref); - } - return info->classref; -} - -jclass -class_get_class(JNIEnv *env, ClassIndex index) -{ - ClassInfo *info; - jclass clazz; - - info = get_info(index); - clazz = info->classref; - if ( env != NULL && clazz == NULL ) { - WITH_LOCAL_REFS(env, 1) { - jclass new_clazz; - char *class_name; - - class_name = string_get(info->name); - /* This really only makes sense for the bootclass classes, - * since FindClass doesn't provide a way to load a class in - * a specific class loader. - */ - new_clazz = findClass(env, class_name); - if ( new_clazz == NULL ) { - HPROF_ERROR(JNI_TRUE, "Cannot load class with findClass"); - } - HPROF_ASSERT(new_clazz!=NULL); - clazz = class_new_classref(env, index, new_clazz); - } END_WITH_LOCAL_REFS; - HPROF_ASSERT(clazz!=NULL); - } - return clazz; -} - -jmethodID -class_get_methodID(JNIEnv *env, ClassIndex index, MethodIndex mnum) -{ - ClassInfo *info; - jmethodID method; - - info = get_info(index); - if (mnum >= info->method_count) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal mnum"); - - return NULL; - } - method = info->method[mnum].method_id; - if ( method == NULL ) { - char * name; - char * sig; - jclass clazz; - - name = (char *)string_get(info->method[mnum].name_index); - if (name==NULL) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Name not found"); - - return NULL; - } - sig = (char *)string_get(info->method[mnum].sig_index); - HPROF_ASSERT(sig!=NULL); - clazz = class_get_class(env, index); - if ( clazz != NULL ) { - method = getMethodID(env, clazz, name, sig); - HPROF_ASSERT(method!=NULL); - info = get_info(index); - info->method[mnum].method_id = method; - } - } - return method; -} - -void -class_set_inst_size(ClassIndex index, jint inst_size) -{ - ClassInfo *info; - - info = get_info(index); - info->inst_size = inst_size; -} - -jint -class_get_inst_size(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->inst_size; -} - -void -class_set_object_index(ClassIndex index, ObjectIndex object_index) -{ - ClassInfo *info; - - info = get_info(index); - info->object_index = object_index; -} - -ObjectIndex -class_get_object_index(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->object_index; -} - -ClassIndex -class_get_super(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->super; -} - -void -class_set_super(ClassIndex index, ClassIndex super) -{ - ClassInfo *info; - - info = get_info(index); - info->super = super; -} - -LoaderIndex -class_get_loader(ClassIndex index) -{ - ClassKey *pkey; - - pkey = get_pkey(index); - HPROF_ASSERT(pkey->loader_index!=0); - return pkey->loader_index; -} - -/* Get ALL class fields (supers too), return 1 on error, 0 if ok */ -jint -class_get_all_fields(JNIEnv *env, ClassIndex index, - jint *pfield_count, FieldInfo **pfield) -{ - ClassInfo *info; - FieldInfo *finfo; - jint count; - jint ret; - - count = 0; - finfo = NULL; - ret = 1; /* Default is to return an error condition */ - - info = get_info(index); - if ( info != NULL ) { - if ( info->field_count >= 0 ) { - /* Get cache */ - count = info->field_count; - finfo = info->field; - ret = 0; /* Return of cache data, no error */ - } else { - jclass klass; - - klass = info->classref; - if ( klass == NULL || isSameObject(env, klass, NULL) ) { - /* This is probably an error because this will cause the field - * index values to be off, but I'm hesitant to generate a - * fatal error here, so I will issue something and continue. - * I should have been holding a global reference to all the - * jclass, so I'm not sure how this could happen. - * Issuing a FindClass() here is just asking for trouble - * because if the class went away, we aren't even sure - * what ClassLoader to use. - */ - HPROF_ERROR(JNI_FALSE, "Missing jclass when fields needed"); - } else { - jint status; - - status = getClassStatus(klass); - if ( status & - (JVMTI_CLASS_STATUS_PRIMITIVE|JVMTI_CLASS_STATUS_ARRAY) ) { - /* Set cache */ - info->field_count = count; - info->field = finfo; - ret = 0; /* Primitive or array ok */ - } else if ( status & JVMTI_CLASS_STATUS_PREPARED ) { - /* Call JVMTI to get them */ - getAllClassFieldInfo(env, klass, &count, &finfo); - /* Set cache */ - info->field_count = count; - info->field = finfo; - ret = 0; - } - } - } - } - *pfield_count = count; - *pfield = finfo; - return ret; -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.h deleted file mode 100644 index 6b4bc9c397d..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_CLASS_H -#define HPROF_CLASS_H - -void class_init(void); -ClassIndex class_find_or_create(const char *sig, LoaderIndex loader); -ClassIndex class_create(const char *sig, LoaderIndex loader); -SerialNumber class_get_serial_number(ClassIndex index); -StringIndex class_get_signature(ClassIndex index); -ClassStatus class_get_status(ClassIndex index); -void class_add_status(ClassIndex index, ClassStatus status); -void class_all_status_remove(ClassStatus status); -void class_do_unloads(JNIEnv *env); -void class_list(void); -void class_delete_global_references(JNIEnv* env); -void class_cleanup(void); -void class_set_methods(ClassIndex index, const char**name, - const char**descr, int count); -jmethodID class_get_methodID(JNIEnv *env, ClassIndex index, - MethodIndex mnum); -jclass class_new_classref(JNIEnv *env, ClassIndex index, - jclass classref); -void class_delete_classref(JNIEnv *env, ClassIndex index); -jclass class_get_class(JNIEnv *env, ClassIndex index); -void class_set_inst_size(ClassIndex index, jint inst_size); -jint class_get_inst_size(ClassIndex index); -void class_set_object_index(ClassIndex index, - ObjectIndex object_index); -ObjectIndex class_get_object_index(ClassIndex index); -ClassIndex class_get_super(ClassIndex index); -void class_set_super(ClassIndex index, ClassIndex super); -void class_set_loader(ClassIndex index, LoaderIndex loader); -LoaderIndex class_get_loader(ClassIndex index); -void class_prime_system_classes(void); -jint class_get_all_fields(JNIEnv *env, ClassIndex cnum, - jint *pfield_count, FieldInfo **pfield); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.c deleted file mode 100644 index 5c1b953a401..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include "hprof.h" - -/* This file contains the cpu loop for the option cpu=samples */ - -/* The cpu_loop thread basically waits for gdata->sample_interval millisecs - * then wakes up, and for each running thread it gets their stack trace, - * and updates the traces with 'hits'. - * - * No threads are suspended or resumed, and the thread sampling is in the - * file hprof_tls.c, which manages all active threads. The sampling - * technique (what is sampled) is also in hprof_tls.c. - * - * No adjustments are made to the pause time or sample interval except - * by the user via the interval=n option (default is 10ms). - * - * This thread can cause havoc when started prematurely or not terminated - * properly, see cpu_sample_init() and cpu_term(), and their calls in hprof_init.c. - * - * The listener loop (hprof_listener.c) can dynamically turn on or off the - * sampling of all or selected threads. - * - */ - -/* Private functions */ - -static void JNICALL -cpu_loop_function(jvmtiEnv *jvmti, JNIEnv *env, void *p) -{ - int loop_trip_counter; - jboolean cpu_loop_running; - - loop_trip_counter = 0; - - rawMonitorEnter(gdata->cpu_loop_lock); { - gdata->cpu_loop_running = JNI_TRUE; - cpu_loop_running = gdata->cpu_loop_running; - /* Notify cpu_sample_init() that we have started */ - rawMonitorNotifyAll(gdata->cpu_loop_lock); - } rawMonitorExit(gdata->cpu_loop_lock); - - rawMonitorEnter(gdata->cpu_sample_lock); /* Only waits inside loop let go */ - - while ( cpu_loop_running ) { - - ++loop_trip_counter; - - LOG3("cpu_loop()", "iteration", loop_trip_counter); - - /* If a dump is in progress, we pause sampling. */ - rawMonitorEnter(gdata->dump_lock); { - if (gdata->dump_in_process) { - gdata->pause_cpu_sampling = JNI_TRUE; - } - } rawMonitorExit(gdata->dump_lock); - - /* Check to see if we need to pause sampling (listener_loop command) */ - if (gdata->pause_cpu_sampling) { - - /* - * Pause sampling for now. Reset sample controls if - * sampling is resumed again. - */ - - rawMonitorWait(gdata->cpu_sample_lock, 0); - - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - /* Continue the while loop, which will terminate if done. */ - continue; - } - - /* This is the normal short timed wait before getting a sample */ - rawMonitorWait(gdata->cpu_sample_lock, (jlong)gdata->sample_interval); - - /* Make sure we really want to continue */ - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - /* Break out if we are done */ - if ( !cpu_loop_running ) { - break; - } - - /* - * If a dump request came in after we checked at the top of - * the while loop, then we catch that fact here. We - * don't want to perturb the data that is being dumped so - * we just ignore the data from this sampling loop. - */ - rawMonitorEnter(gdata->dump_lock); { - if (gdata->dump_in_process) { - gdata->pause_cpu_sampling = JNI_TRUE; - } - } rawMonitorExit(gdata->dump_lock); - - /* Sample all the threads and update trace costs */ - if ( !gdata->pause_cpu_sampling) { - tls_sample_all_threads(env); - } - - /* Check to see if we need to finish */ - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - } - rawMonitorExit(gdata->cpu_sample_lock); - - rawMonitorEnter(gdata->cpu_loop_lock); { - /* Notify cpu_sample_term() that we are done. */ - rawMonitorNotifyAll(gdata->cpu_loop_lock); - } rawMonitorExit(gdata->cpu_loop_lock); - - LOG2("cpu_loop()", "clean termination"); -} - -/* External functions */ - -void -cpu_sample_init(JNIEnv *env) -{ - gdata->cpu_sampling = JNI_TRUE; - - /* Create the raw monitors needed */ - gdata->cpu_loop_lock = createRawMonitor("HPROF cpu loop lock"); - gdata->cpu_sample_lock = createRawMonitor("HPROF cpu sample lock"); - - rawMonitorEnter(gdata->cpu_loop_lock); { - createAgentThread(env, "HPROF cpu sampling thread", - &cpu_loop_function); - /* Wait for cpu_loop_function() to notify us it has started. */ - rawMonitorWait(gdata->cpu_loop_lock, 0); - } rawMonitorExit(gdata->cpu_loop_lock); -} - -void -cpu_sample_off(JNIEnv *env, ObjectIndex object_index) -{ - jint count; - - count = 1; - if (object_index != 0) { - tls_set_sample_status(object_index, 0); - count = tls_sum_sample_status(); - } - if ( count == 0 ) { - gdata->pause_cpu_sampling = JNI_TRUE; - } else { - gdata->pause_cpu_sampling = JNI_FALSE; - } -} - -void -cpu_sample_on(JNIEnv *env, ObjectIndex object_index) -{ - if ( gdata->cpu_loop_lock == NULL ) { - cpu_sample_init(env); - } - - if (object_index == 0) { - gdata->cpu_sampling = JNI_TRUE; - gdata->pause_cpu_sampling = JNI_FALSE; - } else { - jint count; - - tls_set_sample_status(object_index, 1); - count = tls_sum_sample_status(); - if ( count > 0 ) { - gdata->pause_cpu_sampling = JNI_FALSE; - } - } - - /* Notify the CPU sampling thread that sampling is on */ - rawMonitorEnter(gdata->cpu_sample_lock); { - rawMonitorNotifyAll(gdata->cpu_sample_lock); - } rawMonitorExit(gdata->cpu_sample_lock); - -} - -void -cpu_sample_term(JNIEnv *env) -{ - gdata->pause_cpu_sampling = JNI_FALSE; - rawMonitorEnter(gdata->cpu_sample_lock); { - /* Notify the CPU sampling thread to get out of any sampling Wait */ - rawMonitorNotifyAll(gdata->cpu_sample_lock); - } rawMonitorExit(gdata->cpu_sample_lock); - rawMonitorEnter(gdata->cpu_loop_lock); { - if ( gdata->cpu_loop_running ) { - gdata->cpu_loop_running = JNI_FALSE; - /* Wait for cpu_loop_function() thread to tell us it completed. */ - rawMonitorWait(gdata->cpu_loop_lock, 0); - } - } rawMonitorExit(gdata->cpu_loop_lock); -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.h deleted file mode 100644 index e63747ec3dc..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_CPU_H -#define HPROF_CPU_H - -void cpu_sample_off(JNIEnv *env, ObjectIndex object_index); -void cpu_sample_on(JNIEnv *env, ObjectIndex object_index); - -void cpu_sample_init(JNIEnv *env); -void cpu_sample_term(JNIEnv *env); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c deleted file mode 100644 index 9776a1da4f0..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include "hprof.h" - -/* The error handling logic. */ - -/* - * Most hprof error processing and error functions are kept here, along with - * termination functions and signal handling (used in debug version only). - * - */ - -#include - -static int p = 1; /* Used with pause=y|n option */ - -/* Private functions */ - -static void -error_message(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); -} - -static void -error_abort(void) -{ - /* Important to remove existing signal handler */ - (void)signal(SIGABRT, NULL); - error_message("HPROF DUMPING CORE\n"); - abort(); /* Sends SIGABRT signal, usually also caught by libjvm */ -} - -static void -signal_handler(int sig) -{ - /* Caught a signal, most likely a SIGABRT */ - error_message("HPROF SIGNAL %d TERMINATED PROCESS\n", sig); - error_abort(); -} - -static void -setup_signal_handler(int sig) -{ - /* Only if debug version or debug=y */ - if ( gdata->debug ) { - (void)signal(sig, (void(*)(int))(void*)&signal_handler); - } -} - -static void -terminate_everything(jint exit_code) -{ - if ( exit_code > 0 ) { - /* Could be a fatal error or assert error or a sanity error */ - error_message("HPROF TERMINATED PROCESS\n"); - if ( gdata->coredump || gdata->debug ) { - /* Core dump here by request */ - error_abort(); - } - } - /* Terminate the process */ - error_exit_process(exit_code); -} - -/* External functions */ - -void -error_setup(void) -{ - setup_signal_handler(SIGABRT); -} - -void -error_do_pause(void) -{ - int pid = md_getpid(); - int timeleft = 600; /* 10 minutes max */ - int interval = 10; /* 10 second message check */ - - /*LINTED*/ - error_message("\nHPROF pause for PID %d\n", (int)pid); - while ( p && timeleft > 0 ) { - md_sleep(interval); /* 'assign p=0' to stop pause loop */ - timeleft -= interval; - } - if ( timeleft <= 0 ) { - error_message("\n HPROF pause got tired of waiting and gave up.\n"); - } -} - -void -error_exit_process(int exit_code) -{ - exit(exit_code); -} - -static const char * -source_basename(const char *file) -{ - const char *p; - - if ( file == NULL ) { - return "UnknownSourceFile"; - } - p = strrchr(file, '/'); - if ( p == NULL ) { - p = strrchr(file, '\\'); - } - if ( p == NULL ) { - p = file; - } else { - p++; /* go past / */ - } - return p; -} - -void -error_assert(const char *condition, const char *file, int line) -{ - error_message("ASSERTION FAILURE: %s [%s:%d]\n", condition, - source_basename(file), line); - error_abort(); -} - -void -error_handler(jboolean fatal, jvmtiError error, - const char *message, const char *file, int line) -{ - char *error_name; - - if ( message==NULL ) { - message = ""; - } - if ( error != JVMTI_ERROR_NONE ) { - error_name = getErrorName(error); - if ( error_name == NULL ) { - error_name = "?"; - } - error_message("HPROF ERROR: %s (JVMTI Error %s(%d)) [%s:%d]\n", - message, error_name, error, - source_basename(file), line); - } else { - error_message("HPROF ERROR: %s [%s:%d]\n", message, - source_basename(file), line); - } - if ( fatal || gdata->errorexit ) { - /* If it's fatal, or the user wants termination on any error, die */ - terminate_everything(9); - } -} - -void -debug_message(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); -} - -void -verbose_message(const char * format, ...) -{ - if ( gdata->verbose ) { - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); - } -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.h deleted file mode 100644 index 6dd06e02ec3..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_ERROR_H -#define HPROF_ERROR_H - -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - -/* Macros over assert and error functions so we can capture the source loc. */ - -#define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE)) - -#define HPROF_ERROR(fatal,msg) \ - error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__) - -#define HPROF_JVMTI_ERROR(error,msg) \ - error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \ - error, msg, THIS_FILE, __LINE__) - -#if defined(DEBUG) || !defined(NDEBUG) - #define HPROF_ASSERT(cond) \ - (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__)) -#else - #define HPROF_ASSERT(cond) -#endif - -#define LOG_DUMP_MISC 0x1 /* Misc. logging info */ -#define LOG_DUMP_LISTS 0x2 /* Dump tables at vm init and death */ -#define LOG_CHECK_BINARY 0x4 /* If format=b, verify binary format */ - -#ifdef HPROF_LOGGING - #define LOG_STDERR(args) \ - { \ - if ( gdata != NULL && (gdata->logflags & LOG_DUMP_MISC) ) { \ - (void)fprintf args ; \ - } \ - } -#else - #define LOG_STDERR(args) -#endif - -#define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n" - -#define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \ - str1, THIS_FILE, __LINE__ )) -#define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \ - str1, str2, THIS_FILE, __LINE__ )) -#define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \ - str1, str2, num, THIS_FILE, __LINE__ )) - -#define LOG(str) LOG1(str) - -void error_handler(jboolean fatal, jvmtiError error, - const char *message, const char *file, int line); -void error_assert(const char *condition, const char *file, int line); -void error_exit_process(int exit_code); -void error_do_pause(void); -void error_setup(void); -void debug_message(const char * format, ...); -void verbose_message(const char * format, ...); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.c deleted file mode 100644 index 194ef360e5a..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* This file contains all class, method and allocation event support functions, - * both JVMTI and BCI events. - * (See hprof_monitor.c for the monitor event handlers). - */ - -#include "hprof.h" - -/* Private internal functions. */ - -/* Return a TraceIndex for the given thread. */ -static TraceIndex -get_current(TlsIndex tls_index, JNIEnv *env, jboolean skip_init) -{ - TraceIndex trace_index; - - trace_index = tls_get_trace(tls_index, env, gdata->max_trace_depth, skip_init); - return trace_index; -} - -/* Return a ClassIndex for the given jclass, loader supplied or looked up. */ -static ClassIndex -find_cnum(JNIEnv *env, jclass klass, jobject loader) -{ - LoaderIndex loader_index; - ClassIndex cnum; - char * signature; - - HPROF_ASSERT(klass!=NULL); - - /* Get the loader index */ - loader_index = loader_find_or_create(env, loader); - - /* Get the signature for this class */ - getClassSignature(klass, &signature, NULL); - - /* Find the ClassIndex for this class */ - cnum = class_find_or_create(signature, loader_index); - - /* Free the signature space */ - jvmtiDeallocate(signature); - - /* Make sure we save a global reference to this class in the table */ - HPROF_ASSERT(cnum!=0); - (void)class_new_classref(env, cnum, klass); - return cnum; -} - -/* Get the ClassIndex for the superClass of this jclass. */ -static ClassIndex -get_super(JNIEnv *env, jclass klass) -{ - ClassIndex super_cnum; - - super_cnum = 0; - WITH_LOCAL_REFS(env, 1) { - jclass super_klass; - - super_klass = getSuperclass(env, klass); - if ( super_klass != NULL ) { - super_cnum = find_cnum(env, super_klass, - getClassLoader(super_klass)); - } - } END_WITH_LOCAL_REFS; - return super_cnum; -} - -/* Record an allocation. Could be jobject, jclass, jarray or primitive type. */ -static void -any_allocation(JNIEnv *env, SerialNumber thread_serial_num, - TraceIndex trace_index, jobject object) -{ - SiteIndex site_index; - ClassIndex cnum; - jint size; - jclass klass; - - /* NOTE: Normally the getObjectClass() and getClassLoader() - * would require a - * WITH_LOCAL_REFS(env, 1) { - * } END_WITH_LOCAL_REFS; - * but for performance reasons we skip it here. - */ - - /* Get and tag the klass */ - klass = getObjectClass(env, object); - cnum = find_cnum(env, klass, getClassLoader(klass)); - site_index = site_find_or_create(cnum, trace_index); - tag_class(env, klass, cnum, thread_serial_num, site_index); - - /* Tag the object */ - size = (jint)getObjectSize(object); - tag_new_object(object, OBJECT_NORMAL, thread_serial_num, size, site_index); -} - -/* Handle a java.lang.Object. object allocation. */ -void -event_object_init(JNIEnv *env, jthread thread, jobject object) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - jint *pstatus; - TraceIndex trace_index; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(object!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_TRUE, - &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) { - (*pstatus) = 1; - any_allocation(env, thread_serial_num, trace_index, object); - (*pstatus) = 0; - } -} - -/* Handle any newarray opcode allocation. */ -void -event_newarray(JNIEnv *env, jthread thread, jobject object) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - jint *pstatus; - TraceIndex trace_index; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(object!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) { - (*pstatus) = 1; - any_allocation(env, thread_serial_num, trace_index, object); - (*pstatus) = 0; - } -} - -/* Handle tracking of a method call. */ -void -event_call(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - if (cnum == 0 || cnum == gdata->tracker_cnum) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); - - return; - } - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - jmethodID method; - - (*pstatus) = 1; - method = class_get_methodID(env, cnum, mnum); - if (method != NULL) { - tls_push_method(tls_index, method); - } - - (*pstatus) = 0; - } -} - -/* Handle tracking of an exception catch */ -void -event_exception_catch(JNIEnv *env, jthread thread, jmethodID method, - jlocation location, jobject exception) -{ - /* Called via JVMTI_EVENT_EXCEPTION_CATCH callback */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(method!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - (*pstatus) = 1; - tls_pop_exception_catch(tls_index, thread, method); - (*pstatus) = 0; - } -} - -/* Handle tracking of a method return pop one (maybe more) methods. */ -void -event_return(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - if (cnum == 0 || cnum == gdata->tracker_cnum) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); - - return; - } - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - jmethodID method; - - (*pstatus) = 1; - method = class_get_methodID(env, cnum, mnum); - if (method != NULL) { - tls_pop_method(tls_index, thread, method); - } - - (*pstatus) = 0; - } -} - -/* Handle a class prepare (should have been already loaded) */ -void -event_class_prepare(JNIEnv *env, jthread thread, jclass klass, jobject loader) -{ - /* Called via JVMTI_EVENT_CLASS_PREPARE event */ - - ClassIndex cnum; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(klass!=NULL); - - /* Find the ClassIndex for this class */ - cnum = find_cnum(env, klass, loader); - class_add_status(cnum, CLASS_PREPARED); - -} - -/* Handle a class load (could have been already loaded) */ -void -event_class_load(JNIEnv *env, jthread thread, jclass klass, jobject loader) -{ - /* Called via JVMTI_EVENT_CLASS_LOAD event or reset_class_load_status() */ - - ClassIndex cnum; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(klass!=NULL); - - /* Find the ClassIndex for this class */ - cnum = find_cnum(env, klass, loader); - - /* Always mark it as being in the load list */ - class_add_status(cnum, CLASS_IN_LOAD_LIST); - - /* If we are seeing this as a new loaded class, extra work */ - if ( ! ( class_get_status(cnum) & CLASS_LOADED ) ) { - TraceIndex trace_index; - SiteIndex site_index; - ClassIndex super; - SerialNumber class_serial_num; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - ObjectIndex class_object_index; - char *signature; - - /* Get the TlsIndex and a TraceIndex for this location */ - if ( thread == NULL ) { - /* This should be very rare, but if this class load was simulated - * from hprof_init.c due to a reset of the class load status, - * and it originated from a pre-VM_INIT event, the jthread - * would be NULL, or it was a jclass created that didn't get - * reported to us, like an array class or a primitive class? - */ - trace_index = gdata->system_trace_index; - thread_serial_num = gdata->unknown_thread_serial_num; - } else { - TlsIndex tls_index; - - tls_index = tls_find_or_create(env, thread); - trace_index = get_current(tls_index, env, JNI_FALSE); - thread_serial_num = tls_get_thread_serial_number(tls_index); - } - - /* Get the SiteIndex for this location and a java.lang.Class object */ - /* Note that the target cnum, not the cnum for java.lang.Class. */ - site_index = site_find_or_create(cnum, trace_index); - - /* Tag this java.lang.Class object */ - tag_class(env, klass, cnum, thread_serial_num, site_index); - - class_add_status(cnum, CLASS_LOADED); - - class_serial_num = class_get_serial_number(cnum); - class_object_index = class_get_object_index(cnum); - trace_serial_num = trace_get_serial_number(trace_index); - signature = string_get(class_get_signature(cnum)); - - rawMonitorEnter(gdata->data_access_lock); { - io_write_class_load(class_serial_num, class_object_index, - trace_serial_num, signature); - } rawMonitorExit(gdata->data_access_lock); - - super = get_super(env, klass); - class_set_super(cnum, super); - } - -} - -/* Handle a thread start event */ -void -event_thread_start(JNIEnv *env, jthread thread) -{ - /* Called via JVMTI_EVENT_THREAD_START event */ - - TlsIndex tls_index; - ObjectIndex object_index; - TraceIndex trace_index; - jlong tag; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - tls_index = tls_find_or_create(env, thread); - thread_serial_num = tls_get_thread_serial_number(tls_index); - trace_index = get_current(tls_index, env, JNI_FALSE); - - tag = getTag(thread); - if ( tag == (jlong)0 ) { - SiteIndex site_index; - jint size; - - size = (jint)getObjectSize(thread); - site_index = site_find_or_create(gdata->thread_cnum, trace_index); - /* We create a new object with this thread's serial number */ - object_index = object_new(site_index, size, OBJECT_NORMAL, - thread_serial_num); - } else { - object_index = tag_extract(tag); - /* Normally the Thread object is created and tagged before we get - * here, but the thread_serial_number on this object isn't what - * we want. So we update it to the serial number of this thread. - */ - object_set_thread_serial_number(object_index, thread_serial_num); - } - tls_set_thread_object_index(tls_index, object_index); - - WITH_LOCAL_REFS(env, 1) { - jvmtiThreadInfo threadInfo; - jvmtiThreadGroupInfo threadGroupInfo; - jvmtiThreadGroupInfo parentGroupInfo; - - getThreadInfo(thread, &threadInfo); - getThreadGroupInfo(threadInfo.thread_group, &threadGroupInfo); - if ( threadGroupInfo.parent != NULL ) { - getThreadGroupInfo(threadGroupInfo.parent, &parentGroupInfo); - } else { - (void)memset(&parentGroupInfo, 0, sizeof(parentGroupInfo)); - } - - rawMonitorEnter(gdata->data_access_lock); { - io_write_thread_start(thread_serial_num, - object_index, trace_get_serial_number(trace_index), - threadInfo.name, threadGroupInfo.name, parentGroupInfo.name); - } rawMonitorExit(gdata->data_access_lock); - - jvmtiDeallocate(threadInfo.name); - jvmtiDeallocate(threadGroupInfo.name); - jvmtiDeallocate(parentGroupInfo.name); - - } END_WITH_LOCAL_REFS; -} - -void -event_thread_end(JNIEnv *env, jthread thread) -{ - /* Called via JVMTI_EVENT_THREAD_END event */ - TlsIndex tls_index; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - tls_index = tls_find_or_create(env, thread); - rawMonitorEnter(gdata->data_access_lock); { - io_write_thread_end(tls_get_thread_serial_number(tls_index)); - } rawMonitorExit(gdata->data_access_lock); - tls_thread_ended(env, tls_index); - setThreadLocalStorage(thread, (void*)NULL); -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.h deleted file mode 100644 index ebc372e8511..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_EVENT_H -#define HPROF_EVENT_H - -/* From BCI: */ -void event_object_init(JNIEnv *env, jthread thread, jobject obj); -void event_newarray(JNIEnv *env, jthread thread, jobject obj); -void event_call(JNIEnv *env, jthread thread, - ClassIndex cnum, MethodIndex mnum); -void event_return(JNIEnv *env, jthread thread, - ClassIndex cnum, MethodIndex mnum); - -/* From JVMTI: */ -void event_class_load(JNIEnv *env, jthread thread, jclass klass, jobject loader); -void event_class_prepare(JNIEnv *env, jthread thread, jclass klass, jobject loader); -void event_thread_start(JNIEnv *env_id, jthread thread); -void event_thread_end(JNIEnv *env_id, jthread thread); -void event_exception_catch(JNIEnv *env, jthread thread, jmethodID method, - jlocation location, jobject exception); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.c deleted file mode 100644 index df99d9aa9d7..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* This file contains support for handling frames, or (method,location) pairs. */ - -#include "hprof.h" - -/* - * Frames map 1-to-1 to (methodID,location) pairs. - * When no line number is known, -1 should be used. - * - * Frames are mostly used in traces (see hprof_trace.c) and will be marked - * with their status flag as they are written out to the hprof output file. - * - */ - -enum LinenoState { - LINENUM_UNINITIALIZED = 0, - LINENUM_AVAILABLE = 1, - LINENUM_UNAVAILABLE = 2 -}; - -typedef struct FrameKey { - jmethodID method; - jlocation location; -} FrameKey; - -typedef struct FrameInfo { - unsigned short lineno; - unsigned char lineno_state; /* LinenoState */ - unsigned char status; - SerialNumber serial_num; -} FrameInfo; - -static FrameKey* -get_pkey(FrameIndex index) -{ - void *key_ptr; - int key_len; - - table_get_key(gdata->frame_table, index, &key_ptr, &key_len); - HPROF_ASSERT(key_len==sizeof(FrameKey)); - HPROF_ASSERT(key_ptr!=NULL); - return (FrameKey*)key_ptr; -} - -static FrameInfo * -get_info(FrameIndex index) -{ - FrameInfo *info; - - info = (FrameInfo*)table_get_info(gdata->frame_table, index); - return info; -} - -static void -list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg) -{ - FrameKey key; - FrameInfo *info; - - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(FrameKey)); - HPROF_ASSERT(info_ptr!=NULL); - - key = *((FrameKey*)key_ptr); - info = (FrameInfo*)info_ptr; - debug_message( - "Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n", - i, (void*)key.method, (jint)key.location, - info->lineno, info->lineno_state, info->status); -} - -void -frame_init(void) -{ - gdata->frame_table = table_initialize("Frame", - 1024, 1024, 1023, (int)sizeof(FrameInfo)); -} - -FrameIndex -frame_find_or_create(jmethodID method, jlocation location) -{ - FrameIndex index; - static FrameKey empty_key; - FrameKey key; - jboolean new_one; - - key = empty_key; - key.method = method; - key.location = location; - new_one = JNI_FALSE; - index = table_find_or_create_entry(gdata->frame_table, - &key, (int)sizeof(key), &new_one, NULL); - if ( new_one ) { - FrameInfo *info; - - info = get_info(index); - info->lineno_state = LINENUM_UNINITIALIZED; - if ( location < 0 ) { - info->lineno_state = LINENUM_UNAVAILABLE; - } - info->serial_num = gdata->frame_serial_number_counter++; - } - return index; -} - -void -frame_list(void) -{ - debug_message( - "--------------------- Frame Table ------------------------\n"); - table_walk_items(gdata->frame_table, &list_item, NULL); - debug_message( - "----------------------------------------------------------\n"); -} - -void -frame_cleanup(void) -{ - table_cleanup(gdata->frame_table, NULL, NULL); - gdata->frame_table = NULL; -} - -void -frame_set_status(FrameIndex index, jint status) -{ - FrameInfo *info; - - info = get_info(index); - info->status = (unsigned char)status; -} - -void -frame_get_location(FrameIndex index, SerialNumber *pserial_num, - jmethodID *pmethod, jlocation *plocation, jint *plineno) -{ - FrameKey *pkey; - FrameInfo *info; - jint lineno; - - pkey = get_pkey(index); - *pmethod = pkey->method; - *plocation = pkey->location; - info = get_info(index); - lineno = (jint)info->lineno; - if ( info->lineno_state == LINENUM_UNINITIALIZED ) { - info->lineno_state = LINENUM_UNAVAILABLE; - if ( gdata->lineno_in_traces ) { - if ( pkey->location >= 0 && !isMethodNative(pkey->method) ) { - lineno = getLineNumber(pkey->method, pkey->location); - if ( lineno >= 0 ) { - info->lineno = (unsigned short)lineno; /* save it */ - info->lineno_state = LINENUM_AVAILABLE; - } - } - } - } - if ( info->lineno_state == LINENUM_UNAVAILABLE ) { - lineno = -1; - } - *plineno = lineno; - *pserial_num = info->serial_num; -} - -jint -frame_get_status(FrameIndex index) -{ - FrameInfo *info; - - info = get_info(index); - return (jint)info->status; -} diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.h b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.h deleted file mode 100644 index 5b94414291f..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef HPROF_FRAME_H -#define HPROF_FRAME_H - -void frame_init(void); -FrameIndex frame_find_or_create(jmethodID method, jlocation location); -void frame_list(void); -void frame_cleanup(void); -void frame_get_location(FrameIndex frame_num, SerialNumber *serial_num, - jmethodID *pmethod, - jlocation *plocation, jint *plineno); -void frame_set_status(FrameIndex frame_num, jint status); -jint frame_get_status(FrameIndex frame_num); - -#endif diff --git a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.c b/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.c deleted file mode 100644 index 6190e6a0ffa..00000000000 --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.c +++ /dev/null @@ -1,2145 +0,0 @@ -/* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Main source file, the basic JVMTI connection/startup code. */ - -#include "hprof.h" - -#include "java_crw_demo.h" - -/* - * This file contains all the startup logic (Agent_Onload) and - * connection to the JVMTI interface. - * All JVMTI Event callbacks are in this file. - * All setting of global data (gdata) is done here. - * Options are parsed here. - * Option help messages are here. - * Termination handled here (VM_DEATH) and shutdown (Agent_OnUnload). - * Spawning of the cpu sample loop thread and listener thread is done here. - * - * Use of private 'static' data has been limited, most shared static data - * should be found in the GlobalData structure pointed to by gdata - * (see hprof.h). - * - */ - -/* The default output filenames. */ - -#define DEFAULT_TXT_SUFFIX ".txt" -#define DEFAULT_OUTPUTFILE "java.hprof" -#define DEFAULT_OUTPUTTEMP "java.hprof.temp" - -/* The only global variable, defined by this library */ -GlobalData *gdata; - -/* Experimental options */ -#define EXPERIMENT_NO_EARLY_HOOK 0x1 - -/* Default trace depth */ -#define DEFAULT_TRACE_DEPTH 4 - -/* Default sample interval */ -#define DEFAULT_SAMPLE_INTERVAL 10 - -/* Default cutoff */ -#define DEFAULT_CUTOFF_POINT 0.0001 - -/* Stringize macros for help. */ -#define _TO_STR(a) #a -#define TO_STR(a) _TO_STR(a) - -/* Macros to surround callback code (non-VM_DEATH callbacks). - * Note that this just keeps a count of the non-VM_DEATH callbacks that - * are currently active, it does not prevent these callbacks from - * operating in parallel. It's the VM_DEATH callback that will wait - * for all these callbacks to either complete and block, or just block. - * We need to hold back these threads so they don't die during the final - * VM_DEATH processing. - * If the VM_DEATH callback is active in the beginning, then this callback - * just blocks to prevent further execution of the thread. - * If the VM_DEATH callback is active at the end, then this callback - * will notify the VM_DEATH callback if it's the last one. - * In all cases, the last thing they do is Enter/Exit the monitor - * gdata->callbackBlock, which will block this callback if VM_DEATH - * is running. - * - * WARNING: No not 'return' or 'goto' out of the BEGIN_CALLBACK/END_CALLBACK - * block, this will mess up the count. - */ - -#define BEGIN_CALLBACK() \ -{ /* BEGIN OF CALLBACK */ \ - jboolean bypass; \ - rawMonitorEnter(gdata->callbackLock); \ - if (gdata->vm_death_callback_active) { \ - /* VM_DEATH is active, we will bypass the CALLBACK CODE */ \ - bypass = JNI_TRUE; \ - rawMonitorExit(gdata->callbackLock); \ - /* Bypassed CALLBACKS block here until VM_DEATH done */ \ - rawMonitorEnter(gdata->callbackBlock); \ - rawMonitorExit(gdata->callbackBlock); \ - } else { \ - /* We will be executing the CALLBACK CODE in this case */ \ - gdata->active_callbacks++; \ - bypass = JNI_FALSE; \ - rawMonitorExit(gdata->callbackLock); \ - } \ - if ( !bypass ) { \ - /* BODY OF CALLBACK CODE (with no callback locks held) */ - -#define END_CALLBACK() /* Part of bypass if body */ \ - rawMonitorEnter(gdata->callbackLock); \ - gdata->active_callbacks--; \ - /* If VM_DEATH is active, and last one, send notify. */ \ - if (gdata->vm_death_callback_active) { \ - if (gdata->active_callbacks == 0) { \ - rawMonitorNotifyAll(gdata->callbackLock); \ - } \ - } \ - rawMonitorExit(gdata->callbackLock); \ - /* Non-Bypassed CALLBACKS block here until VM_DEATH done */ \ - rawMonitorEnter(gdata->callbackBlock); \ - rawMonitorExit(gdata->callbackBlock); \ - } \ -} /* END OF CALLBACK */ - -/* Forward declarations */ -static void set_callbacks(jboolean on); - -/* ------------------------------------------------------------------- */ -/* Global data initialization */ - -/* Get initialized global data area */ -static GlobalData * -get_gdata(void) -{ - static GlobalData data; - - /* Create initial default values */ - (void)memset(&data, 0, sizeof(GlobalData)); - - data.fd = -1; /* Non-zero file or socket. */ - data.heap_fd = -1; /* For heap=dump, see hprof_io */ - data.check_fd = -1; /* For heap=dump, see hprof_io */ - data.max_trace_depth = DEFAULT_TRACE_DEPTH; - data.prof_trace_depth = DEFAULT_TRACE_DEPTH; - data.sample_interval = DEFAULT_SAMPLE_INTERVAL; - data.lineno_in_traces = JNI_TRUE; - data.output_format = 'a'; /* 'b' for binary */ - data.cutoff_point = DEFAULT_CUTOFF_POINT; - data.dump_on_exit = JNI_TRUE; - data.gc_start_time = -1L; -#ifdef DEBUG - data.debug = JNI_TRUE; - data.coredump = JNI_TRUE; -#endif - data.micro_state_accounting = JNI_FALSE; - data.force_output = JNI_TRUE; - data.verbose = JNI_TRUE; - data.primfields = JNI_TRUE; - data.primarrays = JNI_TRUE; - - data.table_serial_number_start = 1; - data.class_serial_number_start = 100000; - data.thread_serial_number_start = 200000; - data.trace_serial_number_start = 300000; - data.object_serial_number_start = 400000; - data.frame_serial_number_start = 500000; - data.gref_serial_number_start = 1; - - data.table_serial_number_counter = data.table_serial_number_start; - data.class_serial_number_counter = data.class_serial_number_start; - data.thread_serial_number_counter = data.thread_serial_number_start; - data.trace_serial_number_counter = data.trace_serial_number_start; - data.object_serial_number_counter = data.object_serial_number_start; - data.frame_serial_number_counter = data.frame_serial_number_start; - data.gref_serial_number_counter = data.gref_serial_number_start; - - data.unknown_thread_serial_num = data.thread_serial_number_counter++; - return &data; -} - -/* ------------------------------------------------------------------- */ -/* Error handler callback for the java_crw_demo (classfile read write) functions. */ - -static void -my_crw_fatal_error_handler(const char * msg, const char *file, int line) -{ - char errmsg[256]; - - (void)md_snprintf(errmsg, sizeof(errmsg), - "%s [%s:%d]", msg, file, line); - errmsg[sizeof(errmsg)-1] = 0; - HPROF_ERROR(JNI_TRUE, errmsg); -} - -static void -list_all_tables(void) -{ - string_list(); - class_list(); - frame_list(); - site_list(); - object_list(); - trace_list(); - monitor_list(); - tls_list(); - loader_list(); -} - -/* ------------------------------------------------------------------- */ -/* Option Parsing support */ - -/** - * Socket connection - */ - -/* - * Return a socket connect()ed to a "hostname" that is - * accept()ing heap profile data on "port." Return a value <= 0 if - * such a connection can't be made. - */ -static int -connect_to_socket(char *hostname, int port) -{ - int fd; - - if (port == 0 || port > 65535) { - HPROF_ERROR(JNI_FALSE, "invalid port number"); - return -1; - } - if (hostname == NULL) { - HPROF_ERROR(JNI_FALSE, "hostname is NULL"); - return -1; - } - - /* create a socket */ - fd = md_connect(hostname, (unsigned short)port); - return fd; -} - -/* Accept a filename, and adjust the name so that it is unique for this PID */ -static void -make_unique_filename(char **filename) -{ - int fd; - - /* Find a file that doesn't exist */ - fd = md_open(*filename); - if ( fd >= 0 ) { - int pid; - char *new_name; - char *old_name; - char *prefix; - char suffix[5]; - int new_len; - - /* Close the file. */ - md_close(fd); - - /* Make filename name.PID[.txt] */ - pid = md_getpid(); - old_name = *filename; - new_len = (int)strlen(old_name)+64; - new_name = HPROF_MALLOC(new_len); - prefix = old_name; - suffix[0] = 0; - - /* Look for .txt suffix if not binary output */ - if (gdata->output_format != 'b') { - char *dot; - char *format_suffix; - - format_suffix = DEFAULT_TXT_SUFFIX; - - (void)strcpy(suffix, format_suffix); - - dot = strrchr(old_name, '.'); - if ( dot != NULL ) { - int i; - int slen; - int match; - - slen = (int)strlen(format_suffix); - match = 1; - for ( i = 0; i < slen; i++ ) { - if ( dot[i]==0 || - tolower(format_suffix[i]) != tolower(dot[i]) ) { - match = 0; - break; - } - } - if ( match ) { - (void)strcpy(suffix, dot); - *dot = 0; /* truncates prefix and old_name */ - } - } - } - - /* Construct the name */ - (void)md_snprintf(new_name, new_len, - "%s.%d%s", prefix, pid, suffix); - *filename = new_name; - HPROF_FREE(old_name); - - /* Odds are with Windows, this file may not be so unique. */ - (void)remove(gdata->output_filename); - } -} - -static int -get_tok(char **src, char *buf, int buflen, int sep) -{ - int len; - char *p; - - buf[0] = 0; - if ( **src == 0 ) { - return 0; - } - p = strchr(*src, sep); - if ( p==NULL ) { - len = (int)strlen(*src); - p = (*src) + len; - } else { - /*LINTED*/ - len = (int)(p - (*src)); - } - if ( (len+1) > buflen ) { - return 0; - } - (void)memcpy(buf, *src, len); - buf[len] = 0; - if ( *p != 0 && *p == sep ) { - (*src) = p+1; - } else { - (*src) = p; - } - return len; -} - -static jboolean -setBinarySwitch(char **src, jboolean *ptr) -{ - char buf[80]; - - if (!get_tok(src, buf, (int)sizeof(buf), ',')) { - return JNI_FALSE; - } - if (strcmp(buf, "y") == 0) { - *ptr = JNI_TRUE; - } else if (strcmp(buf, "n") == 0) { - *ptr = JNI_FALSE; - } else { - return JNI_FALSE; - } - return JNI_TRUE; -} - -static void -print_usage(void) -{ - - (void)fprintf(stdout, -"\n" -" HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)\n" -"\n" -AGENTNAME " usage: java " AGENTLIB "=[help]|[

HPROF -Agent
-

-

Contents

- -
    -
  1. HPROF -Agent -
      -
    1. Contents
    2. -
    3. Overview
    4. -
    5. Start-up
    6. -
    7. Heap Allocation -Profiles (heap=sites)
    8. -
    9. Heap Dump (heap=dump)
    10. -
    11. CPU Usage Sampling -Profiles (cpu=samples)
    12. -
    13. CPU Usage Times Profile (cpu=times) -
    14. -
    15. Binary Dump Format -(format=b) -
        -
      1. Socket Connection and -Communication
      2. -
      -
        -
      1. Handling of Arrays
      2. -
      -
    16. -
    17. Source Code
    18. -
    -
  2. -
- -

Overview

-

This document describes the JVM TI Agent HPROF delivered in -the Java Development Kit (JDK). It is intended as demonstration code -for JVM TI, and as a functional -replacement for the older HPROF JVMPI Agent delivered in past releases.
-

-Previous 1.4 and earlier releases of the JDK contained an HPROF -agent built on the experimental JVMPI.  -The newer JVM TI replaces both JVMDI and JVMPI.   -

Note: Differences between -this HPROF implementation and the older JVMPI based HPROF are marked in -RED ITALICS -throughout this document.
-

-
-

Start-up

-

HPROF is a simple profiler agent shipped with the JDK. It is -a dynamically-linked -library that interacts with the JVM TI and -writes out profiling -information either to a file or to a socket in ascii or binary format. -This information can -be further processed by a profiler front-end tool.

-

It is capable of presenting CPU usage, heap allocation statistics -and monitor contention -profiles. In addition it can also report complete heap dumps and states -of all the monitors and threads in the Java virtual machine. -

-

HPROF can be invoked by: -

-
java -agentlib:hprof ToBeProfiledClass
-Depending on the type of profiling requested, HPROF instructs the -virtual machine to send it the relevant JVM TI events and processes -the event data into profiling information. For example, the following -command obtains the heap allocation profile: -
java -agentlib:hprof=heap=sites ToBeProfiledClass
-Following is the complete list of options that can passed to hprof : -
-
java -agentlib:hprof=help

HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)

hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]

Option Name and Value Description Default
--------------------- ----------- -------
heap=dump|sites|all heap profiling all
cpu=samples|times|old CPU usage off
monitor=y|n monitor contention n
format=a|b text(txt) or binary output a
file=<file> write data to file java.hprof[{.txt}]
net=<host>:<port> send data over a socket off
depth=<size> stack trace depth 4
interval=<ms> sample interval in ms 10
cutoff=<value> output cutoff point 0.0001
lineno=y|n line number in traces? y
thread=y|n thread in traces? n
doe=y|n dump on exit? y
msa=y|n Solaris micro state accounting n
force=y|n force output to <file> y
verbose=y|n print messages about dumps y

Obsolete Options
----------------
gc_okay=y|n

Examples
--------
- Get sample cpu information every 20 millisec, with a stack depth of 3:
java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname
- Get heap usage information based on the allocation sites:
java -agentlib:hprof=heap=sites classname

Notes
-----
- The option format=b cannot be used with monitor=y.
- The option format=b cannot be used with cpu=old|times.
- Use of the -Xrunhprof interface can still be used, e.g.
java -Xrunhprof:[help]|[<option>=<value>, ...]
will behave exactly the same as:
java -agentlib:hprof=[help]|[<option>=<value>, ...]

Warnings
--------
- This is demonstration code for the JVMTI interface and use of BCI,
it is not an official product or formal part of the JDK.
- The -Xrunhprof interface will be removed in a future release.
- The option format=b is considered experimental, this format may change
in a future release.
-
-

By default, heap profiling information (sites and dump) is written -out -to java.hprof.txt (ascii).  -The monitor=y|n option has proven to be problematic and may be replaced -with something more useful.
-

-

The output in most cases will contain ID's for traces, threads, -objects, etc.  Each type of ID will typically start with a -different number than the other ID's, e.g. traces might start with -300000.
-

-

Note: The gc_okay option -is no longer supported.
-

-

Heap Allocation -Profiles (heap=sites)
-

-Following is the heap allocation profile generated by running the Java -compiler -(javac) on a set of input files. Only parts of the -profiler output are shown here. -

-
Command used: javac -J-agentlib:hprof=heap=sites Hello.java

SITES BEGIN (ordered by live bytes) Fri Feb 6 13:13:42 2004
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 44.13% 44.13% 1117360 13967 1117360 13967 301926 java.util.zip.ZipEntry
2 8.83% 52.95% 223472 13967 223472 13967 301927 com.sun.tools.javac.util.List
3 5.18% 58.13% 131088 1 131088 1 300996 byte[]
4 5.18% 63.31% 131088 1 131088 1 300995 com.sun.tools.javac.util.Name[]

-A crucial piece of information in heap profile is the amount of -allocation that occurs -in various parts of the program. The SITES record above -tells us that 44.13% of the total space was allocated for -java.util.zip.ZipEntry objects. Note that the amount of live data is -only a fraction -of the total allocation that has occurred at a given site; the rest has -been garbage collected. -

A good way to relate allocation sites to the source code is to -record -the dynamic stack traces that led to the heap allocation. Following is -another part of the profiler output that illustrates the stack traces -referred to by the four allocation sites in output shown above. -
-

-
TRACE 301926:
java.util.zip.ZipEntry.<init>(ZipEntry.java:101)
java.util.zip.ZipFile+3.nextElement(ZipFile.java:417)
com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)
com.sun.tools.javac.jvm.ClassReader.list(ClassReader.java:1631)

TRACE 301927:
com.sun.tools.javac.util.List.<init>(List.java:42)
com.sun.tools.javac.util.List.<init>(List.java:50)
com.sun.tools.javac.util.ListBuffer.append(ListBuffer.java:94)
com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)

TRACE 300996:
com.sun.tools.javac.util.Name$Table.<init>(Name.java:379)
com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)
com.sun.tools.javac.util.Name$Table.make(Name.java:332)
com.sun.tools.javac.util.Name$Table.instance(Name.java:349)

TRACE 300995:
com.sun.tools.javac.util.Name$Table.<init>(Name.java:378)
com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)
com.sun.tools.javac.util.Name$Table.make(Name.java:332)
com.sun.tools.javac.util.Name$Table.instance(Name.java:349)
-
-

-Each frame in the stack trace contains class name, method name, source -file name, and the line number. The user can set the maximum number -of frames collected by the HPROF agent. The default limit is 4. Stack -traces reveal not only which methods performed heap allocation, but -also which methods were ultimately responsible for making calls that -resulted in memory allocation.
-

-

Heap Dump (heap=dump)

-A complete dump of the current live objects in the heap can be obtained -with:
-
Command used: javac -J-agentlib:hprof=heap=dump Hello.java
-This is a very large output file, but can be viewed and searched in any -editor.
-
-

CPU Usage Sampling -Profiles (cpu=samples)
-

-HPROF can collect CPU usage information by sampling threads. Following -is part of the output collected from a run -of the javac compiler. -

-
Command used: javac -J-agentlib:hprof=cpu=samples Hello.java

CPU SAMPLES BEGIN (total = 462) Fri Feb 6 13:33:07 2004
rank self accum count trace method
1 49.57% 49.57% 229 300187 java.util.zip.ZipFile.getNextEntry
2 6.93% 56.49% 32 300190 java.util.zip.ZipEntry.initFields
3 4.76% 61.26% 22 300122 java.lang.ClassLoader.defineClass2
4 2.81% 64.07% 13 300188 java.util.zip.ZipFile.freeEntry
5 1.95% 66.02% 9 300129 java.util.Vector.addElement
6 1.73% 67.75% 8 300124 java.util.zip.ZipFile.getEntry
7 1.52% 69.26% 7 300125 java.lang.ClassLoader.findBootstrapClass
8 0.87% 70.13% 4 300172 com.sun.tools.javac.main.JavaCompiler.<init>
9 0.65% 70.78% 3 300030 java.util.zip.ZipFile.open
10 0.65% 71.43% 3 300175 com.sun.tools.javac.main.JavaCompiler.<init>
-... -CPU SAMPLES END -
-
-
-

-The HPROF agent periodically samples the stack of all running threads -to record the most frequently active stack traces. The count -field above indicates how many times a particular stack trace was found -to be active. These stack traces correspond to the CPU usage hot spots -in the application.
-

-

CPU Usage Times -Profile (cpu=times)
-

-HPROF can collect CPU usage information by injecting code into every -method entry and exit, keeping track of exact method call counts and -the time spent in each method. This uses Byte Code Injection (BCI) and -runs considerably slower than cpu=samples. Following is part of the -output collected from a run -of the javac compiler. -

-
Command used: javac -J-agentlib:hprof=cpu=times Hello.java

CPU TIME (ms) BEGIN (total = 2082665289) Fri Feb 6 13:43:42 2004
rank self accum count trace method
1 3.70% 3.70% 1 311243 com.sun.tools.javac.Main.compile
2 3.64% 7.34% 1 311242 com.sun.tools.javac.main.Main.compile
3 3.64% 10.97% 1 311241 com.sun.tools.javac.main.Main.compile
4 3.11% 14.08% 1 311173 com.sun.tools.javac.main.JavaCompiler.compile
5 2.54% 16.62% 8 306183 com.sun.tools.javac.jvm.ClassReader.listAll
6 2.53% 19.15% 36 306182 com.sun.tools.javac.jvm.ClassReader.list
7 2.03% 21.18% 1 307195 com.sun.tools.javac.comp.Enter.main
8 2.03% 23.21% 1 307194 com.sun.tools.javac.comp.Enter.complete
9 1.68% 24.90% 1 306392 com.sun.tools.javac.comp.Enter.classEnter
10 1.68% 26.58% 1 306388 com.sun.tools.javac.comp.Enter.classEnter

...
CPU TIME (ms) END
-Here the count represents the true count of the times this method was -entered, and the percentages represent a measure of thread CPU time -spent in those methods.
-
-

Binary Dump Format -(format=b)

-The basic fields in the binary output are u1 (1 byte), u2 (2 byte), u4 -(4 byte), and u8 (8 byte). An ID in this implementation is a u4, -however the size of an ID is really determined by the "size of -identifiers" field in the header.
-
-WARNING: This format is still -considered highly experimental, however, all attempts were made to -match the format of past HPROF implementations.
-
-The binary output begins with the information:
-
- - - - - - - - - - - - - - - - - - - -
[u1]*
-
An initial NULL terminated -series of bytes representing the format name and version, in this -implementation and historically, the string "JAVA PROFILE 1.0.1" (18 -u1 bytes) followed by a NULL byte. If the TAG "HEAP DUMP SEGMENT" is -used this string will be "JAVA PROFILE 1.0.2".
u4
-
size of identifiers. Identifiers -are used to represent UTF8 strings, objects, stack traces, etc. They -can have the same size as host pointers or sizeof(void*), but are not -required to be.
u4
-
high word of number of -milliseconds since 0:00 GMT, 1/1/70
u4
-
low word of number of -milliseconds since 0:00 GMT, 1/1/70
-
-Followed by a sequence of -records that look like:
-
- - - - - - - - - - - - - - - - - - - -
u1
-
TAG: denoting the type of the -record
u4
-
TIME: number of microseconds -since the -time stamp in the header
-
u4
-
LENGTH: number of bytes that -follow this -u4 field and belong to this record
-
[u1]*
-
BODY: as many bytes as specified -in -the above u4 field
-
-
-
-The following TAGs are supported:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STRING IN UTF8
-
0x01
-
- - - - - - - - - - - -
ID
-
ID for this string
-
[u1]*
-
UTF8 characters for string -(NOT NULL terminated)
-
-
-
LOAD CLASS
-
0x02
-
- - - - - - - - - - - - - - - - - - - -
u4
-
class serial number -(always > 0)
-
ID
-
class object ID
-
u4
-
stack trace serial number
-
ID
-
class name string ID
-
-
-
UNLOAD CLASS
-
0x03
-
- - - - - - - -
u4
-
class serial number
-
-
-
STACK FRAME
-
0x04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
ID
-
stack frame ID
-
ID
-
method name string ID
-
ID
-
method signature string ID
-
ID
-
source file name string ID
-
u4
-
class serial number
-
u4
-
- - - - - - - - - - - - - - - - - - - - - - - -
> 0
-
line number
-
0
-
no line information -available
-
-1
-
unknown location
-
-2
-
compiled method (Not implemented)
-
-3
-
native method (Not implemented)
-
-
-
-
-
STACK TRACE
-
0x05
-
- - - - - - - - - - - - - - - - - - - -
u4
-
stack trace serial number
-
u4
-
thread serial number
-
u4
-
number of frames
-
[ID]*
-
series of stack frame ID's
-
-
-
ALLOC SITES
-
0x06
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u2
-
Bit mask flags:
- - - - - - - - - - - - - - - -
0x1
-
incremental vs. -complete
-
0x2
-
sorted -by allocation vs. line
-
0x4
-
whether to force GC -(Not -Implemented)
-
-
-
u4
-
cutoff ratio (floating -point)
-
u4
-
total live bytes
-
u4
-
total live instances
-
u8
-
total bytes allocated
-
u8
-
total instances allocated
-
u4
-
number of sites that -follow:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u1
-
array indicator: 0 -means not an array, non-zero means an array of this type (See Basic Type)
-
u4
-
class serial number
-
u4
-
stack trace serial -number
-
u4
-
number of live bytes
-
u4
-
number of live -instances
-
u4
-
number of bytes -allocated
-
u4
-
number of instances -allocated
-
-
-
-
-
HEAP SUMMARY
-
0x07
-
- - - - - - - - - - - - - - - - - - - -
u4
-
total live bytes
-
u4
-
total live instances
-
u8
-
total bytes allocated
-
u8
-
total instances allocated
-
-
-
START THREAD
-
0x0A
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
u4
-
thread serial number
-
ID
-
thread object ID
-
u4
-
stack trace serial number
-
ID
-
thread name string ID
-
ID
-
thread group name ID
-
ID
-
thread parent group name ID
-
-
-
END THREAD
-
0x0B
-
- - - - - - - -
u4
-
thread serial number
-
-
-
HEAP DUMP
- or
-HEAP DUMP SEGMENT
-
0x0C
- or
-0x1C
-
Contains any number of sub-tags, -each begins a u1 field (no order implied here):
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ROOT UNKNOWN
-
0xFF
-
- - - - - - - -
ID
-
object ID
-
-
-
ROOT JNI GLOBAL
-
0x01
-
- - - - - - - - - - - -
ID
-
object ID
-
ID
-
JNI global ref ID
-
-
-
ROOT JNI LOCAL
-
0x02
-
- - - - - - - - - - - - - - - -
ID
-
object ID
-
u4
-
thread serial number
-
u4
-
frame number in -stack trace (-1 for empty)
-
-
-
ROOT JAVA FRAME
-
0x03
-
- - - - - - - - - - - - - - - -
ID
-
object ID
-
u4
-
thread serial number
-
u4
-
frame number in -stack trace (-1 for empty)
-
-
ROOT NATIVE STACK
-
0x04
-
- - - - - - - - - - - -
ID
-
object ID
-
u4
-
thread serial number
-
-
-
ROOT STICKY CLASS
-
0x05
-
- - - - - - - -
ID
-
object ID
-
-
-
ROOT THREAD BLOCK
-
0x06
-
- - - - - - - - - - - -
ID
-
object ID
-
u4
-
thread serial number
-
-
-
ROOT MONITOR USED
-
0x07
-
- - - - - - - -
ID
-
object ID
-
-
-
ROOT THREAD OBJECT
-
0x08
-
- - - - - - - - - - - - - - - -
ID
-
thread object ID
-
u4
-
thread serial number
-
u4
-
stack trace serial -number
-
-
-
CLASS DUMP
-
0x20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ID
-
class object ID
-
u4
-
stack trace serial -number
-
ID
-
super class object ID
-
ID
-
class loader object -ID
-
ID
-
signers object ID
-
ID
-
protection domain -object ID
-
ID
-
reserved
-
ID
-
reserved
-
u4
-
instance size (in -bytes)
-
u2
-
size of constant -pool and number of records that follow:
- - - - - - - - - - - - - - - -
u2
-
constant pool -index
-
u1
-
type of entry: -(See Basic Type)
-
value
-
value of entry -(u1, u2, u4, or u8 based on type of entry)
-
-
-
u2
-
Number of static -fields:
- - - - - - - - - - - - - - - -
ID
-
static field -name string ID
-
u1
-
type of field: -(See Basic Type)
-
value
-
value of entry -(u1, u2, u4, or u8 based on type of field)
-
-
-
u2
-
Number of instance -fields (not including super class's)
- - - - - - - - - - - -
ID
-
field name -string ID
-
u1
-
type of field: -(See Basic Type)
-
-
-
-
-
INSTANCE DUMP
-
0x21
-

- - - - - - - - - - - - - - - - - - - - - - - -
ID
-
object ID
-
u4
-
stack trace serial -number
-
ID
-
class object ID
-
u4
-
number of bytes that -follow
-
[value]*
-
instance field -values (this class, followed by super class, etc)
-
-
-
OBJECT ARRAY DUMP
-
0x22
-

- - - - - - - - - - - - - - - - - - - - - - - -
ID
-
array object ID
-
u4
-
stack trace serial -number
-
u4
-
number of elements
-
ID
-
array class object -ID
-
[ID]*
-
elements
-
-
-
PRIMITIVE ARRAY DUMP
-
0x23
-
- - - - - - - - - - - - - - - - - - - - - - - -
ID
-
array object ID
-
u4
-
stack trace serial -number
-
u4
-
number of elements
-
u1
-
element type (See Basic Type)
-
[u1]*
-
elements (packed -array)
-
-
-
-
HEAP DUMP END
-
0x2C
-
Terminates a series of HEAP DUMP -SEGMENTS.  Concatenation of HEAP DUMP SEGMENTS equals a HEAP DUMP.
-
CPU SAMPLES
-
0x0D
-
- - - - - - - - - - - -
u4
-
total number of samples
-
u4
-
number of traces that -follow:
- - - - - - - - - - - -
u4
-
number of samples
-
u4
-
stack trace serial -number
-
-
-
-
-
CONTROL SETTINGS
-
0x0E
-
- - - - - - - - - - - -
u4
-
Bit mask flags:
- - - - - - - - - - - -
0x1
-
alloc traces on/off
-
0x2
-
cpu sampling on/off
-
-
-
u2
-
stack trace depth
-
-
-
-
-
Basic Type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2
-
object
-
4
-
boolean
-
5
-
char
-
6
-
float
-
7
-
double
-
8
-
byte
-
9
-
short
-
10
-
int
-
11
-
long
-
-

Handling of Arrays

-
-There will be a "LOAD CLASS" tag for type type of each array -in the dump. In the LOAD CLASS record, the class name string ID -will refer to a string with a human-readable name of the array -type that is formatted as the type name would be in Java source -code. Thus, the LOAD CLASS record for the type char[] will -be "char[]", for short[][][] will be "short[][][]" and for -MyType[] will be "MyType[]". -
-

Socket Connection and -Communication

-
-WARNING: This command format is -still -considered highly experimental, however, all attempts were made to -match the format of past HPROF implementations.
-
-
-Commands can be sent to HPROF via the socket connection, the accepted -COMMAND TAGS are:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FORCE GC (Not implemented)
-
0x01
-
DUMP HEAP
-
0x02
-
ALLOC SITES
-
0x03
-
HEAP SUMMARY
-
0x04
-
EXIT THE VM
-
0x05
-
DUMP TRACES
-
0x06
-
CPU SAMPLES
-
0x07
-
CONTROL
-
0x08
-
EOF (used to terminate socket -connection)
-
0xFF
-
-
-The commands take the form:
-
- - - - - - - - - - - - - - - - - - - -
u1
-
COMMAND TAG
-
u4
-
serial number
-
u4
-
number of bytes that follow
-
[u1]*
-
- - - - - - - - - - - - - - - -
ALLOC SITES
-
- - - - - - - - - - - -
u2
-
Flags:
-
u4
-
cutoff ratio -(floating point between 0.0 and 1.0)
-
-
-
CPU SAMPLES
-
- - - - - - - - - - - -
u2
-
ignored
-
u4
-
cutoff ratio -(floating point between 0.0 and 1.0)
-
-
-
CONTROL
-
- - - - - - - -
u2
-
Sub option:
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1
-
Turn alloc -traces on
-
0x2
-
Turn alloc -traces off
-
0x3
-
Turn CPU -sampling on:
- - - - - - - -
ID
-
thread -object ID (0 for all threads)
-
-
-
0x4
-
Turn CPU -sampling off:
- - - - - - - -
ID
-
thread -object ID (0 for all threads)
-
-
0x5
-
Clear CPU -sampling
-
0x6
-
Set max stack -depth:
- - - - - - - -
u2
-
New max -stack depth
-
-
-
-
-
-
-
-
-
-

-
-Last modified: 2005 - - diff --git a/jdk/src/jdk.hprof.agent/unix/native/libhprof/hprof_md.c b/jdk/src/jdk.hprof.agent/unix/native/libhprof/hprof_md.c deleted file mode 100644 index 9b3063562d5..00000000000 --- a/jdk/src/jdk.hprof.agent/unix/native/libhprof/hprof_md.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include - -#if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX) -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "jni.h" -#include "jvm_md.h" -#include "hprof.h" - -#ifdef AIX -#include "porting_aix.h" /* For the 'dladdr' function. */ -#endif - -int -md_getpid(void) -{ - static int pid = -1; - - if ( pid >= 0 ) { - return pid; - } - pid = getpid(); - return pid; -} - -void -md_sleep(unsigned seconds) -{ - sleep(seconds); -} - -void -md_init(void) -{ -#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX) - /* No Hi-Res timer option? */ -#else - if ( gdata->micro_state_accounting ) { - char proc_ctl_fn[48]; - int procfd; - - /* Turn on micro state accounting, once per process */ - (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn), - "/proc/%d/ctl", md_getpid()); - - procfd = open(proc_ctl_fn, O_WRONLY); - if (procfd >= 0) { - long ctl_op[2]; - - ctl_op[0] = PCSET; - ctl_op[1] = PR_MSACCT; - (void)write(procfd, ctl_op, sizeof(ctl_op)); - (void)close(procfd); - } - } -#endif -} - -int -md_connect(char *hostname, unsigned short port) -{ - struct hostent *hentry; - struct sockaddr_in s; - int fd; - - /* create a socket */ - fd = socket(AF_INET, SOCK_STREAM, 0); - if ( fd < 0 ) { - return -1; - } - - /* find remote host's addr from name */ - if ((hentry = gethostbyname(hostname)) == NULL) { - (void)close(fd); - return -1; - } - (void)memset((char *)&s, 0, sizeof(s)); - /* set remote host's addr; its already in network byte order */ - (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list), - (int)sizeof(s.sin_addr.s_addr)); - /* set remote host's port */ - s.sin_port = htons(port); - s.sin_family = AF_INET; - - /* now try connecting */ - if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) { - (void)close(fd); - return 0; - } - return fd; -} - -int -md_recv(int f, char *buf, int len, int option) -{ - return recv(f, buf, len, option); -} - -int -md_shutdown(int filedes, int option) -{ - return shutdown(filedes, option); -} - -int -md_open(const char *filename) -{ - return open(filename, O_RDONLY); -} - -int -md_open_binary(const char *filename) -{ - return md_open(filename); -} - -int -md_creat(const char *filename) -{ - return open(filename, O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -} - -int -md_creat_binary(const char *filename) -{ - return md_creat(filename); -} - -jlong -md_seek(int filedes, jlong cur) -{ - jlong new_pos; - - if ( cur == (jlong)-1 ) { - new_pos = lseek(filedes, 0, SEEK_END); - } else { - new_pos = lseek(filedes, cur, SEEK_SET); - } - return new_pos; -} - -void -md_close(int filedes) -{ - (void)close(filedes); -} - -int -md_send(int s, const char *msg, int len, int flags) -{ - int res; - - do { - res = send(s, msg, len, flags); - } while ((res < 0) && (errno == EINTR)); - - return res; -} - -int -md_write(int filedes, const void *buf, int nbyte) -{ - int res; - - do { - res = write(filedes, buf, nbyte); - } while ((res < 0) && (errno == EINTR)); - - return res; -} - -int -md_read(int filedes, void *buf, int nbyte) -{ - int res; - - do { - res = read(filedes, buf, nbyte); - } while ((res < 0) && (errno == EINTR)); - - return res; -} - -/* Time of day in milli-seconds */ -static jlong -md_timeofday(void) -{ - struct timeval tv; - - if ( gettimeofday(&tv, (void *)0) != 0 ) { - return (jlong)0; /* EOVERFLOW ? */ - } - /*LINTED*/ - return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000); -} - -/* Hi-res timer in micro-seconds */ -jlong -md_get_microsecs(void) -{ -#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX) - return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */ -#else - return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */ -#endif -} - -/* Time of day in milli-seconds */ -jlong -md_get_timemillis(void) -{ - return md_timeofday(); -} - -/* Current CPU hi-res CPU time used */ -jlong -md_get_thread_cpu_timemillis(void) -{ -#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX) - return md_timeofday(); -#else - return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */ -#endif -} - -void -md_get_prelude_path(char *path, int path_len, char *filename) -{ - void *addr; - char libdir[FILENAME_MAX+1]; - Dl_info dlinfo; - - libdir[0] = 0; - addr = (void*)&md_get_prelude_path; - - /* Use dladdr() to get the full path to libhprof.so, which we use to find - * the prelude file. - */ - dlinfo.dli_fname = NULL; - (void)dladdr(addr, &dlinfo); - if ( dlinfo.dli_fname != NULL ) { - char * lastSlash; - - /* Full path to library name, need to move up one directory to 'lib' */ - (void)strcpy(libdir, (char *)dlinfo.dli_fname); - lastSlash = strrchr(libdir, '/'); - if ( lastSlash != NULL ) { - *lastSlash = '\0'; - } -#ifndef __APPLE__ - // not sure why other platforms have to go up two levels, but on macos we only need up one - lastSlash = strrchr(libdir, '/'); - if ( lastSlash != NULL ) { - *lastSlash = '\0'; - } -#endif /* __APPLE__ */ - } - (void)snprintf(path, path_len, "%s/%s", libdir, filename); -} - - -int -md_vsnprintf(char *s, int n, const char *format, va_list ap) -{ - return vsnprintf(s, n, format, ap); -} - -int -md_snprintf(char *s, int n, const char *format, ...) -{ - int ret; - va_list ap; - - va_start(ap, format); - ret = md_vsnprintf(s, n, format, ap); - va_end(ap); - return ret; -} - -void -md_system_error(char *buf, int len) -{ - char *p; - - buf[0] = 0; - p = strerror(errno); - if ( p != NULL ) { - (void)strcpy(buf, p); - } -} - -unsigned -md_htons(unsigned short s) -{ - return htons(s); -} - -unsigned -md_htonl(unsigned l) -{ - return htonl(l); -} - -unsigned -md_ntohs(unsigned short s) -{ - return ntohs(s); -} - -unsigned -md_ntohl(unsigned l) -{ - return ntohl(l); -} - -static void dll_build_name(char* buffer, size_t buflen, - const char* paths, const char* fname) { - char *path, *paths_copy, *next_token; - - paths_copy = strdup(paths); - if (paths_copy == NULL) { - return; - } - - next_token = NULL; - path = strtok_r(paths_copy, ":", &next_token); - - while (path != NULL) { - snprintf(buffer, buflen, "%s/lib%s" JNI_LIB_SUFFIX, path, fname); - if (access(buffer, F_OK) == 0) { - break; - } - *buffer = '\0'; - path = strtok_r(NULL, ":", &next_token); - } - - free(paths_copy); -} - -/* Create the actual fill filename for a dynamic library. */ -void -md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname) -{ - int pnamelen; - - /* Length of options directory location. */ - pnamelen = pname ? strlen(pname) : 0; - - *holder = '\0'; - /* Quietly truncate on buffer overflow. Should be an error. */ - if (pnamelen + (int)strlen(fname) + 10 > holderlen) { - return; - } - - /* Construct path to library */ - if (pnamelen == 0) { - (void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname); - } else { - dll_build_name(holder, holderlen, pname, fname); - } -} - -/* Load this library (return NULL on error, and error message in err_buf) */ -void * -md_load_library(const char *name, char *err_buf, int err_buflen) -{ - void * result; - - result = dlopen(name, RTLD_LAZY); - if (result == NULL) { - (void)strncpy(err_buf, dlerror(), err_buflen-2); - err_buf[err_buflen-1] = '\0'; - } - return result; -} - -/* Unload this library */ -void -md_unload_library(void *handle) -{ - (void)dlclose(handle); -} - -/* Find an entry point inside this library (return NULL if not found) */ -void * -md_find_library_entry(void *handle, const char *name) -{ - void * sym; - - sym = dlsym(handle, name); - return sym; -} - - diff --git a/jdk/src/jdk.hprof.agent/windows/native/libhprof/hprof_md.c b/jdk/src/jdk.hprof.agent/windows/native/libhprof/hprof_md.c deleted file mode 100644 index d2d68821133..00000000000 --- a/jdk/src/jdk.hprof.agent/windows/native/libhprof/hprof_md.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -// To ensure winsock2.h is used, it has to be included ahead of -// windows.h, which includes winsock.h by default. -#include -#include -#include -#include -#include -#include -#include -#include - -#include "jni.h" -#include "hprof.h" - -int -md_getpid(void) -{ - static int pid = -1; - - if ( pid >= 0 ) { - return pid; - } - pid = getpid(); - return pid; -} - -void -md_sleep(unsigned seconds) -{ - Sleep((DWORD)seconds*1000); -} - -void -md_init(void) -{ -} - -int -md_connect(char *hostname, unsigned short port) -{ - struct hostent *hentry; - struct sockaddr_in s; - int fd; - - /* find remote host's addr from name */ - if ((hentry = gethostbyname(hostname)) == NULL) { - return -1; - } - (void)memset((char *)&s, 0, sizeof(s)); - /* set remote host's addr; its already in network byte order */ - (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list), - (int)sizeof(s.sin_addr.s_addr)); - /* set remote host's port */ - s.sin_port = htons(port); - s.sin_family = AF_INET; - - /* create a socket */ - fd = (int)socket(AF_INET, SOCK_STREAM, 0); - if (INVALID_SOCKET == fd) { - return 0; - } - - /* now try connecting */ - if (SOCKET_ERROR == connect(fd, (struct sockaddr*)&s, sizeof(s))) { - closesocket(fd); - return 0; - } - return fd; -} - -int -md_recv(int f, char *buf, int len, int option) -{ - return recv(f, buf, len, option); -} - -int -md_shutdown(int filedes, int option) -{ - return shutdown(filedes, option); -} - -int -md_open(const char *filename) -{ - return open(filename, O_RDONLY); -} - -int -md_open_binary(const char *filename) -{ - return open(filename, O_RDONLY|O_BINARY); -} - -int -md_creat(const char *filename) -{ - return open(filename, O_CREAT | O_WRONLY | O_TRUNC, - _S_IREAD | _S_IWRITE); -} - -int -md_creat_binary(const char *filename) -{ - return open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, - _S_IREAD | _S_IWRITE); -} - -jlong -md_seek(int filedes, jlong pos) -{ - jlong new_pos; - - if ( pos == (jlong)-1 ) { - new_pos = _lseeki64(filedes, 0L, SEEK_END); - } else { - new_pos = _lseeki64(filedes, pos, SEEK_SET); - } - return new_pos; -} - -void -md_close(int filedes) -{ - (void)closesocket(filedes); -} - -int -md_send(int s, const char *msg, int len, int flags) -{ - return send(s, msg, len, flags); -} - -int -md_read(int filedes, void *buf, int nbyte) -{ - return read(filedes, buf, nbyte); -} - -int -md_write(int filedes, const void *buf, int nbyte) -{ - return write(filedes, buf, nbyte); -} - -jlong -md_get_microsecs(void) -{ - return (jlong)(timeGetTime())*(jlong)1000; -} - -#define FT2JLONG(ft) \ - ((jlong)(ft).dwHighDateTime << 32 | (jlong)(ft).dwLowDateTime) - -jlong -md_get_timemillis(void) -{ - static jlong fileTime_1_1_70 = 0; - SYSTEMTIME st0; - FILETIME ft0; - - if (fileTime_1_1_70 == 0) { - /* Initialize fileTime_1_1_70 -- the Win32 file time of midnight - * 1/1/70. - */ - - memset(&st0, 0, sizeof(st0)); - st0.wYear = 1970; - st0.wMonth = 1; - st0.wDay = 1; - SystemTimeToFileTime(&st0, &ft0); - fileTime_1_1_70 = FT2JLONG(ft0); - } - - GetSystemTime(&st0); - SystemTimeToFileTime(&st0, &ft0); - - return (FT2JLONG(ft0) - fileTime_1_1_70) / 10000; -} - -jlong -md_get_thread_cpu_timemillis(void) -{ - return md_get_timemillis(); -} - -HINSTANCE hJavaInst; -static int nError = 0; - -BOOL WINAPI -DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) -{ - WSADATA wsaData; - switch (reason) { - case DLL_PROCESS_ATTACH: - hJavaInst = hinst; - nError = WSAStartup(MAKEWORD(2,0), &wsaData); - break; - case DLL_PROCESS_DETACH: - WSACleanup(); - hJavaInst = NULL; - default: - break; - } - return TRUE; -} - -void -md_get_prelude_path(char *path, int path_len, char *filename) -{ - char libdir[FILENAME_MAX+1]; - char *lastSlash; - - GetModuleFileName(hJavaInst, libdir, FILENAME_MAX); - - /* This is actually in the bin directory, so move above bin for lib */ - lastSlash = strrchr(libdir, '\\'); - if ( lastSlash != NULL ) { - *lastSlash = '\0'; - } - lastSlash = strrchr(libdir, '\\'); - if ( lastSlash != NULL ) { - *lastSlash = '\0'; - } - (void)md_snprintf(path, path_len, "%s\\lib\\%s", libdir, filename); -} - -int -md_vsnprintf(char *s, int n, const char *format, va_list ap) -{ - return _vsnprintf(s, n, format, ap); -} - -int -md_snprintf(char *s, int n, const char *format, ...) -{ - int ret; - va_list ap; - - va_start(ap, format); - ret = md_vsnprintf(s, n, format, ap); - va_end(ap); - return ret; -} - -void -md_system_error(char *buf, int len) -{ - long errval; - - errval = GetLastError(); - buf[0] = '\0'; - if (errval != 0) { - int n; - - n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errval, - 0, buf, len, NULL); - if (n > 3) { - /* Drop final '.', CR, LF */ - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; - } - } -} - -unsigned -md_htons(unsigned short s) -{ - return htons(s); -} - -unsigned -md_htonl(unsigned l) -{ - return htonl(l); -} - -unsigned -md_ntohs(unsigned short s) -{ - return ntohs(s); -} - -unsigned -md_ntohl(unsigned l) -{ - return ntohl(l); -} - -static int -get_last_error_string(char *buf, int len) -{ - long errval; - - errval = GetLastError(); - if (errval != 0) { - /* DOS error */ - int n; - - n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errval, - 0, buf, len, NULL); - if (n > 3) { - /* Drop final '.', CR, LF */ - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; - } - return n; - } - - if (errno != 0) { - /* C runtime error that has no corresponding DOS error code */ - const char *s; - int n; - - s = strerror(errno); - n = (int)strlen(s); - if (n >= len) { - n = len - 1; - } - (void)strncpy(buf, s, n); - buf[n] = '\0'; - return n; - } - - return 0; -} - -static void dll_build_name(char* buffer, size_t buflen, - const char* paths, const char* fname) { - char *path, *paths_copy, *next_token; - - paths_copy = strdup(paths); - if (paths_copy == NULL) { - return; - } - - next_token = NULL; - path = strtok_s(paths_copy, ";", &next_token); - - while (path != NULL) { - _snprintf(buffer, buflen, "%s\\%s.dll", path, fname); - if (_access(buffer, 0) == 0) { - break; - } - *buffer = '\0'; - path = strtok_s(NULL, ";", &next_token); - } - - free(paths_copy); -} - -/* Build a machine dependent library name out of a path and file name. */ -void -md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname) -{ - int pnamelen; - - pnamelen = pname ? (int)strlen(pname) : 0; - - *holder = '\0'; - /* Quietly truncates on buffer overflow. Should be an error. */ - if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) { - return; - } - - if (pnamelen == 0) { - sprintf(holder, "%s.dll", fname); - } else { - dll_build_name(holder, holderlen, pname, fname); - } -} - -void * -md_load_library(const char * name, char *err_buf, int err_buflen) -{ - void *result; - - result = LoadLibrary(name); - if (result == NULL) { - /* Error message is pretty lame, try to make a better guess. */ - long errcode; - - errcode = GetLastError(); - if (errcode == ERROR_MOD_NOT_FOUND) { - strncpy(err_buf, "Can't find dependent libraries", err_buflen-2); - err_buf[err_buflen-1] = '\0'; - } else { - get_last_error_string(err_buf, err_buflen); - } - } - return result; -} - -void -md_unload_library(void *handle) -{ - FreeLibrary(handle); -} - -void * -md_find_library_entry(void *handle, const char *name) -{ - return GetProcAddress(handle, name); -} diff --git a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java index f4e53b305d0..c838bd5a28d 100644 --- a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java +++ b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java @@ -142,7 +142,7 @@ public abstract class HttpServerProvider { * visible to the system class loader, and that jar file contains a * provider-configuration file named * {@code com.sun.net.httpserver.HttpServerProvider} in the resource - * directory META-INF/services, then the first class name + * directory {@code META-INF/services}, then the first class name * specified in that file is taken. The class is loaded and * instantiated; if this process fails then an unspecified unchecked error * or exception is thrown.

diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java index 55eb042fefc..dbde25bd19b 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java @@ -197,8 +197,8 @@ import java.io.IOException; * in a jar file that is visible to the defining class loader of * the {@link com.sun.jdi.connect.Connector} type, * and that jar file contains a provider configuration file named - * com.sun.jdi.connect.Connector in the resource directory - * META-INF/services, and the provider configuration file + * {@code com.sun.jdi.connect.Connector} in the resource directory + * {@code META-INF/services}, and the provider configuration file * lists the full-qualified class name of the Connector * implementation. A Connector is a class that implements the * {@link com.sun.jdi.connect.Connector Connector} interface. More @@ -209,7 +209,7 @@ import java.io.IOException; * LaunchingConnector}. The format of the provider configuration file * is one fully-qualified class name per line. Space and tab characters * surrounding each class, as well as blank lines are ignored. The - * comment character is '#' (0x23), and on each + * comment character is {@code '#'} ({@code 0x23}), and on each * line all characters following the first comment character are * ignored. The file must be encoded in UTF-8. * @@ -227,8 +227,8 @@ import java.io.IOException; * visible to the defining class loader for the * {@link com.sun.jdi.connect.spi.TransportService} type, and that jar * file contains a provider configuration file named - * com.sun.jdi.connect.spi.TransportService in the resource - * directory META-INF/services, and the provider + * {@code com.sun.jdi.connect.spi.TransportService} in the resource + * directory {@code META-INF/services}, and the provider * configuration file lists the full-qualified class name of the * TransportService implementation. A TransportService is a concrete * sub-class of {@link com.sun.jdi.connect.spi.TransportService @@ -245,12 +245,12 @@ import java.io.IOException; * com.sun.jdi.connect.Transport Transport} that in turn * encapsulates the TransportService. * The AttachingConnector will be named based on the name of the - * transport service concatenated with the string Attach. + * transport service concatenated with the string {@code Attach}. * For example, if the transport service {@link * com.sun.jdi.connect.spi.TransportService#name() name()} method - * returns telepathic then the AttachingConnector will - * be named telepathicAttach. Similiarly the ListeningConnector - * will be named with the string Listen tagged onto the + * returns {@code telepathic} then the AttachingConnector will + * be named {@code telepathicAttach}. Similiarly the ListeningConnector + * will be named with the string {@code Listen} tagged onto the * name of the transport service. The {@link * com.sun.jdi.connect.Connector#description() description()} method * of both the AttachingConnector, and the ListeningConnector, will @@ -259,10 +259,10 @@ import java.io.IOException; * the AttachingConnector and the ListeningConnector will have two * Connector {@link com.sun.jdi.connect.Connector$Argument Arguments}. * A {@link com.sun.jdi.connect.Connector$StringArgument StringArgument} - * named address is the connector argument to specify the + * named {@code address} is the connector argument to specify the * address to attach too, or to listen on. A * {@link com.sun.jdi.connect.Connector$IntegerArgument IntegerArgument} - * named timeout is the connector argument to specify the + * named {@code timeout} is the connector argument to specify the * timeout when attaching, or accepting. The timeout connector may be * ignored depending on if the transport service supports an attach * timeout or accept timeout. @@ -372,13 +372,13 @@ public interface VirtualMachineManager { * A Connector can then use this method to create a virtual machine * mirror to represent the composite state of the target VM. * - *

The process argument specifies the + *

The {@code process} argument specifies the * {@link java.lang.Process} object for the taget VM. It may be - * specified as null. If the target VM is launched + * specified as {@code null}. If the target VM is launched * by a {@link com.sun.jdi.connect.LaunchingConnector - * LaunchingConnector} the process argument should be + * LaunchingConnector} the {@code process} argument should be * specified, otherwise calling {@link com.sun.jdi.VirtualMachine#process()} - * on the created virtual machine will return null. + * on the created virtual machine will return {@code null}. * *

This method exists so that Connectors may create * a virtual machine mirror when a connection is established @@ -391,7 +391,7 @@ public interface VirtualMachineManager { * * @param process * If launched, the {@link java.lang.Process} object for - * the target VM. null if not launched. + * the target VM. {@code null} if not launched. * * @return new virtual machine representing the target VM. * @@ -413,7 +413,7 @@ public interface VirtualMachineManager { * *

This convenience method works as if by invoking {@link * #createVirtualMachine(Connection, Process)} method and - * specifying null as the process argument. + * specifying {@code null} as the {@code process} argument. * *

This method exists so that Connectors may create * a virtual machine mirror when a connection is established diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/TransportTimeoutException.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/TransportTimeoutException.java index 1ede92bc55e..2a13567af76 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/TransportTimeoutException.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/TransportTimeoutException.java @@ -58,7 +58,7 @@ package com.sun.jdi.connect; public class TransportTimeoutException extends java.io.IOException { private static final long serialVersionUID = 4107035242623365074L; /** - * Constructs a TransportTimeoutException with no detail + * Constructs a {@code TransportTimeoutException} with no detail * message. */ public TransportTimeoutException() { @@ -66,7 +66,7 @@ public class TransportTimeoutException extends java.io.IOException { /** - * Constructs a TransportTimeoutException with the + * Constructs a {@code TransportTimeoutException} with the * specified detail message. * * @param message the detail message pertaining to this exception. diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/ClosedConnectionException.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/ClosedConnectionException.java index a324bc35185..009128b7214 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/ClosedConnectionException.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/ClosedConnectionException.java @@ -49,14 +49,14 @@ package com.sun.jdi.connect.spi; public class ClosedConnectionException extends java.io.IOException { private static final long serialVersionUID = 3877032124297204774L; /** - * Constructs a ClosedConnectionException with no detail + * Constructs a {@code ClosedConnectionException} with no detail * message. */ public ClosedConnectionException() { } /** - * Constructs a ClosedConnectionException with the + * Constructs a {@code ClosedConnectionException} with the * specified detail message. * * @param message the detail message pertaining to this exception. diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/TransportService.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/TransportService.java index f589424afc4..f51c762911a 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/TransportService.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/connect/spi/TransportService.java @@ -105,7 +105,7 @@ public abstract class TransportService { * multiple concurrent connections to a single address that * it is listening on. * - * @return true if, and only if, this transport + * @return {@code true} if, and only if, this transport * service supports multiple connections. */ public abstract boolean supportsMultipleConnections(); @@ -115,7 +115,7 @@ public abstract class TransportService { * Tell whether or not this transport service supports a timeout * when attaching to a target VM. * - * @return true if, and only if, this transport + * @return {@code true} if, and only if, this transport * service supports attaching with a timeout. * * @see #attach(String,long,long) @@ -126,7 +126,7 @@ public abstract class TransportService { * Tell whether or not this transport service supports a * timeout while waiting for a target VM to connect. * - * @return true if, and only if, this transport + * @return {@code true} if, and only if, this transport * service supports timeout while waiting for * a target VM to connect. * @@ -138,7 +138,7 @@ public abstract class TransportService { * Tells whether or not this transport service supports a * timeout when handshaking with the target VM. * - * @return true if, and only if, this transport + * @return {@code true} if, and only if, this transport * service supports a timeout while handshaking * with the target VM. * @@ -176,15 +176,15 @@ public abstract class TransportService { * * @param attachTimeout * If this transport service supports an attach timeout, - * and if attachTimeout is positive, then it specifies + * and if {@code attachTimeout} is positive, then it specifies * the timeout, in milliseconds (more or less), to use * when attaching to the target VM. If the transport service - * does not support an attach timeout, or if attachTimeout + * does not support an attach timeout, or if {@code attachTimeout} * is specified as zero then attach without any timeout. * * @param handshakeTimeout * If this transport service supports a handshake timeout, - * and if handshakeTimeout is positive, then it + * and if {@code handshakeTimeout} is positive, then it * specifies the timeout, in milliseconds (more or less), to * use when handshaking with the target VM. The exact * usage of the timeout are specific to the transport service. @@ -195,7 +195,7 @@ public abstract class TransportService { * use the handshakeTimeout as a timeout for the duration of the * handshake exchange. * If the transport service does not support a handshake - * timeout, or if handshakeTimeout is specified + * timeout, or if {@code handshakeTimeout} is specified * as zero then the handshake does not timeout if there * isn't a response from the target VM. * @@ -221,9 +221,9 @@ public abstract class TransportService { /** * A listen key. * - *

A TransportService may listen on multiple, yet + *

A {@code TransportService} may listen on multiple, yet * different, addresses at the same time. To uniquely identify - * each listener a listen key is created each time that + * each {@code listener} a listen key is created each time that * {@link #startListening startListening} is called. The listen * key is used in calls to the {@link #accept accept} method * to accept inbound connections to that listener. A listen @@ -250,7 +250,7 @@ public abstract class TransportService { * * @param address * The address to start listening for connections, - * or null to listen on an address chosen + * or {@code null} to listen on an address chosen * by the transport service. * * @return a listen key to be used in subsequent calls to be @@ -268,8 +268,8 @@ public abstract class TransportService { /** * Listens on an address chosen by the transport service. * - *

This convenience method works as if by invoking {@link - * #startListening(String) startListening(null)}.

+ *

This convenience method works as if by invoking + * {@link #startListening(String) startListening(null)}. * * @return a listen key to be used in subsequent calls to be * {@link #accept accept} or {@link #stopListening @@ -327,16 +327,16 @@ public abstract class TransportService { * * @param acceptTimeout * if this transport service supports an accept timeout, and - * if acceptTimeout is positive then block for up to - * acceptTimeout milliseconds, more or less, while waiting + * if {@code acceptTimeout} is positive then block for up to + * {@code acceptTimeout} milliseconds, more or less, while waiting * for the target VM to connect. * If the transport service does not support an accept timeout - * or if acceptTimeout is zero then block indefinitely + * or if {@code acceptTimeout} is zero then block indefinitely * for a target VM to connect. * * @param handshakeTimeout * If this transport service supports a handshake timeout, - * and if handshakeTimeout is positive, then it + * and if {@code handshakeTimeout} is positive, then it * specifies the timeout, in milliseconds (more or less), to * use when handshaking with the target VM. The exact * usage of the timeout is specific to the transport service. @@ -347,7 +347,7 @@ public abstract class TransportService { * use the timeout as a timeout for the duration of the * handshake exchange. * If the transport service does not support a handshake - * timeout, of if handshakeTimeout is specified + * timeout, of if {@code handshakeTimeout} is specified * as zero then the handshake does not timeout if there * isn't a response from the target VM. * diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java index 86935d10741..2af043618a9 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java @@ -42,26 +42,26 @@ import java.net.*; * to the string local://localhost. The components of the * HostIdentifier are: *

    - *
  • protocol - The communications protocol. If omitted, + *

  • {@code protocol} - The communications protocol. If omitted, * and a hostname is not specified, then default local protocol, * local:, is assumed. If the protocol is omitted and a * hostname is specified then the default remote protocol, * rmi: is assumed. *

  • - *
  • hostname - The hostname. If omitted, then + *

  • {@code hostname} - The hostname. If omitted, then * localhost is assumed. If the protocol is also omitted, * then default local protocol local: is also assumed. * If the hostname is not omitted but the protocol is omitted, * then the default remote protocol, rmi: is assumed. *

  • - *
  • port - The port for the communications protocol. - * Treatment of the port parameter is implementation + *

  • {@code port} - The port for the communications protocol. + * Treatment of the {@code port} parameter is implementation * (protocol) specific. It is unused by the default local protocol, * local:. For the default remote protocol, rmi:, - * port indicates the port number of the rmiregistry + * {@code port} indicates the port number of the rmiregistry * on the target host and defaults to port 1099. *

  • - *
  • servername - The treatment of the Path, Query, and + *

  • {@code servername} - The treatment of the Path, Query, and * Fragment components of the HostIdentifier are implementation * (protocol) dependent. These components are ignored by the * default local protocol, local:. For the default remote diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java index 037f49e53f6..b119a004520 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java @@ -94,7 +94,7 @@ public abstract class MonitoredHost { /** * Factory method to construct MonitoredHost instances to manage - * connections to the host indicated by hostIdString + * connections to the host indicated by {@code hostIdString} * * @param hostIdString a String representation of a {@link HostIdentifier} * @return MonitoredHost - the MonitoredHost instance for communicating @@ -113,7 +113,7 @@ public abstract class MonitoredHost { /** * Factory method to construct a MonitoredHost instance to manage the - * connection to the Java Virtual Machine indicated by vmid. + * connection to the Java Virtual Machine indicated by {@code vmid}. * * This method provide a convenient short cut for attaching to a specific * instrumented Java Virtual Machine. The information in the VmIdentifier @@ -142,7 +142,7 @@ public abstract class MonitoredHost { /** * Factory method to construct a MonitoredHost instance to manage the - * connection to the host indicated by hostId. + * connection to the host indicated by {@code hostId}. * * @param hostId the identifier for the target host. * @return MonitoredHost - The MonitoredHost object needed to attach to @@ -269,7 +269,7 @@ public abstract class MonitoredHost { * Get the last exception encountered while polling this MonitoredHost. * * @return Exception - the last exception occurred while polling this - * MonitoredHost, or null if no exception + * MonitoredHost, or {@code null} if no exception * has occurred or the exception has been cleared, */ public Exception getLastException() { diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java index 27607a990cd..5c981a91ad1 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java @@ -29,7 +29,7 @@ public interface MonitoredHostService { /** * Construct a MonitoredHost instance to manage the - * connection to the host indicated by hostId. + * connection to the host indicated by {@code hostId}. * * @param hostId the identifier for the target host. * @return MonitoredHost - The MonitoredHost object needed to attach to diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java index 86c2d4fa15e..a1614914794 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java @@ -55,12 +55,12 @@ public interface MonitoredVm { * instrumentation exported by this Java Virtual Machine. If an * instrumentation object with the given name exists, a Monitor interface * to that object will be return. Otherwise, the method returns - * null. + * {@code null}. * * @param name the name of the Instrumentation object to find. * @return Monitor - the {@link Monitor} object that can be used to * monitor the named instrumentation object, or - * null if the named object doesn't exist. + * {@code null} if the named object doesn't exist. * @throws MonitorException Thrown if an error occurs while communicating * with the target Java Virtual Machine. */ @@ -99,7 +99,7 @@ public interface MonitoredVm { /* ---- Methods to support polled MonitoredVm Implementations ---- */ /** - * Set the polling interval to interval milliseconds. + * Set the polling interval to {@code interval} milliseconds. * * Polling based monitoring implementations need to refresh the * instrumentation data on a periodic basis. This interface allows @@ -136,10 +136,10 @@ public interface MonitoredVm { * Get the last exception encountered while polling this MonitoredVm. * * Returns the last exception observed by the implementation dependent - * polling task or null if no such error has occurred. + * polling task or {@code null} if no such error has occurred. * * @return Exception - the last exception that occurred during polling - * or null if no error condition exists. + * or {@code null} if no error condition exists. * @see #isErrored * @see #setLastException */ diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java index 8863a4eb695..7a5e9998bc9 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java @@ -87,12 +87,12 @@ public abstract class AbstractPerfDataBuffer { * instrumentation exported by this Java Virtual Machine. If an * instrumentation object with the given name exists, a Monitor interface * to that object will be return. Otherwise, the method returns - * null. + * {@code null}. * * @param name the name of the Instrumentation object to find. * @return Monitor - the {@link Monitor} object that can be used to * monitor the named instrumentation object, or - * null if the named object doesn't exist. + * {@code null} if the named object doesn't exist. * @throws MonitorException Thrown if an error occurs while communicating * with the target Java Virtual Machine. */ diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java index b2414a37b21..f335b237513 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java @@ -98,7 +98,7 @@ public class PerfByteArrayMonitor extends AbstractMonitor * Get the current value of an element of the byte array instrument. * * @return byte - a copy of the current value of the element at index - * index of the byte array instrument. + * {@code index} of the byte array instrument. */ public byte byteAt(int index) { bb.position(index); diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java index edc024a6660..c83b802306d 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java @@ -222,7 +222,7 @@ public abstract class PerfDataBufferImpl { * instrumentation exported by this Java Virtual Machine. If an * instrumentation object with the given name exists, a Monitor interface * to that object will be return. Otherwise, the method returns - * null. The method will map requests for instrumention objects + * {@code null}. The method will map requests for instrumention objects * using old names to their current names, if applicable. * * @@ -230,7 +230,7 @@ public abstract class PerfDataBufferImpl { * @param name the name of the Instrumentation object to find. * @return Monitor - the {@link Monitor} object that can be used to * monitor the named instrumentation object, or - * null if the named object doesn't exist. + * {@code null} if the named object doesn't exist. * @throws MonitorException Thrown if an error occurs while communicating * with the target Java Virtual Machine. */ diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java index 110c598b6e6..eeea51469a1 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java @@ -66,7 +66,7 @@ public class MonitoredHostProvider extends MonitoredHost { * {@inheritDoc}. *

    * Note - the file: protocol silently ignores the - * interval parameter. + * {@code interval} parameter. */ public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval) throws MonitorException { diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java index 62c64795b1c..d7e839ef4fa 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java @@ -84,7 +84,7 @@ public class PerfDataFile { * for the JVM identified by the given local Vm Identifier. *

    * This method looks for the most up to date backing store file for - * the given lvmid. It will search all the user specific + * the given {@code lvmid}. It will search all the user specific * directories in the temporary directory for the host operating * system, which may be influenced by platform specific environment * variables. diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html index 3f7bac94a38..3855d4748f2 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html @@ -40,7 +40,7 @@ The local: protocol is the default protocol for the PerfData implementation. It utilizes a name shared memory mechanism, identified by a backing store file in the file system name space. The location of the backing store file is platform specific and is dictated primarily by -the JVM implementation. However, the java.io.tmpdir system +the JVM implementation. However, the java.io.tmpdir system property generally contains the location of the files, with the exception of the Solaris implementation, as the SDK and HotSpot JVM use different locations for their temporary file storage. The HotSpot JVM uses the diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java index b4cf2147a9c..4963eac61c4 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java @@ -44,16 +44,16 @@ public interface GarbageCollectorMXBean /** * Returns the GC information about the most recent GC. * This method returns a {@link GcInfo}. - * If no GC information is available, null is returned. + * If no GC information is available, {@code null} is returned. * The collector-specific attributes, if any, can be obtained * via the {@link CompositeData CompositeData} interface. *

    * MBeanServer access: - * The mapped type of GcInfo is CompositeData + * The mapped type of {@code GcInfo} is {@code CompositeData} * with attributes specified in {@link GcInfo#from GcInfo}. * - * @return a GcInfo object representing - * the most GC information; or null if no GC + * @return a {@code GcInfo} object representing + * the most GC information; or {@code null} if no GC * information available. */ public GcInfo getLastGcInfo(); diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index 0fd641e0612..1d64ae0b452 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -33,10 +33,10 @@ import java.lang.management.PlatformManagedObject; *

    The diagnostic MBean is registered to the platform MBeanServer * as are other platform MBeans. * - *

    The ObjectName for uniquely identifying the diagnostic + *

    The {@code ObjectName} for uniquely identifying the diagnostic * MXBean within an MBeanServer is: *

    - * com.sun.management:type=HotSpotDiagnostic + * {@code com.sun.management:type=HotSpotDiagnostic} *
    .* * It can be obtained by calling the @@ -50,22 +50,22 @@ import java.lang.management.PlatformManagedObject; @jdk.Exported public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { /** - * Dumps the heap to the outputFile file in the same + * Dumps the heap to the {@code outputFile} file in the same * format as the hprof heap dump. *

    * If this method is called remotely from another process, - * the heap dump output is written to a file named outputFile + * the heap dump output is written to a file named {@code outputFile} * on the machine where the target VM is running. If outputFile is * a relative path, it is relative to the working directory where * the target VM was started. * * @param outputFile the system-dependent filename - * @param live if true dump only live objects + * @param live if {@code true} dump only live objects * i.e. objects that are reachable from others - * @throws IOException if the outputFile + * @throws IOException if the {@code outputFile} * cannot be created, opened, or written to. * @throws UnsupportedOperationException if this operation is not supported. - * @throws NullPointerException if outputFile is null. + * @throws NullPointerException if {@code outputFile} is {@code null}. * @throws SecurityException * If a security manager exists and its {@link * java.lang.SecurityManager#checkWrite(java.lang.String)} @@ -75,21 +75,21 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { public void dumpHeap(String outputFile, boolean live) throws java.io.IOException; /** - * Returns a list of VMOption objects for all diagnostic options. + * Returns a list of {@code VMOption} objects for all diagnostic options. * A diagnostic option is a {@link VMOption#isWriteable writeable} * VM option that can be set dynamically mainly for troubleshooting * and diagnosis. * - * @return a list of VMOption objects for all diagnostic options. + * @return a list of {@code VMOption} objects for all diagnostic options. */ public java.util.List getDiagnosticOptions(); /** - * Returns a VMOption object for a VM option of the given + * Returns a {@code VMOption} object for a VM option of the given * name. * - * @return a VMOption object for a VM option of the given name. - * @throws NullPointerException if name is null. + * @return a {@code VMOption} object for a VM option of the given name. + * @throws NullPointerException if name is {@code null}. * @throws IllegalArgumentException if a VM option of the given name * does not exist. */ @@ -97,10 +97,10 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { /** * Sets a VM option of the given name to the specified value. - * The new value will be reflected in a new VMOption + * The new value will be reflected in a new {@code VMOption} * object returned by the {@link #getVMOption} method or * the {@link #getDiagnosticOptions} method. This method does - * not change the value of this VMOption object. + * not change the value of this {@code VMOption} object. * * @param name Name of a VM option * @param value New value of the VM option to be set @@ -109,7 +109,7 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { * does not exist. * @throws IllegalArgumentException if the new value is invalid. * @throws IllegalArgumentException if the VM option is not writable. - * @throws NullPointerException if name or value is null. + * @throws NullPointerException if name or value is {@code null}. * * @throws java.lang.SecurityException * if a security manager exists and the caller does not have diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java index 3b928aa7b0f..edee07f1d21 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java @@ -30,7 +30,7 @@ package com.sun.management; * on which the Java virtual machine is running. * *

    - * The OperatingSystemMXBean object returned by + * The {@code OperatingSystemMXBean} object returned by * {@link java.lang.management.ManagementFactory#getOperatingSystemMXBean()} * is an instance of the implementation class of this interface * or {@link UnixOperatingSystemMXBean} interface depending on @@ -46,11 +46,11 @@ public interface OperatingSystemMXBean extends /** * Returns the amount of virtual memory that is guaranteed to * be available to the running process in bytes, - * or -1 if this operation is not supported. + * or {@code -1} if this operation is not supported. * * @return the amount of virtual memory that is guaranteed to * be available to the running process in bytes, - * or -1 if this operation is not supported. + * or {@code -1} if this operation is not supported. */ public long getCommittedVirtualMemorySize(); @@ -72,11 +72,11 @@ public interface OperatingSystemMXBean extends * Returns the CPU time used by the process on which the Java * virtual machine is running in nanoseconds. The returned value * is of nanoseconds precision but not necessarily nanoseconds - * accuracy. This method returns -1 if the + * accuracy. This method returns {@code -1} if the * the platform does not support this operation. * * @return the CPU time used by the process in nanoseconds, - * or -1 if this operation is not supported. + * or {@code -1} if this operation is not supported. */ public long getProcessCpuTime(); diff --git a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java index ee118b8bd24..3038f6fc49e 100644 --- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java +++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java @@ -125,7 +125,7 @@ public class DnsContext extends ComponentDirContext { * Returns a clone of a DNS context. The context's modifiable * private state is independent of the original's (so closing one * context, for example, won't close the other). The two contexts - * share environment, but it's copy-on-write so there's + * share {@code environment}, but it's copy-on-write so there's * no conflict. */ private DnsContext(DnsContext ctx) { diff --git a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java index 68bb9a12214..4bd2b06d877 100644 --- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java +++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java @@ -34,7 +34,7 @@ import javax.naming.*; /** - * DnsName implements compound names for DNS as specified by + * {@code DnsName} implements compound names for DNS as specified by * RFCs 1034 and 1035, and as updated and clarified by RFCs 1123 and 2181. * *

    The labels in a domain name correspond to JNDI atomic names. @@ -57,45 +57,45 @@ import javax.naming.*; *

    DNS does not specify an encoding (such as UTF-8) to use for * octets with non-ASCII values. As of this writing there is some * work going on in this area, but it is not yet finalized. - * DnsName currently converts any non-ASCII octets into + * {@code DnsName} currently converts any non-ASCII octets into * characters using ISO-LATIN-1 encoding, in effect taking the * value of each octet and storing it directly into the low-order byte * of a Java character and vice versa. As a consequence, no * character in a DNS name will ever have a non-zero high-order byte. * When the work on internationalizing domain names has stabilized - * (see for example draft-ietf-idn-idna-10.txt), DnsName + * (see for example draft-ietf-idn-idna-10.txt), {@code DnsName} * may be updated to conform to that work. * - *

    Backslash (\) is used as the escape character in the + *

    Backslash ({@code \}) is used as the escape character in the * textual representation of a domain name. The character sequence - * `\DDD', where DDD is a 3-digit decimal number + * `{@code \DDD}', where {@code DDD} is a 3-digit decimal number * (with leading zeros if needed), represents the octet whose value - * is DDD. The character sequence `\C', where - * C is a character other than '0' through - * '9', represents the octet whose value is that of - * C (again using ISO-LATIN-1 encoding); this is particularly - * useful for escaping '.' or backslash itself. Backslash is + * is {@code DDD}. The character sequence `{@code \C}', where + * {@code C} is a character other than {@code '0'} through + * {@code '9'}, represents the octet whose value is that of + * {@code C} (again using ISO-LATIN-1 encoding); this is particularly + * useful for escaping {@code '.'} or backslash itself. Backslash is * otherwise not allowed in a domain name. Note that escape characters * are interpreted when a name is parsed. So, for example, the character - * sequences `S', `\S', and `\083' each - * represent the same one-octet name. The toString() method + * sequences `{@code S}', `{@code \S}', and `{@code \083}' each + * represent the same one-octet name. The {@code toString()} method * does not generally insert escape sequences except where necessary. - * If, however, the DnsName was constructed using unneeded - * escapes, those escapes may appear in the toString result. + * If, however, the {@code DnsName} was constructed using unneeded + * escapes, those escapes may appear in the {@code toString} result. * *

    Atomic names passed as parameters to methods of - * DnsName, and those returned by them, are unescaped. So, - * for example, (new DnsName()).add("a.b") creates an - * object representing the one-label domain name a\.b, and - * calling get(0) on this object returns "a.b". + * {@code DnsName}, and those returned by them, are unescaped. So, + * for example, (new DnsName()).add("a.b") creates an + * object representing the one-label domain name {@code a\.b}, and + * calling {@code get(0)} on this object returns {@code "a.b"}. * *

    While DNS names are case-preserving, comparisons between them * are case-insensitive. When comparing names containing non-ASCII - * octets, DnsName uses case-insensitive comparison + * octets, {@code DnsName} uses case-insensitive comparison * between pairs of ASCII values, and exact binary comparison * otherwise. - *

    A DnsName instance is not synchronized against + *

    A {@code DnsName} instance is not synchronized against * concurrent access by multiple threads. * * @author Scott Seligman @@ -119,16 +119,16 @@ public final class DnsName implements Name { /** - * Constructs a DnsName representing the empty domain name. + * Constructs a {@code DnsName} representing the empty domain name. */ public DnsName() { } /** - * Constructs a DnsName representing a given domain name. + * Constructs a {@code DnsName} representing a given domain name. * * @param name the domain name to parse - * @throws InvalidNameException if name does not conform + * @throws InvalidNameException if {@code name} does not conform * to DNS syntax. */ public DnsName(String name) throws InvalidNameException { diff --git a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/NameNode.java b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/NameNode.java index 07cdde53ee4..95c3b521259 100644 --- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/NameNode.java +++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/NameNode.java @@ -38,7 +38,7 @@ import java.util.Hashtable; *

    A node may be addressed from another by giving a DnsName * consisting of the sequence of labels from one node to the other. * - *

    Each node also has an isZoneCut flag, used to indicate + *

    Each node also has an {@code isZoneCut} flag, used to indicate * if the node is a zone cut. A zone cut is a node with an NS record * that is contained in one zone, but that actually belongs to a child zone. * @@ -115,7 +115,7 @@ class NameNode { /* * Returns the node at the end of a path, or null if the * node does not exist. - * The path is specified by the labels of name, beginning + * The path is specified by the labels of {@code name}, beginning * at index idx. */ NameNode get(DnsName name, int idx) { @@ -129,7 +129,7 @@ class NameNode { /* * Returns the node at the end of a path, creating it and any * intermediate nodes as needed. - * The path is specified by the labels of name, beginning + * The path is specified by the labels of {@code name}, beginning * at index idx. */ NameNode add(DnsName name, int idx) { diff --git a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/Resolver.java b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/Resolver.java index ec4e0b9ca42..a02825f646f 100644 --- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/Resolver.java +++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/Resolver.java @@ -160,7 +160,7 @@ class Resolver { } /* - * Finds the name servers of a zone. zone is a fully-qualified + * Finds the name servers of a zone. {@code zone} is a fully-qualified * domain name at the top of a zone. * If recursion is true, recursion is requested on the query. */ diff --git a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java index f676d553ff1..352f15df916 100644 --- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java +++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java @@ -154,7 +154,7 @@ class ZoneNode extends NameNode { } /* - * Set this zone's data to expire in secsToExpiration seconds. + * Set this zone's data to expire in {@code secsToExpiration} seconds. */ private void setExpiration(long secsToExpiration) { expiration = new Date(System.currentTimeMillis() + diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 67724532e40..3cce490e325 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -129,6 +129,9 @@ java/beans/XMLDecoder/8028054/TestMethodFinder.java generic-all # 8029891 java/lang/ClassLoader/deadlock/GetResource.java generic-all +# 8133552 +java/lang/ProcessHandle/InfoTest.java generic-all + ############################################################################ # jdk_instrument diff --git a/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java b/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java index 3bb1c714e60..8d5e7c919ba 100644 --- a/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java +++ b/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java @@ -73,6 +73,8 @@ public class TestTotalSwap { private static final long MAX_SIZE_FOR_PASS = Long.MAX_VALUE; public static void main(String args[]) throws Throwable { + // yocto might ignore the request to report swap size in bytes + boolean swapInKB = mbean.getVersion().contains("yocto"); long expected_swap_size = getSwapSizeFromOs(); @@ -87,10 +89,13 @@ public class TestTotalSwap { if (expected_swap_size > -1) { if (size != expected_swap_size) { - throw new RuntimeException("Expected total swap size : " + - expected_swap_size + - " but getTotalSwapSpaceSize returned: " + - size); + // try the expected size in kiloBytes + if (!(swapInKB && expected_swap_size * 1024 == size)) { + throw new RuntimeException("Expected total swap size : " + + expected_swap_size + + " but getTotalSwapSpaceSize returned: " + + size); + } } } diff --git a/jdk/test/java/lang/ClassLoader/GetSystemPackage.java b/jdk/test/java/lang/ClassLoader/GetSystemPackage.java index 09e4afb5a2e..3e7d3261b98 100644 --- a/jdk/test/java/lang/ClassLoader/GetSystemPackage.java +++ b/jdk/test/java/lang/ClassLoader/GetSystemPackage.java @@ -181,7 +181,6 @@ public class GetSystemPackage { private static Package findPackage(String name) { Package[] packages = Package.getPackages(); for (Package p : packages) { - System.out.println(p); if (p.getName().equals(name)) { return p; } diff --git a/jdk/test/java/lang/ProcessHandle/InfoTest.java b/jdk/test/java/lang/ProcessHandle/InfoTest.java index 5efc99062d3..17c8b492cfb 100644 --- a/jdk/test/java/lang/ProcessHandle/InfoTest.java +++ b/jdk/test/java/lang/ProcessHandle/InfoTest.java @@ -49,10 +49,12 @@ import org.testng.TestNG; /* * @test + * @bug 8077350 8081566 8081567 8098852 * @build jdk.testlibrary.* * @library /lib/testlibrary * @summary Functions of ProcessHandle.Info * @author Roger Riggs + * @key intermittent */ public class InfoTest { @@ -136,7 +138,17 @@ public class InfoTest { } } - + if (Platform.isAix()) { + // Unfortunately, on AIX the usr/sys times reported through + // /proc//psinfo which are used by ProcessHandle.Info + // are running slow compared to the corresponding times reported + // by the times()/getrusage() system calls which are used by + // OperatingSystemMXBean.getProcessCpuTime() and returned by + // the JavaChild for the "cputime" command. + // This is because /proc//status is only updated once a second. + // So we better wait a little bit to get plausible values here. + Thread.sleep(1000); + } ProcessHandle.Info info = p1.info(); System.out.printf(" info: %s%n", info); @@ -160,19 +172,10 @@ public class InfoTest { if (info.arguments().isPresent()) { String[] args = info.arguments().get(); - if (Platform.isLinux() || Platform.isOSX()) { - int offset = args.length - extraArgs.length; - for (int i = 0; i < extraArgs.length; i++) { - Assert.assertEquals(args[offset + i], extraArgs[i], - "Actual argument mismatch, index: " + i); - } - } else if (Platform.isSolaris()) { - Assert.assertEquals(args.length, 1, - "Expected argument list length: 1"); - Assert.assertNotNull(args[0], - "Expected an argument"); - } else { - System.out.printf("No argument test for OS: %s%n", Platform.getOsName()); + int offset = args.length - extraArgs.length; + for (int i = 0; i < extraArgs.length; i++) { + Assert.assertEquals(args[offset + i], extraArgs[i], + "Actual argument mismatch, index: " + i); } // Now check that the first argument is not the same as the executed command @@ -183,6 +186,46 @@ public class InfoTest { } } + if (command.isPresent() && info.arguments().isPresent()) { + // If both, 'command' and 'arguments' are present, + // 'commandLine' is just the concatenation of the two. + Assert.assertTrue(info.commandLine().isPresent(), + "commandLine() must be available"); + + String javaExe = System.getProperty("test.jdk") + + File.separator + "bin" + File.separator + "java"; + String expected = Platform.isWindows() ? javaExe + ".exe" : javaExe; + Path expectedPath = Paths.get(expected); + String commandLine = info.commandLine().get(); + String commandLineCmd = commandLine.split(" ")[0]; + Path commandLineCmdPath = Paths.get(commandLineCmd); + Assert.assertTrue(Files.isSameFile(commandLineCmdPath, expectedPath), + "commandLine() should start with: " + expectedPath + + " but starts with " + commandLineCmdPath); + + List allArgs = p1.getArgs(); + for (int i = 0; i < allArgs.size(); i++) { + Assert.assertTrue(commandLine.contains(allArgs.get(i)), + "commandLine() must contain argument: " + allArgs.get(i)); + } + } else if (info.commandLine().isPresent()) { + // If we only have the commandLine() we can only do some basic checks... + String commandLine = info.commandLine().get(); + String javaExe = "java" + (Platform.isWindows() ? ".exe": ""); + int pos = commandLine.indexOf(javaExe); + Assert.assertTrue(pos > 0, "commandLine() should at least contain 'java'"); + + pos += javaExe.length() + 1; // +1 for the space after the command + List allArgs = p1.getArgs(); + // First argument is the command - skip it here as we've already checked that. + for (int i = 1; (i < allArgs.size()) && + (pos + allArgs.get(i).length() < commandLine.length()); i++) { + Assert.assertTrue(commandLine.contains(allArgs.get(i)), + "commandLine() must contain argument: " + allArgs.get(i)); + pos += allArgs.get(i).length() + 1; + } + } + if (info.totalCpuDuration().isPresent()) { Duration totalCPU = info.totalCpuDuration().get(); Duration epsilon = Duration.ofMillis(200L); @@ -269,10 +312,27 @@ public class InfoTest { public static void test4() { Duration myCputime1 = ProcessUtil.MXBeanCpuTime(); + if (Platform.isAix()) { + // Unfortunately, on AIX the usr/sys times reported through + // /proc//psinfo which are used by ProcessHandle.Info + // are running slow compared to the corresponding times reported + // by the times()/getrusage() system calls which are used by + // OperatingSystemMXBean.getProcessCpuTime() and returned by + // the JavaChild for the "cputime" command. + // So we better wait a little bit to get plausible values here. + try { + Thread.sleep(1000); + } catch (InterruptedException ex) {} + } Optional dur1 = ProcessHandle.current().info().totalCpuDuration(); Duration myCputime2 = ProcessUtil.MXBeanCpuTime(); + if (Platform.isAix()) { + try { + Thread.sleep(1000); + } catch (InterruptedException ex) {} + } Optional dur2 = ProcessHandle.current().info().totalCpuDuration(); if (dur1.isPresent() && dur2.isPresent()) { diff --git a/jdk/test/java/lang/ProcessHandle/JavaChild.java b/jdk/test/java/lang/ProcessHandle/JavaChild.java index 9d4a6e1f2f2..b476bf0a567 100644 --- a/jdk/test/java/lang/ProcessHandle/JavaChild.java +++ b/jdk/test/java/lang/ProcessHandle/JavaChild.java @@ -68,8 +68,9 @@ private static volatile int commandSeq = 0; // Command sequence number * {@link #forEachOutputLine} can be used to process output from the child * @param delegate the process to delegate and send commands to and get responses from */ - private JavaChild(Process delegate) { - this.delegate = delegate; + private JavaChild(ProcessBuilder pb) throws IOException { + allArgs = pb.command(); + delegate = pb.start(); // Initialize PrintWriter with autoflush (on println) inputWriter = new PrintWriter(delegate.getOutputStream(), true); outputReader = new BufferedReader(new InputStreamReader(delegate.getInputStream())); @@ -119,6 +120,10 @@ private static volatile int commandSeq = 0; // Command sequence number return "delegate: " + delegate.toString(); } + public List getArgs() { + return allArgs; + } + public CompletableFuture onJavaChildExit() { return onExit().thenApply(ph -> this); } @@ -187,7 +192,7 @@ private static volatile int commandSeq = 0; // Command sequence number } ProcessBuilder pb = build(stringArgs); pb.redirectError(ProcessBuilder.Redirect.INHERIT); - return new JavaChild(pb.start()); + return new JavaChild(pb); } /** @@ -236,6 +241,9 @@ private static volatile int commandSeq = 0; // Command sequence number "-classpath", absolutifyPath(classpath), "JavaChild"); + // Will hold the complete list of arguments which was given to Processbuilder.command() + private List allArgs; + private static String absolutifyPath(String path) { StringBuilder sb = new StringBuilder(); for (String file : path.split(File.pathSeparator)) { diff --git a/jdk/test/java/lang/ProcessHandle/OnExitTest.java b/jdk/test/java/lang/ProcessHandle/OnExitTest.java index 5de89a3a353..b86df47ea67 100644 --- a/jdk/test/java/lang/ProcessHandle/OnExitTest.java +++ b/jdk/test/java/lang/ProcessHandle/OnExitTest.java @@ -126,6 +126,11 @@ public class OnExitTest extends ProcessUtil { } while (processes.size() < expected && Instant.now().isBefore(endTimeout)); + if (processes.size() < expected) { + printf("WARNING: not all children have been started. Can't complete test.%n"); + printf(" You can try to increase the timeout or%n"); + printf(" you can try to use a faster VM (i.e. not a debug version).%n"); + } children = getAllChildren(procHandle); ConcurrentHashMap> completions = diff --git a/jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java b/jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java index 045ec15599e..0bc335181ba 100644 --- a/jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java +++ b/jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -21,79 +21,583 @@ * questions. */ -package java.lang.invoke; - +import com.oracle.testlibrary.jsr292.Helper; +import java.io.File; +import java.io.Serializable; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.WrongMethodTypeException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; import sun.invoke.util.Wrapper; -/* @test +/* + * @test + * @bug 8060483 8066746 + * @key randomness + * @library /lib/testlibrary /lib/testlibrary/jsr292 * @summary unit tests for MethodHandles.explicitCastArguments() - * - * @run main/bootclasspath java.lang.invoke.ExplicitCastArgumentsTest + * @run main ExplicitCastArgumentsTest + */ + +/** + * Tests for MethodHandles.explicitCastArguments(). */ public class ExplicitCastArgumentsTest { - private static final boolean VERBOSE = Boolean.getBoolean("verbose"); + + private static final boolean VERBOSE = Helper.IS_VERBOSE; private static final Class THIS_CLASS = ExplicitCastArgumentsTest.class; + private static final Random RNG = Helper.RNG; + private static final Map RANDOM_VALUES = new HashMap<>(9); + + static { + RANDOM_VALUES.put(Wrapper.BOOLEAN, RNG.nextBoolean()); + RANDOM_VALUES.put(Wrapper.BYTE, (byte) RNG.nextInt()); + RANDOM_VALUES.put(Wrapper.SHORT, (short) RNG.nextInt()); + RANDOM_VALUES.put(Wrapper.CHAR, (char) RNG.nextInt()); + RANDOM_VALUES.put(Wrapper.INT, RNG.nextInt()); + RANDOM_VALUES.put(Wrapper.LONG, RNG.nextLong()); + RANDOM_VALUES.put(Wrapper.FLOAT, RNG.nextFloat()); + RANDOM_VALUES.put(Wrapper.DOUBLE, RNG.nextDouble()); + RANDOM_VALUES.put(Wrapper.OBJECT, new Object()); + } public static void main(String[] args) throws Throwable { testVarargsCollector(); + testNullRef2Prim(); testRef2Prim(); + testPrim2Ref(); + testPrim2Prim(); + testNonBCPRef2NonBCPRef(); + testBCPRef2BCPRef(); + testNonBCPRef2BCPRef(); + testReturnAny2Void(); + testReturnVoid2Any(); + testMultipleArgs(); System.out.println("TEST PASSED"); } - public static String[] f(String... args) { return args; } - - public static void testVarargsCollector() throws Throwable { - MethodType mt = MethodType.methodType(String[].class, String[].class); - MethodHandle mh = MethodHandles.publicLookup().findStatic(THIS_CLASS, "f", mt); - mh = MethodHandles.explicitCastArguments(mh, MethodType.methodType(Object.class, Object.class)); - mh.invokeWithArguments((Object)(new String[] {"str1", "str2"})); + /** + * Dummy method used in {@link #testVarargsCollector} test to form a method + * handle. + * + * @param args - any args + * @return - returns args + */ + public static String[] f(String... args) { + return args; } - public static void testRef2Prim() throws Throwable { + /** + * Tests that MHs.explicitCastArguments does incorrect type checks for + * VarargsCollector. Bug 8066746. + * + * @throws java.lang.Throwable + */ + public static void testVarargsCollector() throws Throwable { + MethodType mt = MethodType.methodType(String[].class, String[].class); + MethodHandle mh = MethodHandles.publicLookup() + .findStatic(THIS_CLASS, "f", mt); + mh = MethodHandles.explicitCastArguments(mh, + MethodType.methodType(Object.class, Object.class)); + mh.invokeWithArguments((Object) (new String[]{"str1", "str2"})); + } + + /** + * Tests that null wrapper reference is successfully converted to primitive + * types. Converted result should be zero for a primitive. Bug 8060483. + */ + public static void testNullRef2Prim() { for (Wrapper from : Wrapper.values()) { for (Wrapper to : Wrapper.values()) { - if (from == Wrapper.VOID || to == Wrapper.VOID) continue; - testRef2Prim(from, to); + if (from == Wrapper.VOID || to == Wrapper.VOID) { + continue; + } + // MHs.eCA javadoc: + // If T0 is a reference and T1 a primitive, and if the reference + // is null at runtime, a zero value is introduced. + for (TestConversionMode mode : TestConversionMode.values()) { + testConversion(mode, from.wrapperType(), + to.primitiveType(), null, to.zero(), false, null); + } } } } - public static void testRef2Prim(Wrapper from, Wrapper to) throws Throwable { - // MHs.eCA javadoc: - // If T0 is a reference and T1 a primitive, and if the reference is null at runtime, a zero value is introduced. - test(from.wrapperType(), to.primitiveType(), null, false); + /** + * Tests that non-null wrapper reference is successfully converted to + * primitive types. + */ + public static void testRef2Prim() { + for (Wrapper from : Wrapper.values()) { + for (Wrapper to : Wrapper.values()) { + if (from == Wrapper.VOID || to == Wrapper.VOID + || to == Wrapper.OBJECT) { + continue; + } + Object value = RANDOM_VALUES.get(from); + for (TestConversionMode mode : TestConversionMode.values()) { + if (from != Wrapper.OBJECT) { + Object convValue = to.wrap(value); + testConversion(mode, from.wrapperType(), + to.primitiveType(), value, convValue, false, null); + } else { + testConversion(mode, from.wrapperType(), + to.primitiveType(), value, null, + true, ClassCastException.class); + } + } + } + } } - public static void test(Class from, Class to, Object param, boolean failureExpected) throws Throwable { - if (VERBOSE) System.out.printf("%-10s => %-10s: %5s: ", from.getSimpleName(), to.getSimpleName(), param); + /** + * Tests that primitive is successfully converted to wrapper reference + * types, to the Number type (if possible) and to the Object type. + */ + public static void testPrim2Ref() { + for (Wrapper from : Wrapper.values()) { + for (Wrapper to : Wrapper.values()) { + if (from == Wrapper.VOID || from == Wrapper.OBJECT + || to == Wrapper.VOID || to == Wrapper.OBJECT) { + continue; + } + Object value = RANDOM_VALUES.get(from); + for (TestConversionMode mode : TestConversionMode.values()) { + if (from == to) { + testConversion(mode, from.primitiveType(), + to.wrapperType(), value, value, false, null); + } else { + testConversion(mode, from.primitiveType(), + to.wrapperType(), value, null, true, ClassCastException.class); + } + if (from != Wrapper.BOOLEAN && from != Wrapper.CHAR) { + testConversion(mode, from.primitiveType(), + Number.class, value, value, false, null); + } else { + testConversion(mode, from.primitiveType(), + Number.class, value, null, + true, ClassCastException.class); + } + testConversion(mode, from.primitiveType(), + Object.class, value, value, false, null); + } + } + } + } - MethodHandle original = MethodHandles.identity(from); - MethodType newType = original.type().changeReturnType(to); + /** + * Tests that primitive is successfully converted to other primitive type. + */ + public static void testPrim2Prim() { + for (Wrapper from : Wrapper.values()) { + for (Wrapper to : Wrapper.values()) { + if (from == Wrapper.VOID || to == Wrapper.VOID + || from == Wrapper.OBJECT || to == Wrapper.OBJECT) { + continue; + } + Object value = RANDOM_VALUES.get(from); + Object convValue = to.wrap(value); + for (TestConversionMode mode : TestConversionMode.values()) { + testConversion(mode, from.primitiveType(), + to.primitiveType(), value, convValue, false, null); + } + } + } + } + /** + * Dummy interface for {@link #testNonBCPRef2Ref} test. + */ + public static interface TestInterface {} + + /** + * Dummy class for {@link #testNonBCPRef2Ref} test. + */ + public static class TestSuperClass implements TestInterface {} + + /** + * Dummy class for {@link #testNonBCPRef2Ref} test. + */ + public static class TestSubClass1 extends TestSuperClass {} + + /** + * Dummy class for {@link #testNonBCPRef2Ref} test. + */ + public static class TestSubClass2 extends TestSuperClass {} + + /** + * Tests non-bootclasspath reference to reference conversions. + * + * @throws java.lang.Throwable + */ + public static void testNonBCPRef2NonBCPRef() throws Throwable { + Class testInterface = TestInterface.class; + Class testSuperClass = TestSuperClass.class; + Class testSubClass1 = TestSubClass1.class; + Class testSubClass2 = TestSubClass2.class; + Object testSuperObj = new TestSuperClass(); + Object testObj01 = new TestSubClass1(); + Object testObj02 = new TestSubClass2(); + Class[] parents = {testInterface, testSuperClass}; + Class[] children = {testSubClass1, testSubClass2}; + Object[] childInst = {testObj01, testObj02}; + for (TestConversionMode mode : TestConversionMode.values()) { + for (Class parent : parents) { + for (int j = 0; j < children.length; j++) { + // Child type to parent type non-null conversion, shoud succeed + testConversion(mode, children[j], parent, childInst[j], childInst[j], false, null); + // Child type to parent type null conversion, shoud succeed + testConversion(mode, children[j], parent, null, null, false, null); + // Parent type to child type non-null conversion with parent + // type instance, should fail + testConversion(mode, parent, children[j], testSuperObj, null, true, ClassCastException.class); + // Parent type to child type non-null conversion with child + // type instance, should succeed + testConversion(mode, parent, children[j], childInst[j], childInst[j], false, null); + // Parent type to child type null conversion, should succeed + testConversion(mode, parent, children[j], null, null, false, null); + } + // Parent type to child type non-null conversion with sibling + // type instance, should fail + testConversion(mode, parent, testSubClass1, testObj02, null, true, ClassCastException.class); + } + // Sibling type non-null conversion, should fail + testConversion(mode, testSubClass1, + testSubClass2, testObj01, null, true, + ClassCastException.class); + // Sibling type null conversion, should succeed + testConversion(mode, testSubClass1, + testSubClass2, null, null, false, null); + } + } + + /** + * Dummy interface for {@link #testNonBCPRef2BCPRef} test. + */ + public static interface TestSerializableInterface extends Serializable {} + + /** + * Dummy class for {@link #testNonBCPRef2BCPRef} test. + */ + public static class TestSerializableClass + implements TestSerializableInterface {} + + /** + * Dummy class for {@link #testNonBCPRef2BCPRef} test. + */ + public static class TestFileChildClass extends File + implements TestSerializableInterface { + public TestFileChildClass(String pathname) { + super(pathname); + } + } + + /** + * Tests non-bootclasspath reference to bootclasspath reference conversions + * and vice-versa. + * + * @throws java.lang.Throwable + */ + public static void testNonBCPRef2BCPRef() throws Throwable { + Class bcpInterface = Serializable.class; + Class bcpSuperClass = File.class; + Class nonBcpInterface = TestSerializableInterface.class; + Class nonBcpSuperSiblingClass = TestSerializableClass.class; + Class nonBcpSubClass = TestFileChildClass.class; + Object bcpSuperObj = new File("."); + Object testSuperSiblingObj = new TestSerializableClass(); + Object testSubObj = new TestFileChildClass("."); + Class[] parents = {bcpInterface, bcpSuperClass}; + for (TestConversionMode mode : TestConversionMode.values()) { + for (Class parent : parents) { + // Child type to parent type non-null conversion, shoud succeed + testConversion(mode, nonBcpSubClass, parent, testSubObj, + testSubObj, false, null); + // Child type to parent type null conversion, shoud succeed + testConversion(mode, nonBcpSubClass, parent, null, null, + false, null); + // Parent type to child type non-null conversion with parent + // type instance, should fail + testConversion(mode, parent, nonBcpSubClass, bcpSuperObj, null, + true, ClassCastException.class); + // Parent type to child type non-null conversion with child + // type instance, should succeed + testConversion(mode, parent, nonBcpSubClass, testSubObj, + testSubObj, false, null); + // Parent type to child type null conversion, should succeed + testConversion(mode, parent, nonBcpSubClass, null, null, + false, null); + } + // Parent type to child type non-null conversion with + // super sibling type instance, should fail + testConversion(mode, bcpInterface, nonBcpSubClass, + testSuperSiblingObj, null, true, ClassCastException.class); + Class[] siblings = {nonBcpSubClass, bcpSuperClass}; + for (Class sibling : siblings) { + // Non-bcp class to bcp/non-bcp sibling class non-null + // conversion with nonBcpSuperSiblingClass instance, should fail + testConversion(mode, nonBcpSuperSiblingClass, sibling, + testSuperSiblingObj, null, true, ClassCastException.class); + // Non-bcp class to bcp/non-bcp sibling class null conversion, + // should succeed + testConversion(mode, nonBcpSuperSiblingClass, sibling, + null, null, false, null); + // Non-bcp interface to bcp/non-bcp sibling class non-null + // conversion with nonBcpSubClass instance, should succeed + testConversion(mode, nonBcpInterface, sibling, testSubObj, + testSubObj, false, null); + // Non-bcp interface to bcp/non-bcp sibling class + // null conversion, should succeed + testConversion(mode, nonBcpInterface, sibling, null, null, + false, null); + // Non-bcp interface to bcp/non-bcp sibling class non-null + // conversion with nonBcpSuperSiblingClass instance, should fail + testConversion(mode, nonBcpInterface, sibling, + testSuperSiblingObj, testSubObj, + true, ClassCastException.class); + } + } + } + + /** + * Tests bootclasspath reference to reference conversions. + */ + public static void testBCPRef2BCPRef() { + Class bcpInterface = CharSequence.class; + Class bcpSubClass1 = String.class; + Class bcpSubClass2 = StringBuffer.class; + Object testObj01 = new String("test"); + Object testObj02 = new StringBuffer("test"); + Class[] children = {bcpSubClass1, bcpSubClass2}; + Object[] childInst = {testObj01, testObj02}; + for (TestConversionMode mode : TestConversionMode.values()) { + for (int i = 0; i < children.length; i++) { + // Child type to parent type non-null conversion, shoud succeed + testConversion(mode, children[i], bcpInterface, childInst[i], + childInst[i], false, null); + // Child type to parent type null conversion, shoud succeed + testConversion(mode, children[i], bcpInterface, null, + null, false, null); + // Parent type to child type non-null conversion with child + // type instance, should succeed + testConversion(mode, bcpInterface, + children[i], childInst[i], childInst[i], false, null); + // Parent type to child type null conversion, should succeed + testConversion(mode, bcpInterface, + children[i], null, null, false, null); + } + // Sibling type non-null conversion, should fail + testConversion(mode, bcpSubClass1, + bcpSubClass2, testObj01, null, true, + ClassCastException.class); + // Sibling type null conversion, should succeed + testConversion(mode, bcpSubClass1, + bcpSubClass2, null, null, false, null); + // Parent type to child type non-null conversion with sibling + // type instance, should fail + testConversion(mode, bcpInterface, bcpSubClass1, testObj02, + null, true, ClassCastException.class); + } + } + + /** + * Dummy method used in {@link #testReturnAny2Void} and + * {@link #testReturnVoid2Any} tests to form a method handle. + */ + public static void retVoid() {} + + /** + * Tests that non-null any return is successfully converted to non-type + * void. + */ + public static void testReturnAny2Void() { + for (Wrapper from : Wrapper.values()) { + testConversion(TestConversionMode.RETURN_VALUE, from.wrapperType(), + void.class, RANDOM_VALUES.get(from), + null, false, null); + testConversion(TestConversionMode.RETURN_VALUE, from.primitiveType(), + void.class, RANDOM_VALUES.get(from), + null, false, null); + } + } + + /** + * Tests that void return is successfully converted to primitive and + * reference. Result should be zero for primitives and null for references. + */ + public static void testReturnVoid2Any() { + for (Wrapper to : Wrapper.values()) { + testConversion(TestConversionMode.RETURN_VALUE, void.class, + to.primitiveType(), null, + to.zero(), false, null); + testConversion(TestConversionMode.RETURN_VALUE, void.class, + to.wrapperType(), null, + null, false, null); + } + } + + private static void checkForWrongMethodTypeException(MethodHandle mh, MethodType mt) { try { - MethodHandle target = MethodHandles.explicitCastArguments(original, newType); - Object result = target.invokeWithArguments(param); + MethodHandles.explicitCastArguments(mh, mt); + throw new AssertionError("Expected WrongMethodTypeException is not thrown"); + } catch (WrongMethodTypeException wmte) { + if (VERBOSE) { + System.out.printf("Expected exception %s: %s\n", + wmte.getClass(), wmte.getMessage()); + } + } + } + /** + * Tests that MHs.eCA method works correctly with MHs with multiple arguments. + * @throws Throwable + */ + public static void testMultipleArgs() throws Throwable { + int arity = 1 + RNG.nextInt(Helper.MAX_ARITY / 2 - 2); + int arityMinus = RNG.nextInt(arity); + int arityPlus = arity + RNG.nextInt(Helper.MAX_ARITY / 2 - arity) + 1; + MethodType mType = Helper.randomMethodTypeGenerator(arity); + MethodType mTypeNew = Helper.randomMethodTypeGenerator(arity); + MethodType mTypeNewMinus = Helper.randomMethodTypeGenerator(arityMinus); + MethodType mTypeNewPlus = Helper.randomMethodTypeGenerator(arityPlus); + Class rType = mType.returnType(); + MethodHandle original; + if (rType.equals(void.class)) { + MethodType mt = MethodType.methodType(void.class); + original = MethodHandles.publicLookup() + .findStatic(THIS_CLASS, "retVoid", mt); + } else { + Object rValue = Helper.castToWrapper(1, rType); + original = MethodHandles.constant(rType, rValue); + } + original = Helper.addTrailingArgs(original, arity, mType.parameterList()); + MethodHandle target = MethodHandles + .explicitCastArguments(original, mTypeNew); + Object[] parList = Helper.randomArgs(mTypeNew.parameterList()); + for (int i = 0; i < parList.length; i++) { + if (parList[i] instanceof String) { + parList[i] = null; //getting rid of Stings produced by randomArgs + } + } + target.invokeWithArguments(parList); + checkForWrongMethodTypeException(original, mTypeNewMinus); + checkForWrongMethodTypeException(original, mTypeNewPlus); + } + + /** + * Enumeration of test conversion modes. + */ + public enum TestConversionMode { + RETURN_VALUE, + ARGUMENT; + } + + /** + * Tests type and value conversion. Comparing with the given expected result. + * + * @param mode - test conversion mode. See {@link #TestConversionMode}. + * @param from - source type. + * @param to - destination type. + * @param param - value to be converted. + * @param expectedResult - expected value after conversion. + * @param failureExpected - true if conversion failure expected. + * @param expectedException - expected exception class if + * {@code failureExpected} is true. + */ + public static void testConversion(TestConversionMode mode, + Class from, Class to, Object param, + Object expectedResult, boolean failureExpected, + Class expectedException) { + if (VERBOSE) { + System.out.printf("Testing return value conversion: " + + "%-10s => %-10s: %5s: ", from.getSimpleName(), + to.getSimpleName(), param); + } + MethodHandle original = null; + MethodType newType = null; + switch (mode) { + case RETURN_VALUE: + if (from.equals(void.class)) { + MethodType mt = MethodType.methodType(void.class); + try { + original = MethodHandles.publicLookup() + .findStatic(THIS_CLASS, "retVoid", mt); + } catch (NoSuchMethodException | IllegalAccessException ex) { + throw new Error("Unexpected issue", ex); + } + } else { + original = MethodHandles.constant(from, param); + } + newType = original.type().changeReturnType(to); + break; + case ARGUMENT: + if (from.equals(void.class) || to.equals(void.class)) { + throw new Error("Test issue: argument conversion does not" + + " work with non-type void"); + } + original = MethodHandles.identity(to); + newType = original.type().changeParameterType(0, from); + break; + default: + String msg = String.format("Test issue: unknown test" + + " convertion mode %s.", mode.name()); + throw new Error(msg); + } + try { + MethodHandle target = MethodHandles + .explicitCastArguments(original, newType); + Object result; + switch (mode) { + case RETURN_VALUE: + result = target.invokeWithArguments(); + break; + case ARGUMENT: + result = target.invokeWithArguments(param); + break; + default: + String msg = String.format("Test issue: unknown test" + + " convertion mode %s.", mode.name()); + throw new Error(msg); + } + if (!failureExpected + && (expectedResult != null && !expectedResult.equals(result) + || expectedResult == null && result != null)) { + String msg = String.format("Conversion result %s is not equal" + + " to the expected result %10s", + result, expectedResult); + throw new AssertionError(msg); + } if (VERBOSE) { String resultStr; if (result != null) { - resultStr = String.format("%10s (%10s)", "'"+result+"'", result.getClass().getSimpleName()); + resultStr = String.format("Converted value and type are" + + " %10s (%10s)", "'" + result + "'", + result.getClass().getSimpleName()); } else { - resultStr = String.format("%10s", result); + resultStr = String.format("Converted value is %10s", result); } System.out.println(resultStr); } - if (failureExpected) { - String msg = String.format("No exception thrown: %s => %s; parameter: %s", from, to, param); + String msg = String.format("No exception thrown while testing" + + " return value conversion: %10s => %10s;" + + " parameter: %10s", + from, to, param); throw new AssertionError(msg); } } catch (AssertionError e) { throw e; // report test failure } catch (Throwable e) { - if (VERBOSE) System.out.printf("%s: %s\n", e.getClass(), e.getMessage()); - if (!failureExpected) { - String msg = String.format("Unexpected exception was thrown: %s => %s; parameter: %s", from, to, param); + if (VERBOSE) { + System.out.printf("%s: %s\n", e.getClass(), e.getMessage()); + } + if (!failureExpected || !e.getClass().equals(expectedException)) { + String msg = String.format("Unexpected exception was thrown" + + " while testing return value conversion:" + + " %s => %s; parameter: %s", from, to, param); throw new AssertionError(msg, e); } } diff --git a/jdk/test/java/lang/invoke/LFCaching/TestMethods.java b/jdk/test/java/lang/invoke/LFCaching/TestMethods.java index 875307387a4..fe63b252d5d 100644 --- a/jdk/test/java/lang/invoke/LFCaching/TestMethods.java +++ b/jdk/test/java/lang/invoke/LFCaching/TestMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -207,7 +207,7 @@ public enum TestMethods { return MethodHandles.filterReturnValue(target, filter); } }, - INSERT_ARGUMENTS("insertArguments") { + INSERT_ARGUMENTS("insertArguments", Helper.MAX_ARITY - 3) { @Override public Map getTestCaseData() { Map data = new HashMap<>(); @@ -610,26 +610,7 @@ public enum TestMethods { * @return MethodType generated randomly. */ private static MethodType randomMethodTypeGenerator(int arity) { - final Class[] CLASSES = { - Object.class, - int.class, - boolean.class, - byte.class, - short.class, - char.class, - long.class, - float.class, - double.class - }; - if (arity > Helper.MAX_ARITY) { - throw new IllegalArgumentException( - String.format("Arity should not exceed %d!", Helper.MAX_ARITY)); - } - List> list = Helper.randomClasses(CLASSES, arity); - list = Helper.getParams(list, false, arity); - int i = Helper.RNG.nextInt(CLASSES.length + 1); - Class rtype = i == CLASSES.length ? void.class : CLASSES[i]; - return MethodType.methodType(rtype, list); + return Helper.randomMethodTypeGenerator(arity); } /** diff --git a/jdk/test/java/lang/ref/ReferenceEnqueue.java b/jdk/test/java/lang/ref/ReferenceEnqueue.java index 25907a034cc..c246591f12a 100644 --- a/jdk/test/java/lang/ref/ReferenceEnqueue.java +++ b/jdk/test/java/lang/ref/ReferenceEnqueue.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4268317 + * @bug 4268317 8132306 * @summary Test if Reference.enqueue() works properly with GC */ diff --git a/jdk/test/java/util/Formatter/NullArg.java b/jdk/test/java/util/Formatter/NullArg.java new file mode 100644 index 00000000000..79b979e36fe --- /dev/null +++ b/jdk/test/java/util/Formatter/NullArg.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, 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 8039390 + * @summary Basic test for null argument + */ + +import java.util.Formatter; +import java.util.Locale; + +public class NullArg { + + public static void main(String [] args) { + char[] cs = new char[] { + 'b', 'B', 'h', 'H', 's', 'S', 'c', 'C', 'd', 'o', 'x', 'X', + 'e', 'E', 'f', 'g', 'G', 'a', 'A', 't', 'T', + }; + char[] tcs = new char[] { + 'H', 'I', 'k', 'l', 'l', 'M', 'S', 'L', 'N', 'p', 'z', 'Z', 's', + 'Q', 'B', 'b', 'h', 'A', 'a', 'C', 'Y', 'y', 'j', 'm', 'd', 'e', + 'R', 'T', 'r', 'D', 'F', 'c' + }; + for (char c : cs) { + String expected = (c == 'b' || c == 'B') ? "false" : "null"; + if (Character.isUpperCase(c)) { + expected = expected.toUpperCase(Locale.ROOT); + } + if (c == 't' || c == 'T') { + for (char ct : tcs) { + if (!String.format("%" + c + ct, null).equals(expected)) { + throw new RuntimeException("%t" + ct + "null check failed."); + } + } + } else { + if (!String.format("%" + c , null).equals(expected)) { + throw new RuntimeException("%" + c + "null check failed."); + } + } + } + } +} diff --git a/jdk/test/javax/security/auth/login/LoginContext/LCTest.jaas.config b/jdk/test/javax/security/auth/login/LoginContext/LCTest.jaas.config new file mode 100644 index 00000000000..f63cff5b04b --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/LCTest.jaas.config @@ -0,0 +1,57 @@ + +"AbortRequired" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleAllPass required; +}; + +"AbortRequisite" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException requisite; + LCTest$LoginModuleAllPass required; +}; + +"AbortSufficient" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LogoutRequisite" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLogoutException requisite; + LCTest$LoginModuleAllPass required; +}; + +"LogoutSufficient" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LogoutRequired" { + LCTest$LoginModuleWithLogoutException required; + LCTest$LoginModuleWithAbortException required; + LCTest$LoginModuleAllPass required; +}; + +"LoginRequired" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException required; + LCTest$LoginModuleAllPass required; +}; + +"LoginSufficient" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LoginRequisite" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException requisite; + LCTest$LoginModuleAllPass required; +}; + +"EmptyModuleConfig" { +}; diff --git a/jdk/test/javax/security/auth/login/LoginContext/LCTest.java b/jdk/test/javax/security/auth/login/LoginContext/LCTest.java new file mode 100644 index 00000000000..e5eeb6c1d7f --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/LCTest.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2015, 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. + */ + +import com.sun.security.auth.UnixPrincipal; + +import javax.security.auth.Subject; +import javax.security.auth.callback.*; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/* + * @test + * @bug 8050460 + * @summary Test checks that proper methods associated with login/logout process + * of LoginContext are called for different configurations and circumstances. + * @modules jdk.security.auth + * + * @run main/othervm LCTest EmptyModuleConfig false + * @run main/othervm LCTest IncorrectName false + * @run main/othervm LCTest AbortRequisite false abort + * @run main/othervm LCTest AbortSufficient false abort + * @run main/othervm LCTest AbortRequired false abort + * @run main/othervm LCTest LogoutRequisite false logout + * @run main/othervm LCTest LogoutSufficient true logout + * @run main/othervm LCTest LogoutRequired false logout + * @run main/othervm LCTest LoginRequisite false login + * @run main/othervm LCTest LoginSufficient true login + * @run main/othervm LCTest LoginRequired false login + */ + +public class LCTest { + + private static final String USER_NAME = "testUser"; + private static final String PASSWORD = "testPassword"; + private static final List loggedActions = new ArrayList<>(); + + static { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "LCTest.jaas.config"); + } + + public static void main(String[] args) { + if (args.length < 2) { + throw new RuntimeException("Incorrect test params"); + } + String nameOfContext = args[0]; + boolean isPositive = Boolean.parseBoolean(args[1]); + String actionName = null; + if (args.length == 3) { + actionName = args[2]; + } + try { + LoginContext lc = new LoginContext(nameOfContext, + new MyCallbackHandler()); + lc.login(); + checkPrincipal(lc, true); + lc.logout(); + checkPrincipal(lc, false); + if (!isPositive) { + throw new RuntimeException("Test failed. Exception expected."); + } + } catch (LoginException le) { + if (isPositive) { + throw new RuntimeException("Test failed. Unexpected " + + "exception", le); + } + System.out.println("Expected exception: " + + le.getMessage()); + } + checkActions(actionName); + System.out.println("Test passed."); + } + + /* + * Log action from login modules + */ + private static void logAction(String actionName) { + loggedActions.add(actionName); + } + + /* + * Check if logged actions are as expected. We always expected 3 actions + * if any. + */ + private static void checkActions(String actionName) { + if (actionName == null) { + if (loggedActions.size() != 0) { + throw new RuntimeException("No logged actions expected"); + } + } else { + int loggedActionsFound = 0; + System.out.println("Logged actions : " + loggedActions); + for (String s : loggedActions) { + if (s.equals(actionName)) { + loggedActionsFound++; + } + } + if (loggedActionsFound != 3) { + throw new RuntimeException("Incorrect number of actions " + + actionName + " : " + loggedActionsFound); + } + } + } + + /* + * Check context for principal of the test user. + */ + private static void checkPrincipal(LoginContext loginContext, boolean + principalShouldExist) { + if (!principalShouldExist) { + if (loginContext.getSubject().getPrincipals().size() != 0) { + throw new RuntimeException("Test failed. Principal was not " + + "cleared."); + } + } else { + for (Principal p : loginContext.getSubject().getPrincipals()) { + if (p instanceof UnixPrincipal && + USER_NAME.equals(p.getName())) { + //Proper principal was found, return. + return; + } + } + throw new RuntimeException("Test failed. UnixPrincipal " + + USER_NAME + " expected."); + } + } + + private static class MyCallbackHandler implements CallbackHandler { + + @Override + public void handle(Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + ((NameCallback) callback).setName(USER_NAME); + } else if (callback instanceof PasswordCallback) { + ((PasswordCallback) callback).setPassword( + PASSWORD.toCharArray()); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + } + + /* ------------------------------------------------------------------------- + * Test login modules + * ------------------------------------------------------------------------- + */ + + /* + * Login module that should pass through all phases. + */ + public static class LoginModuleAllPass extends LoginModuleBase { + + } + + /* + * Login module that throws Exception in abort method. + */ + public static class LoginModuleWithAbortException extends LoginModuleBase { + + @Override + public boolean abort() throws LoginException { + super.abort(); + throw new LoginException("Abort failed!"); + } + } + + /* + * Login module that throws Exception in login method. + */ + public static class LoginModuleWithLoginException extends LoginModuleBase { + + @Override + public boolean login() throws LoginException { + super.login(); + throw new FailedLoginException("Login failed!"); + } + } + + /* + * Login module that throws Exception in logout method. + */ + public static class LoginModuleWithLogoutException extends LoginModuleBase { + + @Override + public boolean logout() throws LoginException { + super.logout(); + throw new FailedLoginException("Logout failed!"); + } + } + + /* + * Base class for login modules + */ + public static abstract class LoginModuleBase implements LoginModule { + // initial state + private Subject subject; + private CallbackHandler callbackHandler; + private Map sharedState; + private Map options; + private UnixPrincipal userPrincipal; + + // username and password + private String username; + private String password; + + // the authentication status + private boolean succeeded = false; + private boolean commitSucceeded = false; + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + + this.subject = subject; + this.callbackHandler = callbackHandler; + this.sharedState = sharedState; + this.options = options; + System.out.println("Login module initialized."); + } + + /* + * Authenticate the user by prompting for a username and password. + */ + @Override + public boolean login() throws LoginException { + LCTest.logAction("login"); + if (callbackHandler == null) { + throw new LoginException("No CallbackHandler available"); + } + + Callback[] callbacks = new Callback[2]; + callbacks[0] = new NameCallback("Username: "); + callbacks[1] = new PasswordCallback("Password: ", false); + + try { + callbackHandler.handle(callbacks); + username = ((NameCallback) callbacks[0]).getName(); + password = new String(((PasswordCallback) callbacks[1]) + .getPassword()); + if (username.equals(LCTest.USER_NAME) && + password.equals(LCTest.PASSWORD)) { + succeeded = true; + return true; + } + throw new FailedLoginException("Incorrect username/password!"); + } catch (IOException | UnsupportedCallbackException e) { + throw new LoginException("Login failed: " + e.getMessage()); + } + } + + @Override + public boolean commit() throws LoginException { + LCTest.logAction("commit"); + if (succeeded == false) { + return false; + } + userPrincipal = new UnixPrincipal(username); + final Subject s = subject; + final UnixPrincipal up = userPrincipal; + java.security.AccessController.doPrivileged + ((java.security.PrivilegedAction) () -> { + if (!s.getPrincipals().contains(up)) { + s.getPrincipals().add(up); + } + return null; + }); + password = null; + commitSucceeded = true; + return true; + } + + @Override + public boolean abort() throws LoginException { + LCTest.logAction("abort"); + if (succeeded == false) { + return false; + } + clearState(); + return true; + } + + @Override + public boolean logout() throws LoginException { + LCTest.logAction("logout"); + clearState(); + return true; + } + + private void clearState() { + if (commitSucceeded) { + final Subject s = subject; + final UnixPrincipal up = userPrincipal; + java.security.AccessController.doPrivileged + ((java.security.PrivilegedAction) () -> { + s.getPrincipals().remove(up); + return null; + }); + } + username = null; + password = null; + userPrincipal = null; + } + } + +} diff --git a/jdk/test/jdk/internal/jimage/JImageTest.java b/jdk/test/jdk/internal/jimage/JImageTest.java index 51c0bfdbf57..2e7ec735c94 100644 --- a/jdk/test/jdk/internal/jimage/JImageTest.java +++ b/jdk/test/jdk/internal/jimage/JImageTest.java @@ -66,9 +66,10 @@ public class JImageTest { String bootimage = bootimagePath.toAbsolutePath().toString(); String extractDir = Paths.get(".", "extract").toAbsolutePath().toString(); String recreateImage = Paths.get(".", "recreate.jimage").toAbsolutePath().toString(); - + String relativeRecreateImage = Paths.get(".", "recreate2.jimage").toString(); jimage("extract", "--dir", extractDir, bootimage); jimage("recreate", "--dir", extractDir, recreateImage); + jimage("recreate", "--dir", extractDir, relativeRecreateImage); System.out.println("Test successful"); } else { diff --git a/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java b/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java index 3d720b3507c..1f82399434a 100644 --- a/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java +++ b/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -315,4 +315,33 @@ public class Helper { } return null; } + + /** + * Routine used to obtain a randomly generated method type. + * + * @param arity Arity of returned method type. + * @return MethodType generated randomly. + */ + public static MethodType randomMethodTypeGenerator(int arity) { + final Class[] CLASSES = { + Object.class, + int.class, + boolean.class, + byte.class, + short.class, + char.class, + long.class, + float.class, + double.class + }; + if (arity > MAX_ARITY) { + throw new IllegalArgumentException( + String.format("Arity should not exceed %d!", MAX_ARITY)); + } + List> list = randomClasses(CLASSES, arity); + list = getParams(list, false, arity); + int i = RNG.nextInt(CLASSES.length + 1); + Class rtype = i == CLASSES.length ? void.class : CLASSES[i]; + return MethodType.methodType(rtype, list); + } } diff --git a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java index 4d7a81c152b..7111598d316 100644 --- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java +++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java @@ -42,6 +42,7 @@ import jdk.testlibrary.Utils; import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.ProcessTools; import jdk.test.lib.apps.LingeredApp; +import jdk.testlibrary.Platform; public class BasicLauncherTest { @@ -131,10 +132,16 @@ public class BasicLauncherTest { public static void main(String[] args) throws IOException { + if (!Platform.shouldSAAttach()) { + // Silently skip the test if we don't have enough permissions to attach + System.err.println("Error! Insufficient permissions to attach."); + return; + } + launchCLHSDB(); launch("No deadlocks found", "jstack"); - launch("Server compiler detected", "jmap"); + launch("compiler detected", "jmap"); launch("Java System Properties", "jinfo"); // The test throws RuntimeException on error. diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION index d6f6f158d1d..4bb2351d627 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION +++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2015e +tzdata2015f diff --git a/jdk/test/sun/util/calendar/zi/tzdata/africa b/jdk/test/sun/util/calendar/zi/tzdata/africa index 049861192cc..00150c68ef0 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/africa +++ b/jdk/test/sun/util/calendar/zi/tzdata/africa @@ -561,7 +561,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 # From Alex Krivenyshev (2008-07-11): # Seems that English language article "The revival of daylight saving -# time: Energy conservation?"-# No. 16578 (07/11/2008) was originally +# time: Energy conservation?"- No. 16578 (07/11/2008) was originally # published on Monday, June 30, 2008... # # I guess that article in French "Le gouvernement avance l'introduction @@ -693,7 +693,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # Here is a link to official document from Royaume du Maroc Premier Ministre, # Ministère de la Modernisation des Secteurs Publics # -# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967) +# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 June 1967) # concerning the amendment of the legal time, the Ministry of Modernization of # Public Sectors announced that the official time in the Kingdom will be # advanced 60 minutes from Sunday 31 May 2009 at midnight. diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia index fa4f2461cbb..8a1f75fe7c0 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/asia +++ b/jdk/test/sun/util/calendar/zi/tzdata/asia @@ -29,7 +29,7 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2014-10-31): +# From Paul Eggert (2015-08-08): # # Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), @@ -66,7 +66,7 @@ # 2:00 EET EEST Eastern European Time # 2:00 IST IDT Israel # 3:00 AST ADT Arabia* -# 3:30 IRST IRDT Iran +# 3:30 IRST IRDT Iran* # 4:00 GST Gulf* # 5:30 IST India # 7:00 ICT Indochina, most times and locations* @@ -75,10 +75,11 @@ # 8:00 CST China # 8:00 IDT Indochina, 1943-45, 1947-55, 1960-75 (some locations)* # 8:00 JWST Western Standard Time (Japan, 1896/1937)* +# 8:30 KST KDT Korea when at +0830* # 9:00 JCST Central Standard Time (Japan, 1896/1937) # 9:00 WIT east Indonesia (Waktu Indonesia Timur) # 9:00 JST JDT Japan -# 9:00 KST KDT Korea +# 9:00 KST KDT Korea when at +09 # 9:30 ACST Australian Central Standard Time # # See the 'europe' file for Russia and Turkey in Asia. @@ -1050,7 +1051,7 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov # # From Roozbeh Pournader (2007-11-05): # This is quoted from Official Gazette of the Islamic Republic of -# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24 +# Iran, Volume 63, No. 18242, dated Tuesday 1386/6/24 # [2007-10-16]. I am doing the best translation I can:... # The official time of the country will be moved forward for one hour # on the 24 hours of the first day of the month of Farvardin and will @@ -1580,7 +1581,7 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00. # - Oral switched from +5:00 to +4:00 in spring 1989. -# From Kazakhstan Embassy's News Bulletin #11 +# From Kazakhstan Embassy's News Bulletin No. 11 # (2005-03-21): # The Government of Kazakhstan passed a resolution March 15 abolishing # daylight saving time citing lack of economic benefits and health @@ -1734,6 +1735,17 @@ Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S # # For Pyongyang we have no information; guess no changes since World War II. +# From Steffen Thorsen (2015-08-07): +# According to many news sources, North Korea is going to change to +# the 8:30 time zone on August 15, one example: +# http://www.bbc.com/news/world-asia-33815049 +# +# From Paul Eggert (2015-08-07): +# No transition time is specified; assume 00:00. +# There is no common English-language abbreviation for this time zone. +# Use %z rather than invent one. We can't assume %z works everywhere yet, +# so for now substitute its output manually. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1 8:30 - KST 1912 Jan 1 @@ -1746,7 +1758,8 @@ Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1 8:30 - KST 1912 Jan 1 9:00 - JCST 1937 Oct 1 9:00 - JST 1945 Aug 24 - 9:00 - KST + 9:00 - KST 2015 Aug 15 + 8:30 - KST ############################################################################### diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe index 7cee9a81527..b3a9854fc4f 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/europe +++ b/jdk/test/sun/util/calendar/zi/tzdata/europe @@ -216,11 +216,14 @@ # republished in Finest Hour (Spring 2002) 1(114):26 # http://www.winstonchurchill.org/images/finesthour/Vol.01%20No.114.pdf -# From Paul Eggert (1996-09-03): +# From Paul Eggert (2015-08-08): # The OED Supplement says that the English originally said "Daylight Saving" # when they were debating the adoption of DST in 1908; but by 1916 this # term appears only in quotes taken from DST's opponents, whereas the # proponents (who eventually won the argument) are quoted as using "Summer". +# The term "Summer Time" was introduced by Herbert Samuel, Home Secretary; see: +# Viscount Samuel. Leisure in a Democracy. Cambridge University Press +# ISBN 978-1-107-49471-8 (1949, reissued 2015), p 8. # From Arthur David Olson (1989-01-19): # A source at the British Information Office in New York avers that it's @@ -366,7 +369,7 @@ # From an anonymous contributor (1996-06-02): # The law governing time in Ireland is under Statutory Instrument SI 395/94, -# which gives force to European Union 7th Council Directive # 94/21/EC. +# which gives force to European Union 7th Council Directive No. 94/21/EC. # Under this directive, the Minister for Justice in Ireland makes appropriate # regulations. I spoke this morning with the Secretary of the Department of # Justice (tel +353 1 678 9711) who confirmed to me that the correct name is @@ -615,11 +618,11 @@ Rule Russia 1921 only - Feb 14 23:00 1:00 MSD Rule Russia 1921 only - Mar 20 23:00 2:00 MSM # Midsummer Rule Russia 1921 only - Sep 1 0:00 1:00 MSD Rule Russia 1921 only - Oct 1 0:00 0 - -# Act No.925 of the Council of Ministers of the USSR (1980-10-24): +# Act No. 925 of the Council of Ministers of the USSR (1980-10-24): Rule Russia 1981 1984 - Apr 1 0:00 1:00 S Rule Russia 1981 1983 - Oct 1 0:00 0 - -# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in -# Act No.227 of the Council of Ministers of the USSR (1989-03-14): +# Act No. 967 of the Council of Ministers of the USSR (1984-09-13), repeated in +# Act No. 227 of the Council of Ministers of the USSR (1989-03-14): Rule Russia 1984 1991 - Sep lastSun 2:00s 0 - Rule Russia 1985 1991 - Mar lastSun 2:00s 1:00 S # @@ -851,7 +854,7 @@ Zone Europe/Brussels 0:17:30 - LMT 1880 # Bulgaria # # From Plamen Simenov via Steffen Thorsen (1999-09-09): -# A document of Government of Bulgaria (No.94/1997) says: +# A document of Government of Bulgaria (No. 94/1997) says: # EET -> EETDST is in 03:00 Local time in last Sunday of March ... # EETDST -> EET is in 04:00 Local time in last Sunday of October # @@ -868,7 +871,7 @@ Zone Europe/Sofia 1:33:16 - LMT 1880 1:00 C-Eur CE%sT 1945 1:00 - CET 1945 Apr 2 3:00 2:00 - EET 1979 Mar 31 23:00 - 2:00 Bulg EE%sT 1982 Sep 26 2:00 + 2:00 Bulg EE%sT 1982 Sep 26 3:00 2:00 C-Eur EE%sT 1991 2:00 E-Eur EE%sT 1997 2:00 EU EE%sT @@ -1085,8 +1088,8 @@ Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base # after that. # From Mart Oruaas (2000-01-29): -# Regulation no. 301 (1999-10-12) obsoletes previous regulation -# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all +# Regulation No. 301 (1999-10-12) obsoletes previous regulation +# No. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all # the year round. The regulation is effective 1999-11-01. # From Toomas Soome (2002-02-21): @@ -1107,7 +1110,7 @@ Zone Europe/Tallinn 1:39:00 - LMT 1880 3:00 Russia MSK/MSD 1989 Mar 26 2:00s 2:00 1:00 EEST 1989 Sep 24 2:00s 2:00 C-Eur EE%sT 1998 Sep 22 - 2:00 EU EE%sT 1999 Nov 1 + 2:00 EU EE%sT 1999 Oct 31 4:00 2:00 - EET 2002 Feb 21 2:00 EU EE%sT @@ -1550,21 +1553,21 @@ Link Europe/Rome Europe/San_Marino # correct data in juridical acts and I found some juridical documents about # changes in the counting of time in Latvia from 1981.... # -# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ... -# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24 +# Act No. 35 of the Council of Ministers of Latvian SSR of 1981-01-22 ... +# according to the Act No. 925 of the Council of Ministers of USSR of 1980-10-24 # ...: all year round the time of 2nd time zone + 1 hour, in addition turning # the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00) # and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00). # -# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ... -# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13 +# Act No. 592 of the Council of Ministers of Latvian SSR of 1984-09-24 ... +# according to the Act No. 967 of the Council of Ministers of USSR of 1984-09-13 # ...: all year round the time of 2nd time zone + 1 hour, in addition turning # the hands of the clock 1 hour forward on the last Sunday of March at 02:00 # (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of # September at 03:00 (GMT 23:00 on the previous day). # -# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ... -# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14 +# Act No. 81 of the Council of Ministers of Latvian SSR of 1989-03-22 ... +# according to the Act No. 227 of the Council of Ministers of USSR of 1989-03-14 # ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR, # Estonian SSR and Kaliningrad region of Russian Federation all year round the # time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia @@ -1581,7 +1584,7 @@ Link Europe/Rome Europe/San_Marino # From Andrei Ivanov (2000-03-06): # This year Latvia will not switch to Daylight Savings Time (as specified in # The Regulations of the Cabinet of Ministers of the Rep. of Latvia of -# 29-Feb-2000 (#79) , +# 29-Feb-2000 (No. 79) , # in Latvian for subscribers only). # From RFE/RL Newsline @@ -1786,6 +1789,18 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta # News from Moldova (in russian): # http://ru.publika.md/link_317061.html +# From Roman Tudos (2015-07-02): +# http://lex.justice.md/index.php?action=view&view=doc&lang=1&id=355077 +# From Paul Eggert (2015-07-01): +# The abovementioned official link to IGO1445-868/2014 states that +# 2014-10-26's fallback transition occurred at 03:00 local time. Also, +# http://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara +# says the 2014-03-30 spring-forward transition was at 02:00 local time. +# Guess that since 1997 Moldova has switched one hour before the EU. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Moldova 1997 max - Mar lastSun 2:00 1:00 S +Rule Moldova 1997 max - Oct lastSun 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Chisinau 1:55:20 - LMT 1880 @@ -1800,7 +1815,7 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880 2:00 Russia EE%sT 1992 2:00 E-Eur EE%sT 1997 # See Romania commentary for the guessed 1997 transition to EU rules. - 2:00 EU EE%sT + 2:00 Moldova EE%sT # Monaco # Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's @@ -2146,7 +2161,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # Russia # From Alexander Krivenyshev (2011-09-15): -# Based on last Russian Government Decree # 725 on August 31, 2011 +# Based on last Russian Government Decree No. 725 on August 31, 2011 # (Government document # http://www.government.ru/gov/results/16355/print/ # in Russian) @@ -2156,7 +2171,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # http://www.worldtimezone.com/dst_news/dst_news_russia36.htm # From Sanjeev Gupta (2011-09-27): -# Scans of [Decree #23 of January 8, 1992] are available at: +# Scans of [Decree No. 23 of January 8, 1992] are available at: # http://government.consultant.ru/page.aspx?1223966 # They are in Cyrillic letters (presumably Russian). @@ -2167,19 +2182,19 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # One source is # http://government.ru/gov/results/16355/ # which, according to translate.google.com, begins "Decree of August 31, -# 2011 No 725" and contains no other dates or "effective date" information. +# 2011 No. 725" and contains no other dates or "effective date" information. # # Another source is # http://www.rg.ru/2011/09/06/chas-zona-dok.html # which, according to translate.google.com, begins "Resolution of the # Government of the Russian Federation on August 31, 2011 N 725" and also # contains "Date first official publication: September 6, 2011 Posted on: -# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which +# in the 'RG' - Federal Issue No. 5573 September 6, 2011" but which # does not contain any "effective date" information. # # Another source is # http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7 -# which, in note 8, contains "Resolution #725 of August 31, 2011... +# which, in note 8, contains "Resolution No. 725 of August 31, 2011... # Effective as of after 7 days following the day of the official publication" # but which does not contain any reference to September 6, 2011. # @@ -2387,7 +2402,7 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880 # changed in May. 2:00 E-Eur EE%sT 1994 May # From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev. - 3:00 E-Eur MSK/MSD 1996 Mar 31 3:00s + 3:00 E-Eur MSK/MSD 1996 Mar 31 0:00s 3:00 1:00 MSD 1996 Oct 27 3:00s # IATA SSIM (1997-09) says Crimea switched to EET/EEST. # Assume it happened in March by not changing the clocks. @@ -2522,7 +2537,7 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 # from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700 # to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600 # -# This is according to Government of Russia decree # 740, on September +# This is according to Government of Russia decree No. 740, on September # 14, 2009 "Application in the territory of the Kemerovo region the Fifth # time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600) # @@ -2945,7 +2960,7 @@ Zone Africa/Ceuta -0:21:16 - LMT 1901 Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. -1:00 - CANT 1946 Sep 30 1:00 # Canaries T 0:00 - WET 1980 Apr 6 0:00s - 0:00 1:00 WEST 1980 Sep 28 0:00s + 0:00 1:00 WEST 1980 Sep 28 1:00u 0:00 EU WE%sT # IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u. # Ignore this for now, as the Canaries are part of the EU. @@ -3235,7 +3250,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # From Igor Karpov, who works for the Ukrainian Ministry of Justice, # via Garrett Wollman (2003-01-27): # BTW, I've found the official document on this matter. It's government -# regulations number 509, May 13, 1996. In my poor translation it says: +# regulations No. 509, May 13, 1996. In my poor translation it says: # "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday # of March at 3am the time is changing to 4am and each last Sunday of # October the time at 4am is changing to 3am" @@ -3244,7 +3259,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # On September 20, 2011 the deputies of the Verkhovna Rada agreed to # abolish the transfer clock to winter time. # -# Bill number 8330 of MP from the Party of Regions Oleg Nadoshi got +# Bill No. 8330 of MP from the Party of Regions Oleg Nadoshi got # approval from 266 deputies. # # Ukraine abolishes transfer back to the winter time (in Russian) diff --git a/jdk/test/sun/util/calendar/zi/tzdata/leapseconds b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds index 9b0a2278433..de698eaa562 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/leapseconds +++ b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds @@ -79,5 +79,5 @@ Leap 2008 Dec 31 23:59:60 + S Leap 2012 Jun 30 23:59:60 + S Leap 2015 Jun 30 23:59:60 + S -# Updated through IERS Bulletin C49 -# File expires on: 28 December 2015 +# Updated through IERS Bulletin C50 +# File expires on: 28 June 2016 diff --git a/jdk/test/sun/util/calendar/zi/tzdata/northamerica b/jdk/test/sun/util/calendar/zi/tzdata/northamerica index 09b1b7fad9f..f8197462426 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica +++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica @@ -1258,10 +1258,19 @@ Zone America/Goose_Bay -4:01:40 - LMT 1884 # Happy Valley-Goose Bay # west Labrador, Nova Scotia, Prince Edward I -# From Paul Eggert (2006-03-22): +# From Brian Inglis (2015-07-20): +# From the historical weather station records available at: +# https://weatherspark.com/history/28351/1971/Sydney-Nova-Scotia-Canada +# Sydney shares the same time history as Glace Bay, so was +# likely to be the same across the island.... +# Sydney, as the capital and most populous location, or Cape Breton, would +# have been better names for the zone had we known this in 1996. + +# From Paul Eggert (2015-07-20): # Shanks & Pottenger write that since 1970 most of this region has been like # Halifax. Many locales did not observe peacetime DST until 1972; -# Glace Bay, NS is the largest that we know of. +# the Cape Breton area, represented by Glace Bay, is the largest we know of +# (Glace Bay was perhaps not the best name choice but no point changing now). # Shanks & Pottenger also write that Liverpool, NS was the only town # in Canada to observe DST in 1971 but not 1970; for now we'll assume # this is a typo. @@ -1819,13 +1828,13 @@ Zone America/Edmonton -7:33:52 - LMT 1906 Sep # Exact date in October unknown; Sunday October 1 is a reasonable guess. # 3. June 1918: switch to Pacific Daylight Time (GMT-7) # Exact date in June unknown; Sunday June 2 is a reasonable guess. -# note#1: +# note 1: # On Oct 27/1918 when daylight saving ended in the rest of Canada, # Creston did not change its clocks. -# note#2: +# note 2: # During WWII when the Federal Government legislated a mandatory clock change, # Creston did not oblige. -# note#3: +# note 3: # There is no guarantee that Creston will remain on Mountain Standard Time # (UTC-7) forever. # The subject was debated at least once this year by the town Council. diff --git a/jdk/test/sun/util/calendar/zi/tzdata/southamerica b/jdk/test/sun/util/calendar/zi/tzdata/southamerica index 6cf0b2bff37..082018691d6 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica +++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica @@ -154,7 +154,7 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # Timezone Law (which never was effectively applied) will (would?) be # in effect.... The article is at # http://ar.clarin.com/diario/2001-06-06/e-01701.htm -# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted +# ... The Law itself is "Ley No. 25155", sanctioned on 1999-08-25, enacted # 1999-09-17, and published 1999-09-21. The official publication is at: # http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF # Regretfully, you have to subscribe (and pay) for the on-line version.... @@ -198,15 +198,11 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # http://www.worldtimezone.com/dst_news/dst_news_argentina03.html # http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish) -# From Rodrigo Severo (2008-10-06): -# Here is some info available at a Gentoo bug related to TZ on Argentina's DST: -# ... -# ------- Comment #1 from [jmdocile] 2008-10-06 16:28 0000 ------- -# Hi, there is a problem with timezone-data-2008e and maybe with -# timezone-data-2008f -# Argentinian law [Number] 25.155 is no longer valid. +# From Juan Manuel Docile in https://bugs.gentoo.org/240339 (2008-10-07) +# via Rodrigo Severo: +# Argentinian law No. 25.155 is no longer valid. # http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm -# The new one is law [Number] 26.350 +# The new one is law No. 26.350 # http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm # So there is no summer time in Argentina for now. @@ -794,7 +790,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # [ and in a second message (same day): ] # I found the decree. # -# DECRETO No- 7.584, DE 13 DE OUTUBRO DE 2011 +# DECRETO No. 7.584, DE 13 DE OUTUBRO DE 2011 # Link : # http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6 @@ -1148,7 +1144,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # Conflicts between [1] and [2] were resolved as follows: # # - [1] says the 1910 transition was Jan 1, [2] says Jan 10 and cites -# Boletín Nº 1, Aviso Nº 1 (1910). Go with [2]. +# Boletín No. 1, Aviso No. 1 (1910). Go with [2]. # # - [1] says SMT was -4:42:45, [2] says Chile's official time from # 1916 to 1919 was -4:42:46.3, the meridian of Chile's National @@ -1156,7 +1152,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # Quinta Normal in Santiago. Go with [2], rounding it to -4:42:46. # # - [1] says the 1918 transition was Sep 1, [2] says Sep 10 and cites -# Boletín Nº 22, Aviso Nº 129/1918 (1918-08-23). Go with [2]. +# Boletín No. 22, Aviso No. 129/1918 (1918-08-23). Go with [2]. # # - [1] does not give times for transitions; assume they occur # at midnight mainland time, the current common practice. However, @@ -1556,7 +1552,7 @@ Rule Para 1997 only - Feb lastSun 0:00 0 - # (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27). Rule Para 1998 2001 - Mar Sun>=1 0:00 0 - # From Rives McDow (2002-02-28): -# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the +# A decree was issued in Paraguay (No. 16350) on 2002-02-26 that changed the # dst method to be from the first Sunday in September to the first Sunday in # April. Rule Para 2002 2004 - Apr Sun>=1 0:00 0 - @@ -1736,8 +1732,19 @@ Rule Uruguay 2005 only - Oct 9 2:00 1:00 S Rule Uruguay 2006 only - Mar 12 2:00 0 - # From Jesper Nørgaard Welen (2006-09-06): # http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF -Rule Uruguay 2006 max - Oct Sun>=1 2:00 1:00 S -Rule Uruguay 2007 max - Mar Sun>=8 2:00 0 - +# +# From Steffen Thorsen (2015-06-30): +# ... it looks like they will not be using DST the coming summer: +# http://www.elobservador.com.uy/gobierno-resolvio-que-no-habra-cambio-horario-verano-n656787 +# http://www.republica.com.uy/este-ano-no-se-modificara-el-huso-horario-en-uruguay/523760/ +# From Paul Eggert (2015-06-30): +# Apparently restaurateurs complained that DST caused people to go to the beach +# instead of out to dinner. +# From Pablo Camargo (2015-07-13): +# http://archivo.presidencia.gub.uy/sci/decretos/2015/06/cons_min_201.pdf +# [dated 2015-06-29; repeals Decree 311/006 dated 2006-09-04] +Rule Uruguay 2006 2014 - Oct Sun>=1 2:00 1:00 S +Rule Uruguay 2007 2015 - Mar Sun>=8 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 -3:44:44 - MMT 1920 May 1 # Montevideo MT @@ -1746,6 +1753,10 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # Venezuela # +# From Paul Eggert (2015-07-28): +# For the 1965 transition see Gaceta Oficial No. 27.619 (1964-12-15), p 205.533 +# http://www.pgr.gob.ve/dmdocuments/1964/27619.pdf +# # From John Stainforth (2007-11-28): # ... the change for Venezuela originally expected for 2007-12-31 has # been brought forward to 2007-12-09. The official announcement was @@ -1757,6 +1768,6 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time? - -4:30 - VET 1965 # Venezuela Time + -4:30 - VET 1965 Jan 1 0:00 # Venezuela T. -4:00 - VET 2007 Dec 9 3:00 -4:30 - VET diff --git a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab index ffb6469676e..3fe4a3f2b57 100644 --- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab +++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab @@ -129,8 +129,8 @@ BW -2439+02555 Africa/Gaborone BY +5354+02734 Europe/Minsk BZ +1730-08812 America/Belize CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador -CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI -CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971 +CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (peninsula), PEI +CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia (Cape Breton) CA +4606-06447 America/Moncton Atlantic Time - New Brunswick CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore diff --git a/jdk/test/tools/pack200/CommandLineTests.java b/jdk/test/tools/pack200/CommandLineTests.java index d2904b70ea1..0eff5388e45 100644 --- a/jdk/test/tools/pack200/CommandLineTests.java +++ b/jdk/test/tools/pack200/CommandLineTests.java @@ -110,7 +110,6 @@ public class CommandLineTests { ps.println("pack.pass.file.2=java/lang/Object.class"); ps.println("pack.pass.file.3=java/lang/Throwable.class"); ps.println("pack.pass.file.4=java/lang/VerifyError.class"); - ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class"); } finally { Utils.close(ps); Utils.close(fos); diff --git a/make/Images.gmk b/make/Images.gmk index d3b60a22e6b..36b889e96a4 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -47,7 +47,7 @@ PROVIDER_MODULES += jdk.charsets jdk.crypto.ec jdk.crypto.pkcs11 jdk.jvmstat jdk # tools TOOLS_MODULES += jdk.attach jdk.compiler jdk.dev jdk.internal.le jdk.scripting.nashorn.shell \ - jdk.javadoc jdk.jcmd jdk.jconsole jdk.hotspot.agent jdk.hprof.agent jdk.jartool \ + jdk.javadoc jdk.jcmd jdk.jconsole jdk.hotspot.agent jdk.jartool \ jdk.jdeps jdk.jdi jdk.jdwp.agent jdk.policytool jdk.rmic jdk.xml.bind jdk.xml.ws ifeq ($(OPENJDK_TARGET_OS), windows) diff --git a/modules.xml b/modules.xml index 0445602d877..9259443888a 100644 --- a/modules.xml +++ b/modules.xml @@ -1622,10 +1622,6 @@ java.scripting jdk.jdi - - jdk.hprof.agent - java.base - jdk.httpserver java.base @@ -1798,7 +1794,7 @@ jdk.scripting.nashorn java.base java.logging - java.scripting + java.scripting jdk.nashorn.internal.runtime jdk.scripting.nashorn.shell @@ -1811,11 +1807,16 @@ jdk.nashorn.tools jdk.scripting.nashorn.shell + + jdk.nashorn.api.scripting + + + jdk.nashorn.api.tree + jdk.scripting.nashorn.shell java.base - java.prefs jdk.scripting.nashorn jdk.internal.le diff --git a/nashorn/.hgtags b/nashorn/.hgtags index c929021d887..e83176cfb04 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -311,3 +311,4 @@ d017877b3b8cd39337f1bdc00d958f821433c4c3 jdk9-b72 f884dff432a7ac349153f3d1ea1eb222f3764c6c jdk9-b75 ab231613d7206431ba31917a02e7cedd70e88e70 jdk9-b76 33cecbc59f2ad78ac0934cbc3e014d346077e848 jdk9-b77 +6f634e84387e97b2421d5e776e46935784156d1c jdk9-b78 diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java index 932eb7ab055..3ecee8c7d11 100644 --- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java @@ -25,6 +25,7 @@ package jdk.nashorn.tools.jjs; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; @@ -33,71 +34,41 @@ import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.prefs.BackingStoreException; -import java.util.prefs.Preferences; import jdk.internal.jline.console.ConsoleReader; -import jdk.internal.jline.console.history.History.Entry; -import jdk.internal.jline.console.history.MemoryHistory; +import jdk.internal.jline.console.completer.Completer; +import jdk.internal.jline.console.history.FileHistory; class Console implements AutoCloseable { private final ConsoleReader in; - private final PersistentHistory history; + private final FileHistory history; - Console(InputStream cmdin, PrintStream cmdout, Preferences prefs) throws IOException { + Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile, + final Completer completer) throws IOException { in = new ConsoleReader(cmdin, cmdout); in.setExpandEvents(false); in.setHandleUserInterrupt(true); - in.setHistory(history = new PersistentHistory(prefs)); - Runtime.getRuntime().addShutdownHook(new Thread(()->close())); + in.setBellEnabled(true); + in.setHistory(history = new FileHistory(historyFile)); + in.addCompleter(completer); + Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory)); } - String readLine(String prompt) throws IOException { + String readLine(final String prompt) throws IOException { return in.readLine(prompt); } - @Override public void close() { - history.save(); + saveHistory(); } - public static class PersistentHistory extends MemoryHistory { - - private final Preferences prefs; - - protected PersistentHistory(Preferences prefs) { - this.prefs = prefs; - load(); - } - - private static final String HISTORY_LINE_PREFIX = "HISTORY_LINE_"; - - public final void load() { - try { - List keys = new ArrayList<>(Arrays.asList(prefs.keys())); - Collections.sort(keys); - for (String key : keys) { - if (!key.startsWith(HISTORY_LINE_PREFIX)) - continue; - CharSequence line = prefs.get(key, ""); - add(line); - } - } catch (BackingStoreException ex) { - throw new IllegalStateException(ex); - } - } - - public void save() { - Iterator entries = iterator(); - if (entries.hasNext()) { - int len = (int) Math.ceil(Math.log10(size()+1)); - String format = HISTORY_LINE_PREFIX + "%0" + len + "d"; - while (entries.hasNext()) { - Entry entry = entries.next(); - prefs.put(String.format(format, entry.index()), entry.value().toString()); - } - } - } + private void saveHistory() { + try { + getHistory().flush(); + } catch (final IOException exp) {} + } + FileHistory getHistory() { + return (FileHistory) in.getHistory(); } } diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java new file mode 100644 index 00000000000..590108ff015 --- /dev/null +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools.jjs; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; +import jdk.internal.jline.console.history.FileHistory; +import jdk.internal.jline.console.history.History; +import jdk.nashorn.api.scripting.AbstractJSObject; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.internal.runtime.JSType; +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; + +/* + * A script friendly object that exposes history of commands to scripts. + */ +final class HistoryObject extends AbstractJSObject { + private static final Set props; + static { + final HashSet s = new HashSet<>(); + s.add("clear"); + s.add("forEach"); + s.add("print"); + s.add("size"); + props = Collections.unmodifiableSet(s); + } + + private final FileHistory hist; + + HistoryObject(final FileHistory hist) { + this.hist = hist; + } + + @Override + public Object getMember(final String name) { + switch (name) { + case "clear": + return (Runnable)hist::clear; + case "forEach": + return (Function)this::iterate; + case "print": + return (Runnable)this::print; + case "size": + return hist.size(); + } + return UNDEFINED; + } + + @Override + public Object getDefaultValue(final Class hint) { + if (hint == String.class) { + return toString(); + } + return UNDEFINED; + } + + @Override + public String toString() { + return "[object history]"; + } + + @Override + public Set keySet() { + return props; + } + + private void print() { + for (History.Entry e : hist) { + System.out.println(e.value()); + } + } + + private Object iterate(final JSObject func) { + for (History.Entry e : hist) { + if (JSType.toBoolean(func.call(this, e.value().toString()))) { + break; // return true from callback to skip iteration + } + } + return UNDEFINED; + } +} diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java index 9bc4b56638e..e0edd4dad5d 100644 --- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java @@ -26,20 +26,21 @@ package jdk.nashorn.tools.jjs; import java.io.BufferedReader; +import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.util.prefs.Preferences; +import jdk.internal.jline.console.completer.Completer; +import jdk.internal.jline.console.UserInterruptException; +import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.tools.Shell; -import jdk.internal.jline.console.UserInterruptException; /** * Interactive command line Shell for Nashorn. @@ -47,7 +48,8 @@ import jdk.internal.jline.console.UserInterruptException; public final class Main extends Shell { private Main() {} - static final Preferences PREFS = Preferences.userRoot().node("tool/jjs"); + // file where history is persisted. + private static final File HIST_FILE = new File(new File(System.getProperty("user.home")), ".jjs.history"); /** * Main entry point with the default input, output and error streams. @@ -83,6 +85,7 @@ public final class Main extends Shell { return new Main().run(in, out, err, args); } + /** * read-eval-print loop for Nashorn shell. * @@ -96,13 +99,16 @@ public final class Main extends Shell { final PrintWriter err = context.getErr(); final Global oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); + final Completer completer = new NashornCompleter(context, global, this); - try (final Console in = new Console(System.in, System.out, PREFS)) { + try (final Console in = new Console(System.in, System.out, HIST_FILE, completer)) { if (globalChanged) { Context.setGlobal(global); } global.addShellBuiltins(); + // expose history object for reflecting on command line history + global.put("history", new HistoryObject(in.getHistory()), false); while (true) { String source = ""; diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java new file mode 100644 index 00000000000..5a676da4d89 --- /dev/null +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools.jjs; + +import java.util.List; +import java.util.regex.Pattern; +import jdk.internal.jline.console.completer.Completer; +import jdk.nashorn.api.tree.AssignmentTree; +import jdk.nashorn.api.tree.BinaryTree; +import jdk.nashorn.api.tree.CompilationUnitTree; +import jdk.nashorn.api.tree.CompoundAssignmentTree; +import jdk.nashorn.api.tree.ConditionalExpressionTree; +import jdk.nashorn.api.tree.ExpressionTree; +import jdk.nashorn.api.tree.ExpressionStatementTree; +import jdk.nashorn.api.tree.FunctionCallTree; +import jdk.nashorn.api.tree.IdentifierTree; +import jdk.nashorn.api.tree.InstanceOfTree; +import jdk.nashorn.api.tree.MemberSelectTree; +import jdk.nashorn.api.tree.NewTree; +import jdk.nashorn.api.tree.SimpleTreeVisitorES5_1; +import jdk.nashorn.api.tree.Tree; +import jdk.nashorn.api.tree.UnaryTree; +import jdk.nashorn.api.tree.Parser; +import jdk.nashorn.api.scripting.NashornException; +import jdk.nashorn.tools.PartialParser; +import jdk.nashorn.internal.objects.Global; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ScriptRuntime; + +// A simple source completer for nashorn +final class NashornCompleter implements Completer { + private final Context context; + private final Global global; + private final PartialParser partialParser; + private final Parser parser; + + NashornCompleter(final Context context, final Global global, final PartialParser partialParser) { + this.context = context; + this.global = global; + this.partialParser = partialParser; + this.parser = Parser.create(); + } + + // Pattern to match a unfinished member selection expression. object part and "." + // but property name missing pattern. + private static final Pattern SELECT_PROP_MISSING = Pattern.compile(".*\\.\\s*"); + + @Override + public int complete(final String test, final int cursor, final List result) { + // check that cursor is at the end of test string. Do not complete in the middle! + if (cursor != test.length()) { + return cursor; + } + + // get the start of the last expression embedded in the given code + // using the partial parsing support - so that we can complete expressions + // inside statements, function call argument lists, array index etc. + final int exprStart = partialParser.getLastExpressionStart(context, test); + if (exprStart == -1) { + return cursor; + } + + + // extract the last expression string + final String exprStr = test.substring(exprStart); + + // do we have an incomplete member selection expression that misses property name? + final boolean endsWithDot = SELECT_PROP_MISSING.matcher(exprStr).matches(); + + // If this is an incomplete member selection, then it is not legal code. + // Make it legal by adding a random property name "x" to it. + final String completeExpr = endsWithDot? exprStr + "x" : exprStr; + + final ExpressionTree topExpr = getTopLevelExpression(parser, completeExpr); + if (topExpr == null) { + // did not parse to be a top level expression, no suggestions! + return cursor; + } + + + // Find 'right most' expression of the top level expression + final Tree rightMostExpr = getRightMostExpression(topExpr); + if (rightMostExpr instanceof MemberSelectTree) { + return completeMemberSelect(exprStr, cursor, result, (MemberSelectTree)rightMostExpr, endsWithDot); + } else if (rightMostExpr instanceof IdentifierTree) { + return completeIdentifier(exprStr, cursor, result, (IdentifierTree)rightMostExpr); + } else { + // expression that we cannot handle for completion + return cursor; + } + } + + private int completeMemberSelect(final String exprStr, final int cursor, final List result, + final MemberSelectTree select, final boolean endsWithDot) { + final ExpressionTree objExpr = select.getExpression(); + final String objExprCode = exprStr.substring((int)objExpr.getStartPosition(), (int)objExpr.getEndPosition()); + + // try to evaluate the object expression part as a script + Object obj = null; + try { + obj = context.eval(global, objExprCode, global, ""); + } catch (Exception ignored) { + // throw the exception - this is during tab-completion + } + + if (obj != null && obj != ScriptRuntime.UNDEFINED) { + if (endsWithDot) { + // no user specified "prefix". List all properties of the object + result.addAll(PropertiesHelper.getProperties(obj)); + return cursor; + } else { + // list of properties matching the user specified prefix + final String prefix = select.getIdentifier(); + result.addAll(PropertiesHelper.getProperties(obj, prefix)); + return cursor - prefix.length(); + } + } + + return cursor; + } + + private int completeIdentifier(final String test, final int cursor, final List result, + final IdentifierTree ident) { + final String name = ident.getName(); + result.addAll(PropertiesHelper.getProperties(global, name)); + return cursor - name.length(); + } + + // returns ExpressionTree if the given code parses to a top level expression. + // Or else returns null. + private ExpressionTree getTopLevelExpression(final Parser parser, final String code) { + try { + final CompilationUnitTree cut = parser.parse("", code, null); + final List stats = cut.getSourceElements(); + if (stats.size() == 1) { + final Tree stat = stats.get(0); + if (stat instanceof ExpressionStatementTree) { + return ((ExpressionStatementTree)stat).getExpression(); + } + } + } catch (final NashornException ignored) { + // ignore any parser error. This is for completion anyway! + // And user will get that error later when the expression is evaluated. + } + + return null; + } + + private Tree getRightMostExpression(final ExpressionTree expr) { + return expr.accept(new SimpleTreeVisitorES5_1() { + @Override + public Tree visitAssignment(final AssignmentTree at, final Void v) { + return getRightMostExpression(at.getExpression()); + } + + @Override + public Tree visitCompoundAssignment(final CompoundAssignmentTree cat, final Void v) { + return getRightMostExpression(cat.getExpression()); + } + + @Override + public Tree visitConditionalExpression(final ConditionalExpressionTree cet, final Void v) { + return getRightMostExpression(cet.getFalseExpression()); + } + + @Override + public Tree visitBinary(final BinaryTree bt, final Void v) { + return getRightMostExpression(bt.getRightOperand()); + } + + @Override + public Tree visitIdentifier(final IdentifierTree ident, final Void v) { + return ident; + } + + + @Override + public Tree visitInstanceOf(final InstanceOfTree it, final Void v) { + return it.getType(); + } + + + @Override + public Tree visitMemberSelect(final MemberSelectTree select, final Void v) { + return select; + } + + @Override + public Tree visitNew(final NewTree nt, final Void v) { + final ExpressionTree call = nt.getConstructorExpression(); + if (call instanceof FunctionCallTree) { + final ExpressionTree func = ((FunctionCallTree)call).getFunctionSelect(); + // Is this "new Foo" or "new obj.Foo" with no user arguments? + // If so, we may be able to do completion of constructor name. + if (func.getEndPosition() == nt.getEndPosition()) { + return func; + } + } + return null; + } + + @Override + public Tree visitUnary(final UnaryTree ut, final Void v) { + return getRightMostExpression(ut.getExpression()); + } + }, null); + } +} diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java new file mode 100644 index 00000000000..aada9223bf9 --- /dev/null +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools.jjs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.WeakHashMap; +import java.util.stream.Collectors; +import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.objects.NativeJava; + +/* + * A helper class to get properties of a given object for source code completion. + */ +final class PropertiesHelper { + private PropertiesHelper() {} + + // cached properties list + private static final WeakHashMap> propsCache = new WeakHashMap<>(); + + // returns the list of properties of the given object + static List getProperties(final Object obj) { + assert obj != null && obj != ScriptRuntime.UNDEFINED; + + if (JSType.isPrimitive(obj)) { + return getProperties(JSType.toScriptObject(obj)); + } + + if (obj instanceof ScriptObject) { + final ScriptObject sobj = (ScriptObject)obj; + final PropertyMap pmap = sobj.getMap(); + if (propsCache.containsKey(pmap)) { + return propsCache.get(pmap); + } + final String[] keys = sobj.getAllKeys(); + List props = Arrays.asList(keys); + props = props.stream() + .filter(s -> Character.isJavaIdentifierStart(s.charAt(0))) + .collect(Collectors.toList()); + Collections.sort(props); + // cache properties against the PropertyMap + propsCache.put(pmap, props); + return props; + } + + if (NativeJava.isType(ScriptRuntime.UNDEFINED, obj)) { + if (propsCache.containsKey(obj)) { + return propsCache.get(obj); + } + final List props = NativeJava.getProperties(obj); + Collections.sort(props); + // cache properties against the StaticClass representing the class + propsCache.put(obj, props); + return props; + } + + final Class clazz = obj.getClass(); + if (propsCache.containsKey(clazz)) { + return propsCache.get(clazz); + } + + final List props = NativeJava.getProperties(obj); + Collections.sort(props); + // cache properties against the Class object + propsCache.put(clazz, props); + return props; + } + + // returns the list of properties of the given object that start with the given prefix + static List getProperties(final Object obj, final String prefix) { + assert prefix != null && !prefix.isEmpty(); + return getProperties(obj).stream() + .filter(s -> s.startsWith(prefix)) + .collect(Collectors.toList()); + } +} diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java index 86339d81fd0..dfaecb2411b 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java @@ -398,7 +398,7 @@ public final class OptimisticTypesPersistence { } else if(protocol.equals("jrt")) { return getJrtVersionDirName(); } else { - throw new AssertionError(); + throw new AssertionError("unknown protocol"); } } @@ -556,13 +556,15 @@ public final class OptimisticTypesPersistence { return Math.max(0, Integer.parseInt(str)); } + private static final String JRT_NASHORN_DIR = "/modules/jdk.scripting.nashorn"; + // version directory name if nashorn is loaded from jrt:/ URL private static String getJrtVersionDirName() throws Exception { final FileSystem fs = getJrtFileSystem(); // consider all .class resources under nashorn module to compute checksum - final Path nashorn = fs.getPath("/jdk.scripting.nashorn"); + final Path nashorn = fs.getPath(JRT_NASHORN_DIR); if (! Files.isDirectory(nashorn)) { - throw new FileNotFoundException("missing /jdk.scripting.nashorn dir in jrt fs"); + throw new FileNotFoundException("missing " + JRT_NASHORN_DIR + " dir in jrt fs"); } final MessageDigest digest = MessageDigest.getInstance("SHA-1"); Files.walk(nashorn).forEach(new Consumer() { diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java index 743f055cfab..9d08a9bd4ca 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java @@ -30,11 +30,14 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandles; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Deque; import java.util.List; import java.util.Map; import java.util.Queue; +import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; import jdk.nashorn.api.scripting.JSObject; @@ -443,6 +446,47 @@ public final class NativeJava { throw typeError("cant.convert.to.javascript.array", objArray.getClass().getName()); } + /** + * Return properties of the given object. Properties also include "method names". + * This is meant for source code completion in interactive shells or editors. + * + * @param object the object whose properties are returned. + * @return list of properties + */ + public static List getProperties(final Object object) { + if (object instanceof StaticClass) { + // static properties of the given class + final Class clazz = ((StaticClass)object).getRepresentedClass(); + final ArrayList props = new ArrayList<>(); + try { + Bootstrap.checkReflectionAccess(clazz, true); + // Usually writable properties are a subset as 'write-only' properties are rare + props.addAll(BeansLinker.getReadableStaticPropertyNames(clazz)); + props.addAll(BeansLinker.getStaticMethodNames(clazz)); + } catch (Exception ignored) {} + return props; + } else if (object instanceof JSObject) { + final JSObject jsObj = ((JSObject)object); + final ArrayList props = new ArrayList<>(); + props.addAll(jsObj.keySet()); + return props; + } else if (object != null && object != UNDEFINED) { + // instance properties of the given object + final Class clazz = object.getClass(); + final ArrayList props = new ArrayList<>(); + try { + Bootstrap.checkReflectionAccess(clazz, false); + // Usually writable properties are a subset as 'write-only' properties are rare + props.addAll(BeansLinker.getReadableInstancePropertyNames(clazz)); + props.addAll(BeansLinker.getInstanceMethodNames(clazz)); + } catch (Exception ignored) {} + return props; + } + + // don't know about that object + return Collections.emptyList(); + } + private static int[] copyArray(final byte[] in) { final int[] out = new int[in.length]; for(int i = 0; i < in.length; ++i) { diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java index bc7028683c2..4a84e4ea9bf 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java @@ -3237,6 +3237,7 @@ loop: } /** + * {@code * MultiplicativeExpression : * UnaryExpression * MultiplicativeExpression * UnaryExpression @@ -3323,11 +3324,15 @@ loop: * Expression , AssignmentExpression * * See 11.14 + * } * * Parse expression. * @return Expression node. */ - private Expression expression() { + protected Expression expression() { + // This method is protected so that subclass can get details + // at expression start point! + // TODO - Destructuring array. // Include commas in expression parsing. return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false); @@ -3398,7 +3403,10 @@ loop: return lhs; } - private Expression assignmentExpression(final boolean noIn) { + protected Expression assignmentExpression(final boolean noIn) { + // This method is protected so that subclass can get details + // at assignment expression start point! + // TODO - Handle decompose. // Exclude commas in expression parsing. return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn); diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java index 946604ffce2..69b84167f83 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java @@ -1339,6 +1339,21 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable { } } + /** + * return an array of all property keys - all inherited, non-enumerable included. + * This is meant for source code completion by interactive shells or editors. + * + * @return Array of keys, order of properties is undefined. + */ + public String[] getAllKeys() { + final Set keys = new HashSet<>(); + final Set nonEnumerable = new HashSet<>(); + for (ScriptObject self = this; self != null; self = self.getProto()) { + keys.addAll(Arrays.asList(self.getOwnKeys(true, nonEnumerable))); + } + return keys.toArray(new String[keys.size()]); + } + /** * return an array of own property keys associated with the object. * diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/PartialParser.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/PartialParser.java new file mode 100644 index 00000000000..db87140c2c9 --- /dev/null +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/PartialParser.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools; + +import jdk.nashorn.internal.runtime.Context; + +/** + * Partial parsing support for code completion of expressions. + */ +public interface PartialParser { + /** + * Parse potentially partial code and keep track of the start of last expression. + * + * @param context the nashorn context + * @param code code that is to be parsed + * @return the start index of the last expression parsed in the (incomplete) code. + */ + public int getLastExpressionStart(final Context context, final String code); +} diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java index ec0397a7b37..1629762a55f 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java @@ -43,6 +43,7 @@ import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.Compiler.CompilationPhases; import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.objects.Global; @@ -59,7 +60,7 @@ import jdk.nashorn.internal.runtime.options.Options; /** * Command line Shell for processing JavaScript files. */ -public class Shell { +public class Shell implements PartialParser { /** * Resource name for properties file @@ -396,6 +397,42 @@ public class Shell { return ScriptRuntime.apply(target, self); } + /** + * Parse potentially partial code and keep track of the start of last expression. + * This 'partial' parsing support is meant to be used for code-completion. + * + * @param context the nashorn context + * @param code code that is to be parsed + * @return the start index of the last expression parsed in the (incomplete) code. + */ + @Override + public final int getLastExpressionStart(final Context context, final String code) { + final int[] exprStart = { -1 }; + + final Parser p = new Parser(context.getEnv(), sourceFor("", code),new Context.ThrowErrorManager()) { + @Override + protected Expression expression() { + exprStart[0] = this.start; + return super.expression(); + } + + @Override + protected Expression assignmentExpression(final boolean noIn) { + exprStart[0] = this.start; + return super.expression(); + } + }; + + try { + p.parse(); + } catch (final Exception ignored) { + // throw any parser exception, but we are partial parsing anyway + } + + return exprStart[0]; + } + + /** * read-eval-print loop for Nashorn shell. * diff --git a/nashorn/test/script/nosecurity/JDK-8055034.js b/nashorn/test/script/currently-failing/JDK-8055034.js similarity index 100% rename from nashorn/test/script/nosecurity/JDK-8055034.js rename to nashorn/test/script/currently-failing/JDK-8055034.js diff --git a/nashorn/test/script/nosecurity/JDK-8055034.js.EXPECTED b/nashorn/test/script/currently-failing/JDK-8055034.js.EXPECTED similarity index 100% rename from nashorn/test/script/nosecurity/JDK-8055034.js.EXPECTED rename to nashorn/test/script/currently-failing/JDK-8055034.js.EXPECTED diff --git a/nashorn/test/script/nosecurity/JDK-8130127.js b/nashorn/test/script/currently-failing/JDK-8130127.js similarity index 100% rename from nashorn/test/script/nosecurity/JDK-8130127.js rename to nashorn/test/script/currently-failing/JDK-8130127.js diff --git a/nashorn/test/script/nosecurity/JDK-8130127.js.EXPECTED b/nashorn/test/script/currently-failing/JDK-8130127.js.EXPECTED similarity index 100% rename from nashorn/test/script/nosecurity/JDK-8130127.js.EXPECTED rename to nashorn/test/script/currently-failing/JDK-8130127.js.EXPECTED diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java index 46f57fd059a..4b8944099a9 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.runtime.test; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; @@ -38,7 +39,6 @@ import jdk.nashorn.api.scripting.NashornScriptEngineFactory; import org.testng.annotations.Test; /** - * @ignore Fails with jtreg, but passes with ant test run. Ignore for now. * @test * @bug 8039185 8039403 * @summary Test for persistent code cache and path handling @@ -113,7 +113,8 @@ public class CodeStoreAndPathTest { assertEquals(actualCodeCachePath, expectedCodeCachePath); // Check that code cache dir exists and it's not empty final File file = new File(actualCodeCachePath.toUri()); - assertFalse(!file.isDirectory(), "No code cache directory was created!"); + assertTrue(file.exists(), "No code cache directory was created!"); + assertTrue(file.isDirectory(), "Code cache location is not a directory!"); assertFalse(file.list().length == 0, "Code cache directory is empty!"); } @@ -174,7 +175,7 @@ public class CodeStoreAndPathTest { return codeCachePath.resolve(file); } } - throw new AssertionError("Code cache path not found"); + throw new AssertionError("Code cache path not found: " + codeCachePath.toString()); } private static void checkCompiledScripts(final DirectoryStream stream, final int numberOfScripts) throws IOException {