This commit is contained in:
Henry Jen 2019-04-16 20:47:11 -07:00
commit 930f116ae7
83 changed files with 1572 additions and 1569 deletions

View file

@ -1,4 +1,4 @@
# Name#
# Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
@ -66,7 +66,33 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
AC_SUBST(PRODUCT_SUFFIX) AC_SUBST(PRODUCT_SUFFIX)
AC_SUBST(JDK_RC_PLATFORM_NAME) AC_SUBST(JDK_RC_PLATFORM_NAME)
AC_SUBST(HOTSPOT_VM_DISTRO) AC_SUBST(HOTSPOT_VM_DISTRO)
# Set the MACOSX Bundle Name base
AC_ARG_WITH(macosx-bundle-name-base, [AS_HELP_STRING([--with-macosx-bundle-name-base],
[Set the MacOSX Bundle Name base. This is the base name for calculating MacOSX Bundle Names.
@<:@not specified@:>@])])
if test "x$with_macosx_bundle_name_base" = xyes; then
AC_MSG_ERROR([--with-macosx-bundle-name-base must have a value])
elif [ ! [[ $with_macosx_bundle_name_base =~ ^[[:print:]]*$ ]] ]; then
AC_MSG_ERROR([--with-macosx-bundle-name-base contains non-printing characters: $with_macosx_bundle_name_base])
elif test "x$with_macosx_bundle_name_base" != x; then
# Set MACOSX_BUNDLE_NAME_BASE to the configured value.
MACOSX_BUNDLE_NAME_BASE="$with_macosx_bundle_name_base"
fi
AC_SUBST(MACOSX_BUNDLE_NAME_BASE) AC_SUBST(MACOSX_BUNDLE_NAME_BASE)
# Set the MACOSX Bundle ID base
AC_ARG_WITH(macosx-bundle-id-base, [AS_HELP_STRING([--with-macosx-bundle-id-base],
[Set the MacOSX Bundle ID base. This is the base ID for calculating MacOSX Bundle IDs.
@<:@not specified@:>@])])
if test "x$with_macosx_bundle_id_base" = xyes; then
AC_MSG_ERROR([--with-macosx-bundle-id-base must have a value])
elif [ ! [[ $with_macosx_bundle_id_base =~ ^[[:print:]]*$ ]] ]; then
AC_MSG_ERROR([--with-macosx-bundle-id-base contains non-printing characters: $with_macosx_bundle_id_base])
elif test "x$with_macosx_bundle_id_base" != x; then
# Set MACOSX_BUNDLE_ID_BASE to the configured value.
MACOSX_BUNDLE_ID_BASE="$with_macosx_bundle_id_base"
fi
AC_SUBST(MACOSX_BUNDLE_ID_BASE) AC_SUBST(MACOSX_BUNDLE_ID_BASE)
# Set the JDK RC name # Set the JDK RC name

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -67,13 +67,24 @@ public class HelloClasslist {
.forEach(System.out::println); .forEach(System.out::println);
// Common concatenation patterns // Common concatenation patterns
String const_I = "string" + args.length; String SS = String.valueOf(args.length) + String.valueOf(args.length);
String const_S = "string" + String.valueOf(args.length); String CS = "string" + String.valueOf(args.length);
String S_const = String.valueOf(args.length) + "string"; String SC = String.valueOf(args.length) + "string";
String S_S = String.valueOf(args.length) + String.valueOf(args.length); String SCS = String.valueOf(args.length) + "string" + String.valueOf(args.length);
String const_J = "string" + System.currentTimeMillis(); String CSS = "string" + String.valueOf(args.length) + String.valueOf(args.length);
String I_const = args.length + "string"; String CSCS = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length);
String J_const = System.currentTimeMillis() + "string"; String SCSC = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string";
String CSCSC = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string";
String SCSCS = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length);
String CI = "string" + args.length;
String IC = args.length + "string";
String CIC = "string" + args.length + "string";
String CICI = "string" + args.length + "string" + args.length;
String CJ = "string" + System.currentTimeMillis();
String JC = System.currentTimeMillis() + "string";
String CJC = "string" + System.currentTimeMillis() + "string";
String CJCJ = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis();
String CJCJC = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis() + "string";
String newDate = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( String newDate = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(
LocalDateTime.now(ZoneId.of("GMT"))); LocalDateTime.now(ZoneId.of("GMT")));

View file

@ -39,7 +39,6 @@ JAVA_RC_FLAGS += -I$(TOPDIR)/src/java.base/windows/native/launcher/icons
# overwritten. # overwritten.
$(eval $(call SetupBuildLauncher, java, \ $(eval $(call SetupBuildLauncher, java, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \
LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR), \
EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \ EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \
VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \

View file

@ -73,8 +73,7 @@ JAVA_MANIFEST := $(TOPDIR)/src/java.base/windows/native/launcher/java.manifest
# compile time defines exceeding Visual Studio 2013 limitations. # compile time defines exceeding Visual Studio 2013 limitations.
# CFLAGS Additional CFLAGS # CFLAGS Additional CFLAGS
# CFLAGS_windows Additional CFLAGS_windows # CFLAGS_windows Additional CFLAGS_windows
# LDFLAGS_solaris Additional LDFLAGS_solaris # EXTRA_RC_FLAGS Additional EXTRA_RC_FLAGS
# RC_FLAGS Additional RC_FLAGS
# MACOSX_SIGNED On macosx, sign this binary # MACOSX_SIGNED On macosx, sign this binary
# OPTIMIZATION Override default optimization level (LOW) # OPTIMIZATION Override default optimization level (LOW)
# OUTPUT_DIR Override default output directory # OUTPUT_DIR Override default output directory
@ -139,7 +138,7 @@ define SetupBuildLauncherBody
NAME := $1, \ NAME := $1, \
EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \ EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \
OPTIMIZATION := $$($1_OPTIMIZATION), \ OPTIMIZATION := $$($1_OPTIMIZATION), \
CFLAGS := $$(CFLAGS_JDKEXE) $$($1_CFLAGS) \ CFLAGS := $$(CFLAGS_JDKEXE) \
$(LAUNCHER_CFLAGS) \ $(LAUNCHER_CFLAGS) \
$(VERSION_CFLAGS) \ $(VERSION_CFLAGS) \
-DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \ -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \

View file

@ -4355,12 +4355,9 @@ void MacroAssembler::load_mirror(Register mirror, Register method) {
// Emitter does not KILL cnt and base arguments, since they need to be copied to // Emitter does not KILL cnt and base arguments, since they need to be copied to
// work registers anyway. // work registers anyway.
// Actually, only r0, r1, and r5 are killed. // Actually, only r0, r1, and r5 are killed.
unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len) { unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg) {
// Src_addr is evenReg.
// Src_len is odd_Reg.
int block_start = offset(); int block_start = offset();
Register tmp_reg = src_len; // Holds target instr addr for EX.
Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_len = Z_R1; // Holds dst len for MVCLE.
Register dst_addr = Z_R0; // Holds dst addr for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE.
@ -4369,7 +4366,7 @@ unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer
BLOCK_COMMENT("Clear_Array {"); BLOCK_COMMENT("Clear_Array {");
// Check for zero len and convert to long. // Check for zero len and convert to long.
z_ltgfr(src_len, cnt_arg); // Remember casted value for doSTG case. z_ltgfr(odd_tmp_reg, cnt_arg);
z_bre(done); // Nothing to do if len == 0. z_bre(done); // Nothing to do if len == 0.
// Prefetch data to be cleared. // Prefetch data to be cleared.
@ -4378,16 +4375,17 @@ unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer
z_pfd(0x02, 256, Z_R0, base_pointer_arg); z_pfd(0x02, 256, Z_R0, base_pointer_arg);
} }
z_sllg(dst_len, src_len, 3); // #bytes to clear. z_sllg(dst_len, odd_tmp_reg, 3); // #bytes to clear.
z_cghi(src_len, 32); // Check for len <= 256 bytes (<=32 DW). z_cghi(odd_tmp_reg, 32); // Check for len <= 256 bytes (<=32 DW).
z_brnh(doXC); // If so, use executed XC to clear. z_brnh(doXC); // If so, use executed XC to clear.
// MVCLE: initialize long arrays (general case). // MVCLE: initialize long arrays (general case).
bind(doMVCLE); bind(doMVCLE);
z_lgr(dst_addr, base_pointer_arg); z_lgr(dst_addr, base_pointer_arg);
clear_reg(src_len, true, false); // Src len of MVCLE is zero. // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0.
// The even register of the register pair is not killed.
MacroAssembler::move_long_ext(dst_addr, src_addr, 0); clear_reg(odd_tmp_reg, true, false);
MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding()-1), 0);
z_bru(done); z_bru(done);
// XC: initialize short arrays. // XC: initialize short arrays.
@ -4400,8 +4398,8 @@ unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer
if (VM_Version::has_ExecuteExtensions()) { if (VM_Version::has_ExecuteExtensions()) {
z_exrl(dst_len, XC_template); // Execute XC with var. len. z_exrl(dst_len, XC_template); // Execute XC with var. len.
} else { } else {
z_larl(tmp_reg, XC_template); z_larl(odd_tmp_reg, XC_template);
z_ex(dst_len,0,Z_R0,tmp_reg); // Execute XC with var. len. z_ex(dst_len,0,Z_R0,odd_tmp_reg); // Execute XC with var. len.
} }
// z_bru(done); // fallthru // z_bru(done); // fallthru
@ -4463,7 +4461,7 @@ unsigned int MacroAssembler::Clear_Array_Const(long cnt, Register base) {
// Compiler ensures base is doubleword aligned and cnt is #doublewords. // Compiler ensures base is doubleword aligned and cnt is #doublewords.
// Emitter does not KILL cnt and base arguments, since they need to be copied to // Emitter does not KILL cnt and base arguments, since they need to be copied to
// work registers anyway. // work registers anyway.
// Actually, only r0, r1, r4, and r5 (which are work registers) are killed. // Actually, only r0, r1, (which are work registers) and odd_tmp_reg are killed.
// //
// For very large arrays, exploit MVCLE H/W support. // For very large arrays, exploit MVCLE H/W support.
// MVCLE instruction automatically exploits H/W-optimized page mover. // MVCLE instruction automatically exploits H/W-optimized page mover.
@ -4471,9 +4469,7 @@ unsigned int MacroAssembler::Clear_Array_Const(long cnt, Register base) {
// - All full pages are cleared with the page mover H/W assist. // - All full pages are cleared with the page mover H/W assist.
// - Remaining bytes are again cleared by a series of XC to self. // - Remaining bytes are again cleared by a series of XC to self.
// //
unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register src_addr, Register src_len) { unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg) {
// Src_addr is evenReg.
// Src_len is odd_Reg.
int block_start = offset(); int block_start = offset();
Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_len = Z_R1; // Holds dst len for MVCLE.
@ -4486,11 +4482,10 @@ unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_point
// Prepare other args to MVCLE. // Prepare other args to MVCLE.
z_lgr(dst_addr, base_pointer_arg); z_lgr(dst_addr, base_pointer_arg);
// Indicate unused result. // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0.
(void) clear_reg(src_len, true, false); // Src len of MVCLE is zero. // The even register of the register pair is not killed.
(void) clear_reg(odd_tmp_reg, true, false); // Src len of MVCLE is zero.
// Clear. MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding() - 1), 0);
MacroAssembler::move_long_ext(dst_addr, src_addr, 0);
BLOCK_COMMENT("} Clear_Array_Const_Big"); BLOCK_COMMENT("} Clear_Array_Const_Big");
int block_end = offset(); int block_end = offset();

View file

@ -828,9 +828,9 @@ class MacroAssembler: public Assembler {
//-------------------------- //--------------------------
//--- Operations on arrays. //--- Operations on arrays.
//-------------------------- //--------------------------
unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len); unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg);
unsigned int Clear_Array_Const(long cnt, Register base); unsigned int Clear_Array_Const(long cnt, Register base);
unsigned int Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register src_addr, Register src_len); unsigned int Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg);
unsigned int CopyRawMemory_AlignedDisjoint(Register src_reg, Register dst_reg, unsigned int CopyRawMemory_AlignedDisjoint(Register src_reg, Register dst_reg,
Register cnt_reg, Register cnt_reg,
Register tmp1_reg, Register tmp2_reg); Register tmp1_reg, Register tmp2_reg);

View file

@ -474,6 +474,19 @@ reg_class z_long_reg(
/*Z_R15_H,Z_R15*/ // SP /*Z_R15_H,Z_R15*/ // SP
); );
// z_long_reg without even registers
reg_class z_long_odd_reg(
/*Z_R0_H,Z_R0*/ // R0
/*Z_R1_H,Z_R1*/
Z_R3_H,Z_R3,
Z_R5_H,Z_R5,
Z_R7_H,Z_R7,
Z_R9_H,Z_R9,
Z_R11_H,Z_R11,
Z_R13_H,Z_R13
/*Z_R14_H,Z_R14,*/ // return_pc
/*Z_R15_H,Z_R15*/ // SP
);
// Special Class for Condition Code Flags Register // Special Class for Condition Code Flags Register
@ -3378,6 +3391,7 @@ operand iRegL() %{
match(RegL); match(RegL);
match(revenRegL); match(revenRegL);
match(roddRegL); match(roddRegL);
match(allRoddRegL);
match(rarg1RegL); match(rarg1RegL);
match(rarg5RegL); match(rarg5RegL);
format %{ %} format %{ %}
@ -3400,6 +3414,14 @@ operand roddRegL() %{
interface(REG_INTER); interface(REG_INTER);
%} %}
// available odd registers for iRegL
operand allRoddRegL() %{
constraint(ALLOC_IN_RC(z_long_odd_reg));
match(iRegL);
format %{ %}
interface(REG_INTER);
%}
operand rarg1RegL() %{ operand rarg1RegL() %{
constraint(ALLOC_IN_RC(z_rarg1_long_reg)); constraint(ALLOC_IN_RC(z_rarg1_long_reg));
match(iRegL); match(iRegL);
@ -9899,23 +9921,23 @@ instruct inlineCallClearArrayConst(SSlenDW cnt, iRegP_N2P base, Universe dummy,
ins_pipe(pipe_class_dummy); ins_pipe(pipe_class_dummy);
%} %}
instruct inlineCallClearArrayConstBig(immL cnt, iRegP_N2P base, Universe dummy, revenRegL srcA, roddRegL srcL, flagsReg cr) %{ instruct inlineCallClearArrayConstBig(immL cnt, iRegP_N2P base, Universe dummy, allRoddRegL tmpL, flagsReg cr) %{
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(TEMP srcA, TEMP srcL, KILL cr); // R0, R1 are killed, too. effect(TEMP tmpL, KILL cr); // R0, R1 are killed, too.
ins_cost(200); ins_cost(200);
// TODO: s390 port size(VARIABLE_SIZE); // Variable in size due to optimized constant loader. // TODO: s390 port size(VARIABLE_SIZE); // Variable in size due to optimized constant loader.
format %{ "ClearArrayConstBig $cnt,$base" %} format %{ "ClearArrayConstBig $cnt,$base" %}
ins_encode %{ __ Clear_Array_Const_Big($cnt$$constant, $base$$Register, $srcA$$Register, $srcL$$Register); %} ins_encode %{ __ Clear_Array_Const_Big($cnt$$constant, $base$$Register, $tmpL$$Register); %}
ins_pipe(pipe_class_dummy); ins_pipe(pipe_class_dummy);
%} %}
instruct inlineCallClearArray(iRegL cnt, iRegP_N2P base, Universe dummy, revenRegL srcA, roddRegL srcL, flagsReg cr) %{ instruct inlineCallClearArray(iRegL cnt, iRegP_N2P base, Universe dummy, allRoddRegL tmpL, flagsReg cr) %{
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(TEMP srcA, TEMP srcL, KILL cr); // R0, R1 are killed, too. effect(TEMP tmpL, KILL cr); // R0, R1 are killed, too.
ins_cost(300); ins_cost(300);
// TODO: s390 port size(FIXED_SIZE); // z/Architecture: emitted code depends on PreferLAoverADD being on/off. // TODO: s390 port size(FIXED_SIZE); // z/Architecture: emitted code depends on PreferLAoverADD being on/off.
format %{ "ClearArrayVar $cnt,$base" %} format %{ "ClearArrayVar $cnt,$base" %}
ins_encode %{ __ Clear_Array($cnt$$Register, $base$$Register, $srcA$$Register, $srcL$$Register); %} ins_encode %{ __ Clear_Array($cnt$$Register, $base$$Register, $tmpL$$Register); %}
ins_pipe(pipe_class_dummy); ins_pipe(pipe_class_dummy);
%} %}

View file

@ -2968,9 +2968,8 @@ class StubGenerator: public StubCodeGenerator {
__ enter(); __ enter();
__ subptr(rsp, 8 * wordSize); __ subptr(rsp, 8 * wordSize);
if (multi_block) { handleSOERegisters(true /*saving*/);
__ push(limit);
}
__ movptr(buf, buf_param); __ movptr(buf, buf_param);
__ movptr(state, state_param); __ movptr(state, state_param);
if (multi_block) { if (multi_block) {
@ -2981,9 +2980,7 @@ class StubGenerator: public StubCodeGenerator {
__ fast_sha1(abcd, e0, e1, msg0, msg1, msg2, msg3, shuf_mask, __ fast_sha1(abcd, e0, e1, msg0, msg1, msg2, msg3, shuf_mask,
buf, state, ofs, limit, rsp, multi_block); buf, state, ofs, limit, rsp, multi_block);
if (multi_block) { handleSOERegisters(false /*restoring*/);
__ pop(limit);
}
__ addptr(rsp, 8 * wordSize); __ addptr(rsp, 8 * wordSize);
__ leave(); __ leave();
__ ret(0); __ ret(0);

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
*
* 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_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
#include "memory/iterator.hpp"
class ShenandoahHeap;
class ShenandoahMarkingContext;
class Thread;
class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure {
private:
ShenandoahMarkingContext* const _mark_context;
public:
inline ShenandoahForwardedIsAliveClosure();
inline bool do_object_b(oop obj);
};
class ShenandoahIsAliveClosure: public BoolObjectClosure {
private:
ShenandoahMarkingContext* const _mark_context;
public:
inline ShenandoahIsAliveClosure();
inline bool do_object_b(oop obj);
};
class ShenandoahIsAliveSelector : public StackObj {
private:
ShenandoahIsAliveClosure _alive_cl;
ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
public:
inline BoolObjectClosure* is_alive_closure();
};
class ShenandoahUpdateRefsClosure: public OopClosure {
private:
ShenandoahHeap* _heap;
public:
inline ShenandoahUpdateRefsClosure();
inline void do_oop(oop* p);
inline void do_oop(narrowOop* p);
private:
template <class T>
inline void do_oop_work(T* p);
};
class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure {
private:
ShenandoahHeap* _heap;
Thread* _thread;
public:
inline ShenandoahEvacuateUpdateRootsClosure();
inline void do_oop(oop* p);
inline void do_oop(narrowOop* p);
private:
template <class T>
inline void do_oop_work(T* p);
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
*
* 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_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP
#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahClosures.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "oops/compressedOops.inline.hpp"
#include "runtime/thread.hpp"
ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
_mark_context(ShenandoahHeap::heap()->marking_context()) {
}
bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {
if (CompressedOops::is_null(obj)) {
return false;
}
obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
shenandoah_assert_not_forwarded_if(NULL, obj,
(ShenandoahHeap::heap()->is_concurrent_mark_in_progress() ||
ShenandoahHeap::heap()->is_concurrent_traversal_in_progress()));
return _mark_context->is_marked(obj);
}
ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :
_mark_context(ShenandoahHeap::heap()->marking_context()) {
}
bool ShenandoahIsAliveClosure::do_object_b(oop obj) {
if (CompressedOops::is_null(obj)) {
return false;
}
shenandoah_assert_not_forwarded(NULL, obj);
return _mark_context->is_marked(obj);
}
BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() {
return ShenandoahHeap::heap()->has_forwarded_objects() ?
reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) :
reinterpret_cast<BoolObjectClosure*>(&_alive_cl);
}
ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() :
_heap(ShenandoahHeap::heap()) {
}
template <class T>
void ShenandoahUpdateRefsClosure::do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
_heap->update_with_forwarded_not_null(p, obj);
}
}
void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :
_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
}
template <class T>
void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
T o = RawAccess<>::oop_load(p);
if (! CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
if (_heap->in_collection_set(obj)) {
shenandoah_assert_marked(p, obj);
oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
if (oopDesc::equals_raw(resolved, obj)) {
resolved = _heap->evacuate_object(obj, _thread);
}
RawAccess<IS_NOT_NULL>::oop_store(p, resolved);
}
}
}
void ShenandoahEvacuateUpdateRootsClosure::do_oop(oop* p) {
do_oop_work(p);
}
void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) {
do_oop_work(p);
}
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP

