Merge
@ -1,4 +1,4 @@
|
||||
#
|
||||
Name#
|
||||
# Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
# 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(JDK_RC_PLATFORM_NAME)
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
# Set the JDK RC name
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -67,13 +67,24 @@ public class HelloClasslist {
|
||||
.forEach(System.out::println);
|
||||
|
||||
// Common concatenation patterns
|
||||
String const_I = "string" + args.length;
|
||||
String const_S = "string" + String.valueOf(args.length);
|
||||
String S_const = String.valueOf(args.length) + "string";
|
||||
String S_S = String.valueOf(args.length) + String.valueOf(args.length);
|
||||
String const_J = "string" + System.currentTimeMillis();
|
||||
String I_const = args.length + "string";
|
||||
String J_const = System.currentTimeMillis() + "string";
|
||||
String SS = String.valueOf(args.length) + String.valueOf(args.length);
|
||||
String CS = "string" + String.valueOf(args.length);
|
||||
String SC = String.valueOf(args.length) + "string";
|
||||
String SCS = String.valueOf(args.length) + "string" + String.valueOf(args.length);
|
||||
String CSS = "string" + String.valueOf(args.length) + String.valueOf(args.length);
|
||||
String CSCS = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length);
|
||||
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(
|
||||
LocalDateTime.now(ZoneId.of("GMT")));
|
||||
|
@ -39,7 +39,6 @@ JAVA_RC_FLAGS += -I$(TOPDIR)/src/java.base/windows/native/launcher/icons
|
||||
# overwritten.
|
||||
$(eval $(call SetupBuildLauncher, java, \
|
||||
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \
|
||||
LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR), \
|
||||
EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \
|
||||
VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \
|
||||
|
@ -73,8 +73,7 @@ JAVA_MANIFEST := $(TOPDIR)/src/java.base/windows/native/launcher/java.manifest
|
||||
# compile time defines exceeding Visual Studio 2013 limitations.
|
||||
# CFLAGS Additional CFLAGS
|
||||
# CFLAGS_windows Additional CFLAGS_windows
|
||||
# LDFLAGS_solaris Additional LDFLAGS_solaris
|
||||
# RC_FLAGS Additional RC_FLAGS
|
||||
# EXTRA_RC_FLAGS Additional EXTRA_RC_FLAGS
|
||||
# MACOSX_SIGNED On macosx, sign this binary
|
||||
# OPTIMIZATION Override default optimization level (LOW)
|
||||
# OUTPUT_DIR Override default output directory
|
||||
@ -139,7 +138,7 @@ define SetupBuildLauncherBody
|
||||
NAME := $1, \
|
||||
EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \
|
||||
OPTIMIZATION := $$($1_OPTIMIZATION), \
|
||||
CFLAGS := $$(CFLAGS_JDKEXE) $$($1_CFLAGS) \
|
||||
CFLAGS := $$(CFLAGS_JDKEXE) \
|
||||
$(LAUNCHER_CFLAGS) \
|
||||
$(VERSION_CFLAGS) \
|
||||
-DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \
|
||||
|
@ -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
|
||||
// work registers anyway.
|
||||
// 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) {
|
||||
// Src_addr is evenReg.
|
||||
// Src_len is odd_Reg.
|
||||
unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg) {
|
||||
|
||||
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_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 {");
|
||||
|
||||
// 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.
|
||||
|
||||
// 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_sllg(dst_len, src_len, 3); // #bytes to clear.
|
||||
z_cghi(src_len, 32); // Check for len <= 256 bytes (<=32 DW).
|
||||
z_brnh(doXC); // If so, use executed XC to clear.
|
||||
z_sllg(dst_len, odd_tmp_reg, 3); // #bytes to clear.
|
||||
z_cghi(odd_tmp_reg, 32); // Check for len <= 256 bytes (<=32 DW).
|
||||
z_brnh(doXC); // If so, use executed XC to clear.
|
||||
|
||||
// MVCLE: initialize long arrays (general case).
|
||||
bind(doMVCLE);
|
||||
z_lgr(dst_addr, base_pointer_arg);
|
||||
clear_reg(src_len, true, false); // Src len of MVCLE is zero.
|
||||
|
||||
MacroAssembler::move_long_ext(dst_addr, src_addr, 0);
|
||||
// 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.
|
||||
clear_reg(odd_tmp_reg, true, false);
|
||||
MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding()-1), 0);
|
||||
z_bru(done);
|
||||
|
||||
// XC: initialize short arrays.
|
||||
@ -4396,12 +4394,12 @@ unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer
|
||||
z_xc(0,0,base_pointer_arg,0,base_pointer_arg);
|
||||
|
||||
bind(doXC);
|
||||
add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE.
|
||||
add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE.
|
||||
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 {
|
||||
z_larl(tmp_reg, XC_template);
|
||||
z_ex(dst_len,0,Z_R0,tmp_reg); // Execute XC with var. len.
|
||||
z_larl(odd_tmp_reg, XC_template);
|
||||
z_ex(dst_len,0,Z_R0,odd_tmp_reg); // Execute XC with var. len.
|
||||
}
|
||||
// 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.
|
||||
// Emitter does not KILL cnt and base arguments, since they need to be copied to
|
||||
// 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.
|
||||
// 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.
|
||||
// - 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) {
|
||||
// Src_addr is evenReg.
|
||||
// Src_len is odd_Reg.
|
||||
unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg) {
|
||||
|
||||
int block_start = offset();
|
||||
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.
|
||||
z_lgr(dst_addr, base_pointer_arg);
|
||||
// Indicate unused result.
|
||||
(void) clear_reg(src_len, true, false); // Src len of MVCLE is zero.
|
||||
|
||||
// Clear.
|
||||
MacroAssembler::move_long_ext(dst_addr, src_addr, 0);
|
||||
// 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.
|
||||
(void) clear_reg(odd_tmp_reg, true, false); // Src len of MVCLE is zero.
|
||||
MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding() - 1), 0);
|
||||
BLOCK_COMMENT("} Clear_Array_Const_Big");
|
||||
|
||||
int block_end = offset();
|
||||
|
@ -828,9 +828,9 @@ class MacroAssembler: public Assembler {
|
||||
//--------------------------
|
||||
//--- 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_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,
|
||||
Register cnt_reg,
|
||||
Register tmp1_reg, Register tmp2_reg);
|
||||
|
@ -474,6 +474,19 @@ reg_class z_long_reg(
|
||||
/*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
|
||||
|
||||
@ -3378,6 +3391,7 @@ operand iRegL() %{
|
||||
match(RegL);
|
||||
match(revenRegL);
|
||||
match(roddRegL);
|
||||
match(allRoddRegL);
|
||||
match(rarg1RegL);
|
||||
match(rarg5RegL);
|
||||
format %{ %}
|
||||
@ -3400,6 +3414,14 @@ operand roddRegL() %{
|
||||
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() %{
|
||||
constraint(ALLOC_IN_RC(z_rarg1_long_reg));
|
||||
match(iRegL);
|
||||
@ -9899,23 +9921,23 @@ instruct inlineCallClearArrayConst(SSlenDW cnt, iRegP_N2P base, Universe 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));
|
||||
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);
|
||||
// TODO: s390 port size(VARIABLE_SIZE); // Variable in size due to optimized constant loader.
|
||||
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);
|
||||
%}
|
||||
|
||||
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));
|
||||
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);
|
||||
// TODO: s390 port size(FIXED_SIZE); // z/Architecture: emitted code depends on PreferLAoverADD being on/off.
|
||||
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);
|
||||
%}
|
||||
|
||||
|
@ -2968,9 +2968,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
__ enter();
|
||||
__ subptr(rsp, 8 * wordSize);
|
||||
if (multi_block) {
|
||||
__ push(limit);
|
||||
}
|
||||
handleSOERegisters(true /*saving*/);
|
||||
|
||||
__ movptr(buf, buf_param);
|
||||
__ movptr(state, state_param);
|
||||
if (multi_block) {
|
||||
@ -2981,9 +2980,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ fast_sha1(abcd, e0, e1, msg0, msg1, msg2, msg3, shuf_mask,
|
||||
buf, state, ofs, limit, rsp, multi_block);
|
||||
|
||||
if (multi_block) {
|
||||
__ pop(limit);
|
||||
}
|
||||
handleSOERegisters(false /*restoring*/);
|
||||
__ addptr(rsp, 8 * wordSize);
|
||||
__ leave();
|
||||
__ ret(0);
|
||||
|
82
src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp
Normal 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
|
110
src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp
Normal 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
|
@ -33,6 +33,7 @@
|
||||
#include "gc/shared/referenceProcessorPhaseTimes.hpp"
|
||||
|
||||
#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahMarkCompact.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "gc/shenandoah/shenandoahAllocTracker.hpp"
|
||||
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahBrooksPointer.hpp"
|
||||
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
|
||||
#include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
|
||||
@ -70,8 +71,6 @@
|
||||
#include "runtime/vmThread.hpp"
|
||||
#include "services/mallocTracker.hpp"
|
||||
|
||||
ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : _heap(ShenandoahHeap::heap()) {}
|
||||
|
||||
#ifdef ASSERT
|
||||
template <class T>
|
||||
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();
|
||||
}
|
||||
|
||||
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 {
|
||||
private:
|
||||
ShenandoahHeap* const _heap;
|
||||
@ -1884,31 +1846,6 @@ HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) {
|
||||
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() {
|
||||
assert(_max_workers > 0, "Sanity");
|
||||
|
||||
@ -2879,8 +2816,3 @@ size_t ShenandoahHeap::obj_size(oop obj) const {
|
||||
ptrdiff_t ShenandoahHeap::cell_header_size() const {
|
||||
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);
|
||||
}
|
||||
|
@ -91,19 +91,6 @@ public:
|
||||
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
|
||||
class ShenandoahAssertToSpaceClosure : public OopClosure {
|
||||
private:
|
||||
@ -115,29 +102,6 @@ public:
|
||||
};
|
||||
#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
|
||||
// to encode forwarding data. See BrooksPointer for details on forwarding data encoding.
|
||||
|
@ -46,17 +46,6 @@
|
||||
#include "utilities/copy.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() {
|
||||
size_t new_index = Atomic::add((size_t) 1, &_index);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahRootProcessor.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeap.hpp"
|
||||
#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
|
||||
@ -242,10 +243,7 @@ ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_wo
|
||||
_evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
|
||||
_srs(n_workers),
|
||||
_phase(phase),
|
||||
_coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()),
|
||||
_par_state_string(StringTable::weak_storage())
|
||||
|
||||
{
|
||||
_coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()) {
|
||||
heap->phase_timings()->record_workers_start(_phase);
|
||||
if (ShenandoahStringDedup::is_enabled()) {
|
||||
StringDedup::gc_prologue(false);
|
||||
|
@ -119,7 +119,6 @@ class ShenandoahRootEvacuator : public StackObj {
|
||||
StrongRootsScope _srs;
|
||||
ShenandoahPhaseTimings::Phase _phase;
|
||||
ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator;
|
||||
OopStorage::ParState<false, false> _par_state_string;
|
||||
|
||||
enum Shenandoah_evacuate_roots_tasks {
|
||||
SHENANDOAH_EVAC_Universe_oops_do,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "gc/shared/weakProcessor.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahCodeRoots.hpp"
|
||||
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
|
||||
|
@ -1965,20 +1965,7 @@ public final class String
|
||||
if (str.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
if (coder() == str.coder()) {
|
||||
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);
|
||||
return StringConcatHelper.simpleConcat(this, str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
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
|
||||
* 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.
|
||||
* @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) {
|
||||
if ((int)lengthCoder >= 0) {
|
||||
@ -50,76 +55,83 @@ final class StringConcatHelper {
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, boolean value) {
|
||||
return checkOverflow(current + (value ? 4 : 5));
|
||||
static long mix(long lengthCoder, boolean value) {
|
||||
return checkOverflow(lengthCoder + (value ? 4 : 5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, byte value) {
|
||||
return mix(current, (int)value);
|
||||
static long mix(long lengthCoder, byte value) {
|
||||
return mix(lengthCoder, (int)value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, char value) {
|
||||
return checkOverflow(current + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16);
|
||||
static long mix(long lengthCoder, char value) {
|
||||
return checkOverflow(lengthCoder + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, short value) {
|
||||
return mix(current, (int)value);
|
||||
static long mix(long lengthCoder, short value) {
|
||||
return mix(lengthCoder, (int)value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, int value) {
|
||||
return checkOverflow(current + Integer.stringSize(value));
|
||||
static long mix(long lengthCoder, int value) {
|
||||
return checkOverflow(lengthCoder + Integer.stringSize(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, long value) {
|
||||
return checkOverflow(current + Long.stringSize(value));
|
||||
static long mix(long lengthCoder, long value) {
|
||||
return checkOverflow(lengthCoder + Long.stringSize(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix value length and coder into current length and coder.
|
||||
* @param current current length
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
* @param lengthCoder String length with coder packed into higher bits
|
||||
* the upper word.
|
||||
* @param value value to mix in
|
||||
* @return new length and coder
|
||||
*/
|
||||
static long mix(long current, String value) {
|
||||
current += value.length();
|
||||
static long mix(long lengthCoder, String value) {
|
||||
lengthCoder += value.length();
|
||||
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 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.
|
||||
* @return initial coder, adjusted into the upper half
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,7 @@
|
||||
package java.lang.invoke;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.Label;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
@ -191,6 +192,8 @@ public final class StringConcatFactory {
|
||||
*/
|
||||
private static final ProxyClassesDumper DUMPER;
|
||||
|
||||
private static final Class<?> STRING_HELPER;
|
||||
|
||||
static {
|
||||
// In case we need to double-back onto the StringConcatFactory during this
|
||||
// static initialization, make sure we have the reasonable defaults to complete
|
||||
@ -202,15 +205,20 @@ public final class StringConcatFactory {
|
||||
// DEBUG = false; // 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 =
|
||||
props.getProperty("java.lang.invoke.stringConcat");
|
||||
VM.getSavedProperty("java.lang.invoke.stringConcat");
|
||||
CACHE_ENABLE = Boolean.parseBoolean(
|
||||
props.getProperty("java.lang.invoke.stringConcat.cache"));
|
||||
VM.getSavedProperty("java.lang.invoke.stringConcat.cache"));
|
||||
DEBUG = Boolean.parseBoolean(
|
||||
props.getProperty("java.lang.invoke.stringConcat.debug"));
|
||||
VM.getSavedProperty("java.lang.invoke.stringConcat.debug"));
|
||||
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);
|
||||
CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
|
||||
@ -1519,6 +1527,33 @@ public final class StringConcatFactory {
|
||||
|
||||
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
|
||||
// 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.
|
||||
@ -1626,13 +1661,6 @@ public final class StringConcatFactory {
|
||||
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) {
|
||||
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_ARRAY;
|
||||
private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
|
||||
private static final ConcurrentMap<Class<?>, MethodHandle> MIXERS;
|
||||
private static final long INITIAL_CODER;
|
||||
static final Class<?> STRING_HELPER;
|
||||
|
||||
static {
|
||||
try {
|
||||
STRING_HELPER = Class.forName("java.lang.StringConcatHelper");
|
||||
MethodHandle initCoder = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "initialCoder", long.class);
|
||||
INITIAL_CODER = (long) initCoder.invoke();
|
||||
} catch (Throwable e) {
|
||||
@ -1678,8 +1705,9 @@ public final class StringConcatFactory {
|
||||
PREPENDERS = 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_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
|
||||
}
|
||||
|
||||
private static class ObjectStringifier {
|
||||
|
||||
// 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 final MethodHandle OBJECT_INSTANCE =
|
||||
lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "stringOf", String.class, Object.class);
|
||||
|
||||
private static class FloatStringifiers {
|
||||
private static final MethodHandle FLOAT_INSTANCE =
|
||||
@ -1751,7 +1765,7 @@ public final class StringConcatFactory {
|
||||
*/
|
||||
static MethodHandle forMost(Class<?> t) {
|
||||
if (!t.isPrimitive()) {
|
||||
return ObjectStringifier.INSTANCE;
|
||||
return OBJECT_INSTANCE;
|
||||
} else if (t == float.class) {
|
||||
return FloatStringifiers.FLOAT_INSTANCE;
|
||||
} else if (t == double.class) {
|
||||
|
@ -791,7 +791,7 @@ public abstract class FileChannel
|
||||
// -- Memory-mapped buffers --
|
||||
|
||||
/**
|
||||
* A typesafe enumeration for file-mapping modes.
|
||||
* A file-mapping mode.
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
@ -819,6 +819,12 @@ public abstract class FileChannel
|
||||
|
||||
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) {
|
||||
this.name = name;
|
||||
}
|
||||
@ -837,8 +843,8 @@ public abstract class FileChannel
|
||||
/**
|
||||
* 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>
|
||||
* <p> The {@code mode} parameter specifies how the region of the file is
|
||||
* mapped and may be one of the following modes:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
@ -859,6 +865,8 @@ public abstract class FileChannel
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p> An implementation may support additional map modes.
|
||||
*
|
||||
* <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
|
||||
* been opened for both reading and writing.
|
||||
@ -892,7 +900,8 @@ public abstract class FileChannel
|
||||
* MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE
|
||||
* PRIVATE} defined in the {@link MapMode} class, according to
|
||||
* 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
|
||||
* The position within the file at which the mapped region
|
||||
@ -905,25 +914,29 @@ public abstract class FileChannel
|
||||
* @return The mapped byte buffer
|
||||
*
|
||||
* @throws NonReadableChannelException
|
||||
* If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} but
|
||||
* this channel was not opened for reading
|
||||
* If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} or
|
||||
* an implementation specific map mode requiring read access
|
||||
* but this channel was not opened for reading
|
||||
*
|
||||
* @throws NonWritableChannelException
|
||||
* If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE} or
|
||||
* {@link MapMode#PRIVATE PRIVATE} but this channel was not opened
|
||||
* for both reading and writing
|
||||
* If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE}.
|
||||
* {@link MapMode#PRIVATE PRIVATE} or an implementation specific
|
||||
* map mode requiring write access but this channel was not
|
||||
* opened for both reading and writing
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the preconditions on the parameters do not hold
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* If an unsupported map mode is specified
|
||||
*
|
||||
* @throws IOException
|
||||
* If some other I/O error occurs
|
||||
*
|
||||
* @see java.nio.channels.FileChannel.MapMode
|
||||
* @see java.nio.MappedByteBuffer
|
||||
*/
|
||||
public abstract MappedByteBuffer map(MapMode mode,
|
||||
long position, long size)
|
||||
public abstract MappedByteBuffer map(MapMode mode, long position, long size)
|
||||
throws IOException;
|
||||
|
||||
|
||||
|
@ -940,14 +940,15 @@ public class FileChannelImpl
|
||||
if (size > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
|
||||
|
||||
int imode = -1;
|
||||
int imode;
|
||||
if (mode == MapMode.READ_ONLY)
|
||||
imode = MAP_RO;
|
||||
else if (mode == MapMode.READ_WRITE)
|
||||
imode = MAP_RW;
|
||||
else if (mode == MapMode.PRIVATE)
|
||||
imode = MAP_PV;
|
||||
assert (imode >= 0);
|
||||
else
|
||||
throw new UnsupportedOperationException();
|
||||
if ((mode != MapMode.READ_ONLY) && !writable)
|
||||
throw new NonWritableChannelException();
|
||||
if (!readable)
|
||||
|
@ -980,7 +980,7 @@ public final class SSLSocketImpl
|
||||
}
|
||||
|
||||
try {
|
||||
shutdownInput(false);
|
||||
SSLSocketImpl.this.close();
|
||||
} catch (IOException ioe) {
|
||||
// ignore the exception
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
@ -1146,7 +1146,7 @@ public final class SSLSocketImpl
|
||||
}
|
||||
|
||||
try {
|
||||
shutdownOutput();
|
||||
SSLSocketImpl.this.close();
|
||||
} catch (IOException ioe) {
|
||||
// ignore the exception
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
|
@ -204,11 +204,14 @@ static jboolean IsWildCardEnabled();
|
||||
*/
|
||||
static jlong threadStackSize = 0; /* stack size of the new thread */
|
||||
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
|
||||
#define STACK_SIZE_MINIMUM (64 * KB)
|
||||
#endif
|
||||
@ -934,16 +937,18 @@ AddOption(char *str, void *info)
|
||||
options[numOptions].optionString = str;
|
||||
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) {
|
||||
jlong tmp;
|
||||
if (parse_size(str + 4, &tmp)) {
|
||||
threadStackSize = tmp;
|
||||
/*
|
||||
* 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) {
|
||||
if (threadStackSize > 0 && threadStackSize < (jlong)STACK_SIZE_MINIMUM) {
|
||||
threadStackSize = STACK_SIZE_MINIMUM;
|
||||
}
|
||||
}
|
||||
@ -2322,38 +2327,38 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
|
||||
int argc, char **argv,
|
||||
int mode, char *what, int ret)
|
||||
{
|
||||
|
||||
/*
|
||||
* If user doesn't specify stack size, check if VM has a preference.
|
||||
* Note that HotSpot no longer supports JNI_VERSION_1_1 but it will
|
||||
* return its default stack size through the init args structure.
|
||||
*/
|
||||
if (threadStackSize == 0) {
|
||||
struct JDK1_1InitArgs args1_1;
|
||||
memset((void*)&args1_1, 0, sizeof(args1_1));
|
||||
args1_1.version = JNI_VERSION_1_1;
|
||||
ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */
|
||||
if (args1_1.javaStackSize > 0) {
|
||||
threadStackSize = args1_1.javaStackSize;
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
* return its default stack size through the init args structure.
|
||||
*/
|
||||
struct JDK1_1InitArgs args1_1;
|
||||
memset((void*)&args1_1, 0, sizeof(args1_1));
|
||||
args1_1.version = JNI_VERSION_1_1;
|
||||
ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */
|
||||
if (args1_1.javaStackSize > 0) {
|
||||
threadStackSize = args1_1.javaStackSize;
|
||||
}
|
||||
}
|
||||
|
||||
{ /* Create a new thread to create JVM and invoke main method */
|
||||
JavaMainArgs args;
|
||||
int rslt;
|
||||
JavaMainArgs args;
|
||||
int rslt;
|
||||
|
||||
args.argc = argc;
|
||||
args.argv = argv;
|
||||
args.mode = mode;
|
||||
args.what = what;
|
||||
args.ifn = *ifn;
|
||||
args.argc = argc;
|
||||
args.argv = argv;
|
||||
args.mode = mode;
|
||||
args.what = what;
|
||||
args.ifn = *ifn;
|
||||
|
||||
rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args);
|
||||
/* If the caller has deemed there is an error we
|
||||
* simply return that, otherwise we return the value of
|
||||
* the callee
|
||||
*/
|
||||
return (ret != 0) ? ret : rslt;
|
||||
rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args);
|
||||
/* If the caller has deemed there is an error we
|
||||
* simply return that, otherwise we return the value of
|
||||
* the callee
|
||||
*/
|
||||
return (ret != 0) ? ret : rslt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -131,4 +131,18 @@ public interface ProcessingEnvironment {
|
||||
* effect
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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.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.msg.XMLMessageFormatter;
|
||||
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 Neeraj Bajaj SUN Microsystems
|
||||
* @author Sunitha Reddy SUN Microsystems
|
||||
* @LastModified: Nov 2018
|
||||
* @LastModified: Apr 2019
|
||||
*/
|
||||
public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
|
||||
@ -412,9 +413,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
/** Augmentations for entities. */
|
||||
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 */
|
||||
private boolean fUseCatalog = true;
|
||||
CatalogFeatures fCatalogFeatures;
|
||||
@ -694,7 +692,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
}
|
||||
|
||||
// wrap this stream in RewindableInputStream
|
||||
stream = new RewindableInputStream(stream);
|
||||
RewindableInputStream rewindableStream = new RewindableInputStream(stream);
|
||||
stream = rewindableStream;
|
||||
|
||||
// perform auto-detect of encoding if necessary
|
||||
if (encoding == null) {
|
||||
@ -702,27 +701,30 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
final byte[] b4 = new byte[4];
|
||||
int count = 0;
|
||||
for (; count<4; count++ ) {
|
||||
b4[count] = (byte)stream.read();
|
||||
b4[count] = (byte)rewindableStream.readAndBuffer();
|
||||
}
|
||||
if (count == 4) {
|
||||
Object [] encodingDesc = getEncodingName(b4, count);
|
||||
encoding = (String)(encodingDesc[0]);
|
||||
isBigEndian = (Boolean)(encodingDesc[1]);
|
||||
|
||||
final EncodingInfo info = getEncodingInfo(b4, count);
|
||||
encoding = info.autoDetectedEncoding;
|
||||
final String readerEncoding = info.readerEncoding;
|
||||
isBigEndian = info.isBigEndian;
|
||||
stream.reset();
|
||||
// Special case UTF-8 files with BOM created by Microsoft
|
||||
// tools. It's more efficient to consume the BOM than make
|
||||
// the reader perform extra checks. -Ac
|
||||
if (count > 2 && encoding.equals("UTF-8")) {
|
||||
int b0 = b4[0] & 0xFF;
|
||||
int b1 = b4[1] & 0xFF;
|
||||
int b2 = b4[2] & 0xFF;
|
||||
if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
|
||||
// ignore first three bytes...
|
||||
if (info.hasBOM) {
|
||||
// Special case UTF-8 files with BOM created by Microsoft
|
||||
// tools. It's more efficient to consume the BOM than make
|
||||
// the reader perform extra checks. -Ac
|
||||
if (EncodingInfo.STR_UTF8.equals(readerEncoding)) {
|
||||
// UTF-8 BOM: 0xEF 0xBB 0xBF
|
||||
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 {
|
||||
reader = createReader(stream, encoding, isBigEndian);
|
||||
}
|
||||
@ -733,11 +735,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
encoding = encoding.toUpperCase(Locale.ENGLISH);
|
||||
|
||||
// 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];
|
||||
int count = 0;
|
||||
for (; count < 3; ++count) {
|
||||
b3[count] = stream.read();
|
||||
b3[count] = rewindableStream.readAndBuffer();
|
||||
if (b3[count] == -1)
|
||||
break;
|
||||
}
|
||||
@ -750,56 +752,51 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
// If encoding is UTF-16, we still need to read the first four bytes
|
||||
// in order to discover the byte order.
|
||||
else if (encoding.equals("UTF-16")) {
|
||||
// If encoding is UTF-16, we still need to read the first
|
||||
// four bytes, in order to discover the byte order.
|
||||
else if (EncodingInfo.STR_UTF16.equals(encoding)) {
|
||||
final int[] b4 = new int[4];
|
||||
int count = 0;
|
||||
for (; count < 4; ++count) {
|
||||
b4[count] = stream.read();
|
||||
b4[count] = rewindableStream.readAndBuffer();
|
||||
if (b4[count] == -1)
|
||||
break;
|
||||
}
|
||||
stream.reset();
|
||||
|
||||
String utf16Encoding = "UTF-16";
|
||||
if (count >= 2) {
|
||||
final int b0 = b4[0];
|
||||
final int b1 = b4[1];
|
||||
if (b0 == 0xFE && b1 == 0xFF) {
|
||||
// UTF-16, big-endian
|
||||
utf16Encoding = "UTF-16BE";
|
||||
isBigEndian = Boolean.TRUE;
|
||||
stream.skip(2);
|
||||
}
|
||||
else if (b0 == 0xFF && b1 == 0xFE) {
|
||||
// UTF-16, little-endian
|
||||
utf16Encoding = "UTF-16LE";
|
||||
isBigEndian = Boolean.FALSE;
|
||||
stream.skip(2);
|
||||
}
|
||||
else if (count == 4) {
|
||||
final int b2 = b4[2];
|
||||
final int b3 = b4[3];
|
||||
if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) {
|
||||
// UTF-16, big-endian, no BOM
|
||||
utf16Encoding = "UTF-16BE";
|
||||
isBigEndian = Boolean.TRUE;
|
||||
}
|
||||
if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) {
|
||||
// UTF-16, little-endian, no BOM
|
||||
utf16Encoding = "UTF-16LE";
|
||||
isBigEndian = Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
reader = createReader(stream, utf16Encoding, isBigEndian);
|
||||
}
|
||||
// If encoding is UCS-4, we still need to read the first four bytes
|
||||
// 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];
|
||||
int count = 0;
|
||||
for (; count < 4; ++count) {
|
||||
b4[count] = stream.read();
|
||||
b4[count] = rewindableStream.readAndBuffer();
|
||||
if (b4[count] == -1)
|
||||
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
|
||||
// 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];
|
||||
int count = 0;
|
||||
for (; count < 4; ++count) {
|
||||
b4[count] = stream.read();
|
||||
b4[count] = rewindableStream.readAndBuffer();
|
||||
if (b4[count] == -1)
|
||||
break;
|
||||
}
|
||||
@ -1798,7 +1795,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
bufferSize.intValue() > DEFAULT_XMLDECL_BUFFER_SIZE) {
|
||||
fBufferSize = bufferSize.intValue();
|
||||
fEntityScanner.setBufferSize(fBufferSize);
|
||||
fBufferPool.setExternalBufferSize(fBufferSize);
|
||||
}
|
||||
}
|
||||
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 count The number of bytes actually read.
|
||||
* @return a 2-element array: the first element, an IANA-encoding string,
|
||||
* 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.
|
||||
* @return an instance of EncodingInfo which represents the auto-detected encoding.
|
||||
*/
|
||||
protected Object[] getEncodingName(byte[] b4, int count) {
|
||||
protected EncodingInfo getEncodingInfo(byte[] b4, int count) {
|
||||
|
||||
if (count < 2) {
|
||||
return defaultEncoding;
|
||||
return EncodingInfo.UTF_8;
|
||||
}
|
||||
|
||||
// UTF-16, with BOM
|
||||
@ -2440,69 +2434,70 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
int b1 = b4[1] & 0xFF;
|
||||
if (b0 == 0xFE && b1 == 0xFF) {
|
||||
// UTF-16, big-endian
|
||||
return new Object [] {"UTF-16BE", true};
|
||||
return EncodingInfo.UTF_16_BIG_ENDIAN_WITH_BOM;
|
||||
}
|
||||
if (b0 == 0xFF && b1 == 0xFE) {
|
||||
// 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
|
||||
// good determination of the encoding
|
||||
if (count < 3) {
|
||||
return defaultEncoding;
|
||||
return EncodingInfo.UTF_8;
|
||||
}
|
||||
|
||||
// UTF-8 with a BOM
|
||||
int b2 = b4[2] & 0xFF;
|
||||
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
|
||||
// good determination of the encoding
|
||||
if (count < 4) {
|
||||
return defaultEncoding;
|
||||
return EncodingInfo.UTF_8;
|
||||
}
|
||||
|
||||
// other encodings
|
||||
int b3 = b4[3] & 0xFF;
|
||||
if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) {
|
||||
// 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) {
|
||||
// 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) {
|
||||
// UCS-4, unusual octet order (2143)
|
||||
// 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) {
|
||||
// UCS-4, unusual octect order (3412)
|
||||
// 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) {
|
||||
// UTF-16, big-endian, no BOM
|
||||
// (or could turn out to be UCS-2...
|
||||
// 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) {
|
||||
// UTF-16, little-endian, no BOM
|
||||
// (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) {
|
||||
// EBCDIC
|
||||
// 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[]
|
||||
|
||||
@ -2517,95 +2512,95 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
* encoding name may be a Java encoding name;
|
||||
* otherwise, it is an ianaEncoding name.
|
||||
* @param isBigEndian For encodings (like uCS-4), whose names cannot
|
||||
* specify a byte order, this tells whether the order is bigEndian. null menas
|
||||
* unknown or not relevant.
|
||||
* specify a byte order, this tells whether the order
|
||||
* is bigEndian. null if unknown or irrelevant.
|
||||
*
|
||||
* @return Returns a reader.
|
||||
*/
|
||||
protected Reader createReader(InputStream inputStream, String encoding, Boolean isBigEndian)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
|
||||
// normalize encoding name
|
||||
if (encoding == null) {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
|
||||
// try to use an optimized reader
|
||||
String ENCODING = encoding.toUpperCase(Locale.ENGLISH);
|
||||
if (ENCODING.equals("UTF-8")) {
|
||||
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) {
|
||||
boolean isBE = isBigEndian.booleanValue();
|
||||
if(isBE) {
|
||||
return new UCSReader(inputStream, UCSReader.UCS4BE);
|
||||
} else {
|
||||
return new UCSReader(inputStream, UCSReader.UCS4LE);
|
||||
String enc = (encoding != null) ? encoding : EncodingInfo.STR_UTF8;
|
||||
enc = enc.toUpperCase(Locale.ENGLISH);
|
||||
MessageFormatter f = fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN);
|
||||
Locale l = fErrorReporter.getLocale();
|
||||
switch (enc) {
|
||||
case EncodingInfo.STR_UTF8:
|
||||
return new UTF8Reader(inputStream, fBufferSize, f, l);
|
||||
case EncodingInfo.STR_UTF16:
|
||||
if (isBigEndian != null) {
|
||||
return new UTF16Reader(inputStream, fBufferSize, isBigEndian, f, l);
|
||||
}
|
||||
} else {
|
||||
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingByteOrderUnsupported",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
if(ENCODING.equals("ISO-10646-UCS-2")) {
|
||||
if(isBigEndian != null) { // sould never happen with this encoding...
|
||||
boolean isBE = isBigEndian.booleanValue();
|
||||
if(isBE) {
|
||||
return new UCSReader(inputStream, UCSReader.UCS2BE);
|
||||
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);
|
||||
} else {
|
||||
return new UCSReader(inputStream, UCSReader.UCS4LE);
|
||||
}
|
||||
} else {
|
||||
return new UCSReader(inputStream, UCSReader.UCS2LE);
|
||||
fErrorReporter.reportError(this.getEntityScanner(),
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingByteOrderUnsupported",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
}
|
||||
} else {
|
||||
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingByteOrderUnsupported",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
}
|
||||
break;
|
||||
case EncodingInfo.STR_UCS2:
|
||||
if(isBigEndian != null) {
|
||||
if(isBigEndian) {
|
||||
return new UCSReader(inputStream, UCSReader.UCS2BE);
|
||||
} else {
|
||||
return new UCSReader(inputStream, UCSReader.UCS2LE);
|
||||
}
|
||||
} else {
|
||||
fErrorReporter.reportError(this.getEntityScanner(),
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingByteOrderUnsupported",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// check for valid name
|
||||
boolean validIANA = XMLChar.isValidIANAEncoding(encoding);
|
||||
boolean validJava = XMLChar.isValidJavaEncoding(encoding);
|
||||
if (!validIANA || (fAllowJavaEncodings && !validJava)) {
|
||||
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
|
||||
fErrorReporter.reportError(this.getEntityScanner(),
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingDeclInvalid",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
// NOTE: AndyH suggested that, on failure, we use ISO Latin 1
|
||||
// because every byte is a valid ISO Latin 1 character.
|
||||
// It may not translate correctly but if we failed on
|
||||
// the encoding anyway, then we're expecting the content
|
||||
// of the document to be bad. This will just prevent an
|
||||
// invalid UTF-8 sequence to be detected. This is only
|
||||
// important when continue-after-fatal-error is turned
|
||||
// on. -Ac
|
||||
// NOTE: AndyH suggested that, on failure, we use ISO Latin 1
|
||||
// because every byte is a valid ISO Latin 1 character.
|
||||
// It may not translate correctly but if we failed on
|
||||
// the encoding anyway, then we're expecting the content
|
||||
// of the document to be bad. This will just prevent an
|
||||
// invalid UTF-8 sequence to be detected. This is only
|
||||
// important when continue-after-fatal-error is turned
|
||||
// on. -Ac
|
||||
encoding = "ISO-8859-1";
|
||||
}
|
||||
|
||||
// try to use a Java reader
|
||||
String javaEncoding = EncodingMap.getIANA2JavaMapping(ENCODING);
|
||||
String javaEncoding = EncodingMap.getIANA2JavaMapping(enc);
|
||||
if (javaEncoding == null) {
|
||||
if(fAllowJavaEncodings) {
|
||||
if (fAllowJavaEncodings) {
|
||||
javaEncoding = encoding;
|
||||
} else {
|
||||
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
|
||||
fErrorReporter.reportError(this.getEntityScanner(),
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"EncodingDeclInvalid",
|
||||
new Object[] { encoding },
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
// see comment above.
|
||||
javaEncoding = "ISO8859_1";
|
||||
// see comment above.
|
||||
javaEncoding = "ISO8859_1";
|
||||
}
|
||||
}
|
||||
if (DEBUG_ENCODINGS) {
|
||||
@ -2898,108 +2893,78 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
} // print()
|
||||
|
||||
/**
|
||||
* Buffer used in entity manager to reuse character arrays instead
|
||||
* of creating new ones every time.
|
||||
* Information about auto-detectable encodings.
|
||||
*
|
||||
* @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 */
|
||||
private char[] ch;
|
||||
/** UTF-8 **/
|
||||
public static final EncodingInfo UTF_8 =
|
||||
new EncodingInfo(STR_UTF8, null, false);
|
||||
|
||||
/** whether the buffer is for an external or internal scanned entity */
|
||||
private boolean isExternal;
|
||||
/** UTF-8, with BOM **/
|
||||
public static final EncodingInfo UTF_8_WITH_BOM =
|
||||
new EncodingInfo(STR_UTF8, null, true);
|
||||
|
||||
public CharacterBuffer(boolean isExternal, int size) {
|
||||
this.isExternal = isExternal;
|
||||
ch = new char[size];
|
||||
}
|
||||
}
|
||||
/** UTF-16, big-endian **/
|
||||
public static final EncodingInfo UTF_16_BIG_ENDIAN =
|
||||
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);
|
||||
|
||||
/**
|
||||
* Stores a number of character buffers and provides it to the entity
|
||||
* manager to use when an entity is seen.
|
||||
*
|
||||
* @xerces.internal
|
||||
*
|
||||
* @author Ankit Pasricha, IBM
|
||||
*/
|
||||
private static class CharacterBufferPool {
|
||||
/** UTF-16, little-endian **/
|
||||
public static final EncodingInfo UTF_16_LITTLE_ENDIAN =
|
||||
new EncodingInfo(STR_UTF16LE, STR_UTF16, Boolean.FALSE, false);
|
||||
|
||||
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;
|
||||
private CharacterBuffer[] fExternalBufferPool;
|
||||
/** UCS-4, big-endian **/
|
||||
public static final EncodingInfo UCS_4_BIG_ENDIAN =
|
||||
new EncodingInfo(STR_UCS4, Boolean.TRUE, false);
|
||||
|
||||
private int fExternalBufferSize;
|
||||
private int fInternalBufferSize;
|
||||
private int poolSize;
|
||||
/** UCS-4, little-endian **/
|
||||
public static final EncodingInfo UCS_4_LITTLE_ENDIAN =
|
||||
new EncodingInfo(STR_UCS4, Boolean.FALSE, false);
|
||||
|
||||
private int fInternalTop;
|
||||
private int fExternalTop;
|
||||
/** UCS-4, unusual byte-order (2143) or (3412) **/
|
||||
public static final EncodingInfo UCS_4_UNUSUAL_BYTE_ORDER =
|
||||
new EncodingInfo(STR_UCS4, null, false);
|
||||
|
||||
public CharacterBufferPool(int externalBufferSize, int internalBufferSize) {
|
||||
this(DEFAULT_POOL_SIZE, externalBufferSize, internalBufferSize);
|
||||
}
|
||||
/** EBCDIC **/
|
||||
public static final EncodingInfo EBCDIC = new EncodingInfo(STR_CP037, null, false);
|
||||
|
||||
public CharacterBufferPool(int poolSize, int externalBufferSize, int internalBufferSize) {
|
||||
fExternalBufferSize = externalBufferSize;
|
||||
fInternalBufferSize = internalBufferSize;
|
||||
this.poolSize = poolSize;
|
||||
init();
|
||||
}
|
||||
public final String autoDetectedEncoding;
|
||||
public final String readerEncoding;
|
||||
public final Boolean isBigEndian;
|
||||
public final boolean hasBOM;
|
||||
|
||||
/** Initializes buffer pool. **/
|
||||
private void init() {
|
||||
fInternalBufferPool = new CharacterBuffer[poolSize];
|
||||
fExternalBufferPool = new CharacterBuffer[poolSize];
|
||||
fInternalTop = -1;
|
||||
fExternalTop = -1;
|
||||
}
|
||||
private EncodingInfo(String autoDetectedEncoding, Boolean isBigEndian, boolean hasBOM) {
|
||||
this(autoDetectedEncoding, autoDetectedEncoding, isBigEndian, hasBOM);
|
||||
} // <init>(String,Boolean,boolean)
|
||||
|
||||
/** Retrieves buffer from pool. **/
|
||||
public CharacterBuffer getBuffer(boolean external) {
|
||||
if (external) {
|
||||
if (fExternalTop > -1) {
|
||||
return fExternalBufferPool[fExternalTop--];
|
||||
}
|
||||
else {
|
||||
return new CharacterBuffer(true, fExternalBufferSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fInternalTop > -1) {
|
||||
return fInternalBufferPool[fInternalTop--];
|
||||
}
|
||||
else {
|
||||
return new CharacterBuffer(false, fInternalBufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
private EncodingInfo(String autoDetectedEncoding, String readerEncoding,
|
||||
Boolean isBigEndian, boolean hasBOM) {
|
||||
this.autoDetectedEncoding = autoDetectedEncoding;
|
||||
this.readerEncoding = readerEncoding;
|
||||
this.isBigEndian = isBigEndian;
|
||||
this.hasBOM = hasBOM;
|
||||
} // <init>(String,String,Boolean,boolean)
|
||||
|
||||
/** Returns buffer to pool. **/
|
||||
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;
|
||||
}
|
||||
}
|
||||
} // class EncodingInfo
|
||||
|
||||
/**
|
||||
* This class wraps the byte inputstreams we're presented with.
|
||||
@ -3052,20 +3017,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
fOffset = fStartOffset;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
int b = 0;
|
||||
if (fOffset < fLength) {
|
||||
return fData[fOffset++] & 0xff;
|
||||
}
|
||||
if (fOffset == fEndOffset) {
|
||||
return -1;
|
||||
}
|
||||
public int readAndBuffer() throws IOException {
|
||||
if (fOffset == fData.length) {
|
||||
byte[] newData = new byte[fOffset << 1];
|
||||
System.arraycopy(fData, 0, newData, 0, fOffset);
|
||||
fData = newData;
|
||||
}
|
||||
b = fInputStream.read();
|
||||
final int b = fInputStream.read();
|
||||
if (b == -1) {
|
||||
fEndOffset = fOffset;
|
||||
return -1;
|
||||
@ -3075,18 +3033,27 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
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 {
|
||||
int bytesLeft = fLength - fOffset;
|
||||
final int bytesLeft = fLength - fOffset;
|
||||
if (bytesLeft == 0) {
|
||||
if (fOffset == fEndOffset) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* //System.out.println("fCurrentEntitty = " + fCurrentEntity );
|
||||
* //System.out.println("fInputStream = " + fInputStream );
|
||||
* // better get some more for the voracious reader... */
|
||||
|
||||
// read a block of data as requested
|
||||
if(fCurrentEntity.mayReadChunks || !fCurrentEntity.xmlDeclChunkRead) {
|
||||
|
||||
if (!fCurrentEntity.xmlDeclChunkRead)
|
||||
@ -3096,15 +3063,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
}
|
||||
return fInputStream.read(b, off, len);
|
||||
}
|
||||
|
||||
int returnedVal = read();
|
||||
if(returnedVal == -1) {
|
||||
fEndOffset = fOffset;
|
||||
return -1;
|
||||
int returnedVal = readAndBuffer();
|
||||
if (returnedVal == -1) {
|
||||
fEndOffset = fOffset;
|
||||
return -1;
|
||||
}
|
||||
b[off] = (byte)returnedVal;
|
||||
return 1;
|
||||
|
||||
}
|
||||
if (len < bytesLeft) {
|
||||
if (len <= 0) {
|
||||
@ -3120,8 +3085,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
return len;
|
||||
}
|
||||
|
||||
public long skip(long n)
|
||||
throws IOException {
|
||||
public long skip(long n) throws IOException {
|
||||
int bytesLeft;
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
@ -3142,7 +3106,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
return bytesLeft;
|
||||
}
|
||||
n -= bytesLeft;
|
||||
/*
|
||||
/*
|
||||
* In a manner of speaking, when this class isn't permitting more
|
||||
* than one byte at a time to be read, it is "blocking". The
|
||||
* available() method should indicate how much can be read without
|
||||
@ -3154,13 +3118,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
int bytesLeft = fLength - fOffset;
|
||||
final int bytesLeft = fLength - fOffset;
|
||||
if (bytesLeft == 0) {
|
||||
if (fOffset == fEndOffset) {
|
||||
return -1;
|
||||
}
|
||||
return fCurrentEntity.mayReadChunks ? fInputStream.available()
|
||||
: 0;
|
||||
: 0;
|
||||
}
|
||||
return bytesLeft;
|
||||
}
|
||||
@ -3171,7 +3135,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||
|
||||
public void reset() {
|
||||
fOffset = fMark;
|
||||
//test();
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Support for preview language features.
|
||||
*/
|
||||
private final Preview preview;
|
||||
|
||||
/** Get the JavacProcessingEnvironment instance for this context. */
|
||||
public static JavacProcessingEnvironment instance(Context context) {
|
||||
JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
|
||||
@ -236,6 +241,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
enter = Enter.instance(context);
|
||||
initialCompleter = ClassFinder.instance(context).getCompleter();
|
||||
chk = Check.instance(context);
|
||||
preview = Preview.instance(context);
|
||||
initProcessorLoader();
|
||||
}
|
||||
|
||||
@ -1675,6 +1681,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
return messages.getCurrentLocale();
|
||||
}
|
||||
|
||||
@DefinedBy(Api.ANNOTATION_PROCESSING)
|
||||
public boolean isPreviewEnabled() {
|
||||
return preview.isEnabled();
|
||||
}
|
||||
|
||||
public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
|
||||
return specifiedPackages;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ import java.util.Objects;
|
||||
* .withNamespace(StandardNamespace.PROPERTY)
|
||||
* .named("color");
|
||||
* </pre>
|
||||
* <h3>Operations on multiple namespaces</h3>
|
||||
* <h2>Operations on multiple namespaces</h2>
|
||||
* If multiple namespaces are specified, the namespaces are treated as
|
||||
* alternatives to each other in order of preference. The semantics of
|
||||
* such operation is "first applicable".
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,6 @@
|
||||
|
||||
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.HtmlTag;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Abstract class to generate the overview files. This will be sub-classed to
|
||||
* generate overview-summary.html.
|
||||
* Abstract class to generate the 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 Atul M Dambalkar
|
||||
* @author Bhavesh Patel (Modified)
|
||||
*/
|
||||
public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
|
||||
|
||||
/**
|
||||
* A Set of Packages to be documented.
|
||||
*/
|
||||
protected SortedSet<PackageElement> packages;
|
||||
public abstract class AbstractOverviewIndexWriter extends HtmlDocletWriter {
|
||||
|
||||
protected Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor. Also initializes the packages variable.
|
||||
* Constructs the AbstractOverviewIndexWriter.
|
||||
*
|
||||
* @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) {
|
||||
super(configuration, filename);
|
||||
packages = configuration.packages;
|
||||
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 description the content for the description META tag
|
||||
* @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 {
|
||||
String windowOverview = resources.getText(title);
|
||||
Content body = getBody(getWindowTitle(windowOverview));
|
||||
@ -116,8 +130,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
|
||||
addNavigationBarHeader(header);
|
||||
Content main = HtmlTree.MAIN();
|
||||
addOverviewHeader(main);
|
||||
addIndex(header, main);
|
||||
addOverview(main);
|
||||
addIndex(main);
|
||||
Content footer = HtmlTree.FOOTER();
|
||||
addNavigationBarFooter(footer);
|
||||
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) { }
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
protected abstract void addIndex(Content main);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
}
|
||||
}
|
@ -53,15 +53,22 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
*
|
||||
* @author Bhavesh Patel
|
||||
*/
|
||||
public class ModuleIndexWriter extends AbstractModuleIndexWriter {
|
||||
public class ModuleIndexWriter extends AbstractOverviewIndexWriter {
|
||||
|
||||
/**
|
||||
* Modules to be documented.
|
||||
*/
|
||||
protected SortedSet<ModuleElement> modules;
|
||||
|
||||
/**
|
||||
* Construct the ModuleIndexWriter.
|
||||
*
|
||||
* @param configuration the configuration object
|
||||
* @param filename the name of the generated file
|
||||
*/
|
||||
public ModuleIndexWriter(HtmlConfiguration configuration, DocPath filename) {
|
||||
super(configuration, filename);
|
||||
modules = configuration.modules;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,46 +80,23 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
|
||||
public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
|
||||
DocPath filename = DocPaths.INDEX;
|
||||
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
|
||||
*/
|
||||
@Override
|
||||
protected void addIndex(Content header, 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) {
|
||||
protected void addIndex(Content main) {
|
||||
Map<String, SortedSet<ModuleElement>> groupModuleMap
|
||||
= configuration.group.groupModules(configuration.modules);
|
||||
= configuration.group.groupModules(modules);
|
||||
|
||||
if (!groupModuleMap.keySet().isEmpty()) {
|
||||
String tableSummary = resources.getText("doclet.Member_Table_Summary",
|
||||
resources.getText("doclet.Module_Summary"), resources.getText("doclet.modules"));
|
||||
TableHeader header = new TableHeader(contents.moduleLabel, contents.descriptionLabel);
|
||||
TableHeader tableHeader = new TableHeader(contents.moduleLabel, contents.descriptionLabel);
|
||||
Table table = new Table(HtmlStyle.overviewSummary)
|
||||
.setHeader(header)
|
||||
.setHeader(tableHeader)
|
||||
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast)
|
||||
.setDefaultTab(resources.getText("doclet.All_Modules"))
|
||||
.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 (!(configuration.nodeprecated && utils.isDeprecated(mdle))) {
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,12 @@ import jdk.javadoc.internal.doclets.toolkit.util.Group;
|
||||
* @author Atul M Dambalkar
|
||||
* @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
|
||||
@ -65,6 +70,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
|
||||
*/
|
||||
public PackageIndexWriter(HtmlConfiguration configuration, DocPath filename) {
|
||||
super(configuration, filename);
|
||||
packages = configuration.packages;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,26 +82,16 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
|
||||
public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
|
||||
DocPath filename = DocPaths.INDEX;
|
||||
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
|
||||
* separate table indices for each package group.
|
||||
* Adds the packages list to the documentation tree.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@Override
|
||||
protected void addIndex(Content header, Content main) {
|
||||
addIndexContents(header, main);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addPackagesList(Content main) {
|
||||
protected void addIndex(Content main) {
|
||||
Map<String, SortedSet<PackageElement>> groupPackageMap
|
||||
= 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);
|
||||
}
|
||||
}
|
||||
|
Before ![]() (image error) Size: 335 B After ![]() (image error) Size: 335 B ![]() ![]() |
Before ![]() (image error) Size: 262 B After ![]() (image error) Size: 262 B ![]() ![]() |
Before ![]() (image error) Size: 262 B After ![]() (image error) Size: 262 B ![]() ![]() |
Before ![]() (image error) Size: 262 B After ![]() (image error) Size: 262 B ![]() ![]() |
Before ![]() (image error) Size: 332 B After ![]() (image error) Size: 332 B ![]() ![]() |
Before ![]() (image error) Size: 280 B After ![]() (image error) Size: 280 B ![]() ![]() |
Before ![]() (image error) Size: 6.8 KiB After ![]() (image error) Size: 6.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 4.4 KiB After ![]() (image error) Size: 4.4 KiB ![]() ![]() |
Before ![]() (image error) Size: 6.8 KiB After ![]() (image error) Size: 6.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 6.8 KiB After ![]() (image error) Size: 6.8 KiB ![]() ![]() |
Before ![]() (image error) Size: 4.4 KiB After ![]() (image error) Size: 4.4 KiB ![]() ![]() |
@ -98,7 +98,6 @@ doclet.Concealed_Packages_Summary=Concealed
|
||||
doclet.From=From
|
||||
doclet.Uses_Summary=Uses
|
||||
doclet.Provides_Summary=Provides
|
||||
doclet.Module_Summary=Module Summary
|
||||
doclet.Interface_Summary=Interface Summary
|
||||
doclet.Annotation_Types_Summary=Annotation Types Summary
|
||||
doclet.Enum_Summary=Enum Summary
|
||||
|
@ -100,7 +100,7 @@ public class DocPaths {
|
||||
public static final DocPath JAVASCRIPT = DocPath.create("script.js");
|
||||
|
||||
/** 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. */
|
||||
public static final DocPath JQUERY_STYLESHEET_FILE = DocPath.create("jquery-ui.css");
|
||||
|
@ -39,11 +39,11 @@ package jdk.nashorn.internal.runtime.linker;
|
||||
* to nashorn module.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Comment from BytecodeName class reproduced here:</h3>
|
||||
* <h2>Comment from BytecodeName class reproduced here:</h2>
|
||||
*
|
||||
* Includes universal mangling rules for the JVM.
|
||||
*
|
||||
* <h3>Avoiding Dangerous Characters </h3>
|
||||
* <h2>Avoiding Dangerous Characters </h2>
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* </p>
|
||||
* <h3> Replacement Characters </h3>
|
||||
* <h2> Replacement Characters </h2>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
@ -159,7 +159,7 @@ package jdk.nashorn.internal.runtime.linker;
|
||||
* to check for dangerous characters.
|
||||
*
|
||||
* </p>
|
||||
* <h3> Nice Properties </h3>
|
||||
* <h2> Nice Properties </h2>
|
||||
*
|
||||
* <p>
|
||||
* If a bytecode name does not contain any escape sequence,
|
||||
@ -222,7 +222,7 @@ package jdk.nashorn.internal.runtime.linker;
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* <h3> Suggestions for Human Readable Presentations </h3>
|
||||
* <h2> Suggestions for Human Readable Presentations </h2>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
|
@ -30,7 +30,7 @@
|
||||
* Nashorn is a runtime environment for programs written in ECMAScript 5.1.
|
||||
* </p>
|
||||
*
|
||||
* <h1>Usage</h1>
|
||||
* <h2>Usage</h2>
|
||||
*
|
||||
* The recommended way to use Nashorn is through the
|
||||
* <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
|
||||
* {@link jdk.nashorn.api.scripting} package for details.
|
||||
* <h1>Compatibility</h1>
|
||||
* <h2>Compatibility</h2>
|
||||
* Nashorn is 100% compliant with the
|
||||
* <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* the {@code length} property.
|
||||
*
|
||||
* <h2>ECMAScript primitive types</h2>
|
||||
* <h3>ECMAScript primitive types</h3>
|
||||
*
|
||||
* ECMAScript primitive types for number, string, and boolean are represented
|
||||
* 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
|
||||
* {@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
|
||||
* 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
|
||||
* the required type is passed.
|
||||
*
|
||||
* <h2>SAM types</h2>
|
||||
* <h3>SAM types</h3>
|
||||
*
|
||||
* 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
|
||||
@ -122,14 +122,14 @@ ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn"
|
||||
* the same name</em>. This is done to be consistent with the fact that
|
||||
* 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
|
||||
* the primary API entry point into Java platform-specific functionality.
|
||||
* You can use it to create instances of Java classes, convert from Java arrays
|
||||
* 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
|
||||
* non-standard built-in objects:
|
||||
|
163
test/hotspot/jtreg/containers/docker/JfrNetwork.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -22,53 +22,30 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import jdk.jfr.Recording;
|
||||
import jdk.jfr.ValueDescriptor;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
import jdk.jfr.consumer.RecordingFile;
|
||||
|
||||
|
||||
// This class is intended to run inside a container
|
||||
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 {
|
||||
String testCase = args[0];
|
||||
System.out.println("Testcase: " + testCase);
|
||||
switch (testCase) {
|
||||
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");
|
||||
String eventName = args[0];
|
||||
try(Recording r = new Recording()) {
|
||||
r.enable(eventName);
|
||||
r.start();
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.stop();
|
||||
|
||||
RecordedEvent recordedEvent = RecordingFile.readAllEvents(r.getDestination()).get(0);
|
||||
System.out.println("RecordedEvent: " + recordedEvent);
|
||||
return recordedEvent;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,8 @@
|
||||
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.Asserts;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
|
||||
@ -68,6 +70,7 @@ public class TestJFREvents {
|
||||
|
||||
testProcessInfo();
|
||||
|
||||
testEnvironmentVariables();
|
||||
} finally {
|
||||
DockerTestUtils.removeDockerImage(imageName);
|
||||
}
|
||||
@ -79,14 +82,12 @@ public class TestJFREvents {
|
||||
DockerTestUtils.dockerRunJava(
|
||||
commonDockerOpts()
|
||||
.addDockerOpts("--cpus=" + valueToSet)
|
||||
.addClassOptions(JfrReporter.TESTCASE_CPU))
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain(JfrReporter.TEST_REPORTED_CORES);
|
||||
|
||||
.addClassOptions("jdk.CPUInformation"))
|
||||
.shouldHaveExitValue(0);
|
||||
// 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.
|
||||
// @ignore 8219999
|
||||
// .shouldContain(JfrReporter.TEST_REPORTED_CORES + "=" + expectedValue);
|
||||
// .shouldContain("cores = " + expectedValue");
|
||||
}
|
||||
|
||||
|
||||
@ -95,9 +96,9 @@ public class TestJFREvents {
|
||||
DockerTestUtils.dockerRunJava(
|
||||
commonDockerOpts()
|
||||
.addDockerOpts("--memory=" + valueToSet)
|
||||
.addClassOptions(JfrReporter.TESTCASE_MEMORY))
|
||||
.addClassOptions("jdk.PhysicalMemory"))
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain(JfrReporter.TEST_REPORTED_MEMORY + "=" + expectedValue);
|
||||
.shouldContain("totalSize = " + expectedValue);
|
||||
}
|
||||
|
||||
|
||||
@ -105,10 +106,9 @@ public class TestJFREvents {
|
||||
Common.logNewTestCase("ProcessInfo");
|
||||
DockerTestUtils.dockerRunJava(
|
||||
commonDockerOpts()
|
||||
.addClassOptions(JfrReporter.TESTCASE_PROCESS))
|
||||
.addClassOptions("jdk.SystemProcess"))
|
||||
.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/")
|
||||
.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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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"
|
||||
};
|
||||
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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");
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*/
|
||||
@ -193,6 +198,7 @@ public class TooSmallStackSize {
|
||||
min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "64");
|
||||
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed);
|
||||
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "513");
|
||||
checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "0");
|
||||
|
||||
/*
|
||||
* 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");
|
||||
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed);
|
||||
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "513");
|
||||
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "0");
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,19 +22,22 @@
|
||||
*/
|
||||
package parsers;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8169450
|
||||
* @bug 8169450 8222415
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true parsers.BaseParsingTest
|
||||
* @run testng/othervm parsers.BaseParsingTest
|
||||
@ -143,7 +146,7 @@ public class BaseParsingTest {
|
||||
* @bug 8169450
|
||||
* 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
|
||||
* 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
|
||||
* @throws Exception if the parser fails to parse the xml
|
||||
@ -151,8 +154,24 @@ public class BaseParsingTest {
|
||||
@Test(dataProvider = "xmlDeclarations")
|
||||
public void testWithDOM(String xml) throws Exception {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setValidating(true);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,14 @@ public class UnixSocketFile {
|
||||
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
|
||||
// 'nc' will create the socket file.
|
||||
String testSubDir = System.getProperty("test.dir", ".")
|
||||
|
82
test/jdk/javax/net/ssl/SSLSocket/InputStreamClosure.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
82
test/jdk/javax/net/ssl/SSLSocket/OutputStreamClosure.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
@ -68,6 +68,7 @@ public class Settings extends TestHelper {
|
||||
private static final String PROP_SETTINGS = "Property settings:";
|
||||
private static final String LOCALE_SETTINGS = "Locale settings:";
|
||||
private static final String SYSTEM_SETTINGS = "Operating System Metrics:";
|
||||
private static final String STACKSIZE_SETTINGS = "Stack Size:";
|
||||
|
||||
static void containsAllOptions(TestResult tr) {
|
||||
checkContains(tr, VM_SETTINGS);
|
||||
@ -82,10 +83,22 @@ public class Settings extends TestHelper {
|
||||
int stackSize = 256; // in kb
|
||||
if (getArch().equals("ppc64") || getArch().equals("ppc64le")) {
|
||||
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;
|
||||
tr = doExec(javaCmd, "-Xms64m", "-Xmx512m",
|
||||
"-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);
|
||||
if (!tr.isOK()) {
|
||||
System.out.println(tr);
|
||||
@ -93,6 +106,7 @@ public class Settings extends TestHelper {
|
||||
}
|
||||
tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m",
|
||||
"-Xss" + (stackSize * 1024), "-XshowSettings", "-jar", testJar.getAbsolutePath());
|
||||
checkContains(tr, STACKSIZE_SETTINGS);
|
||||
containsAllOptions(tr);
|
||||
if (!tr.isOK()) {
|
||||
System.out.println(tr);
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6762191
|
||||
* @bug 6762191 8222334
|
||||
* @summary Setting stack size to 16K causes segmentation fault
|
||||
* @compile TooSmallStackSize.java
|
||||
* @run main TooSmallStackSize
|
||||
@ -171,5 +171,11 @@ public class TooSmallStackSize extends TestHelper {
|
||||
* asserts added for 8176768 are not triggered.
|
||||
*/
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -7,15 +7,15 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="date" content="(removed)">
|
||||
<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="jquery/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/dist/jszip.min.js"></script>
|
||||
<script type="text/javascript" src="script-dir/jszip-utils/dist/jszip-utils.min.js"></script>
|
||||
<!--[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]-->
|
||||
<script type="text/javascript" src="jquery/jquery-1.10.2.js"></script>
|
||||
<script type="text/javascript" src="jquery/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script-dir/jquery-1.10.2.js"></script>
|
||||
<script type="text/javascript" src="script-dir/jquery-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript"><!--
|
||||
|
@ -386,15 +386,15 @@ public class TestSearch extends JavadocTester {
|
||||
void checkSearchOutput(String fileName, boolean expectedOutput, boolean moduleDirectoriesVar) {
|
||||
// Test for search related markup
|
||||
checkOutput(fileName, expectedOutput,
|
||||
"<link rel=\"stylesheet\" type=\"text/css\" href=\"jquery/jquery-ui.css\" title=\"Style\">\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jszip/dist/jszip.min.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jszip-utils/dist/jszip-utils.min.js\"></script>\n",
|
||||
"<link rel=\"stylesheet\" type=\"text/css\" href=\"script-dir/jquery-ui.css\" title=\"Style\">\n",
|
||||
"<script type=\"text/javascript\" src=\"script-dir/jszip/dist/jszip.min.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"script-dir/jszip-utils/dist/jszip-utils.min.js\"></script>\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",
|
||||
"<script type=\"text/javascript\" src=\"jquery/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=\"jquery/jquery-ui.js\"></script>",
|
||||
"<script type=\"text/javascript\" src=\"script-dir/jquery-3.3.1.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"script-dir/jquery-migrate-3.0.1.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"script-dir/jquery-ui.js\"></script>",
|
||||
"var pathtoroot = \"./\";\n"
|
||||
+ "var useModuleDirectories = " + moduleDirectoriesVar + ";\n"
|
||||
+ "loadScripts(document, 'script');",
|
||||
@ -585,32 +585,32 @@ public class TestSearch extends JavadocTester {
|
||||
void checkJqueryAndImageFiles(boolean expectedOutput) {
|
||||
checkFiles(expectedOutput,
|
||||
"search.js",
|
||||
"jquery/jquery-3.3.1.js",
|
||||
"jquery/jquery-migrate-3.0.1.js",
|
||||
"jquery/jquery-ui.js",
|
||||
"jquery/jquery-ui.css",
|
||||
"jquery/jquery-ui.min.js",
|
||||
"jquery/jquery-ui.min.css",
|
||||
"jquery/jquery-ui.structure.min.css",
|
||||
"jquery/jquery-ui.structure.css",
|
||||
"jquery/external/jquery/jquery.js",
|
||||
"jquery/jszip/dist/jszip.js",
|
||||
"jquery/jszip/dist/jszip.min.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils.min.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils-ie.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils-ie.min.js",
|
||||
"jquery/images/ui-bg_glass_65_dadada_1x400.png",
|
||||
"jquery/images/ui-icons_454545_256x240.png",
|
||||
"jquery/images/ui-bg_glass_95_fef1ec_1x400.png",
|
||||
"jquery/images/ui-bg_glass_75_dadada_1x400.png",
|
||||
"jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
|
||||
"jquery/images/ui-icons_888888_256x240.png",
|
||||
"jquery/images/ui-icons_2e83ff_256x240.png",
|
||||
"jquery/images/ui-icons_cd0a0a_256x240.png",
|
||||
"jquery/images/ui-bg_glass_55_fbf9ee_1x400.png",
|
||||
"jquery/images/ui-icons_222222_256x240.png",
|
||||
"jquery/images/ui-bg_glass_75_e6e6e6_1x400.png",
|
||||
"script-dir/jquery-3.3.1.js",
|
||||
"script-dir/jquery-migrate-3.0.1.js",
|
||||
"script-dir/jquery-ui.js",
|
||||
"script-dir/jquery-ui.css",
|
||||
"script-dir/jquery-ui.min.js",
|
||||
"script-dir/jquery-ui.min.css",
|
||||
"script-dir/jquery-ui.structure.min.css",
|
||||
"script-dir/jquery-ui.structure.css",
|
||||
"script-dir/external/jquery/jquery.js",
|
||||
"script-dir/jszip/dist/jszip.js",
|
||||
"script-dir/jszip/dist/jszip.min.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils.min.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils-ie.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils-ie.min.js",
|
||||
"script-dir/images/ui-bg_glass_65_dadada_1x400.png",
|
||||
"script-dir/images/ui-icons_454545_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_95_fef1ec_1x400.png",
|
||||
"script-dir/images/ui-bg_glass_75_dadada_1x400.png",
|
||||
"script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
|
||||
"script-dir/images/ui-icons_888888_256x240.png",
|
||||
"script-dir/images/ui-icons_2e83ff_256x240.png",
|
||||
"script-dir/images/ui-icons_cd0a0a_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png",
|
||||
"script-dir/images/ui-icons_222222_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png",
|
||||
"resources/x.png",
|
||||
"resources/glass.png");
|
||||
}
|
||||
|
@ -197,32 +197,32 @@ class APITest {
|
||||
"help-doc.html",
|
||||
"index-all.html",
|
||||
"index.html",
|
||||
"jquery/jquery-3.3.1.js",
|
||||
"jquery/jquery-migrate-3.0.1.js",
|
||||
"jquery/jquery-ui.js",
|
||||
"jquery/jquery-ui.css",
|
||||
"jquery/jquery-ui.min.js",
|
||||
"jquery/jquery-ui.min.css",
|
||||
"jquery/jquery-ui.structure.min.css",
|
||||
"jquery/jquery-ui.structure.css",
|
||||
"jquery/external/jquery/jquery.js",
|
||||
"jquery/jszip/dist/jszip.js",
|
||||
"jquery/jszip/dist/jszip.min.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils.min.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils-ie.js",
|
||||
"jquery/jszip-utils/dist/jszip-utils-ie.min.js",
|
||||
"jquery/images/ui-bg_glass_65_dadada_1x400.png",
|
||||
"jquery/images/ui-icons_454545_256x240.png",
|
||||
"jquery/images/ui-bg_glass_95_fef1ec_1x400.png",
|
||||
"jquery/images/ui-bg_glass_75_dadada_1x400.png",
|
||||
"jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
|
||||
"jquery/images/ui-icons_888888_256x240.png",
|
||||
"jquery/images/ui-icons_2e83ff_256x240.png",
|
||||
"jquery/images/ui-icons_cd0a0a_256x240.png",
|
||||
"jquery/images/ui-bg_glass_55_fbf9ee_1x400.png",
|
||||
"jquery/images/ui-icons_222222_256x240.png",
|
||||
"jquery/images/ui-bg_glass_75_e6e6e6_1x400.png",
|
||||
"script-dir/jquery-3.3.1.js",
|
||||
"script-dir/jquery-migrate-3.0.1.js",
|
||||
"script-dir/jquery-ui.js",
|
||||
"script-dir/jquery-ui.css",
|
||||
"script-dir/jquery-ui.min.js",
|
||||
"script-dir/jquery-ui.min.css",
|
||||
"script-dir/jquery-ui.structure.min.css",
|
||||
"script-dir/jquery-ui.structure.css",
|
||||
"script-dir/external/jquery/jquery.js",
|
||||
"script-dir/jszip/dist/jszip.js",
|
||||
"script-dir/jszip/dist/jszip.min.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils.min.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils-ie.js",
|
||||
"script-dir/jszip-utils/dist/jszip-utils-ie.min.js",
|
||||
"script-dir/images/ui-bg_glass_65_dadada_1x400.png",
|
||||
"script-dir/images/ui-icons_454545_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_95_fef1ec_1x400.png",
|
||||
"script-dir/images/ui-bg_glass_75_dadada_1x400.png",
|
||||
"script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
|
||||
"script-dir/images/ui-icons_888888_256x240.png",
|
||||
"script-dir/images/ui-icons_2e83ff_256x240.png",
|
||||
"script-dir/images/ui-icons_cd0a0a_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png",
|
||||
"script-dir/images/ui-icons_222222_256x240.png",
|
||||
"script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png",
|
||||
"member-search-index.js",
|
||||
"member-search-index.zip",
|
||||
"overview-tree.html",
|
||||
@ -242,7 +242,7 @@ class APITest {
|
||||
));
|
||||
|
||||
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("allclasses-index.html") && !s.equals("allpackages-index.html"))
|
||||
.collect(Collectors.toSet());
|
||||
|
@ -134,6 +134,8 @@ public class BadConstantValue {
|
||||
"class Lib { static final int A = %s; static final %s B = %s; }",
|
||||
value, type, (type.equals("boolean") ? "false" : "0")));
|
||||
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");
|
||||
// Rewrite the class to only have field B of type "type" and with "value" (potentially
|
||||
// out of range).
|
||||
@ -147,6 +149,8 @@ public class BadConstantValue {
|
||||
"class Lib { static final String A = \"hello\"; static final %s CONST = %s; }",
|
||||
type, type.equals("boolean") ? "false" : "0"));
|
||||
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");
|
||||
swapConstantValues(libClass);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -62,6 +62,11 @@ public class StringConcat {
|
||||
return "string" + stringValue;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String concatMethodConstString() {
|
||||
return "string".concat(stringValue);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String concatConstIntConstInt() {
|
||||
return "string" + intValue + "string" + intValue;
|
||||
|