View file

@ -33,6 +33,7 @@
#include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/referenceProcessorPhaseTimes.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
#include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
#include "gc/shenandoah/shenandoahMarkCompact.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp"

View file

@ -33,6 +33,7 @@
#include "gc/shenandoah/shenandoahAllocTracker.hpp" #include "gc/shenandoah/shenandoahAllocTracker.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBrooksPointer.hpp" #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
#include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
@ -70,8 +71,6 @@
#include "runtime/vmThread.hpp" #include "runtime/vmThread.hpp"
#include "services/mallocTracker.hpp" #include "services/mallocTracker.hpp"
ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : _heap(ShenandoahHeap::heap()) {}
#ifdef ASSERT #ifdef ASSERT
template <class T> template <class T>
void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) { void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) {
@ -940,43 +939,6 @@ size_t ShenandoahHeap::min_dummy_object_size() const {
return CollectedHeap::min_dummy_object_size() + ShenandoahBrooksPointer::word_size(); return CollectedHeap::min_dummy_object_size() + ShenandoahBrooksPointer::word_size();
} }
class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure {
private:
ShenandoahHeap* _heap;
Thread* _thread;
public:
ShenandoahEvacuateUpdateRootsClosure() :
_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
}
private:
template <class T>
void do_oop_work(T* p) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
T o = RawAccess<>::oop_load(p);
if (! CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
if (_heap->in_collection_set(obj)) {
shenandoah_assert_marked(p, obj);
oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
if (oopDesc::equals_raw(resolved, obj)) {
resolved = _heap->evacuate_object(obj, _thread);
}
RawAccess<IS_NOT_NULL>::oop_store(p, resolved);
}
}
}
public:
void do_oop(oop* p) {
do_oop_work(p);
}
void do_oop(narrowOop* p) {
do_oop_work(p);
}
};
class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure { class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure {
private: private:
ShenandoahHeap* const _heap; ShenandoahHeap* const _heap;
@ -1884,31 +1846,6 @@ HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) {
return result; return result;
} }
ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
_mark_context(ShenandoahHeap::heap()->marking_context()) {
}
ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :
_mark_context(ShenandoahHeap::heap()->marking_context()) {
}
bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {
if (CompressedOops::is_null(obj)) {
return false;
}
obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
shenandoah_assert_not_forwarded_if(NULL, obj, ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || ShenandoahHeap::heap()->is_concurrent_traversal_in_progress());
return _mark_context->is_marked(obj);
}
bool ShenandoahIsAliveClosure::do_object_b(oop obj) {
if (CompressedOops::is_null(obj)) {
return false;
}
shenandoah_assert_not_forwarded(NULL, obj);
return _mark_context->is_marked(obj);
}
void ShenandoahHeap::ref_processing_init() { void ShenandoahHeap::ref_processing_init() {
assert(_max_workers > 0, "Sanity"); assert(_max_workers > 0, "Sanity");
@ -2879,8 +2816,3 @@ size_t ShenandoahHeap::obj_size(oop obj) const {
ptrdiff_t ShenandoahHeap::cell_header_size() const { ptrdiff_t ShenandoahHeap::cell_header_size() const {
return ShenandoahBrooksPointer::byte_size(); return ShenandoahBrooksPointer::byte_size();
} }
BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() {
return ShenandoahHeap::heap()->has_forwarded_objects() ? reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl)
: reinterpret_cast<BoolObjectClosure*>(&_alive_cl);
}

View file

@ -91,19 +91,6 @@ public:
virtual bool is_thread_safe() { return false; } virtual bool is_thread_safe() { return false; }
}; };
class ShenandoahUpdateRefsClosure: public OopClosure {
private:
ShenandoahHeap* _heap;
template <class T>
inline void do_oop_work(T* p);
public:
ShenandoahUpdateRefsClosure();
inline void do_oop(oop* p);
inline void do_oop(narrowOop* p);
};
#ifdef ASSERT #ifdef ASSERT
class ShenandoahAssertToSpaceClosure : public OopClosure { class ShenandoahAssertToSpaceClosure : public OopClosure {
private: private:
@ -115,29 +102,6 @@ public:
}; };
#endif #endif
class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure {
private:
ShenandoahMarkingContext* const _mark_context;
public:
ShenandoahForwardedIsAliveClosure();
bool do_object_b(oop obj);
};
class ShenandoahIsAliveClosure: public BoolObjectClosure {
private:
ShenandoahMarkingContext* const _mark_context;
public:
ShenandoahIsAliveClosure();
bool do_object_b(oop obj);
};
class ShenandoahIsAliveSelector : public StackObj {
private:
ShenandoahIsAliveClosure _alive_cl;
ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
public:
BoolObjectClosure* is_alive_closure();
};
// Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers // Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers
// to encode forwarding data. See BrooksPointer for details on forwarding data encoding. // to encode forwarding data. See BrooksPointer for details on forwarding data encoding.

View file

@ -46,17 +46,6 @@
#include "utilities/copy.hpp" #include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
template <class T>
void ShenandoahUpdateRefsClosure::do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
_heap->update_with_forwarded_not_null(p, obj);
}
}
void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
inline ShenandoahHeapRegion* ShenandoahRegionIterator::next() { inline ShenandoahHeapRegion* ShenandoahRegionIterator::next() {
size_t new_index = Atomic::add((size_t) 1, &_index); size_t new_index = Atomic::add((size_t) 1, &_index);

View file

@ -27,6 +27,7 @@
#include "classfile/stringTable.hpp" #include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp" #include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp" #include "code/codeCache.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
#include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
@ -242,10 +243,7 @@ ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_wo
_evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)), _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
_srs(n_workers), _srs(n_workers),
_phase(phase), _phase(phase),
_coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()), _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()) {
_par_state_string(StringTable::weak_storage())
{
heap->phase_timings()->record_workers_start(_phase); heap->phase_timings()->record_workers_start(_phase);
if (ShenandoahStringDedup::is_enabled()) { if (ShenandoahStringDedup::is_enabled()) {
StringDedup::gc_prologue(false); StringDedup::gc_prologue(false);

View file

@ -119,7 +119,6 @@ class ShenandoahRootEvacuator : public StackObj {
StrongRootsScope _srs; StrongRootsScope _srs;
ShenandoahPhaseTimings::Phase _phase; ShenandoahPhaseTimings::Phase _phase;
ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator; ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator;
OopStorage::ParState<false, false> _par_state_string;
enum Shenandoah_evacuate_roots_tasks { enum Shenandoah_evacuate_roots_tasks {
SHENANDOAH_EVAC_Universe_oops_do, SHENANDOAH_EVAC_Universe_oops_do,

View file

@ -30,6 +30,7 @@
#include "gc/shared/workgroup.hpp" #include "gc/shared/workgroup.hpp"
#include "gc/shared/weakProcessor.inline.hpp" #include "gc/shared/weakProcessor.inline.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
#include "gc/shenandoah/shenandoahCodeRoots.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"

View file

@ -1965,20 +1965,7 @@ public final class String
if (str.isEmpty()) { if (str.isEmpty()) {
return this; return this;
} }
if (coder() == str.coder()) { return StringConcatHelper.simpleConcat(this, str);
byte[] val = this.value;
byte[] oval = str.value;
int len = val.length + oval.length;
byte[] buf = Arrays.copyOf(val, len);
System.arraycopy(oval, 0, buf, val.length, oval.length);
return new String(buf, coder);
}
int len = length();
int olen = str.length();
byte[] buf = StringUTF16.newBytesFor(len + olen);
getBytes(buf, 0, UTF16);
str.getBytes(buf, len, UTF16);
return new String(buf, UTF16);
} }
/** /**

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,9 @@
package java.lang; package java.lang;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
/** /**
* Helper for string concatenation. These methods are mostly looked up with private lookups * Helper for string concatenation. These methods are mostly looked up with private lookups
* from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle} * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle}
@ -38,8 +41,10 @@ final class StringConcatHelper {
/** /**
* Check for overflow, throw exception on overflow. * Check for overflow, throw exception on overflow.
* @param lengthCoder String length and coder *
* @return lengthCoder * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @return the given parameter value, if valid
*/ */
private static long checkOverflow(long lengthCoder) { private static long checkOverflow(long lengthCoder) {
if ((int)lengthCoder >= 0) { if ((int)lengthCoder >= 0) {
@ -50,76 +55,83 @@ final class StringConcatHelper {
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, boolean value) { static long mix(long lengthCoder, boolean value) {
return checkOverflow(current + (value ? 4 : 5)); return checkOverflow(lengthCoder + (value ? 4 : 5));
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, byte value) { static long mix(long lengthCoder, byte value) {
return mix(current, (int)value); return mix(lengthCoder, (int)value);
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, char value) { static long mix(long lengthCoder, char value) {
return checkOverflow(current + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16); return checkOverflow(lengthCoder + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16);
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, short value) { static long mix(long lengthCoder, short value) {
return mix(current, (int)value); return mix(lengthCoder, (int)value);
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, int value) { static long mix(long lengthCoder, int value) {
return checkOverflow(current + Integer.stringSize(value)); return checkOverflow(lengthCoder + Integer.stringSize(value));
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, long value) { static long mix(long lengthCoder, long value) {
return checkOverflow(current + Long.stringSize(value)); return checkOverflow(lengthCoder + Long.stringSize(value));
} }
/** /**
* Mix value length and coder into current length and coder. * Mix value length and coder into current length and coder.
* @param current current length * @param lengthCoder String length with coder packed into higher bits
* the upper word.
* @param value value to mix in * @param value value to mix in
* @return new length and coder * @return new length and coder
*/ */
static long mix(long current, String value) { static long mix(long lengthCoder, String value) {
current += value.length(); lengthCoder += value.length();
if (value.coder() == String.UTF16) { if (value.coder() == String.UTF16) {
current |= UTF16; lengthCoder |= UTF16;
} }
return checkOverflow(current); return checkOverflow(lengthCoder);
} }
/** /**
@ -285,10 +297,62 @@ final class StringConcatHelper {
} }
} }
/**
* Perform a simple concatenation between two objects. Added for startup
* performance, but also demonstrates the code that would be emitted by
* {@code java.lang.invoke.StringConcatFactory$MethodHandleInlineCopyStrategy}
* for two Object arguments.
*
* @param first first argument
* @param second second argument
* @return String resulting string
*/
@ForceInline
static String simpleConcat(Object first, Object second) {
String s1 = stringOf(first);
String s2 = stringOf(second);
// start "mixing" in length and coder or arguments, order is not
// important
long indexCoder = mix(initialCoder(), s2);
indexCoder = mix(indexCoder, s1);
byte[] buf = newArray(indexCoder);
// prepend each argument in reverse order, since we prepending
// from the end of the byte array
indexCoder = prepend(indexCoder, buf, s2);
indexCoder = prepend(indexCoder, buf, s1);
return newString(buf, indexCoder);
}
/**
* We need some additional conversion for Objects in general, because
* {@code String.valueOf(Object)} may return null. String conversion rules
* in Java state we need to produce "null" String in this case, so we
* provide a customized version that deals with this problematic corner case.
*/
static String stringOf(Object value) {
String s;
return (value == null || (s = value.toString()) == null) ? "null" : s;
}
private static final long LATIN1 = (long)String.LATIN1 << 32; private static final long LATIN1 = (long)String.LATIN1 << 32;
private static final long UTF16 = (long)String.UTF16 << 32; private static final long UTF16 = (long)String.UTF16 << 32;
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
/**
* Allocates an uninitialized byte array based on the length and coder information
* in indexCoder
* @param indexCoder
* @return the newly allocated byte array
*/
@ForceInline
static byte[] newArray(long indexCoder) {
byte coder = (byte)(indexCoder >> 32);
int index = (int)indexCoder;
return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder);
}
/** /**
* Provides the initial coder for the String. * Provides the initial coder for the String.
* @return initial coder, adjusted into the upper half * @return initial coder, adjusted into the upper half

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package java.lang.invoke; package java.lang.invoke;
import jdk.internal.misc.Unsafe; import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.MethodVisitor;
@ -191,6 +192,8 @@ public final class StringConcatFactory {
*/ */
private static final ProxyClassesDumper DUMPER; private static final ProxyClassesDumper DUMPER;
private static final Class<?> STRING_HELPER;
static { static {
// In case we need to double-back onto the StringConcatFactory during this // In case we need to double-back onto the StringConcatFactory during this
// static initialization, make sure we have the reasonable defaults to complete // static initialization, make sure we have the reasonable defaults to complete
@ -202,15 +205,20 @@ public final class StringConcatFactory {
// DEBUG = false; // implied // DEBUG = false; // implied
// DUMPER = null; // implied // DUMPER = null; // implied
Properties props = GetPropertyAction.privilegedGetProperties(); try {
STRING_HELPER = Class.forName("java.lang.StringConcatHelper");
} catch (Throwable e) {
throw new AssertionError(e);
}
final String strategy = final String strategy =
props.getProperty("java.lang.invoke.stringConcat"); VM.getSavedProperty("java.lang.invoke.stringConcat");
CACHE_ENABLE = Boolean.parseBoolean( CACHE_ENABLE = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.stringConcat.cache")); VM.getSavedProperty("java.lang.invoke.stringConcat.cache"));
DEBUG = Boolean.parseBoolean( DEBUG = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.stringConcat.debug")); VM.getSavedProperty("java.lang.invoke.stringConcat.debug"));
final String dumpPath = final String dumpPath =
props.getProperty("java.lang.invoke.stringConcat.dumpClasses"); VM.getSavedProperty("java.lang.invoke.stringConcat.dumpClasses");
STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy); STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null; CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
@ -1519,6 +1527,33 @@ public final class StringConcatFactory {
static MethodHandle generate(MethodType mt, Recipe recipe) throws Throwable { static MethodHandle generate(MethodType mt, Recipe recipe) throws Throwable {
// Fast-path two-argument Object + Object concatenations
if (recipe.getElements().size() == 2) {
// Two object arguments
if (mt.parameterCount() == 2 &&
!mt.parameterType(0).isPrimitive() &&
!mt.parameterType(1).isPrimitive()) {
return SIMPLE;
}
// One element is a constant
if (mt.parameterCount() == 1 && !mt.parameterType(0).isPrimitive()) {
MethodHandle mh = SIMPLE;
// Insert constant element
// First recipe element is a constant
if (recipe.getElements().get(0).getTag() == TAG_CONST &&
recipe.getElements().get(1).getTag() != TAG_CONST) {
return MethodHandles.insertArguments(mh, 0,
recipe.getElements().get(0).getValue());
} else if (recipe.getElements().get(1).getTag() == TAG_CONST &&
recipe.getElements().get(0).getTag() != TAG_CONST) {
return MethodHandles.insertArguments(mh, 1,
recipe.getElements().get(1).getValue());
}
// else... fall-through to slow-path
}
}
// Create filters and obtain filtered parameter types. Filters would be used in the beginning // Create filters and obtain filtered parameter types. Filters would be used in the beginning
// to convert the incoming arguments into the arguments we can process (e.g. Objects -> Strings). // to convert the incoming arguments into the arguments we can process (e.g. Objects -> Strings).
// The filtered argument type list is used all over in the combinators below. // The filtered argument type list is used all over in the combinators below.
@ -1626,13 +1661,6 @@ public final class StringConcatFactory {
return mh; return mh;
} }
@ForceInline
private static byte[] newArray(long indexCoder) {
byte coder = (byte)(indexCoder >> 32);
int index = (int)indexCoder;
return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder);
}
private static MethodHandle prepender(Class<?> cl) { private static MethodHandle prepender(Class<?> cl) {
return PREPENDERS.computeIfAbsent(cl, PREPEND); return PREPENDERS.computeIfAbsent(cl, PREPEND);
} }
@ -1659,16 +1687,15 @@ public final class StringConcatFactory {
} }
}; };
private static final MethodHandle SIMPLE;
private static final MethodHandle NEW_STRING; private static final MethodHandle NEW_STRING;
private static final MethodHandle NEW_ARRAY; private static final MethodHandle NEW_ARRAY;
private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS; private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
private static final ConcurrentMap<Class<?>, MethodHandle> MIXERS; private static final ConcurrentMap<Class<?>, MethodHandle> MIXERS;
private static final long INITIAL_CODER; private static final long INITIAL_CODER;
static final Class<?> STRING_HELPER;
static { static {
try { try {
STRING_HELPER = Class.forName("java.lang.StringConcatHelper");
MethodHandle initCoder = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "initialCoder", long.class); MethodHandle initCoder = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "initialCoder", long.class);
INITIAL_CODER = (long) initCoder.invoke(); INITIAL_CODER = (long) initCoder.invoke();
} catch (Throwable e) { } catch (Throwable e) {
@ -1678,8 +1705,9 @@ public final class StringConcatFactory {
PREPENDERS = new ConcurrentHashMap<>(); PREPENDERS = new ConcurrentHashMap<>();
MIXERS = new ConcurrentHashMap<>(); MIXERS = new ConcurrentHashMap<>();
SIMPLE = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "simpleConcat", String.class, Object.class, Object.class);
NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, long.class); NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, long.class);
NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "newArray", byte[].class, long.class); NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newArray", byte[].class, long.class);
} }
} }
@ -1692,22 +1720,8 @@ public final class StringConcatFactory {
// no instantiation // no instantiation
} }
private static class ObjectStringifier { private static final MethodHandle OBJECT_INSTANCE =
lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "stringOf", String.class, Object.class);
// We need some additional conversion for Objects in general, because String.valueOf(Object)
// may return null. String conversion rules in Java state we need to produce "null" String
// in this case, so we provide a customized version that deals with this problematic corner case.
private static String valueOf(Object value) {
String s;
return (value == null || (s = value.toString()) == null) ? "null" : s;
}
// Could have used MethodHandles.lookup() instead of Lookup.IMPL_LOOKUP, if not for the fact
// java.lang.invoke Lookups are explicitly forbidden to be retrieved using that API.
private static final MethodHandle INSTANCE =
lookupStatic(Lookup.IMPL_LOOKUP, ObjectStringifier.class, "valueOf", String.class, Object.class);
}
private static class FloatStringifiers { private static class FloatStringifiers {
private static final MethodHandle FLOAT_INSTANCE = private static final MethodHandle FLOAT_INSTANCE =
@ -1751,7 +1765,7 @@ public final class StringConcatFactory {
*/ */
static MethodHandle forMost(Class<?> t) { static MethodHandle forMost(Class<?> t) {
if (!t.isPrimitive()) { if (!t.isPrimitive()) {
return ObjectStringifier.INSTANCE; return OBJECT_INSTANCE;
} else if (t == float.class) { } else if (t == float.class) {
return FloatStringifiers.FLOAT_INSTANCE; return FloatStringifiers.FLOAT_INSTANCE;
} else if (t == double.class) { } else if (t == double.class) {

View file

@ -791,7 +791,7 @@ public abstract class FileChannel
// -- Memory-mapped buffers -- // -- Memory-mapped buffers --
/** /**
* A typesafe enumeration for file-mapping modes. * A file-mapping mode.
* *
* @since 1.4 * @since 1.4
* *
@ -819,6 +819,12 @@ public abstract class FileChannel
private final String name; private final String name;
/**
* Constructs an instance of this class. This constructor may be used
* by code in java.base to create file mapping modes beyond the file
* mapping modes defined here.
* @param name the name of the map mode
*/
private MapMode(String name) { private MapMode(String name) {
this.name = name; this.name = name;
} }
@ -837,8 +843,8 @@ public abstract class FileChannel
/** /**
* Maps a region of this channel's file directly into memory. * Maps a region of this channel's file directly into memory.
* *
* <p> A region of a file may be mapped into memory in one of three modes: * <p> The {@code mode} parameter specifies how the region of the file is
* </p> * mapped and may be one of the following modes:
* *
* <ul> * <ul>
* *
@ -859,6 +865,8 @@ public abstract class FileChannel
* *
* </ul> * </ul>
* *
* <p> An implementation may support additional map modes.
*
* <p> For a read-only mapping, this channel must have been opened for * <p> For a read-only mapping, this channel must have been opened for
* reading; for a read/write or private mapping, this channel must have * reading; for a read/write or private mapping, this channel must have
* been opened for both reading and writing. * been opened for both reading and writing.
@ -892,7 +900,8 @@ public abstract class FileChannel
* MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE * MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE
* PRIVATE} defined in the {@link MapMode} class, according to * PRIVATE} defined in the {@link MapMode} class, according to
* whether the file is to be mapped read-only, read/write, or * whether the file is to be mapped read-only, read/write, or
* privately (copy-on-write), respectively * privately (copy-on-write), respectively, or an implementation
* specific map mode
* *
* @param position * @param position
* The position within the file at which the mapped region * The position within the file at which the mapped region
@ -905,25 +914,29 @@ public abstract class FileChannel
* @return The mapped byte buffer * @return The mapped byte buffer
* *
* @throws NonReadableChannelException * @throws NonReadableChannelException
* If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} but * If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} or
* this channel was not opened for reading * an implementation specific map mode requiring read access
* but this channel was not opened for reading
* *
* @throws NonWritableChannelException * @throws NonWritableChannelException
* If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE} or * If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE}.
* {@link MapMode#PRIVATE PRIVATE} but this channel was not opened * {@link MapMode#PRIVATE PRIVATE} or an implementation specific
* for both reading and writing * map mode requiring write access but this channel was not
* opened for both reading and writing
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* If the preconditions on the parameters do not hold * If the preconditions on the parameters do not hold
* *
* @throws UnsupportedOperationException
* If an unsupported map mode is specified
*
* @throws IOException * @throws IOException
* If some other I/O error occurs * If some other I/O error occurs
* *
* @see java.nio.channels.FileChannel.MapMode * @see java.nio.channels.FileChannel.MapMode
* @see java.nio.MappedByteBuffer * @see java.nio.MappedByteBuffer
*/ */
public abstract MappedByteBuffer map(MapMode mode, public abstract MappedByteBuffer map(MapMode mode, long position, long size)
long position, long size)
throws IOException; throws IOException;

View file

@ -940,14 +940,15 @@ public class FileChannelImpl
if (size > Integer.MAX_VALUE) if (size > Integer.MAX_VALUE)
throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE"); throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
int imode = -1; int imode;
if (mode == MapMode.READ_ONLY) if (mode == MapMode.READ_ONLY)
imode = MAP_RO; imode = MAP_RO;
else if (mode == MapMode.READ_WRITE) else if (mode == MapMode.READ_WRITE)
imode = MAP_RW; imode = MAP_RW;
else if (mode == MapMode.PRIVATE) else if (mode == MapMode.PRIVATE)
imode = MAP_PV; imode = MAP_PV;
assert (imode >= 0); else
throw new UnsupportedOperationException();
if ((mode != MapMode.READ_ONLY) && !writable) if ((mode != MapMode.READ_ONLY) && !writable)
throw new NonWritableChannelException(); throw new NonWritableChannelException();
if (!readable) if (!readable)

View file

@ -980,7 +980,7 @@ public final class SSLSocketImpl
} }
try { try {
shutdownInput(false); SSLSocketImpl.this.close();
} catch (IOException ioe) { } catch (IOException ioe) {
// ignore the exception // ignore the exception
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
@ -1146,7 +1146,7 @@ public final class SSLSocketImpl
} }
try { try {
shutdownOutput(); SSLSocketImpl.this.close();
} catch (IOException ioe) { } catch (IOException ioe) {
// ignore the exception // ignore the exception
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {

View file

@ -204,10 +204,13 @@ static jboolean IsWildCardEnabled();
*/ */
static jlong threadStackSize = 0; /* stack size of the new thread */ static jlong threadStackSize = 0; /* stack size of the new thread */
static jlong maxHeapSize = 0; /* max heap size */ static jlong maxHeapSize = 0; /* max heap size */
static jlong initialHeapSize = 0; /* inital heap size */ static jlong initialHeapSize = 0; /* initial heap size */
/* /*
* A minimum -Xss stack size suitable for all platforms. * A minimum initial-thread stack size suitable for most platforms.
* This is the minimum amount of stack needed to load the JVM such
* that it can reject a too small -Xss value. If this is too small
* JVM initialization would cause a StackOverflowError.
*/ */
#ifndef STACK_SIZE_MINIMUM #ifndef STACK_SIZE_MINIMUM
#define STACK_SIZE_MINIMUM (64 * KB) #define STACK_SIZE_MINIMUM (64 * KB)
@ -934,16 +937,18 @@ AddOption(char *str, void *info)
options[numOptions].optionString = str; options[numOptions].optionString = str;
options[numOptions++].extraInfo = info; options[numOptions++].extraInfo = info;
/*
* -Xss is used both by the JVM and here to establish the stack size of the thread
* created to launch the JVM. In the latter case we need to ensure we don't go
* below the minimum stack size allowed. If -Xss is zero that tells the JVM to use
* 'default' sizes (either from JVM or system configuration, e.g. 'ulimit -s' on linux),
* and is not itself a small stack size that will be rejected. So we ignore -Xss0 here.
*/
if (JLI_StrCCmp(str, "-Xss") == 0) { if (JLI_StrCCmp(str, "-Xss") == 0) {
jlong tmp; jlong tmp;
if (parse_size(str + 4, &tmp)) { if (parse_size(str + 4, &tmp)) {
threadStackSize = tmp; threadStackSize = tmp;
/* if (threadStackSize > 0 && threadStackSize < (jlong)STACK_SIZE_MINIMUM) {
* Make sure the thread stack size is big enough that we won't get a stack
* overflow before the JVM startup code can check to make sure the stack
* is big enough.
*/
if (threadStackSize < (jlong)STACK_SIZE_MINIMUM) {
threadStackSize = STACK_SIZE_MINIMUM; threadStackSize = STACK_SIZE_MINIMUM;
} }
} }
@ -2322,13 +2327,13 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
int argc, char **argv, int argc, char **argv,
int mode, char *what, int ret) int mode, char *what, int ret)
{ {
if (threadStackSize == 0) {
/* /*
* If user doesn't specify stack size, check if VM has a preference. * If the user hasn't specified a non-zero stack size ask the JVM for its default.
* A returned 0 means 'use the system default' for a platform, e.g., Windows.
* Note that HotSpot no longer supports JNI_VERSION_1_1 but it will * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will
* return its default stack size through the init args structure. * return its default stack size through the init args structure.
*/ */
if (threadStackSize == 0) {
struct JDK1_1InitArgs args1_1; struct JDK1_1InitArgs args1_1;
memset((void*)&args1_1, 0, sizeof(args1_1)); memset((void*)&args1_1, 0, sizeof(args1_1));
args1_1.version = JNI_VERSION_1_1; args1_1.version = JNI_VERSION_1_1;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -131,4 +131,18 @@ public interface ProcessingEnvironment {
* effect * effect
*/ */
Locale getLocale(); Locale getLocale();
/**
* Returns {@code true} if <em>preview features</em> are enabled
* and {@code false} otherwise.
* @return whether or not preview features are enabled
*
* @implSpec The default implementation of this method returns
* {@code false}.
*
* @since 13
*/
default boolean isPreviewEnabled() {
return false;
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
@ -22,6 +22,7 @@ package com.sun.org.apache.xerces.internal.impl ;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
import com.sun.org.apache.xerces.internal.impl.io.UTF16Reader;
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
@ -89,7 +90,7 @@ import org.xml.sax.InputSource;
* @author K.Venugopal SUN Microsystems * @author K.Venugopal SUN Microsystems
* @author Neeraj Bajaj SUN Microsystems * @author Neeraj Bajaj SUN Microsystems
* @author Sunitha Reddy SUN Microsystems * @author Sunitha Reddy SUN Microsystems
* @LastModified: Nov 2018 * @LastModified: Apr 2019
*/ */
public class XMLEntityManager implements XMLComponent, XMLEntityResolver { public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
@ -412,9 +413,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
/** Augmentations for entities. */ /** Augmentations for entities. */
private final Augmentations fEntityAugs = new AugmentationsImpl(); private final Augmentations fEntityAugs = new AugmentationsImpl();
/** Pool of character buffers. */
private CharacterBufferPool fBufferPool = new CharacterBufferPool(fBufferSize, DEFAULT_INTERNAL_BUFFER_SIZE);
/** indicate whether Catalog should be used for resolving external resources */ /** indicate whether Catalog should be used for resolving external resources */
private boolean fUseCatalog = true; private boolean fUseCatalog = true;
CatalogFeatures fCatalogFeatures; CatalogFeatures fCatalogFeatures;
@ -694,7 +692,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
// wrap this stream in RewindableInputStream // wrap this stream in RewindableInputStream
stream = new RewindableInputStream(stream); RewindableInputStream rewindableStream = new RewindableInputStream(stream);
stream = rewindableStream;
// perform auto-detect of encoding if necessary // perform auto-detect of encoding if necessary
if (encoding == null) { if (encoding == null) {
@ -702,27 +701,30 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
final byte[] b4 = new byte[4]; final byte[] b4 = new byte[4];
int count = 0; int count = 0;
for (; count<4; count++ ) { for (; count<4; count++ ) {
b4[count] = (byte)stream.read(); b4[count] = (byte)rewindableStream.readAndBuffer();
} }
if (count == 4) { if (count == 4) {
Object [] encodingDesc = getEncodingName(b4, count); final EncodingInfo info = getEncodingInfo(b4, count);
encoding = (String)(encodingDesc[0]); encoding = info.autoDetectedEncoding;
isBigEndian = (Boolean)(encodingDesc[1]); final String readerEncoding = info.readerEncoding;
isBigEndian = info.isBigEndian;
stream.reset(); stream.reset();
if (info.hasBOM) {
// Special case UTF-8 files with BOM created by Microsoft // Special case UTF-8 files with BOM created by Microsoft
// tools. It's more efficient to consume the BOM than make // tools. It's more efficient to consume the BOM than make
// the reader perform extra checks. -Ac // the reader perform extra checks. -Ac
if (count > 2 && encoding.equals("UTF-8")) { if (EncodingInfo.STR_UTF8.equals(readerEncoding)) {
int b0 = b4[0] & 0xFF; // UTF-8 BOM: 0xEF 0xBB 0xBF
int b1 = b4[1] & 0xFF;
int b2 = b4[2] & 0xFF;
if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
// ignore first three bytes...
stream.skip(3); stream.skip(3);
} }
// It's also more efficient to consume the UTF-16 BOM.
else if (EncodingInfo.STR_UTF16.equals(readerEncoding)) {
// UTF-16 BE BOM: 0xFE 0xFF
// UTF-16 LE BOM: 0xFF 0xFE
stream.skip(2);
} }
reader = createReader(stream, encoding, isBigEndian); }
reader = createReader(stream, readerEncoding, isBigEndian);
} else { } else {
reader = createReader(stream, encoding, isBigEndian); reader = createReader(stream, encoding, isBigEndian);
} }
@ -733,11 +735,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
encoding = encoding.toUpperCase(Locale.ENGLISH); encoding = encoding.toUpperCase(Locale.ENGLISH);
// If encoding is UTF-8, consume BOM if one is present. // If encoding is UTF-8, consume BOM if one is present.
if (encoding.equals("UTF-8")) { if (EncodingInfo.STR_UTF8.equals(encoding)) {
final int[] b3 = new int[3]; final int[] b3 = new int[3];
int count = 0; int count = 0;
for (; count < 3; ++count) { for (; count < 3; ++count) {
b3[count] = stream.read(); b3[count] = rewindableStream.readAndBuffer();
if (b3[count] == -1) if (b3[count] == -1)
break; break;
} }
@ -750,56 +752,51 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
stream.reset(); stream.reset();
} }
} }
// If encoding is UTF-16, we still need to read the first four bytes // If encoding is UTF-16, we still need to read the first
// in order to discover the byte order. // four bytes, in order to discover the byte order.
else if (encoding.equals("UTF-16")) { else if (EncodingInfo.STR_UTF16.equals(encoding)) {
final int[] b4 = new int[4]; final int[] b4 = new int[4];
int count = 0; int count = 0;
for (; count < 4; ++count) { for (; count < 4; ++count) {
b4[count] = stream.read(); b4[count] = rewindableStream.readAndBuffer();
if (b4[count] == -1) if (b4[count] == -1)
break; break;
} }
stream.reset(); stream.reset();
String utf16Encoding = "UTF-16";
if (count >= 2) { if (count >= 2) {
final int b0 = b4[0]; final int b0 = b4[0];
final int b1 = b4[1]; final int b1 = b4[1];
if (b0 == 0xFE && b1 == 0xFF) { if (b0 == 0xFE && b1 == 0xFF) {
// UTF-16, big-endian // UTF-16, big-endian
utf16Encoding = "UTF-16BE";
isBigEndian = Boolean.TRUE; isBigEndian = Boolean.TRUE;
stream.skip(2);
} }
else if (b0 == 0xFF && b1 == 0xFE) { else if (b0 == 0xFF && b1 == 0xFE) {
// UTF-16, little-endian // UTF-16, little-endian
utf16Encoding = "UTF-16LE";
isBigEndian = Boolean.FALSE; isBigEndian = Boolean.FALSE;
stream.skip(2);
} }
else if (count == 4) { else if (count == 4) {
final int b2 = b4[2]; final int b2 = b4[2];
final int b3 = b4[3]; final int b3 = b4[3];
if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) {
// UTF-16, big-endian, no BOM // UTF-16, big-endian, no BOM
utf16Encoding = "UTF-16BE";
isBigEndian = Boolean.TRUE; isBigEndian = Boolean.TRUE;
} }
if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) {
// UTF-16, little-endian, no BOM // UTF-16, little-endian, no BOM
utf16Encoding = "UTF-16LE";
isBigEndian = Boolean.FALSE; isBigEndian = Boolean.FALSE;
} }
} }
} }
reader = createReader(stream, utf16Encoding, isBigEndian);
} }
// If encoding is UCS-4, we still need to read the first four bytes // If encoding is UCS-4, we still need to read the first four bytes
// in order to discover the byte order. // in order to discover the byte order.
else if (encoding.equals("ISO-10646-UCS-4")) { else if (EncodingInfo.STR_UCS4.equals(encoding)) {
final int[] b4 = new int[4]; final int[] b4 = new int[4];
int count = 0; int count = 0;
for (; count < 4; ++count) { for (; count < 4; ++count) {
b4[count] = stream.read(); b4[count] = rewindableStream.readAndBuffer();
if (b4[count] == -1) if (b4[count] == -1)
break; break;
} }
@ -819,11 +816,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
// If encoding is UCS-2, we still need to read the first four bytes // If encoding is UCS-2, we still need to read the first four bytes
// in order to discover the byte order. // in order to discover the byte order.
else if (encoding.equals("ISO-10646-UCS-2")) { else if (EncodingInfo.STR_UCS2.equals(encoding)) {
final int[] b4 = new int[4]; final int[] b4 = new int[4];
int count = 0; int count = 0;
for (; count < 4; ++count) { for (; count < 4; ++count) {
b4[count] = stream.read(); b4[count] = rewindableStream.readAndBuffer();
if (b4[count] == -1) if (b4[count] == -1)
break; break;
} }
@ -1798,7 +1795,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
bufferSize.intValue() > DEFAULT_XMLDECL_BUFFER_SIZE) { bufferSize.intValue() > DEFAULT_XMLDECL_BUFFER_SIZE) {
fBufferSize = bufferSize.intValue(); fBufferSize = bufferSize.intValue();
fEntityScanner.setBufferSize(fBufferSize); fEntityScanner.setBufferSize(fBufferSize);
fBufferPool.setExternalBufferSize(fBufferSize);
} }
} }
if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() &&
@ -2425,14 +2421,12 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
* *
* @param b4 The first four bytes of the input. * @param b4 The first four bytes of the input.
* @param count The number of bytes actually read. * @param count The number of bytes actually read.
* @return a 2-element array: the first element, an IANA-encoding string, * @return an instance of EncodingInfo which represents the auto-detected encoding.
* the second element a Boolean which is true iff the document is big endian, false
* if it's little-endian, and null if the distinction isn't relevant.
*/ */
protected Object[] getEncodingName(byte[] b4, int count) { protected EncodingInfo getEncodingInfo(byte[] b4, int count) {
if (count < 2) { if (count < 2) {
return defaultEncoding; return EncodingInfo.UTF_8;
} }
// UTF-16, with BOM // UTF-16, with BOM
@ -2440,69 +2434,70 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
int b1 = b4[1] & 0xFF; int b1 = b4[1] & 0xFF;
if (b0 == 0xFE && b1 == 0xFF) { if (b0 == 0xFE && b1 == 0xFF) {
// UTF-16, big-endian // UTF-16, big-endian
return new Object [] {"UTF-16BE", true}; return EncodingInfo.UTF_16_BIG_ENDIAN_WITH_BOM;
} }
if (b0 == 0xFF && b1 == 0xFE) { if (b0 == 0xFF && b1 == 0xFE) {
// UTF-16, little-endian // UTF-16, little-endian
return new Object [] {"UTF-16LE", false}; return EncodingInfo.UTF_16_LITTLE_ENDIAN_WITH_BOM;
} }
// default to UTF-8 if we don't have enough bytes to make a // default to UTF-8 if we don't have enough bytes to make a
// good determination of the encoding // good determination of the encoding
if (count < 3) { if (count < 3) {
return defaultEncoding; return EncodingInfo.UTF_8;
} }
// UTF-8 with a BOM // UTF-8 with a BOM
int b2 = b4[2] & 0xFF; int b2 = b4[2] & 0xFF;
if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
return defaultEncoding; return EncodingInfo.UTF_8_WITH_BOM;
} }
// default to UTF-8 if we don't have enough bytes to make a // default to UTF-8 if we don't have enough bytes to make a
// good determination of the encoding // good determination of the encoding
if (count < 4) { if (count < 4) {
return defaultEncoding; return EncodingInfo.UTF_8;
} }
// other encodings // other encodings
int b3 = b4[3] & 0xFF; int b3 = b4[3] & 0xFF;
if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) { if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) {
// UCS-4, big endian (1234) // UCS-4, big endian (1234)
return new Object [] {"ISO-10646-UCS-4", true}; return EncodingInfo.UCS_4_BIG_ENDIAN;
} }
if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) { if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) {
// UCS-4, little endian (4321) // UCS-4, little endian (4321)
return new Object [] {"ISO-10646-UCS-4", false}; return EncodingInfo.UCS_4_LITTLE_ENDIAN;
} }
if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) { if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) {
// UCS-4, unusual octet order (2143) // UCS-4, unusual octet order (2143)
// REVISIT: What should this be? // REVISIT: What should this be?
return new Object [] {"ISO-10646-UCS-4", null}; return EncodingInfo.UCS_4_UNUSUAL_BYTE_ORDER;
} }
if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) { if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) {
// UCS-4, unusual octect order (3412) // UCS-4, unusual octect order (3412)
// REVISIT: What should this be? // REVISIT: What should this be?
return new Object [] {"ISO-10646-UCS-4", null}; return EncodingInfo.UCS_4_UNUSUAL_BYTE_ORDER;
} }
if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) {
// UTF-16, big-endian, no BOM // UTF-16, big-endian, no BOM
// (or could turn out to be UCS-2... // (or could turn out to be UCS-2...
// REVISIT: What should this be? // REVISIT: What should this be?
return new Object [] {"UTF-16BE", true}; return EncodingInfo.UTF_16_BIG_ENDIAN;
} }
if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) {
// UTF-16, little-endian, no BOM // UTF-16, little-endian, no BOM
// (or could turn out to be UCS-2... // (or could turn out to be UCS-2...
return new Object [] {"UTF-16LE", false}; return EncodingInfo.UTF_16_LITTLE_ENDIAN;
} }
if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) { if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) {
// EBCDIC // EBCDIC
// a la xerces1, return CP037 instead of EBCDIC here // a la xerces1, return CP037 instead of EBCDIC here
return new Object [] {"CP037", null}; return EncodingInfo.EBCDIC;
} }
return defaultEncoding; // default encoding
return EncodingInfo.UTF_8;
} // getEncodingName(byte[],int):Object[] } // getEncodingName(byte[],int):Object[]
@ -2517,69 +2512,68 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
* encoding name may be a Java encoding name; * encoding name may be a Java encoding name;
* otherwise, it is an ianaEncoding name. * otherwise, it is an ianaEncoding name.
* @param isBigEndian For encodings (like uCS-4), whose names cannot * @param isBigEndian For encodings (like uCS-4), whose names cannot
* specify a byte order, this tells whether the order is bigEndian. null menas * specify a byte order, this tells whether the order
* unknown or not relevant. * is bigEndian. null if unknown or irrelevant.
* *
* @return Returns a reader. * @return Returns a reader.
*/ */
protected Reader createReader(InputStream inputStream, String encoding, Boolean isBigEndian) protected Reader createReader(InputStream inputStream, String encoding, Boolean isBigEndian)
throws IOException { throws IOException {
// normalize encoding name String enc = (encoding != null) ? encoding : EncodingInfo.STR_UTF8;
if (encoding == null) { enc = enc.toUpperCase(Locale.ENGLISH);
encoding = "UTF-8"; MessageFormatter f = fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN);
} Locale l = fErrorReporter.getLocale();
switch (enc) {
// try to use an optimized reader case EncodingInfo.STR_UTF8:
String ENCODING = encoding.toUpperCase(Locale.ENGLISH); return new UTF8Reader(inputStream, fBufferSize, f, l);
if (ENCODING.equals("UTF-8")) { case EncodingInfo.STR_UTF16:
if (DEBUG_ENCODINGS) {
System.out.println("$$$ creating UTF8Reader");
}
return new UTF8Reader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale() );
}
if (ENCODING.equals("US-ASCII")) {
if (DEBUG_ENCODINGS) {
System.out.println("$$$ creating ASCIIReader");
}
return new ASCIIReader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale());
}
if(ENCODING.equals("ISO-10646-UCS-4")) {
if (isBigEndian != null) { if (isBigEndian != null) {
boolean isBE = isBigEndian.booleanValue(); return new UTF16Reader(inputStream, fBufferSize, isBigEndian, f, l);
if(isBE) { }
break;
case EncodingInfo.STR_UTF16BE:
return new UTF16Reader(inputStream, fBufferSize, true, f, l);
case EncodingInfo.STR_UTF16LE:
return new UTF16Reader(inputStream, fBufferSize, false, f, l);
case EncodingInfo.STR_UCS4:
if(isBigEndian != null) {
if(isBigEndian) {
return new UCSReader(inputStream, UCSReader.UCS4BE); return new UCSReader(inputStream, UCSReader.UCS4BE);
} else { } else {
return new UCSReader(inputStream, UCSReader.UCS4LE); return new UCSReader(inputStream, UCSReader.UCS4LE);
} }
} else { } else {
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, fErrorReporter.reportError(this.getEntityScanner(),
XMLMessageFormatter.XML_DOMAIN,
"EncodingByteOrderUnsupported", "EncodingByteOrderUnsupported",
new Object[] { encoding }, new Object[] { encoding },
XMLErrorReporter.SEVERITY_FATAL_ERROR); XMLErrorReporter.SEVERITY_FATAL_ERROR);
} }
} break;
if(ENCODING.equals("ISO-10646-UCS-2")) { case EncodingInfo.STR_UCS2:
if(isBigEndian != null) { // sould never happen with this encoding... if(isBigEndian != null) {
boolean isBE = isBigEndian.booleanValue(); if(isBigEndian) {
if(isBE) {
return new UCSReader(inputStream, UCSReader.UCS2BE); return new UCSReader(inputStream, UCSReader.UCS2BE);
} else { } else {
return new UCSReader(inputStream, UCSReader.UCS2LE); return new UCSReader(inputStream, UCSReader.UCS2LE);
} }
} else { } else {
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, fErrorReporter.reportError(this.getEntityScanner(),
XMLMessageFormatter.XML_DOMAIN,
"EncodingByteOrderUnsupported", "EncodingByteOrderUnsupported",
new Object[] { encoding }, new Object[] { encoding },
XMLErrorReporter.SEVERITY_FATAL_ERROR); XMLErrorReporter.SEVERITY_FATAL_ERROR);
} }
break;
} }
// check for valid name // check for valid name
boolean validIANA = XMLChar.isValidIANAEncoding(encoding); boolean validIANA = XMLChar.isValidIANAEncoding(encoding);
boolean validJava = XMLChar.isValidJavaEncoding(encoding); boolean validJava = XMLChar.isValidJavaEncoding(encoding);
if (!validIANA || (fAllowJavaEncodings && !validJava)) { if (!validIANA || (fAllowJavaEncodings && !validJava)) {
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, fErrorReporter.reportError(this.getEntityScanner(),
XMLMessageFormatter.XML_DOMAIN,
"EncodingDeclInvalid", "EncodingDeclInvalid",
new Object[] { encoding }, new Object[] { encoding },
XMLErrorReporter.SEVERITY_FATAL_ERROR); XMLErrorReporter.SEVERITY_FATAL_ERROR);
@ -2595,12 +2589,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
// try to use a Java reader // try to use a Java reader
String javaEncoding = EncodingMap.getIANA2JavaMapping(ENCODING); String javaEncoding = EncodingMap.getIANA2JavaMapping(enc);
if (javaEncoding == null) { if (javaEncoding == null) {
if (fAllowJavaEncodings) { if (fAllowJavaEncodings) {
javaEncoding = encoding; javaEncoding = encoding;
} else { } else {
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, fErrorReporter.reportError(this.getEntityScanner(),
XMLMessageFormatter.XML_DOMAIN,
"EncodingDeclInvalid", "EncodingDeclInvalid",
new Object[] { encoding }, new Object[] { encoding },
XMLErrorReporter.SEVERITY_FATAL_ERROR); XMLErrorReporter.SEVERITY_FATAL_ERROR);
@ -2898,108 +2893,78 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} // print() } // print()
/** /**
* Buffer used in entity manager to reuse character arrays instead * Information about auto-detectable encodings.
* of creating new ones every time.
* *
* @xerces.internal * @xerces.internal
* *
* @author Ankit Pasricha, IBM * @author Michael Glavassevich, IBM
*/ */
private static class CharacterBuffer { private static class EncodingInfo {
public static final String STR_UTF8 = "UTF-8";
public static final String STR_UTF16 = "UTF-16";
public static final String STR_UTF16BE = "UTF-16BE";
public static final String STR_UTF16LE = "UTF-16LE";
public static final String STR_UCS4 = "ISO-10646-UCS-4";
public static final String STR_UCS2 = "ISO-10646-UCS-2";
public static final String STR_CP037 = "CP037";
/** character buffer */ /** UTF-8 **/
private char[] ch; public static final EncodingInfo UTF_8 =
new EncodingInfo(STR_UTF8, null, false);
/** whether the buffer is for an external or internal scanned entity */ /** UTF-8, with BOM **/
private boolean isExternal; public static final EncodingInfo UTF_8_WITH_BOM =
new EncodingInfo(STR_UTF8, null, true);
public CharacterBuffer(boolean isExternal, int size) { /** UTF-16, big-endian **/
this.isExternal = isExternal; public static final EncodingInfo UTF_16_BIG_ENDIAN =
ch = new char[size]; new EncodingInfo(STR_UTF16BE, STR_UTF16, Boolean.TRUE, false);
}
}
/** UTF-16, big-endian with BOM **/
public static final EncodingInfo UTF_16_BIG_ENDIAN_WITH_BOM =
new EncodingInfo(STR_UTF16BE, STR_UTF16, Boolean.TRUE, true);
/** /** UTF-16, little-endian **/
* Stores a number of character buffers and provides it to the entity public static final EncodingInfo UTF_16_LITTLE_ENDIAN =
* manager to use when an entity is seen. new EncodingInfo(STR_UTF16LE, STR_UTF16, Boolean.FALSE, false);
*
* @xerces.internal
*
* @author Ankit Pasricha, IBM
*/
private static class CharacterBufferPool {
private static final int DEFAULT_POOL_SIZE = 3; /** UTF-16, little-endian with BOM **/
public static final EncodingInfo UTF_16_LITTLE_ENDIAN_WITH_BOM =
new EncodingInfo(STR_UTF16LE, STR_UTF16, Boolean.FALSE, true);
private CharacterBuffer[] fInternalBufferPool; /** UCS-4, big-endian **/
private CharacterBuffer[] fExternalBufferPool; public static final EncodingInfo UCS_4_BIG_ENDIAN =
new EncodingInfo(STR_UCS4, Boolean.TRUE, false);
private int fExternalBufferSize; /** UCS-4, little-endian **/
private int fInternalBufferSize; public static final EncodingInfo UCS_4_LITTLE_ENDIAN =
private int poolSize; new EncodingInfo(STR_UCS4, Boolean.FALSE, false);
private int fInternalTop; /** UCS-4, unusual byte-order (2143) or (3412) **/
private int fExternalTop; public static final EncodingInfo UCS_4_UNUSUAL_BYTE_ORDER =
new EncodingInfo(STR_UCS4, null, false);
public CharacterBufferPool(int externalBufferSize, int internalBufferSize) { /** EBCDIC **/
this(DEFAULT_POOL_SIZE, externalBufferSize, internalBufferSize); public static final EncodingInfo EBCDIC = new EncodingInfo(STR_CP037, null, false);
}
public CharacterBufferPool(int poolSize, int externalBufferSize, int internalBufferSize) { public final String autoDetectedEncoding;
fExternalBufferSize = externalBufferSize; public final String readerEncoding;
fInternalBufferSize = internalBufferSize; public final Boolean isBigEndian;
this.poolSize = poolSize; public final boolean hasBOM;
init();
}
/** Initializes buffer pool. **/ private EncodingInfo(String autoDetectedEncoding, Boolean isBigEndian, boolean hasBOM) {
private void init() { this(autoDetectedEncoding, autoDetectedEncoding, isBigEndian, hasBOM);
fInternalBufferPool = new CharacterBuffer[poolSize]; } // <init>(String,Boolean,boolean)
fExternalBufferPool = new CharacterBuffer[poolSize];
fInternalTop = -1;
fExternalTop = -1;
}
/** Retrieves buffer from pool. **/ private EncodingInfo(String autoDetectedEncoding, String readerEncoding,
public CharacterBuffer getBuffer(boolean external) { Boolean isBigEndian, boolean hasBOM) {
if (external) { this.autoDetectedEncoding = autoDetectedEncoding;
if (fExternalTop > -1) { this.readerEncoding = readerEncoding;
return fExternalBufferPool[fExternalTop--]; this.isBigEndian = isBigEndian;
} this.hasBOM = hasBOM;
else { } // <init>(String,String,Boolean,boolean)
return new CharacterBuffer(true, fExternalBufferSize);
}
}
else {
if (fInternalTop > -1) {
return fInternalBufferPool[fInternalTop--];
}
else {
return new CharacterBuffer(false, fInternalBufferSize);
}
}
}
/** Returns buffer to pool. **/ } // class EncodingInfo
public void returnToPool(CharacterBuffer buffer) {
if (buffer.isExternal) {
if (fExternalTop < fExternalBufferPool.length - 1) {
fExternalBufferPool[++fExternalTop] = buffer;
}
}
else if (fInternalTop < fInternalBufferPool.length - 1) {
fInternalBufferPool[++fInternalTop] = buffer;
}
}
/** Sets the size of external buffers and dumps the old pool. **/
public void setExternalBufferSize(int bufferSize) {
fExternalBufferSize = bufferSize;
fExternalBufferPool = new CharacterBuffer[poolSize];
fExternalTop = -1;
}
}
/** /**
* This class wraps the byte inputstreams we're presented with. * This class wraps the byte inputstreams we're presented with.
@ -3052,20 +3017,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
fOffset = fStartOffset; fOffset = fStartOffset;
} }
public int read() throws IOException { public int readAndBuffer() throws IOException {
int b = 0;
if (fOffset < fLength) {
return fData[fOffset++] & 0xff;
}
if (fOffset == fEndOffset) {
return -1;
}
if (fOffset == fData.length) { if (fOffset == fData.length) {
byte[] newData = new byte[fOffset << 1]; byte[] newData = new byte[fOffset << 1];
System.arraycopy(fData, 0, newData, 0, fOffset); System.arraycopy(fData, 0, newData, 0, fOffset);
fData = newData; fData = newData;
} }
b = fInputStream.read(); final int b = fInputStream.read();
if (b == -1) { if (b == -1) {
fEndOffset = fOffset; fEndOffset = fOffset;
return -1; return -1;
@ -3075,18 +3033,27 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
return b & 0xff; return b & 0xff;
} }
public int read() throws IOException {
if (fOffset < fLength) {
return fData[fOffset++] & 0xff;
}
if (fOffset == fEndOffset) {
return -1;
}
if (fCurrentEntity.mayReadChunks) {
return fInputStream.read();
}
return readAndBuffer();
}
public int read(byte[] b, int off, int len) throws IOException { public int read(byte[] b, int off, int len) throws IOException {
int bytesLeft = fLength - fOffset; final int bytesLeft = fLength - fOffset;
if (bytesLeft == 0) { if (bytesLeft == 0) {
if (fOffset == fEndOffset) { if (fOffset == fEndOffset) {
return -1; return -1;
} }
/** // read a block of data as requested
* //System.out.println("fCurrentEntitty = " + fCurrentEntity );
* //System.out.println("fInputStream = " + fInputStream );
* // better get some more for the voracious reader... */
if(fCurrentEntity.mayReadChunks || !fCurrentEntity.xmlDeclChunkRead) { if(fCurrentEntity.mayReadChunks || !fCurrentEntity.xmlDeclChunkRead) {
if (!fCurrentEntity.xmlDeclChunkRead) if (!fCurrentEntity.xmlDeclChunkRead)
@ -3096,15 +3063,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
return fInputStream.read(b, off, len); return fInputStream.read(b, off, len);
} }
int returnedVal = readAndBuffer();
int returnedVal = read();
if (returnedVal == -1) { if (returnedVal == -1) {
fEndOffset = fOffset; fEndOffset = fOffset;
return -1; return -1;
} }
b[off] = (byte)returnedVal; b[off] = (byte)returnedVal;
return 1; return 1;
} }
if (len < bytesLeft) { if (len < bytesLeft) {
if (len <= 0) { if (len <= 0) {
@ -3120,8 +3085,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
return len; return len;
} }
public long skip(long n) public long skip(long n) throws IOException {
throws IOException {
int bytesLeft; int bytesLeft;
if (n <= 0) { if (n <= 0) {
return 0; return 0;
@ -3154,7 +3118,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
public int available() throws IOException { public int available() throws IOException {
int bytesLeft = fLength - fOffset; final int bytesLeft = fLength - fOffset;
if (bytesLeft == 0) { if (bytesLeft == 0) {
if (fOffset == fEndOffset) { if (fOffset == fEndOffset) {
return -1; return -1;
@ -3171,7 +3135,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
public void reset() { public void reset() {
fOffset = fMark; fOffset = fMark;
//test();
} }
public boolean markSupported() { public boolean markSupported() {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -188,6 +188,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
private final Context context; private final Context context;
/**
* Support for preview language features.
*/
private final Preview preview;
/** Get the JavacProcessingEnvironment instance for this context. */ /** Get the JavacProcessingEnvironment instance for this context. */
public static JavacProcessingEnvironment instance(Context context) { public static JavacProcessingEnvironment instance(Context context) {
JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class); JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
@ -236,6 +241,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
enter = Enter.instance(context); enter = Enter.instance(context);
initialCompleter = ClassFinder.instance(context).getCompleter(); initialCompleter = ClassFinder.instance(context).getCompleter();
chk = Check.instance(context); chk = Check.instance(context);
preview = Preview.instance(context);
initProcessorLoader(); initProcessorLoader();
} }
@ -1675,6 +1681,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return messages.getCurrentLocale(); return messages.getCurrentLocale();
} }
@DefinedBy(Api.ANNOTATION_PROCESSING)
public boolean isPreviewEnabled() {
return preview.isEnabled();
}
public Set<Symbol.PackageSymbol> getSpecifiedPackages() { public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
return specifiedPackages; return specifiedPackages;
} }

View file

@ -89,7 +89,7 @@ import java.util.Objects;
* .withNamespace(StandardNamespace.PROPERTY) * .withNamespace(StandardNamespace.PROPERTY)
* .named("color"); * .named("color");
* </pre> * </pre>
* <h3>Operations on multiple namespaces</h3> * <h2>Operations on multiple namespaces</h2>
* If multiple namespaces are specified, the namespaces are treated as * If multiple namespaces are specified, the namespaces are treated as
* alternatives to each other in order of preference. The semantics of * alternatives to each other in order of preference. The semantics of
* such operation is "first applicable". * such operation is "first applicable".

View file

@ -1,253 +0,0 @@
/*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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.javadoc.internal.doclets.formats.html;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
/**
* Abstract class to generate the module overview files.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @author Bhavesh Patel
*/
public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
/**
* Modules to be documented.
*/
protected SortedMap<ModuleElement, Set<PackageElement>> modules;
protected Navigation navBar;
/**
* Constructor. Also initializes the modules variable.
*
* @param configuration The current configuration
* @param filename Name of the module index file to be generated.
*/
public AbstractModuleIndexWriter(HtmlConfiguration configuration,
DocPath filename) {
super(configuration, filename);
modules = configuration.modulePackages;
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.OVERVIEW, path);
}
/**
* Adds the navigation bar header to the documentation tree.
*
* @param header the document tree to which the navigation bar header will be added
*/
protected abstract void addNavigationBarHeader(Content header);
/**
* Adds the navigation bar footer to the documentation tree.
*
* @param footer the document tree to which the navigation bar footer will be added
*/
protected abstract void addNavigationBarFooter(Content footer);
/**
* Adds the overview header to the documentation tree.
*
* @param main the document tree to which the overview header will be added
*/
protected abstract void addOverviewHeader(Content main);
/**
* Adds the modules list to the documentation tree.
*
* @param main the document tree to which the modules list will be added
*/
protected abstract void addModulesList(Content main);
/**
* Adds the module packages list to the documentation tree.
*
* @param modules the set of modules
* @param text caption for the table
* @param tableSummary summary for the table
* @param main the document tree to which the modules list will be added
* @param mdle the module being documented
*/
protected abstract void addModulePackagesList(Map<ModuleElement, Set<PackageElement>> modules, String text,
String tableSummary, Content main, ModuleElement mdle);
/**
* Generate and prints the contents in the module index file.
*
* @param title the title of the window
* @param description the content for the description META tag
* @throws DocFileIOException if there is a problem building the module index file
*/
protected void buildModuleIndexFile(String title, String description)
throws DocFileIOException {
String windowOverview = resources.getText(title);
Content body = getBody(getWindowTitle(windowOverview));
Content header = HtmlTree.HEADER();
addNavigationBarHeader(header);
Content main = HtmlTree.MAIN();
addOverviewHeader(main);
addIndex(header, main);
addOverview(main);
Content footer = HtmlTree.FOOTER();
addNavigationBarFooter(footer);
body.add(header);
body.add(main);
body.add(footer);
printHtmlDocument(
configuration.metakeywords.getOverviewMetaKeywords(title, configuration.doctitle),
description,
body);
}
/**
* Generate and prints the contents in the module packages index file.
*
* @param title the title of the window.
* @param description the content for the description META tag
* @param mdle the name of the module being documented
* @throws DocFileIOException if there is an exception building the module packages index file
*/
protected void buildModulePackagesIndexFile(String title, String description,
ModuleElement mdle) throws DocFileIOException {
String windowOverview = resources.getText(title);
Content body = getBody(getWindowTitle(windowOverview));
Content header = HtmlTree.HEADER();
addNavigationBarHeader(header);
Content main = HtmlTree.MAIN();
addOverviewHeader(main);
addModulePackagesIndex(header, main, mdle);
addOverview(main);
Content footer = HtmlTree.FOOTER();
addNavigationBarFooter(footer);
body.add(header);
body.add(main);
body.add(footer);
printHtmlDocument(
configuration.metakeywords.getOverviewMetaKeywords(title, configuration.doctitle),
description,
body);
}
/**
* Default to no overview, override to add overview.
*
* @param main the document tree to which the overview will be added
*/
protected void addOverview(Content main) { }
/**
* Adds the module index to the documentation tree.
*
* @param header the document tree to which the navigational links will be added
* @param main the document tree to which the modules list will be added
*/
protected void addIndex(Content header, Content main) {
addIndexContents(configuration.modules, "doclet.Module_Summary",
resources.getText("doclet.Member_Table_Summary",
resources.getText("doclet.Module_Summary"),
resources.getText("doclet.modules")), header, main);
}
/**
* Adds the module packages index to the documentation tree.
*
* @param header the document tree to which the navigational links will be added
* @param main the document tree to which the module packages list will be added
* @param mdle the module being documented
*/
protected void addModulePackagesIndex(Content header, Content main, ModuleElement mdle) {
addModulePackagesIndexContents("doclet.Module_Summary",
resources.getText("doclet.Member_Table_Summary",
resources.getText("doclet.Module_Summary"),
resources.getText("doclet.modules")), header, main, mdle);
}
/**
* Adds module index contents. Call appropriate methods from
* the sub-classes. Adds it to the body HtmlTree
*
* @param modules the modules to be documented
* @param text string which will be used as the heading
* @param tableSummary summary for the table
* @param header the document tree to which the navigational links will be added
* @param main the document tree to which the modules list will be added
*/
protected void addIndexContents(Collection<ModuleElement> modules, String text,
String tableSummary, Content header, Content main) {
addModulesList(main);
}
/**
* Adds module packages index contents. Call appropriate methods from
* the sub-classes. Adds it to the body HtmlTree
*
* @param text string which will be used as the heading
* @param tableSummary summary for the table
* @param header the document tree to which the navigational links will be added
* @param main the document tree to which the module packages list will be added
* @param mdle the module being documented
*/
protected void addModulePackagesIndexContents(String text,
String tableSummary, Content header, Content main, ModuleElement mdle) {
addModulePackagesList(modules, text, tableSummary, main, mdle);
}
/**
* Adds the doctitle to the documentation tree, if it is specified on the command line.
*
* @param body the document tree to which the title will be added
*/
protected void addConfigurationTitle(Content body) {
if (configuration.doctitle.length() > 0) {
Content title = new RawHtml(configuration.doctitle);
Content heading = HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING,
HtmlStyle.title, title);
Content div = HtmlTree.DIV(HtmlStyle.header, heading);
body.add(div);
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,10 +25,6 @@
package jdk.javadoc.internal.doclets.formats.html; package jdk.javadoc.internal.doclets.formats.html;
import java.util.*;
import javax.lang.model.element.PackageElement;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
@ -40,75 +36,93 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
/** /**
* Abstract class to generate the overview files. This will be sub-classed to * Abstract class to generate the overview files.
* generate overview-summary.html.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk. * If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or * This code and its internal interfaces are subject to change or
* deletion without notice.</b> * deletion without notice.</b>
* *
* @author Atul M Dambalkar
* @author Bhavesh Patel (Modified)
*/ */
public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter { public abstract class AbstractOverviewIndexWriter extends HtmlDocletWriter {
/**
* A Set of Packages to be documented.
*/
protected SortedSet<PackageElement> packages;
protected Navigation navBar; protected Navigation navBar;
/** /**
* Constructor. Also initializes the packages variable. * Constructs the AbstractOverviewIndexWriter.
* *
* @param configuration The current configuration * @param configuration The current configuration
* @param filename Name of the package index file to be generated. * @param filename Name of the module index file to be generated.
*/ */
public AbstractPackageIndexWriter(HtmlConfiguration configuration, public AbstractOverviewIndexWriter(HtmlConfiguration configuration,
DocPath filename) { DocPath filename) {
super(configuration, filename); super(configuration, filename);
packages = configuration.packages;
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.OVERVIEW, path); this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.OVERVIEW, path);
} }
/** /**
* Adds the navigation bar header to the documentation tree. * Adds the top text (from the -top option), the upper
* navigation bar, and then the title (from the"-title"
* option), at the top of page.
* *
* @param header the document tree to which the navigation bar header will be added * @param header the documentation tree to which the navigation bar header will be added
*/ */
protected abstract void addNavigationBarHeader(Content header); protected void addNavigationBarHeader(Content header) {
addTop(header);
navBar.setUserHeader(getUserHeaderFooter(true));
header.add(navBar.getContent(true));
}
/** /**
* Adds the navigation bar footer to the documentation tree. * Adds the lower navigation bar and the bottom text
* (from the -bottom option) at the bottom of page.
* *
* @param body the document tree to which the navigation bar footer will be added * @param footer the documentation tree to which the navigation bar footer will be added
*/ */
protected abstract void addNavigationBarFooter(Content body); protected void addNavigationBarFooter(Content footer) {
navBar.setUserFooter(getUserHeaderFooter(false));
footer.add(navBar.getContent(false));
addBottom(footer);
}
/** /**
* Adds the overview header to the documentation tree. * Adds the overview summary comment for this documentation. Add one line
* summary at the top of the page and generate a link to the description,
* which is added at the end of this page.
* *
* @param footer the document tree to which the overview header will be added * @param main the documentation tree to which the overview header will be added
*/ */
protected abstract void addOverviewHeader(Content footer); protected void addOverviewHeader(Content main) {
addConfigurationTitle(main);
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.setStyle(HtmlStyle.contentContainer);
addOverviewComment(div);
main.add(div);
}
}
/** /**
* Adds the packages list to the documentation tree. * Adds the overview comment as provided in the file specified by the
* "-overview" option on the command line.
* *
* @param main the document tree to which the packages list will be added * @param htmltree the documentation tree to which the overview comment will
* be added
*/ */
protected abstract void addPackagesList(Content main); protected void addOverviewComment(Content htmltree) {
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
addInlineComment(configuration.overviewElement, htmltree);
}
}
/** /**
* Generate and prints the contents in the package index file. * Generate and prints the contents in the index file.
* *
* @param title the title of the window * @param title the title of the window
* @param description the content for the description META tag * @param description the content for the description META tag
* @throws DocFileIOException if there is a problem building the package index file * @throws DocFileIOException if there is a problem building the package index file
*/ */
protected void buildPackageIndexFile(String title, String description) protected void buildOverviewIndexFile(String title, String description)
throws DocFileIOException { throws DocFileIOException {
String windowOverview = resources.getText(title); String windowOverview = resources.getText(title);
Content body = getBody(getWindowTitle(windowOverview)); Content body = getBody(getWindowTitle(windowOverview));
@ -116,8 +130,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
addNavigationBarHeader(header); addNavigationBarHeader(header);
Content main = HtmlTree.MAIN(); Content main = HtmlTree.MAIN();
addOverviewHeader(main); addOverviewHeader(main);
addIndex(header, main); addIndex(main);
addOverview(main);
Content footer = HtmlTree.FOOTER(); Content footer = HtmlTree.FOOTER();
addNavigationBarFooter(footer); addNavigationBarFooter(footer);
body.add(header); body.add(header);
@ -129,43 +142,11 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
} }
/** /**
* Default to no overview, override to add overview. * Adds the index to the documentation tree.
* *
* @param main the document tree to which the overview will be added * @param main the document tree to which the packages/modules list will be added
*/ */
protected void addOverview(Content main) { } protected abstract void addIndex(Content main);
/**
* Adds the package index to the documentation tree.
*
* @param header the document tree to which the navigation links will be added
* @param main the document tree to which the packages list will be added
*/
protected void addIndex(Content header, Content main) {
addIndexContents(header, main);
}
/**
* Adds package index contents. Call appropriate methods from
* the sub-classes. Adds it to the body HtmlTree
*
* @param header the document tree to which navigation links will be added
* @param main the document tree to which the packages list will be added
*/
protected void addIndexContents(Content header, Content main) {
if (!packages.isEmpty()) {
HtmlTree htmlTree = HtmlTree.NAV();
htmlTree.setStyle(HtmlStyle.indexNav);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
addAllClassesLink(ul);
if (configuration.showModules && configuration.modules.size() > 1) {
addAllModulesLink(ul);
}
htmlTree.add(ul);
header.add(htmlTree);
addPackagesList(main);
}
}
/** /**
* Adds the doctitle to the documentation tree, if it is specified on the command line. * Adds the doctitle to the documentation tree, if it is specified on the command line.
@ -181,20 +162,4 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
body.add(div); body.add(div);
} }
} }
/**
* Do nothing. This will be overridden.
*
* @param div the document tree to which the all classes link will be added
*/
protected void addAllClassesLink(Content div) {
}
/**
* Do nothing. This will be overridden.
*
* @param div the document tree to which the all modules link will be added
*/
protected void addAllModulesLink(Content div) {
}
} }

View file

@ -53,15 +53,22 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
* *
* @author Bhavesh Patel * @author Bhavesh Patel
*/ */
public class ModuleIndexWriter extends AbstractModuleIndexWriter { public class ModuleIndexWriter extends AbstractOverviewIndexWriter {
/**
* Modules to be documented.
*/
protected SortedSet<ModuleElement> modules;
/** /**
* Construct the ModuleIndexWriter. * Construct the ModuleIndexWriter.
*
* @param configuration the configuration object * @param configuration the configuration object
* @param filename the name of the generated file * @param filename the name of the generated file
*/ */
public ModuleIndexWriter(HtmlConfiguration configuration, DocPath filename) { public ModuleIndexWriter(HtmlConfiguration configuration, DocPath filename) {
super(configuration, filename); super(configuration, filename);
modules = configuration.modules;
} }
/** /**
@ -73,46 +80,23 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
public static void generate(HtmlConfiguration configuration) throws DocFileIOException { public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
DocPath filename = DocPaths.INDEX; DocPath filename = DocPaths.INDEX;
ModuleIndexWriter mdlgen = new ModuleIndexWriter(configuration, filename); ModuleIndexWriter mdlgen = new ModuleIndexWriter(configuration, filename);
mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", "module index"); mdlgen.buildOverviewIndexFile("doclet.Window_Overview_Summary", "module index");
} }
/** /**
* Add the module index. * Adds the list of modules.
* *
* @param header the documentation tree to which the navigational links will be added
* @param main the documentation tree to which the modules list will be added * @param main the documentation tree to which the modules list will be added
*/ */
@Override @Override
protected void addIndex(Content header, Content main) { protected void addIndex(Content main) {
addIndexContents(header, main);
}
/**
* Adds module index contents.
*
* @param header the document tree to which the navigational links will be added
* @param main the document tree to which the modules list will be added
*/
protected void addIndexContents(Content header, Content main) {
addModulesList(main);
}
/**
* Add the list of modules.
*
* @param main the content tree to which the module list will be added
*/
@Override
protected void addModulesList(Content main) {
Map<String, SortedSet<ModuleElement>> groupModuleMap Map<String, SortedSet<ModuleElement>> groupModuleMap
= configuration.group.groupModules(configuration.modules); = configuration.group.groupModules(modules);
if (!groupModuleMap.keySet().isEmpty()) { if (!groupModuleMap.keySet().isEmpty()) {
String tableSummary = resources.getText("doclet.Member_Table_Summary", TableHeader tableHeader = new TableHeader(contents.moduleLabel, contents.descriptionLabel);
resources.getText("doclet.Module_Summary"), resources.getText("doclet.modules"));
TableHeader header = new TableHeader(contents.moduleLabel, contents.descriptionLabel);
Table table = new Table(HtmlStyle.overviewSummary) Table table = new Table(HtmlStyle.overviewSummary)
.setHeader(header) .setHeader(tableHeader)
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast) .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast)
.setDefaultTab(resources.getText("doclet.All_Modules")) .setDefaultTab(resources.getText("doclet.All_Modules"))
.setTabScript(i -> "show(" + i + ");") .setTabScript(i -> "show(" + i + ");")
@ -126,7 +110,7 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
} }
} }
for (ModuleElement mdle : configuration.modules) { for (ModuleElement mdle : modules) {
if (!mdle.isUnnamed()) { if (!mdle.isUnnamed()) {
if (!(configuration.nodeprecated && utils.isDeprecated(mdle))) { if (!(configuration.nodeprecated && utils.isDeprecated(mdle))) {
Content moduleLinkContent = getModuleLink(mdle, new StringContent(mdle.getQualifiedName().toString())); Content moduleLinkContent = getModuleLink(mdle, new StringContent(mdle.getQualifiedName().toString()));
@ -145,67 +129,4 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
} }
} }
} }
/**
* Adds the overview summary comment for this documentation. Add one line
* summary at the top of the page and generate a link to the description,
* which is added at the end of this page.
*
* @param main the documentation tree to which the overview header will be added
*/
@Override
protected void addOverviewHeader(Content main) {
addConfigurationTitle(main);
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.setStyle(HtmlStyle.contentContainer);
addOverviewComment(div);
main.add(div);
}
}
/**
* Adds the overview comment as provided in the file specified by the
* "-overview" option on the command line.
*
* @param htmltree the documentation tree to which the overview comment will
* be added
*/
protected void addOverviewComment(Content htmltree) {
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
addInlineComment(configuration.overviewElement, htmltree);
}
}
/**
* Adds the top text (from the -top option), the upper
* navigation bar, and then the title (from the"-title"
* option), at the top of page.
*
* @param header the documentation tree to which the navigation bar header will be added
*/
@Override
protected void addNavigationBarHeader(Content header) {
addTop(header);
navBar.setUserHeader(getUserHeaderFooter(true));
header.add(navBar.getContent(true));
}
/**
* Adds the lower navigation bar and the bottom text
* (from the -bottom option) at the bottom of page.
*
* @param footer the documentation tree to which the navigation bar footer will be added
*/
@Override
protected void addNavigationBarFooter(Content footer) {
navBar.setUserFooter(getUserHeaderFooter(false));
footer.add(navBar.getContent(false));
addBottom(footer);
}
@Override
protected void addModulePackagesList(Map<ModuleElement, Set<PackageElement>> modules, String text,
String tableSummary, Content main, ModuleElement mdle) {
}
} }

View file

@ -52,7 +52,12 @@ import jdk.javadoc.internal.doclets.toolkit.util.Group;
* @author Atul M Dambalkar * @author Atul M Dambalkar
* @author Bhavesh Patel (Modified) * @author Bhavesh Patel (Modified)
*/ */
public class PackageIndexWriter extends AbstractPackageIndexWriter { public class PackageIndexWriter extends AbstractOverviewIndexWriter {
/**
* A Set of Packages to be documented.
*/
protected SortedSet<PackageElement> packages;
/** /**
* Construct the PackageIndexWriter. Also constructs the grouping * Construct the PackageIndexWriter. Also constructs the grouping
@ -65,6 +70,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
*/ */
public PackageIndexWriter(HtmlConfiguration configuration, DocPath filename) { public PackageIndexWriter(HtmlConfiguration configuration, DocPath filename) {
super(configuration, filename); super(configuration, filename);
packages = configuration.packages;
} }
/** /**
@ -76,26 +82,16 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
public static void generate(HtmlConfiguration configuration) throws DocFileIOException { public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
DocPath filename = DocPaths.INDEX; DocPath filename = DocPaths.INDEX;
PackageIndexWriter packgen = new PackageIndexWriter(configuration, filename); PackageIndexWriter packgen = new PackageIndexWriter(configuration, filename);
packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", "package index"); packgen.buildOverviewIndexFile("doclet.Window_Overview_Summary", "package index");
} }
/** /**
* Depending upon the grouping information and their titles, add * Adds the packages list to the documentation tree.
* separate table indices for each package group.
* *
* @param header the documentation tree to which the navigational links will be added
* @param main the documentation tree to which the packages list will be added * @param main the documentation tree to which the packages list will be added
*/ */
@Override @Override
protected void addIndex(Content header, Content main) { protected void addIndex(Content main) {
addIndexContents(header, main);
}
/**
* {@inheritDoc}
*/
@Override
protected void addPackagesList(Content main) {
Map<String, SortedSet<PackageElement>> groupPackageMap Map<String, SortedSet<PackageElement>> groupPackageMap
= configuration.group.groupPackages(packages); = configuration.group.groupPackages(packages);
@ -134,62 +130,4 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
} }
} }
} }
/**
* Adds the overview summary comment for this documentation. Add one line
* summary at the top of the page and generate a link to the description,
* which is added at the end of this page.
*
* @param main the documentation tree to which the overview header will be added
*/
@Override
protected void addOverviewHeader(Content main) {
addConfigurationTitle(main);
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.setStyle(HtmlStyle.contentContainer);
addOverviewComment(div);
main.add(div);
}
}
/**
* Adds the overview comment as provided in the file specified by the
* "-overview" option on the command line.
*
* @param htmltree the documentation tree to which the overview comment will
* be added
*/
protected void addOverviewComment(Content htmltree) {
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
addInlineComment(configuration.overviewElement, htmltree);
}
}
/**
* Adds the top text (from the -top option), the upper
* navigation bar, and then the title (from the"-title"
* option), at the top of page.
*
* @param header the documentation tree to which the navigation bar header will be added
*/
@Override
protected void addNavigationBarHeader(Content header) {
addTop(header);
navBar.setUserHeader(getUserHeaderFooter(true));
header.add(navBar.getContent(true));
}
/**
* Adds the lower navigation bar and the bottom text
* (from the -bottom option) at the bottom of page.
*
* @param footer the documentation tree to which the navigation bar footer will be added
*/
@Override
protected void addNavigationBarFooter(Content footer) {
navBar.setUserFooter(getUserHeaderFooter(false));
footer.add(navBar.getContent(false));
addBottom(footer);
}
} }

View file

@ -98,7 +98,6 @@ doclet.Concealed_Packages_Summary=Concealed
doclet.From=From doclet.From=From
doclet.Uses_Summary=Uses doclet.Uses_Summary=Uses
doclet.Provides_Summary=Provides doclet.Provides_Summary=Provides
doclet.Module_Summary=Module Summary
doclet.Interface_Summary=Interface Summary doclet.Interface_Summary=Interface Summary
doclet.Annotation_Types_Summary=Annotation Types Summary doclet.Annotation_Types_Summary=Annotation Types Summary
doclet.Enum_Summary=Enum Summary doclet.Enum_Summary=Enum Summary

View file

@ -100,7 +100,7 @@ public class DocPaths {
public static final DocPath JAVASCRIPT = DocPath.create("script.js"); public static final DocPath JAVASCRIPT = DocPath.create("script.js");
/** The name of the directory for the jQuery. */ /** The name of the directory for the jQuery. */
public static final DocPath JQUERY_FILES = DocPath.create("jquery"); public static final DocPath JQUERY_FILES = DocPath.create("script-dir");
/** The name of the default jQuery stylesheet file. */ /** The name of the default jQuery stylesheet file. */
public static final DocPath JQUERY_STYLESHEET_FILE = DocPath.create("jquery-ui.css"); public static final DocPath JQUERY_STYLESHEET_FILE = DocPath.create("jquery-ui.css");

View file

@ -39,11 +39,11 @@ package jdk.nashorn.internal.runtime.linker;
* to nashorn module. * to nashorn module.
* </p> * </p>
* *
* <h3>Comment from BytecodeName class reproduced here:</h3> * <h2>Comment from BytecodeName class reproduced here:</h2>
* *
* Includes universal mangling rules for the JVM. * Includes universal mangling rules for the JVM.
* *
* <h3>Avoiding Dangerous Characters </h3> * <h2>Avoiding Dangerous Characters </h2>
* *
* <p> * <p>
* The JVM defines a very small set of characters which are illegal * The JVM defines a very small set of characters which are illegal
@ -74,7 +74,7 @@ package jdk.nashorn.internal.runtime.linker;
* but traditional in the proposed role. * but traditional in the proposed role.
* *
* </p> * </p>
* <h3> Replacement Characters </h3> * <h2> Replacement Characters </h2>
* *
* *
* <p> * <p>
@ -159,7 +159,7 @@ package jdk.nashorn.internal.runtime.linker;
* to check for dangerous characters. * to check for dangerous characters.
* *
* </p> * </p>
* <h3> Nice Properties </h3> * <h2> Nice Properties </h2>
* *
* <p> * <p>
* If a bytecode name does not contain any escape sequence, * If a bytecode name does not contain any escape sequence,
@ -222,7 +222,7 @@ package jdk.nashorn.internal.runtime.linker;
* </ul> * </ul>
* *
* *
* <h3> Suggestions for Human Readable Presentations </h3> * <h2> Suggestions for Human Readable Presentations </h2>
* *
* *
* <p> * <p>

View file

@ -30,7 +30,7 @@
* Nashorn is a runtime environment for programs written in ECMAScript 5.1. * Nashorn is a runtime environment for programs written in ECMAScript 5.1.
* </p> * </p>
* *
* <h1>Usage</h1> * <h2>Usage</h2>
* *
* The recommended way to use Nashorn is through the * The recommended way to use Nashorn is through the
* <a href="http://jcp.org/en/jsr/detail?id=223" target="_top">JSR-223 * <a href="http://jcp.org/en/jsr/detail?id=223" target="_top">JSR-223
@ -45,7 +45,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* *
* and then use it just as you would any other JSR-223 script engine. See * and then use it just as you would any other JSR-223 script engine. See
* {@link jdk.nashorn.api.scripting} package for details. * {@link jdk.nashorn.api.scripting} package for details.
* <h1>Compatibility</h1> * <h2>Compatibility</h2>
* Nashorn is 100% compliant with the * Nashorn is 100% compliant with the
* <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" * <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"
* target="_top">ECMA-262 Standard, Edition 5.1</a>. * target="_top">ECMA-262 Standard, Edition 5.1</a>.
@ -55,7 +55,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* specification (often referred to as "invokedynamic"), as well as * specification (often referred to as "invokedynamic"), as well as
* the already mentioned JSR-223. * the already mentioned JSR-223.
* *
* <h1>Interoperability with the Java platform</h1> * <h2>Interoperability with the Java platform</h2>
* *
* In addition to being a 100% ECMAScript 5.1 runtime, Nashorn provides features * In addition to being a 100% ECMAScript 5.1 runtime, Nashorn provides features
* for interoperability of the ECMAScript programs with the Java platform. * for interoperability of the ECMAScript programs with the Java platform.
@ -68,7 +68,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* their properties. In most cases, though, you can't add arbitrary properties * their properties. In most cases, though, you can't add arbitrary properties
* to them, nor can you remove existing properties. * to them, nor can you remove existing properties.
* *
* <h2>Java collection handling</h2> * <h3>Java collection handling</h3>
* *
* Native Java arrays and {@link java.util.List}s support indexed access to * Native Java arrays and {@link java.util.List}s support indexed access to
* their elements through the property accessors, and {@link java.util.Map}s * their elements through the property accessors, and {@link java.util.Map}s
@ -79,7 +79,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* operator gives precedence to map elements. Native Java arrays expose * operator gives precedence to map elements. Native Java arrays expose
* the {@code length} property. * the {@code length} property.
* *
* <h2>ECMAScript primitive types</h2> * <h3>ECMAScript primitive types</h3>
* *
* ECMAScript primitive types for number, string, and boolean are represented * ECMAScript primitive types for number, string, and boolean are represented
* with {@link java.lang.Number}, {@link java.lang.CharSequence}, and * with {@link java.lang.Number}, {@link java.lang.CharSequence}, and
@ -89,7 +89,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* cause other subclasses of {@code Number} and internal implementations of * cause other subclasses of {@code Number} and internal implementations of
* {@code CharSequence} to be used. * {@code CharSequence} to be used.
* *
* <h2>Type conversions</h2> * <h3>Type conversions</h3>
* *
* When a method on a Java object is invoked, the arguments are converted to * When a method on a Java object is invoked, the arguments are converted to
* the formal parameter types of the Java method using all allowed ECMAScript * the formal parameter types of the Java method using all allowed ECMAScript
@ -106,7 +106,7 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* {@code java.lang.Double}), then Nashorn will of course ensure * {@code java.lang.Double}), then Nashorn will of course ensure
* the required type is passed. * the required type is passed.
* *
* <h2>SAM types</h2> * <h3>SAM types</h3>
* *
* As a special extension when invoking Java methods, ECMAScript function * As a special extension when invoking Java methods, ECMAScript function
* objects can be passed in place of an argument whose Java type is so-called * objects can be passed in place of an argument whose Java type is so-called
@ -122,14 +122,14 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
* the same name</em>. This is done to be consistent with the fact that * the same name</em>. This is done to be consistent with the fact that
* ECMAScript does not have the concept of overloaded methods. * ECMAScript does not have the concept of overloaded methods.
* *
* <h2>The {@code Java} object</h2> * <h3>The {@code Java} object</h3>
* *
* Nashorn exposes a non-standard global object named {@code Java} that is * Nashorn exposes a non-standard global object named {@code Java} that is
* the primary API entry point into Java platform-specific functionality. * the primary API entry point into Java platform-specific functionality.
* You can use it to create instances of Java classes, convert from Java arrays * You can use it to create instances of Java classes, convert from Java arrays
* to native arrays and back, and so on. * to native arrays and back, and so on.
* *
* <h2>Other non-standard built-in objects</h2> * <h3>Other non-standard built-in objects</h3>
* *
* In addition to {@code Java}, Nashorn also exposes some other * In addition to {@code Java}, Nashorn also exposes some other
* non-standard built-in objects: * non-standard built-in objects:

View file

@ -0,0 +1,163 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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.
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.file.Paths;
import java.util.List;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile;
import jdk.test.lib.process.OutputAnalyzer;
// This class is intended to run inside a container
public class JfrNetwork {
// use a unique hostname for container
public static final String HOST_NAME = "container-unique-8221711";
public static final String JFR_REPORTED_CONTAINER_HOSTNAME_TAG = "jfr_reported_container_hostname=";
public static void main(String[] args) throws Exception {
String event = args[0];
try (ServerSocket ss = new ServerSocket()) {
testNetworkInfo(ss, event);
}
}
private static void assertTrue(boolean expr, String msg) {
if (!expr) {
throw new RuntimeException(msg);
}
}
private static void testNetworkInfo(ServerSocket ss, String event) throws Exception {
ServerSocketListener server = new ServerSocketListener(ss);
server.start();
SocketWriter writer = new SocketWriter(ss.getLocalSocketAddress());
// setup and start the recording
String recordingPath = event + ".jfr";
log("========= Recording event: " + event);
Recording r = new Recording();
r.enable(event);
r.setDestination(Paths.get("/", "tmp", recordingPath));
r.start();
// start the socker writer thread, write some data into the socket
writer.start();
// wait for writer thread to terminate, then for server thread, then stop recording
writer.joinAndThrow();
server.joinAndThrow();
r.stop();
// analyze the recording
List<RecordedEvent> events = RecordingFile.readAllEvents(r.getDestination());
events.forEach(e -> log ("event = " + e));
assertTrue(!events.isEmpty(), "No recorded network events");
RecordedEvent e = events.get(0);
log(JFR_REPORTED_CONTAINER_HOSTNAME_TAG + e.getString("host"));
verifyIpAddress(e.getString("address"));
}
private static void verifyIpAddress(String eventIp) throws Exception {
ProcessBuilder pb = new ProcessBuilder("hostname", "--ip-address");
OutputAnalyzer out = new OutputAnalyzer(pb.start());
out.shouldHaveExitValue(0);
log("hostname --ip-address returned: " + out.getOutput());
out.shouldContain(eventIp);
}
private static void log(String msg) {
System.out.println(msg);
}
private static class ServerSocketListener extends Thread {
Exception exception;
ServerSocket ss;
ServerSocketListener(ServerSocket socket) throws Exception {
ss = socket;
ss.setReuseAddress(true);
ss.bind(null);
log("ServerSocker Local Address: " + ss.getLocalSocketAddress());
}
public void joinAndThrow() throws Exception {
join();
if (exception != null) {
throw exception;
}
}
public void run() {
try {
try (Socket s = ss.accept(); InputStream is = s.getInputStream()) {
System.out.println("ServerSocketListener: accepted socket connection: s = " + s);
is.read();
is.read();
is.read();
}
} catch (Exception e) {
exception = e;
}
}
}
private static class SocketWriter extends Thread {
Exception exception;
private SocketAddress ssAddr;
public SocketWriter(SocketAddress sa) {
this.ssAddr = sa;
System.out.println("SocketWriter(): sa = " + sa);
}
public void joinAndThrow() throws Exception {
join();
if (exception != null) {
throw exception;
}
}
public void run() {
try (Socket s = new Socket()) {
s.connect(ssAddr);
try (OutputStream os = s.getOutputStream()) {
os.write('A');
os.write('B');
os.write('C');
}
} catch (Exception e) {
exception = e;
}
}
}
}

View file

@ -22,53 +22,30 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import jdk.jfr.Recording; import jdk.jfr.Recording;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile; import jdk.jfr.consumer.RecordingFile;
// This class is intended to run inside a container // This class is intended to run inside a container
public class JfrReporter { public class JfrReporter {
public static final String TEST_REPORTED_CORES="TEST_REPORTED_CORES";
public static final String TEST_REPORTED_MEMORY="TEST_REPORTED_MEMORY";
public static final String TEST_REPORTED_PID="TEST_REPORTED_PID";
public static final String TESTCASE_CPU="cpu";
public static final String TESTCASE_MEMORY="memory";
public static final String TESTCASE_PROCESS="process";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String testCase = args[0]; String eventName = args[0];
System.out.println("Testcase: " + testCase); try(Recording r = new Recording()) {
switch (testCase) { r.enable(eventName);
case TESTCASE_CPU:
RecordedEvent event = testEvent("jdk.CPUInformation", "cpu.jfr");
System.out.println(TEST_REPORTED_CORES + "=" + event.getInt("cores"));
break;
case TESTCASE_MEMORY:
event = testEvent("jdk.PhysicalMemory", "memory.jfr");
System.out.println(TEST_REPORTED_MEMORY + "=" + event.getLong("totalSize"));
break;
case TESTCASE_PROCESS:
event = testEvent("jdk.SystemProcess", "process.jfr");
System.out.println(TEST_REPORTED_PID + "=" + event.getString("pid"));
break;
default:
throw new IllegalArgumentException("Invalid test case");
}
}
private static RecordedEvent testEvent(String event, String recordingPath) throws Exception {
System.out.println("========= Testing event: " + event);
Recording r = new Recording();
r.enable(event);
r.setDestination(Paths.get("tmp", recordingPath));
r.start(); r.start();
r.stop(); r.stop();
Path p = Paths.get("/", "tmp", eventName + ".jfr");
r.dump(p);
for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
System.out.println("===== EventType: " + e.getEventType().getName());
for (ValueDescriptor v : e.getEventType().getFields()) {
System.out.println(v.getName() + " = " + e.getValue(v.getName()));
}
}
}
}
}
RecordedEvent recordedEvent = RecordingFile.readAllEvents(r.getDestination()).get(0);
System.out.println("RecordedEvent: " + recordedEvent);
return recordedEvent;
}
}

View file

@ -39,6 +39,8 @@
import jdk.test.lib.containers.docker.Common; import jdk.test.lib.containers.docker.Common;
import jdk.test.lib.containers.docker.DockerRunOptions; import jdk.test.lib.containers.docker.DockerRunOptions;
import jdk.test.lib.containers.docker.DockerTestUtils; import jdk.test.lib.containers.docker.DockerTestUtils;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.Utils; import jdk.test.lib.Utils;
@ -68,6 +70,7 @@ public class TestJFREvents {
testProcessInfo(); testProcessInfo();
testEnvironmentVariables();
} finally { } finally {
DockerTestUtils.removeDockerImage(imageName); DockerTestUtils.removeDockerImage(imageName);
} }
@ -79,14 +82,12 @@ public class TestJFREvents {
DockerTestUtils.dockerRunJava( DockerTestUtils.dockerRunJava(
commonDockerOpts() commonDockerOpts()
.addDockerOpts("--cpus=" + valueToSet) .addDockerOpts("--cpus=" + valueToSet)
.addClassOptions(JfrReporter.TESTCASE_CPU)) .addClassOptions("jdk.CPUInformation"))
.shouldHaveExitValue(0) .shouldHaveExitValue(0);
.shouldContain(JfrReporter.TEST_REPORTED_CORES);
// The following assertion is currently disabled due to JFR reporting incorrect values. // The following assertion is currently disabled due to JFR reporting incorrect values.
// JFR reports values for the host system as opposed to values for the container. // JFR reports values for the host system as opposed to values for the container.
// @ignore 8219999 // @ignore 8219999
// .shouldContain(JfrReporter.TEST_REPORTED_CORES + "=" + expectedValue); // .shouldContain("cores = " + expectedValue");
} }
@ -95,9 +96,9 @@ public class TestJFREvents {
DockerTestUtils.dockerRunJava( DockerTestUtils.dockerRunJava(
commonDockerOpts() commonDockerOpts()
.addDockerOpts("--memory=" + valueToSet) .addDockerOpts("--memory=" + valueToSet)
.addClassOptions(JfrReporter.TESTCASE_MEMORY)) .addClassOptions("jdk.PhysicalMemory"))
.shouldHaveExitValue(0) .shouldHaveExitValue(0)
.shouldContain(JfrReporter.TEST_REPORTED_MEMORY + "=" + expectedValue); .shouldContain("totalSize = " + expectedValue);
} }
@ -105,10 +106,9 @@ public class TestJFREvents {
Common.logNewTestCase("ProcessInfo"); Common.logNewTestCase("ProcessInfo");
DockerTestUtils.dockerRunJava( DockerTestUtils.dockerRunJava(
commonDockerOpts() commonDockerOpts()
.addClassOptions(JfrReporter.TESTCASE_PROCESS)) .addClassOptions("jdk.SystemProcess"))
.shouldHaveExitValue(0) .shouldHaveExitValue(0)
.shouldContain(JfrReporter.TEST_REPORTED_PID + "=1"); .shouldContain("pid = 1");
} }
@ -117,4 +117,28 @@ public class TestJFREvents {
.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/") .addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
.addJavaOpts("-cp", "/test-classes/"); .addJavaOpts("-cp", "/test-classes/");
} }
// JTReg always defines the environment variable JAVA_MAIN_CLASS_<SOME_NUMBER>.
// This variable fits well for use in this test, since it is rather unique.
private static String getTestEnvironmentVariable() throws Exception {
for (String key : System.getenv().keySet()) {
if (key.startsWith("JAVA_MAIN_CLASS")) {
return key;
}
}
throw new RuntimeException("JAVA_MAIN_CLASS_* is not defined");
}
private static void testEnvironmentVariables() throws Exception {
Common.logNewTestCase("EnvironmentVariables");
DockerTestUtils.dockerRunJava(
commonDockerOpts()
.addClassOptions("jdk.InitialEnvironmentVariable"))
.shouldHaveExitValue(0)
.shouldContain("key = JAVA_HOME")
.shouldNotContain(getTestEnvironmentVariable());
}
} }

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test JFR network related events inside a container; make sure
* the reported host ip and host name are correctly reported within
* the container.
* @requires docker.support
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* jdk.jartool/sun.tools.jar
* @build JfrNetwork
* @run driver TestJFRNetworkEvents
*/
import jdk.test.lib.containers.docker.Common;
import jdk.test.lib.containers.docker.DockerRunOptions;
import jdk.test.lib.containers.docker.DockerTestUtils;
import jdk.test.lib.Utils;
public class TestJFRNetworkEvents {
private static final String imageName = Common.imageName("jfr-network");
private static final int availableCPUs = Runtime.getRuntime().availableProcessors();
public static void main(String[] args) throws Exception {
System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);
if (!DockerTestUtils.canTestDocker()) {
return;
}
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
try {
runTest("jdk.SocketWrite");
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
}
private static void runTest(String event) throws Exception {
DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java", "JfrNetwork")
.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
.addJavaOpts("-cp", "/test-classes/")
.addDockerOpts("--hostname", JfrNetwork.HOST_NAME)
.addClassOptions(event);
DockerTestUtils.dockerRunJava(opts)
.shouldHaveExitValue(0)
.shouldContain(JfrNetwork.JFR_REPORTED_CONTAINER_HOSTNAME_TAG + JfrNetwork.HOST_NAME);
}
}

View file

@ -1,70 +0,0 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 4221448
* @summary Use explicit check for integer arithmetic exception on win32.
*/
public class ExplicitArithmeticCheck {
public static void main(String argv[]) throws Exception {
for (int i = 0; i < 64; i++) {
boolean result = false;
int n;
try {
n = 0 / 0;
} catch (ArithmeticException e) {
result = true;
}
if (result == false) {
throw new Error("Failed to throw correct exception!");
}
result = false;
try {
n = 0 % 0;
} catch (ArithmeticException e) {
result = true;
}
if (result == false) {
throw new Error("Failed to throw correct exception!");
}
try {
n = 0x80000000 / -1;
} catch (Throwable t) {
throw new Error("Failed to throw correct exception!");
}
if (n != 0x80000000) {
throw new Error("Incorrect integer arithmetic ! ");
}
try {
n = 0x80000000 % -1;
} catch (Throwable t) {
throw new Error("Failed to throw correct exception!");
}
if (n != 0) {
throw new Error("Incorrect integer arithmetic!");
}
}
}
}

View file

@ -1,186 +0,0 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 4087516
* @summary Incorrect locking leads to deadlock in monitorCacheMaybeExpand.
* @author Anand Palaniswamy
* @build MonitorCacheMaybeExpand_DeadLock
* @run main/othervm MonitorCacheMaybeExpand_DeadLock
*/
/**
* Background on the bug:
*
* The thread local monitor cache had a locking bug (till
* 1.2beta1) where two threads trying to expand the monitor cache
* at the same time would cause deadlock. The code paths that the
* two threads must be executing for this to happen is described
* in the bug report.
*
* Caveat and red-flag:
*
* Since deadlocks are very timing dependent, there is a good
* chance this test case will not catch the bug most of the time
* -- on your machine and setting, it is _possible_ that the two
* threads might not try a monitorCacheExpand at the same
* time. But in practice, on Solaris native threads, this program
* deadlocks the VM in about 2 seconds pretty consistently,
* whether MP or not.
*
* The rationale for running this test despite this rather large
* caveat is that at worst, it can do no harm.
*
* The idea:
*
* Is to create two monitor hungry threads.
*
* Originally Tom Rodriguez and I suspected that this weird state
* of two threads trying to expand monitor cache can happen only
* if:
*
* Thread 1: Is in the middle of a monitorCacheMaybeExpand.
* Thread 2: Runs GC and tries to freeClasses(). This causes
* sysFree() to be invoked, which in turn needs a
* mutex_lock -- and oops, we end up deadlocking
* with 1 on green_threads.
*
* Which is why this test tries to cause class GC at regular
* intervals.
*
* Turns out that the GC is not required. Two instances of the
* monitor hungry threads deadlock the VM pretty quick. :-) Infact
* the static initializer in the forName'd classes running
* alongside one of the hungry threads is sufficient to
* deadlock. Still keep the GC stuff just-in-case (and also
* because I wrote it :-).
*
*/
public class MonitorCacheMaybeExpand_DeadLock {
/**
* A monitor-hungry thread.
*/
static class LotsaMonitors extends Thread {
/** How many recursions? Could cause Java stack overflow. */
static final int MAX_DEPTH = 800;
/** What is our depth? */
int depth = 0;
/** Thread ID */
int tid;
/** So output will have thread number. */
public LotsaMonitors(int tid, int depth) {
super("LotsaMonitors #" + new Integer(tid).toString());
this.tid = tid;
this.depth = depth;
}
/** Start a recursion that grabs monitors. */
public void run() {
System.out.println(">>>Starting " + this.toString() + " ...");
Thread.currentThread().yield();
this.recurse();
System.out.println("<<<Finished " + this.toString());
}
/** Every call to this method grabs an extra monitor. */
synchronized void recurse() {
if (this.depth > 0) {
new LotsaMonitors(tid, depth-1).recurse();
}
}
}
/**
* The test.
*/
public static void main(String[] args) {
/* Start the two of these crazy threads. */
new LotsaMonitors(1, LotsaMonitors.MAX_DEPTH).start();
new LotsaMonitors(2, LotsaMonitors.MAX_DEPTH).start();
/* And sit there and GC for good measure. */
for (int i = 0; i < MAX_GC_ITERATIONS; i++) {
new LotsaMonitors(i+3, LotsaMonitors.MAX_DEPTH).start();
System.out.println(">>>Loading 10 classes and gc'ing ...");
Class[] classes = new Class[10];
fillClasses(classes);
classes = null;
System.gc();
Thread.currentThread().yield();
System.out.println("<<<Finished loading 10 classes and gc'ing");
}
}
/** How many times to GC? */
static final int MAX_GC_ITERATIONS = 10;
/** Load some classes into the array. */
static void fillClasses(Class[] classes) {
for (int i = 0; i < classes.length; i++) {
try {
classes[i] = Class.forName(classnames[i]);
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
}
/** Some random classes to load. */
private static String[] classnames = {
"java.text.DecimalFormat",
"java.text.MessageFormat",
"java.util.GregorianCalendar",
"java.util.ResourceBundle",
"java.text.Collator",
"java.util.Date",
"java.io.Reader",
"java.io.Writer",
"java.lang.IllegalAccessException",
"java.lang.InstantiationException",
"java.lang.ClassNotFoundException",
"java.lang.CloneNotSupportedException",
"java.lang.InterruptedException",
"java.lang.NoSuchFieldException",
"java.lang.NoSuchMethodException",
"java.lang.RuntimeException",
"java.lang.ArithmeticException",
"java.lang.ArrayStoreException",
"java.lang.ClassCastException",
"java.lang.StringIndexOutOfBoundsException",
"java.lang.NegativeArraySizeException",
"java.lang.IllegalStateException",
"java.lang.IllegalArgumentException",
"java.lang.NumberFormatException",
"java.lang.IllegalThreadStateException",
"java.lang.IllegalMonitorStateException",
"java.lang.SecurityException",
"java.lang.ExceptionInInitializerError"
};
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -186,6 +186,11 @@ public class TooSmallStackSize {
*/ */
checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, "513"); checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, "513");
/*
* Try with 0k which indicates that the default thread stack size from JVM will be used.
*/
checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, "0");
/* /*
* Now redo the same tests with the compiler thread stack size: * Now redo the same tests with the compiler thread stack size:
*/ */
@ -193,6 +198,7 @@ public class TooSmallStackSize {
min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "64"); min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "64");
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed); checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed);
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "513"); checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "513");
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "0");
/* /*
* Now redo the same tests with the VM thread stack size: * Now redo the same tests with the VM thread stack size:
@ -201,5 +207,6 @@ public class TooSmallStackSize {
min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "64"); min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "64");
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed); checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed);
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "513"); checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "513");
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "0");
} }
} }

View file

@ -1,127 +0,0 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 4169183
* @summary Check for correct inlining by the interpreter (widefp and strictfp).
* The default is widefp. A strictfp method was getting inlined
* into a widefp method.
*/
import java.io.PrintStream;
public class WideStrictInline {
static PrintStream out;
static float halfUlp;
static {
halfUlp = 1;
for ( int i = 127 - 24; i > 0; i-- )
halfUlp *= 2;
}
public static void main(String argv[]) throws Exception {
out = System.err;
pr(-1,"halfUlp",halfUlp);
WideStrictInline obj = new WideStrictInline();
for( int i=0; i<48; i++ )
obj.instanceMethod( i );
}
private static void pr(int i, String desc, float r) {
out.print(" i=("+i+") "+desc+" ; == "+r);
out.println(" , 0x"+Integer.toHexString(Float.floatToIntBits(r)));
}
private static strictfp float WideStrictInline(float par) {
return par;
}
public static strictfp float strictValue(int i) {
float r;
switch (i%4) {
case 0: r = -Float.MAX_VALUE; break;
case 1: r = Float.MAX_VALUE; break;
case 2: r = Float.MIN_VALUE; break;
default : r = 1L << 24;
}
return r;
}
void instanceMethod (int i) throws Exception {
float r;
switch (i%4) {
case 0:
if (!Float.isInfinite( WideStrictInline(strictValue(i)*2) +
Float.MAX_VALUE ))
{
pr(i,
"WideStrictInline(-Float.MAX_VALUE * 2) " +
"!= Float.NEGATIVE_INFINITY"
,WideStrictInline(strictValue(i)*2) + Float.MAX_VALUE);
}
r = WideStrictInline(strictValue(i)*2) + Float.MAX_VALUE;
if ( !Float.isInfinite( r ) ) {
pr(i,"r != Float.NEGATIVE_INFINITY",r);
throw new RuntimeException();
}
break;
case 1:
if (!Float.isInfinite(WideStrictInline(strictValue(i)+halfUlp) -
Float.MAX_VALUE )) {
pr(i,"WideStrictInline(Float.MAX_VALUE+halfUlp) " +
"!= Float.POSITIVE_INFINITY"
,WideStrictInline(strictValue(i)+halfUlp) - Float.MAX_VALUE);
}
r = WideStrictInline(strictValue(i)+halfUlp) - Float.MAX_VALUE;
if ( !Float.isInfinite( r ) ) {
pr(i,"r != Float.POSITIVE_INFINITY",r);
throw new RuntimeException();
}
break;
case 2:
if (WideStrictInline(strictValue(i)/2) != 0) {
pr(i,"WideStrictInline(Float.MIN_VALUE/2) != 0",
WideStrictInline(strictValue(i)/2));
}
r = WideStrictInline(strictValue(i)/2);
if ( r != 0 ) {
pr(i,"r != 0",r);
throw new RuntimeException();
}
break;
default:
if (WideStrictInline(strictValue(i)-0.5f) - strictValue(i) != 0) {
pr(i,"WideStrictInline(2^24-0.5) != 2^24",
WideStrictInline(strictValue(i)-0.5f));
}
r = WideStrictInline(strictValue(i)-0.5f);
if ( r - strictValue(i) != 0 ) {
pr(i,"r != 2^24",r);
throw new RuntimeException();
}
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,19 +22,22 @@
*/ */
package parsers; package parsers;
import java.io.ByteArrayInputStream;
import java.io.StringReader; import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamReader;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
/** /**
* @test * @test
* @bug 8169450 * @bug 8169450 8222415
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true parsers.BaseParsingTest * @run testng/othervm -DrunSecMngr=true parsers.BaseParsingTest
* @run testng/othervm parsers.BaseParsingTest * @run testng/othervm parsers.BaseParsingTest
@ -143,7 +146,7 @@ public class BaseParsingTest {
* @bug 8169450 * @bug 8169450
* This particular issue does not appear in DOM parsing since the spaces are * This particular issue does not appear in DOM parsing since the spaces are
* normalized during version detection. This test case then serves as a guard * normalized during version detection. This test case then serves as a guard
* against such an issue from occuring in the version detection. * against such an issue from occurring in the version detection.
* *
* @param xml the test xml * @param xml the test xml
* @throws Exception if the parser fails to parse the xml * @throws Exception if the parser fails to parse the xml
@ -151,8 +154,24 @@ public class BaseParsingTest {
@Test(dataProvider = "xmlDeclarations") @Test(dataProvider = "xmlDeclarations")
public void testWithDOM(String xml) throws Exception { public void testWithDOM(String xml) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder(); DocumentBuilder db = dbf.newDocumentBuilder();
db.parse(new InputSource(new StringReader(xml))); db.parse(new InputSource(new StringReader(xml)));
} }
/**
* @bug 8222415
* Verifies that the parser is configured properly for UTF-16BE or LE.
* @throws Exception
*/
@Test
public void testEncoding() throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(
"<?xml version=\"1.0\" encoding=\"UTF-16\"?> <a/>".getBytes("UnicodeLittle"));
InputSource is = new InputSource(bis);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(is);
assertEquals("UTF-16LE", doc.getInputEncoding());
}
} }

View file

@ -61,6 +61,14 @@ public class UnixSocketFile {
return; return;
} }
// Verify that 'nc' accepts '-U' for Unix domain sockets.
// Skip the test if it is not.
Process procHelp = Runtime.getRuntime().exec(CMD_BASE + " -h");
if (procHelp.waitFor() != 0) {
System.err.println("Netcat does not accept required options; skipping test.");
return;
}
// Create a new sub-directory of the nominal test directory in which // Create a new sub-directory of the nominal test directory in which
// 'nc' will create the socket file. // 'nc' will create the socket file.
String testSubDir = System.getProperty("test.dir", ".") String testSubDir = System.getProperty("test.dir", ".")

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// Please run in othervm mode. SunJSSE does not support dynamic system
// properties, no way to re-use system properties in samevm/agentvm mode.
//
/*
* @test
* @bug 8216326
* @modules jdk.crypto.ec
* @library /javax/net/ssl/templates
* @summary SSLSocket stream close() does not close the associated socket
* @run main/othervm InputStreamClosure
*/
import java.io.InputStream;
import java.io.OutputStream;
import javax.net.ssl.SSLSocket;
public class InputStreamClosure extends SSLSocketTemplate {
// Run the test case.
public static void main(String[] args) throws Exception {
(new InputStreamClosure()).run();
}
@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
// here comes the test logic
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
}
/*
* Define the client side application of the test for the specified socket.
* This method is used if the returned value of
* isCustomizedClientConnection() is false.
*
* @param socket may be null is no client socket is generated.
*
* @see #isCustomizedClientConnection()
*/
protected void runClientApplication(SSLSocket socket) throws Exception {
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
sslIS.close();
if (!socket.isClosed()) {
throw new Exception("Closing the SSLSocket InputStream does " +
"not close the associated socket");
}
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// Please run in othervm mode. SunJSSE does not support dynamic system
// properties, no way to re-use system properties in samevm/agentvm mode.
//
/*
* @test
* @bug 8216326
* @modules jdk.crypto.ec
* @library /javax/net/ssl/templates
* @summary SSLSocket stream close() does not close the associated socket
* @run main/othervm OutputStreamClosure
*/
import java.io.InputStream;
import java.io.OutputStream;
import javax.net.ssl.SSLSocket;
public class OutputStreamClosure extends SSLSocketTemplate {
// Run the test case.
public static void main(String[] args) throws Exception {
(new OutputStreamClosure()).run();
}
@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
// here comes the test logic
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
}
/*
* Define the client side application of the test for the specified socket.
* This method is used if the returned value of
* isCustomizedClientConnection() is false.
*
* @param socket may be null is no client socket is generated.
*
* @see #isCustomizedClientConnection()
*/
protected void runClientApplication(SSLSocket socket) throws Exception {
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
sslOS.close();
if (!socket.isClosed()) {
throw new Exception("Closing the SSLSocket OutputStream does " +
"not close the associated socket");
}
}
}

View file

@ -68,6 +68,7 @@ public class Settings extends TestHelper {
private static final String PROP_SETTINGS = "Property settings:"; private static final String PROP_SETTINGS = "Property settings:";
private static final String LOCALE_SETTINGS = "Locale settings:"; private static final String LOCALE_SETTINGS = "Locale settings:";
private static final String SYSTEM_SETTINGS = "Operating System Metrics:"; private static final String SYSTEM_SETTINGS = "Operating System Metrics:";
private static final String STACKSIZE_SETTINGS = "Stack Size:";
static void containsAllOptions(TestResult tr) { static void containsAllOptions(TestResult tr) {
checkContains(tr, VM_SETTINGS); checkContains(tr, VM_SETTINGS);
@ -82,10 +83,22 @@ public class Settings extends TestHelper {
int stackSize = 256; // in kb int stackSize = 256; // in kb
if (getArch().equals("ppc64") || getArch().equals("ppc64le")) { if (getArch().equals("ppc64") || getArch().equals("ppc64le")) {
stackSize = 800; stackSize = 800;
} else if (getArch().equals("aarch64")) {
/*
* The max value of minimum stack size allowed for aarch64 can be estimated as
* such: suppose the vm page size is 64KB and the test runs with a debug build,
* the initial _java_thread_min_stack_allowed defined in os_linux_aarch64.cpp is
* 72K, stack guard zones could take 192KB, and the shadow zone needs 128KB,
* after aligning up all parts to the page size, the final size would be 448KB.
* See details in JDK-8163363
*/
stackSize = 448;
} }
TestResult tr; TestResult tr;
tr = doExec(javaCmd, "-Xms64m", "-Xmx512m", tr = doExec(javaCmd, "-Xms64m", "-Xmx512m",
"-Xss" + stackSize + "k", "-XshowSettings", "-jar", testJar.getAbsolutePath()); "-Xss" + stackSize + "k", "-XshowSettings", "-jar", testJar.getAbsolutePath());
// Check the stack size logs printed by -XshowSettings to verify -Xss meaningfully.
checkContains(tr, STACKSIZE_SETTINGS);
containsAllOptions(tr); containsAllOptions(tr);
if (!tr.isOK()) { if (!tr.isOK()) {
System.out.println(tr); System.out.println(tr);
@ -93,6 +106,7 @@ public class Settings extends TestHelper {
} }
tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m", tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m",
"-Xss" + (stackSize * 1024), "-XshowSettings", "-jar", testJar.getAbsolutePath()); "-Xss" + (stackSize * 1024), "-XshowSettings", "-jar", testJar.getAbsolutePath());
checkContains(tr, STACKSIZE_SETTINGS);
containsAllOptions(tr); containsAllOptions(tr);
if (!tr.isOK()) { if (!tr.isOK()) {
System.out.println(tr); System.out.println(tr);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6762191 * @bug 6762191 8222334
* @summary Setting stack size to 16K causes segmentation fault * @summary Setting stack size to 16K causes segmentation fault
* @compile TooSmallStackSize.java * @compile TooSmallStackSize.java
* @run main TooSmallStackSize * @run main TooSmallStackSize
@ -171,5 +171,11 @@ public class TooSmallStackSize extends TestHelper {
* asserts added for 8176768 are not triggered. * asserts added for 8176768 are not triggered.
*/ */
checkMinStackAllowed("513k"); checkMinStackAllowed("513k");
/*
* Try with 0k which indicates that the default thread stack size either from JVM or system
* will be used, this should always succeed.
*/
checkMinStackAllowed("0k");
} }
} }

View file

@ -7,15 +7,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="date" content="(removed)"> <meta name="date" content="(removed)">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="jquery/jquery-ui.css" title="Style"> <link rel="stylesheet" type="text/css" href="script-dir/jquery-ui.css" title="Style">
<script type="text/javascript" src="script.js"></script> <script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="jquery/jszip/dist/jszip.min.js"></script> <script type="text/javascript" src="script-dir/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="jquery/jszip-utils/dist/jszip-utils.min.js"></script> <script type="text/javascript" src="script-dir/jszip-utils/dist/jszip-utils.min.js"></script>
<!--[if IE]> <!--[if IE]>
<script type="text/javascript" src="jquery/jszip-utils/dist/jszip-utils-ie.min.js"></script> <script type="text/javascript" src="script-dir/jszip-utils/dist/jszip-utils-ie.min.js"></script>
<![endif]--> <![endif]-->
<script type="text/javascript" src="jquery/jquery-1.10.2.js"></script> <script type="text/javascript" src="script-dir/jquery-1.10.2.js"></script>
<script type="text/javascript" src="jquery/jquery-ui.js"></script> <script type="text/javascript" src="script-dir/jquery-ui.js"></script>
</head> </head>
<body> <body>
<script type="text/javascript"><!-- <script type="text/javascript"><!--

View file

@ -386,15 +386,15 @@ public class TestSearch extends JavadocTester {
void checkSearchOutput(String fileName, boolean expectedOutput, boolean moduleDirectoriesVar) { void checkSearchOutput(String fileName, boolean expectedOutput, boolean moduleDirectoriesVar) {
// Test for search related markup // Test for search related markup
checkOutput(fileName, expectedOutput, checkOutput(fileName, expectedOutput,
"<link rel=\"stylesheet\" type=\"text/css\" href=\"jquery/jquery-ui.css\" title=\"Style\">\n", "<link rel=\"stylesheet\" type=\"text/css\" href=\"script-dir/jquery-ui.css\" title=\"Style\">\n",
"<script type=\"text/javascript\" src=\"jquery/jszip/dist/jszip.min.js\"></script>\n", "<script type=\"text/javascript\" src=\"script-dir/jszip/dist/jszip.min.js\"></script>\n",
"<script type=\"text/javascript\" src=\"jquery/jszip-utils/dist/jszip-utils.min.js\"></script>\n", "<script type=\"text/javascript\" src=\"script-dir/jszip-utils/dist/jszip-utils.min.js\"></script>\n",
"<!--[if IE]>\n", "<!--[if IE]>\n",
"<script type=\"text/javascript\" src=\"jquery/jszip-utils/dist/jszip-utils-ie.min.js\"></script>\n", "<script type=\"text/javascript\" src=\"script-dir/jszip-utils/dist/jszip-utils-ie.min.js\"></script>\n",
"<![endif]-->\n", "<![endif]-->\n",
"<script type=\"text/javascript\" src=\"jquery/jquery-3.3.1.js\"></script>\n", "<script type=\"text/javascript\" src=\"script-dir/jquery-3.3.1.js\"></script>\n",
"<script type=\"text/javascript\" src=\"jquery/jquery-migrate-3.0.1.js\"></script>\n", "<script type=\"text/javascript\" src=\"script-dir/jquery-migrate-3.0.1.js\"></script>\n",
"<script type=\"text/javascript\" src=\"jquery/jquery-ui.js\"></script>", "<script type=\"text/javascript\" src=\"script-dir/jquery-ui.js\"></script>",
"var pathtoroot = \"./\";\n" "var pathtoroot = \"./\";\n"
+ "var useModuleDirectories = " + moduleDirectoriesVar + ";\n" + "var useModuleDirectories = " + moduleDirectoriesVar + ";\n"
+ "loadScripts(document, 'script');", + "loadScripts(document, 'script');",
@ -585,32 +585,32 @@ public class TestSearch extends JavadocTester {
void checkJqueryAndImageFiles(boolean expectedOutput) { void checkJqueryAndImageFiles(boolean expectedOutput) {
checkFiles(expectedOutput, checkFiles(expectedOutput,
"search.js", "search.js",
"jquery/jquery-3.3.1.js", "script-dir/jquery-3.3.1.js",
"jquery/jquery-migrate-3.0.1.js", "script-dir/jquery-migrate-3.0.1.js",
"jquery/jquery-ui.js", "script-dir/jquery-ui.js",
"jquery/jquery-ui.css", "script-dir/jquery-ui.css",
"jquery/jquery-ui.min.js", "script-dir/jquery-ui.min.js",
"jquery/jquery-ui.min.css", "script-dir/jquery-ui.min.css",
"jquery/jquery-ui.structure.min.css", "script-dir/jquery-ui.structure.min.css",
"jquery/jquery-ui.structure.css", "script-dir/jquery-ui.structure.css",
"jquery/external/jquery/jquery.js", "script-dir/external/jquery/jquery.js",
"jquery/jszip/dist/jszip.js", "script-dir/jszip/dist/jszip.js",
"jquery/jszip/dist/jszip.min.js", "script-dir/jszip/dist/jszip.min.js",
"jquery/jszip-utils/dist/jszip-utils.js", "script-dir/jszip-utils/dist/jszip-utils.js",
"jquery/jszip-utils/dist/jszip-utils.min.js", "script-dir/jszip-utils/dist/jszip-utils.min.js",
"jquery/jszip-utils/dist/jszip-utils-ie.js", "script-dir/jszip-utils/dist/jszip-utils-ie.js",
"jquery/jszip-utils/dist/jszip-utils-ie.min.js", "script-dir/jszip-utils/dist/jszip-utils-ie.min.js",
"jquery/images/ui-bg_glass_65_dadada_1x400.png", "script-dir/images/ui-bg_glass_65_dadada_1x400.png",
"jquery/images/ui-icons_454545_256x240.png", "script-dir/images/ui-icons_454545_256x240.png",
"jquery/images/ui-bg_glass_95_fef1ec_1x400.png", "script-dir/images/ui-bg_glass_95_fef1ec_1x400.png",
"jquery/images/ui-bg_glass_75_dadada_1x400.png", "script-dir/images/ui-bg_glass_75_dadada_1x400.png",
"jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
"jquery/images/ui-icons_888888_256x240.png", "script-dir/images/ui-icons_888888_256x240.png",
"jquery/images/ui-icons_2e83ff_256x240.png", "script-dir/images/ui-icons_2e83ff_256x240.png",
"jquery/images/ui-icons_cd0a0a_256x240.png", "script-dir/images/ui-icons_cd0a0a_256x240.png",
"jquery/images/ui-bg_glass_55_fbf9ee_1x400.png", "script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png",
"jquery/images/ui-icons_222222_256x240.png", "script-dir/images/ui-icons_222222_256x240.png",
"jquery/images/ui-bg_glass_75_e6e6e6_1x400.png", "script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png",
"resources/x.png", "resources/x.png",
"resources/glass.png"); "resources/glass.png");
} }

View file

@ -197,32 +197,32 @@ class APITest {
"help-doc.html", "help-doc.html",
"index-all.html", "index-all.html",
"index.html", "index.html",
"jquery/jquery-3.3.1.js", "script-dir/jquery-3.3.1.js",
"jquery/jquery-migrate-3.0.1.js", "script-dir/jquery-migrate-3.0.1.js",
"jquery/jquery-ui.js", "script-dir/jquery-ui.js",
"jquery/jquery-ui.css", "script-dir/jquery-ui.css",
"jquery/jquery-ui.min.js", "script-dir/jquery-ui.min.js",
"jquery/jquery-ui.min.css", "script-dir/jquery-ui.min.css",
"jquery/jquery-ui.structure.min.css", "script-dir/jquery-ui.structure.min.css",
"jquery/jquery-ui.structure.css", "script-dir/jquery-ui.structure.css",
"jquery/external/jquery/jquery.js", "script-dir/external/jquery/jquery.js",
"jquery/jszip/dist/jszip.js", "script-dir/jszip/dist/jszip.js",
"jquery/jszip/dist/jszip.min.js", "script-dir/jszip/dist/jszip.min.js",
"jquery/jszip-utils/dist/jszip-utils.js", "script-dir/jszip-utils/dist/jszip-utils.js",
"jquery/jszip-utils/dist/jszip-utils.min.js", "script-dir/jszip-utils/dist/jszip-utils.min.js",
"jquery/jszip-utils/dist/jszip-utils-ie.js", "script-dir/jszip-utils/dist/jszip-utils-ie.js",
"jquery/jszip-utils/dist/jszip-utils-ie.min.js", "script-dir/jszip-utils/dist/jszip-utils-ie.min.js",
"jquery/images/ui-bg_glass_65_dadada_1x400.png", "script-dir/images/ui-bg_glass_65_dadada_1x400.png",
"jquery/images/ui-icons_454545_256x240.png", "script-dir/images/ui-icons_454545_256x240.png",
"jquery/images/ui-bg_glass_95_fef1ec_1x400.png", "script-dir/images/ui-bg_glass_95_fef1ec_1x400.png",
"jquery/images/ui-bg_glass_75_dadada_1x400.png", "script-dir/images/ui-bg_glass_75_dadada_1x400.png",
"jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png", "script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
"jquery/images/ui-icons_888888_256x240.png", "script-dir/images/ui-icons_888888_256x240.png",
"jquery/images/ui-icons_2e83ff_256x240.png", "script-dir/images/ui-icons_2e83ff_256x240.png",
"jquery/images/ui-icons_cd0a0a_256x240.png", "script-dir/images/ui-icons_cd0a0a_256x240.png",
"jquery/images/ui-bg_glass_55_fbf9ee_1x400.png", "script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png",
"jquery/images/ui-icons_222222_256x240.png", "script-dir/images/ui-icons_222222_256x240.png",
"jquery/images/ui-bg_glass_75_e6e6e6_1x400.png", "script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png",
"member-search-index.js", "member-search-index.js",
"member-search-index.zip", "member-search-index.zip",
"overview-tree.html", "overview-tree.html",
@ -242,7 +242,7 @@ class APITest {
)); ));
protected static Set<String> noIndexFiles = standardExpectFiles.stream() protected static Set<String> noIndexFiles = standardExpectFiles.stream()
.filter(s -> !s.startsWith("jquery") && !s.startsWith("resources") && !s.endsWith("zip") .filter(s -> !s.startsWith("script-dir") && !s.startsWith("resources") && !s.endsWith("zip")
&& !s.equals("index-all.html") && !s.equals("search.js") && !s.endsWith("-search-index.js") && !s.equals("index-all.html") && !s.equals("search.js") && !s.endsWith("-search-index.js")
&& !s.equals("allclasses-index.html") && !s.equals("allpackages-index.html")) && !s.equals("allclasses-index.html") && !s.equals("allpackages-index.html"))
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View file

@ -134,6 +134,8 @@ public class BadConstantValue {
"class Lib { static final int A = %s; static final %s B = %s; }", "class Lib { static final int A = %s; static final %s B = %s; }",
value, type, (type.equals("boolean") ? "false" : "0"))); value, type, (type.equals("boolean") ? "false" : "0")));
compile("-d", classesdir.getPath(), lib.getPath()); compile("-d", classesdir.getPath(), lib.getPath());
// Lib.class may possibly not get a newer timestamp. Make sure .java file won't get used.
lib.delete();
File libClass = new File(classesdir, "Lib.class"); File libClass = new File(classesdir, "Lib.class");
// Rewrite the class to only have field B of type "type" and with "value" (potentially // Rewrite the class to only have field B of type "type" and with "value" (potentially
// out of range). // out of range).
@ -147,6 +149,8 @@ public class BadConstantValue {
"class Lib { static final String A = \"hello\"; static final %s CONST = %s; }", "class Lib { static final String A = \"hello\"; static final %s CONST = %s; }",
type, type.equals("boolean") ? "false" : "0")); type, type.equals("boolean") ? "false" : "0"));
compile("-d", classesdir.getPath(), lib.getPath()); compile("-d", classesdir.getPath(), lib.getPath());
// Lib.class may possibly not get a newer timestamp. Make sure .java file won't get used.
lib.delete();
File libClass = new File(classesdir, "Lib.class"); File libClass = new File(classesdir, "Lib.class");
swapConstantValues(libClass); swapConstantValues(libClass);

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8222378
* @summary Test that ProcessingEnvironment.isPreviewEnabled works properly
* @library /tools/javac/lib
* @modules java.compiler
* @build JavacTestingAbstractProcessor
* @compile TestPreviewEnabled.java
* @compile -processor TestPreviewEnabled -proc:only -source ${jdk.version} -AExpectedPreview=false TestSourceVersion.java
* @compile -processor TestPreviewEnabled -proc:only -source ${jdk.version} -AExpectedPreview=true --enable-preview TestSourceVersion.java
*/
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.annotation.processing.*;
import javax.lang.model.util.*;
/**
* This processor checks that ProcessingEnvironment.isPreviewEnabled
* is consistent with the compiler options.
*/
@SupportedOptions("ExpectedPreview")
public class TestPreviewEnabled extends JavacTestingAbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnvironment) {
if (!roundEnvironment.processingOver()) {
boolean expectedPreview =
Boolean.valueOf(processingEnv.getOptions().get("ExpectedPreview"));
boolean actualPreview = processingEnv.isPreviewEnabled();
System.out.println("Expected PreviewEnabled: " + expectedPreview +
"\n actual PreviewEnabled: " + actualPreview);
if (expectedPreview != actualPreview)
throw new RuntimeException();
if (expectedPreview) {
// Create a ProcessingEnvironment that uses the
// default implemention of isPreviewEnabled.
ProcessingEnvironment testEnv = new ProcessingEnvironment() {
@Override public Elements getElementUtils() {return null;}
@Override public Filer getFiler() {return null;}
@Override public Locale getLocale() {return null;}
@Override public Messager getMessager() {return null;}
@Override public Map<String,String> getOptions() {return null;}
@Override public SourceVersion getSourceVersion() {return null;}
@Override public Types getTypeUtils() {return null;}
};
if (testEnv.isPreviewEnabled()) {
throw new RuntimeException("Bad true return value from default " +
"ProcessingEnvironment.isPreviewEnabled.");
}
}
}
return true;
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8222430
* @summary Test various predicates of ElementKind.
*/
import java.util.Set;
import java.util.function.Predicate;
import javax.lang.model.element.ElementKind;
/**
* Test the isClass, isField, and isInterface predicates of ElementKind.
*/
public class TestElementKindPredicates {
public static void main(String... args) {
Set<ElementKind> ALL_KINDS = Set.of(ElementKind.values());
// isClass: Returns true if this is a kind of class: either CLASS or ENUM.
test(ALL_KINDS,
(ElementKind k) -> Set.of(ElementKind.CLASS,
ElementKind.ENUM).contains(k),
(ElementKind k) -> k.isClass(), "isClass");
// isField: Returns true if this is a kind of field: either FIELD or ENUM_CONSTANT.
test(ALL_KINDS,
(ElementKind k) -> Set.of(ElementKind.FIELD,
ElementKind.ENUM_CONSTANT).contains(k),
(ElementKind k) -> k.isField(), "isField");
// isInterface: Returns true if this is a kind of interface: either INTERFACE or ANNOTATION_TYPE.
test(ALL_KINDS,
(ElementKind k) -> Set.of(ElementKind.INTERFACE,
ElementKind.ANNOTATION_TYPE).contains(k),
(ElementKind k) -> k.isInterface(), "isInterface");
}
private static void test(Set<ElementKind> kinds,
Predicate<ElementKind> expectedPred,
Predicate<ElementKind> actualPred,
String errorMessage) {
for(ElementKind kind : kinds) {
boolean expected = expectedPred.test(kind);
boolean actual = actualPred.test(kind);
if (expected != actual) {
throw new RuntimeException("Error testing ElementKind." + errorMessage + "(" + kind +
"):\texpected " + expected + "\tgot " + actual);
}
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,11 @@ public class StringConcat {
return "string" + stringValue; return "string" + stringValue;
} }
@Benchmark
public String concatMethodConstString() {
return "string".concat(stringValue);
}
@Benchmark @Benchmark
public String concatConstIntConstInt() { public String concatConstIntConstInt() {
return "string" + intValue + "string" + intValue; return "string" + intValue + "string" + intValue;