This commit is contained in:
Jesper Wilhelmsson 2021-06-17 01:05:54 +00:00
commit 3637e50b30
33 changed files with 538 additions and 209 deletions

View File

@ -10,7 +10,7 @@ on:
platforms:
description: "Platform(s) to execute on"
required: true
default: "Linux additional (hotspot only), Linux x64, Linux x86, Windows aarch64, Windows x64, macOS x64"
default: "Linux additional (hotspot only), Linux x64, Linux x86, Windows x64, macOS x64"
jobs:
prerequisites:
@ -22,7 +22,6 @@ jobs:
platform_linux_additional: ${{ steps.check_platforms.outputs.platform_linux_additional }}
platform_linux_x64: ${{ steps.check_platforms.outputs.platform_linux_x64 }}
platform_linux_x86: ${{ steps.check_platforms.outputs.platform_linux_x86 }}
platform_windows_aarch64: ${{ steps.check_platforms.outputs.platform_windows_aarch64 }}
platform_windows_x64: ${{ steps.check_platforms.outputs.platform_windows_x64 }}
platform_macos_x64: ${{ steps.check_platforms.outputs.platform_macos_x64 }}
platform_macos_aarch64: ${{ steps.check_platforms.outputs.platform_macos_aarch64 }}
@ -39,7 +38,6 @@ jobs:
echo "::set-output name=platform_linux_additional::${{ contains(github.event.inputs.platforms, 'linux additional (hotspot only)') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'linux additional (hotspot only)'))) }}"
echo "::set-output name=platform_linux_x64::${{ contains(github.event.inputs.platforms, 'linux x64') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'linux x64'))) }}"
echo "::set-output name=platform_linux_x86::${{ contains(github.event.inputs.platforms, 'linux x86') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'linux x86'))) }}"
echo "::set-output name=platform_windows_aarch64::${{ contains(github.event.inputs.platforms, 'windows aarch64') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'windows aarch64'))) }}"
echo "::set-output name=platform_windows_x64::${{ contains(github.event.inputs.platforms, 'windows x64') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'windows x64'))) }}"
echo "::set-output name=platform_macos_x64::${{ contains(github.event.inputs.platforms, 'macos x64') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'macos x64'))) }}"
echo "::set-output name=platform_macos_aarch64::${{ contains(github.event.inputs.platforms, 'macos aarch64') || (github.event.inputs.platforms == '' && (secrets.JDK_SUBMIT_PLATFORMS == '' || contains(secrets.JDK_SUBMIT_PLATFORMS, 'macos aarch64'))) }}"
@ -849,94 +847,6 @@ jobs:
path: ~/linux-x86${{ matrix.artifact }}_testsupport_${{ env.logsuffix }}.zip
continue-on-error: true
windows_aarch64_build:
name: Windows aarch64
runs-on: "windows-2019"
needs: prerequisites
if: needs.prerequisites.outputs.should_run != 'false' && needs.prerequisites.outputs.platform_windows_aarch64 != 'false'
strategy:
fail-fast: false
matrix:
flavor:
- build debug
include:
- flavor: build debug
flags: --enable-debug
artifact: -debug
env:
JDK_VERSION: "${{ fromJson(needs.prerequisites.outputs.dependencies).DEFAULT_VERSION_FEATURE }}"
BOOT_JDK_VERSION: "${{ fromJson(needs.prerequisites.outputs.dependencies).BOOT_JDK_VERSION }}"
BOOT_JDK_FILENAME: "${{ fromJson(needs.prerequisites.outputs.dependencies).WINDOWS_X64_BOOT_JDK_FILENAME }}"
BOOT_JDK_URL: "${{ fromJson(needs.prerequisites.outputs.dependencies).WINDOWS_X64_BOOT_JDK_URL }}"
BOOT_JDK_SHA256: "${{ fromJson(needs.prerequisites.outputs.dependencies).WINDOWS_X64_BOOT_JDK_SHA256 }}"
steps:
- name: Restore cygwin packages from cache
id: cygwin
uses: actions/cache@v2
with:
path: ~/cygwin/packages
key: cygwin-packages-${{ runner.os }}-v1
- name: Install cygwin
run: |
New-Item -Force -ItemType directory -Path "$HOME\cygwin"
& curl -L "https://www.cygwin.com/setup-x86_64.exe" -o "$HOME/cygwin/setup-x86_64.exe"
Start-Process -FilePath "$HOME\cygwin\setup-x86_64.exe" -ArgumentList "--quiet-mode --packages autoconf,make,zip,unzip --root $HOME\cygwin\cygwin64 --local-package-dir $HOME\cygwin\packages --site http://mirrors.kernel.org/sourceware/cygwin --no-desktop --no-shortcuts --no-startmenu --no-admin" -Wait -NoNewWindow
- name: Checkout the source
uses: actions/checkout@v2
with:
path: jdk
- name: Restore boot JDK from cache
id: bootjdk
uses: actions/cache@v2
with:
path: ~/bootjdk/${{ env.BOOT_JDK_VERSION }}
key: bootjdk-${{ runner.os }}-${{ env.BOOT_JDK_VERSION }}-${{ env.BOOT_JDK_SHA256 }}-v1
- name: Download boot JDK
run: |
mkdir -p "$HOME\bootjdk\$env:BOOT_JDK_VERSION"
& curl -L "$env:BOOT_JDK_URL" -o "$HOME/bootjdk/$env:BOOT_JDK_FILENAME"
$FileHash = Get-FileHash -Algorithm SHA256 "$HOME/bootjdk/$env:BOOT_JDK_FILENAME"
$FileHash.Hash -eq $env:BOOT_JDK_SHA256
& tar -xf "$HOME/bootjdk/$env:BOOT_JDK_FILENAME" -C "$HOME/bootjdk/$env:BOOT_JDK_VERSION"
Get-ChildItem "$HOME\bootjdk\$env:BOOT_JDK_VERSION\*\*" | Move-Item -Destination "$HOME\bootjdk\$env:BOOT_JDK_VERSION"
if: steps.bootjdk.outputs.cache-hit != 'true'
- name: Ensure a specific version of MSVC is installed
run: >
Start-Process -FilePath 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe' -Wait -NoNewWindow -ArgumentList
'modify --installPath "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise" --quiet
--add Microsoft.VisualStudio.Component.VC.14.28.arm64'
- name: Configure
run: >
$env:Path = "$HOME\cygwin\cygwin64\bin;$HOME\cygwin\cygwin64\bin;$env:Path" ;
$env:Path = $env:Path -split ";" -match "C:\\Windows|PowerShell|cygwin" -join ";" ;
$env:BOOT_JDK = cygpath "$HOME/bootjdk/$env:BOOT_JDK_VERSION" ;
& bash configure
--with-conf-name=windows-aarch64
--with-msvc-toolset-version=14.28
--openjdk-target=aarch64-unknown-cygwin
${{ matrix.flags }}
--with-version-opt="$env:GITHUB_ACTOR-$env:GITHUB_SHA"
--with-version-build=0
--with-boot-jdk="$env:BOOT_JDK"
--with-default-make-target="hotspot"
working-directory: jdk
- name: Build
run: |
$env:Path = "$HOME\cygwin\cygwin64\bin;$HOME\cygwin\cygwin64\bin;$env:Path" ;
$env:Path = $env:Path -split ";" -match "C:\\Windows|PowerShell|cygwin" -join ";" ;
& make CONF_NAME=windows-aarch64
working-directory: jdk
windows_x64_build:
name: Windows x64
runs-on: "windows-2019"
@ -1661,7 +1571,6 @@ jobs:
needs:
- prerequisites
- linux_additional_build
- windows_aarch64_build
- linux_x64_test
- linux_x86_test
- windows_x64_test

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://###MODULE_DIR###/###MODULE_CONTENT###">
###SOURCE_DIRS###
</content>
<orderEntry type="sourceFolder" forTests="false" />
###DEPENDENCIES###
<orderEntry type="inheritedJdk" />
</component>
</module>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://###MODULE_DIR###/test/jdk"></content>
<orderEntry type="sourceFolder" forTests="true" />
###TEST_MODULE_DEPENDENCIES###
<orderEntry type="inheritedJdk" />
</component>
</module>

View File

@ -1406,7 +1406,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
}
if (addr->Opcode() == Op_AddP) {
Node* orig_base = addr->in(AddPNode::Base);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), true);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::StrongDependency);
phase->register_new_node(base, ctrl);
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
// Field access

View File

@ -39,7 +39,7 @@ Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
if (dom != NULL) {
return dom;
}
if (_carry_dependency) {
if (_dependency != RegularDependency) {
return this;
}
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
@ -82,46 +82,46 @@ Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
bool ConstraintCastNode::cmp(const Node &n) const {
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._carry_dependency == _carry_dependency;
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency;
}
uint ConstraintCastNode::size_of() const {
return sizeof(*this);
}
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency) {
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) {
switch(opcode) {
case Op_CastII: {
Node* cast = new CastIINode(n, t, carry_dependency);
Node* cast = new CastIINode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastLL: {
Node* cast = new CastLLNode(n, t, carry_dependency);
Node* cast = new CastLLNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastPP: {
Node* cast = new CastPPNode(n, t, carry_dependency);
Node* cast = new CastPPNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastFF: {
Node* cast = new CastFFNode(n, t, carry_dependency);
Node* cast = new CastFFNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastDD: {
Node* cast = new CastDDNode(n, t, carry_dependency);
Node* cast = new CastDDNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastVV: {
Node* cast = new CastVVNode(n, t, carry_dependency);
Node* cast = new CastVVNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, carry_dependency);
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency);
default:
fatal("Bad opcode %d", opcode);
}
@ -131,10 +131,10 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
switch(bt) {
case T_INT: {
return make_cast(Op_CastII, c, n, t, false);
return make_cast(Op_CastII, c, n, t, RegularDependency);
}
case T_LONG: {
return make_cast(Op_CastLL, c, n, t, false);
return make_cast(Op_CastLL, c, n, t, RegularDependency);
}
default:
fatal("Bad basic type %s", type2name(bt));
@ -143,6 +143,9 @@ Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
}
TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const {
if (_dependency == UnconditionalDependency) {
return NULL;
}
Node* val = in(1);
Node* ctl = in(0);
int opc = Opcode();
@ -183,8 +186,8 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
#ifndef PRODUCT
void ConstraintCastNode::dump_spec(outputStream *st) const {
TypeNode::dump_spec(st);
if (_carry_dependency) {
st->print(" carry dependency");
if (_dependency != RegularDependency) {
st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional");
}
}
#endif
@ -194,7 +197,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
// Try to improve the type of the CastII if we recognize a CmpI/If
// pattern.
if (_carry_dependency) {
if (_dependency != RegularDependency) {
if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
Node* proj = in(0);
@ -255,8 +258,8 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
return res;
}
static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, bool carry_dependency) {
Node* n = new CastIINode(parent, type, carry_dependency);
static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, ConstraintCastNode::DependencyType dependency) {
Node* n = new CastIINode(parent, type, dependency);
n->set_req(0, control);
Node* existing = igvn->hash_find_insert(n);
if (existing != NULL) {
@ -289,8 +292,8 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* x = z->in(1);
Node* y = z->in(2);
Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _carry_dependency);
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _carry_dependency);
Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _dependency);
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _dependency);
switch (op) {
case Op_AddI: return new AddINode(cx, cy);
case Op_SubI: return new SubINode(cx, cy);
@ -377,7 +380,7 @@ Node* CheckCastPPNode::Identity(PhaseGVN* phase) {
if (dom != NULL) {
return dom;
}
if (_carry_dependency) {
if (_dependency != RegularDependency) {
return this;
}
const Type* t = phase->type(in(1));
@ -573,20 +576,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
return this;
}
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type) {
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) {
Node* cast= NULL;
if (type->isa_int()) {
cast = make_cast(Op_CastII, c, in, type, true);
cast = make_cast(Op_CastII, c, in, type, dependency);
} else if (type->isa_long()) {
cast = make_cast(Op_CastLL, c, in, type, true);
cast = make_cast(Op_CastLL, c, in, type, dependency);
} else if (type->isa_float()) {
cast = make_cast(Op_CastFF, c, in, type, true);
cast = make_cast(Op_CastFF, c, in, type, dependency);
} else if (type->isa_double()) {
cast = make_cast(Op_CastDD, c, in, type, true);
cast = make_cast(Op_CastDD, c, in, type, dependency);
} else if (type->isa_vect()) {
cast = make_cast(Op_CastVV, c, in, type, true);
cast = make_cast(Op_CastVV, c, in, type, dependency);
} else if (type->isa_ptr()) {
cast = make_cast(Op_CastPP, c, in, type, true);
cast = make_cast(Op_CastPP, c, in, type, dependency);
}
return cast;
}

View File

@ -32,15 +32,21 @@
//------------------------------ConstraintCastNode-----------------------------
// cast to a different range
class ConstraintCastNode: public TypeNode {
public:
enum DependencyType {
RegularDependency, // if cast doesn't improve input type, cast can be removed
StrongDependency, // leave cast in even if _type doesn't improve input type, can be replaced by stricter dominating cast if one exist
UnconditionalDependency // leave cast in unconditionally
};
protected:
// Can this node be removed post CCP or does it carry a required dependency?
const bool _carry_dependency;
const DependencyType _dependency;
virtual bool cmp( const Node &n ) const;
virtual uint size_of() const;
public:
ConstraintCastNode(Node *n, const Type *t, bool carry_dependency)
: TypeNode(t,2), _carry_dependency(carry_dependency) {
ConstraintCastNode(Node *n, const Type *t, DependencyType dependency)
: TypeNode(t,2), _dependency(dependency) {
init_class_id(Class_ConstraintCast);
init_req(1, n);
}
@ -49,10 +55,10 @@ class ConstraintCastNode: public TypeNode {
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual int Opcode() const;
virtual uint ideal_reg() const = 0;
virtual bool depends_only_on_test() const { return !_carry_dependency; }
bool carry_dependency() const { return _carry_dependency; }
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
bool carry_dependency() const { return _dependency != RegularDependency; }
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency);
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency);
static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
@ -63,7 +69,7 @@ class ConstraintCastNode: public TypeNode {
virtual void dump_spec(outputStream *st) const;
#endif
static Node* make_cast_for_type(Node* c, Node* in, const Type* type);
static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency);
};
//------------------------------CastIINode-------------------------------------
@ -76,12 +82,12 @@ class CastIINode: public ConstraintCastNode {
virtual uint size_of() const;
public:
CastIINode(Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
}
CastIINode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
init_req(0, ctrl);
}
@ -110,13 +116,13 @@ class CastIINode: public ConstraintCastNode {
class CastLLNode: public ConstraintCastNode {
public:
CastLLNode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
init_class_id(Class_CastLL);
init_req(0, ctrl);
}
CastLLNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastLL);
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
@ -129,8 +135,8 @@ public:
class CastFFNode: public ConstraintCastNode {
public:
CastFFNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastFF);
}
virtual int Opcode() const;
@ -139,8 +145,8 @@ public:
class CastDDNode: public ConstraintCastNode {
public:
CastDDNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastDD);
}
virtual int Opcode() const;
@ -149,8 +155,8 @@ public:
class CastVVNode: public ConstraintCastNode {
public:
CastVVNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastVV);
}
virtual int Opcode() const;
@ -162,8 +168,8 @@ public:
// cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode {
public:
CastPPNode (Node *n, const Type *t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
@ -173,8 +179,8 @@ class CastPPNode: public ConstraintCastNode {
// for _checkcast, cast pointer to pointer (different type), without JOIN,
class CheckCastPPNode: public ConstraintCastNode {
public:
CheckCastPPNode(Node *c, Node *n, const Type *t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
init_class_id(Class_CheckCastPP);
init_req(0, c);
}

View File

@ -1975,7 +1975,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (phi_type->isa_ptr()) {
const Type* uin_type = phase->type(uin);
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
} else {
// Use a CastPP for a cast to not null and a CheckCastPP for
// a cast to a new klass (and both if both null-ness and
@ -1985,7 +1985,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// null, uin's type must be casted to not null
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency);
}
// If the type of phi and uin, both casted to not null,
@ -1997,14 +1997,14 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = phase->transform(cast);
n = cast;
}
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true);
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency);
}
if (cast == NULL) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
}
}
} else {
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type);
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency);
}
assert(cast != NULL, "cast should be set");
cast = phase->transform(cast);

View File

@ -4135,7 +4135,7 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
if (ctrl != NULL) {
// Express control dependency by a CastII node with a narrow type.
value = new CastIINode(value, itype, carry_dependency, true /* range check dependency */);
value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
// node from floating above the range check during loop optimizations. Otherwise, the
// ConvI2L node may be eliminated independently of the range check, causing the data path

View File

@ -1193,7 +1193,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
}
Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
Node* castii = new CastIINode(incr, TypeInt::INT, true);
Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::StrongDependency);
castii->set_req(0, ctrl);
register_new_node(castii, ctrl);
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {

View File

@ -1503,7 +1503,15 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
assert(!n_loop->is_member(get_loop(x_ctrl)), "should have moved out of loop");
register_new_node(x, x_ctrl);
if (x->in(0) == NULL && !x->is_DecodeNarrowPtr()) {
// Chain of AddP: (AddP base (AddP base )) must keep the same base after sinking so:
// 1- We don't add a CastPP here when the first one is sunk so if the second one is not, their bases remain
// the same.
// (see 2- below)
assert(!x->is_AddP() || !x->in(AddPNode::Address)->is_AddP() ||
x->in(AddPNode::Address)->in(AddPNode::Base) == x->in(AddPNode::Base) ||
!x->in(AddPNode::Address)->in(AddPNode::Base)->eqv_uncast(x->in(AddPNode::Base)), "unexpected AddP shape");
if (x->in(0) == NULL && !x->is_DecodeNarrowPtr() &&
!(x->is_AddP() && x->in(AddPNode::Address)->is_AddP() && x->in(AddPNode::Address)->in(AddPNode::Base) == x->in(AddPNode::Base))) {
assert(!x->is_Load(), "load should be pinned");
// Use a cast node to pin clone out of loop
Node* cast = NULL;
@ -1511,11 +1519,22 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
Node* in = x->in(k);
if (in != NULL && n_loop->is_member(get_loop(get_ctrl(in)))) {
const Type* in_t = _igvn.type(in);
cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t);
cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t, ConstraintCastNode::UnconditionalDependency);
}
if (cast != NULL) {
register_new_node(cast, x_ctrl);
x->replace_edge(in, cast);
// Chain of AddP:
// 2- A CastPP of the base is only added now that both AddP nodes are sunk
if (x->is_AddP() && k == AddPNode::Base) {
for (DUIterator_Fast imax, i = x->fast_outs(imax); i < imax; i++) {
Node* u = x->fast_out(i);
if (u->is_AddP() && u->in(AddPNode::Base) == n->in(AddPNode::Base)) {
_igvn.replace_input_of(u, AddPNode::Base, cast);
assert(u->find_out_with(Op_AddP) == NULL, "more than 2 chained AddP nodes?");
}
}
}
break;
}
}
@ -2800,6 +2819,12 @@ int PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, No
worklist.push(use);
}
}
if (C->check_node_count(worklist.size() + NodeLimitFudgeFactor,
"Too many clones required in clone_for_use_outside_loop in partial peeling")) {
return -1;
}
while( worklist.size() ) {
Node *use = worklist.pop();
if (!has_node(use) || use->in(0) == C->top()) continue;
@ -3352,6 +3377,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
#endif
// Evacuate nodes in peel region into the not_peeled region if possible
bool too_many_clones = false;
uint new_phi_cnt = 0;
uint cloned_for_outside_use = 0;
for (uint i = 0; i < peel_list.size();) {
@ -3368,7 +3394,12 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// if not pinned and not a load (which maybe anti-dependent on a store)
// and not a CMove (Matcher expects only bool->cmove).
if (n->in(0) == NULL && !n->is_Load() && !n->is_CMove()) {
cloned_for_outside_use += clone_for_use_outside_loop(loop, n, worklist);
int new_clones = clone_for_use_outside_loop(loop, n, worklist);
if (new_clones == -1) {
too_many_clones = true;
break;
}
cloned_for_outside_use += new_clones;
sink_list.push(n);
peel.remove(n->_idx);
not_peel.set(n->_idx);
@ -3396,9 +3427,9 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
bool exceed_node_budget = !may_require_nodes(estimate);
bool exceed_phi_limit = new_phi_cnt > old_phi_cnt + PartialPeelNewPhiDelta;
if (exceed_node_budget || exceed_phi_limit) {
if (too_many_clones || exceed_node_budget || exceed_phi_limit) {
#ifndef PRODUCT
if (TracePartialPeeling) {
if (TracePartialPeeling && exceed_phi_limit) {
tty->print_cr("\nToo many new phis: %d old %d new cmpi: %c",
new_phi_cnt, old_phi_cnt, new_peel_if != NULL?'T':'F');
}

View File

@ -794,13 +794,69 @@ list.
.TP
.B \f[CB]\-Xcheck:jni\f[R]
Performs additional checks for Java Native Interface (JNI) functions.
Specifically, it validates the parameters passed to the JNI function and
the runtime environment data before processing the JNI request.
It also checks for pending exceptions between JNI calls.
Any invalid data encountered indicates a problem in the native code, and
the JVM terminates with an irrecoverable error in such cases.
Expect a performance degradation when this option is used.
.RS
.PP
The following checks are considered indicative of significant problems
with the native code, and the JVM terminates with an irrecoverable error
in such cases:
.IP \[bu] 2
The thread doing the call is not attached to the JVM.
.IP \[bu] 2
The thread doing the call is using the \f[CB]JNIEnv\f[R] belonging to
another thread.
.IP \[bu] 2
A parameter validation check fails:
.RS 2
.IP \[bu] 2
A \f[CB]jfieldID\f[R], or \f[CB]jmethodID\f[R], is detected as being
invalid.
For example:
.RS 2
.IP \[bu] 2
Of the wrong type
.IP \[bu] 2
Associated with the wrong class
.RE
.IP \[bu] 2
A parameter of the wrong type is detected.
.IP \[bu] 2
An invalid parameter value is detected.
For example:
.RS 2
.IP \[bu] 2
NULL where not permitted
.IP \[bu] 2
An out\-of\-bounds array index, or frame capacity
.IP \[bu] 2
A non\-UTF\-8 string
.IP \[bu] 2
An invalid JNI reference
.IP \[bu] 2
An attempt to use a \f[CB]ReleaseXXX\f[R] function on a parameter not
produced by the corresponding \f[CB]GetXXX\f[R] function
.RE
.RE
.PP
The following checks only result in warnings being printed:
.IP \[bu] 2
A JNI call was made without checking for a pending exception from a
previous JNI call, and the current call is not safe when an exception
may be pending.
.IP \[bu] 2
The number of JNI local references existing when a JNI function
terminates exceeds the number guaranteed to be available.
See the \f[CB]EnsureLocalcapacity\f[R] function.
.IP \[bu] 2
A class descriptor is in decorated format (\f[CB]Lname;\f[R]) when it
should not be.
.IP \[bu] 2
A \f[CB]NULL\f[R] parameter is allowed, but its use is questionable.
.IP \[bu] 2
Calling other JNI functions in the scope of
\f[CB]Get/ReleasePrimitiveArrayCritical\f[R] or
\f[CB]Get/ReleaseStringCritical\f[R]
.PP
Expect a performance degradation when this option is used.
.RE
.TP
.B \f[CB]\-Xdebug\f[R]

View File

@ -560,7 +560,8 @@ public class Start {
// We're done.
if (options.verbose()) {
long elapsedMillis = (System.nanoTime() - startNanos) / 1_000_000;
log.noticeUsingKey("main.done_in", Long.toString(elapsedMillis));
JavadocLog.printRawLines(log.getDiagnosticWriter(),
log.getText("main.done_in", Long.toString(elapsedMillis)));
}
return returnStatus;

View File

@ -199,7 +199,7 @@ public class ToolEnvironment {
if (quiet) {
return;
}
log.noticeUsingKey(key);
JavadocLog.printRawLines(log.getDiagnosticWriter(), log.getText(key));
}
/**
@ -212,7 +212,7 @@ public class ToolEnvironment {
if (quiet) {
return;
}
log.noticeUsingKey(key, a1);
JavadocLog.printRawLines(log.getDiagnosticWriter(), log.getText(key, a1));
}
TreePath getTreePath(JCCompilationUnit tree) {

View File

@ -39,4 +39,8 @@ serviceability/sa/ClhsdbFindPC.java#id3 8268722 macosx-x
serviceability/sa/ClhsdbPmap.java#id1 8268722 macosx-x64
serviceability/sa/ClhsdbPstack.java#id1 8268722 macosx-x64
serviceability/sa/TestJmapCore.java 8268722,8268283 macosx-x64,linux-aarch64
serviceability/sa/TestJmapCoreMetaspace.java 8268722 macosx-x64
serviceability/sa/TestJmapCoreMetaspace.java 8268722,8268636 macosx-x64,linux-x64
serviceability/dcmd/framework/HelpTest.java 8268433 windows-x64
serviceability/dcmd/framework/InvalidCommandTest.java 8268433 windows-x64
serviceability/dcmd/framework/VMVersionTest.java 8268433 windows-x64

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021, Red Hat, Inc. 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 8267988
* @summary C2: assert(!addp->is_AddP() || addp->in(AddPNode::Base)->is_top() || addp->in(AddPNode::Base) == n->in(AddPNode::Base)) failed: Base pointers must match (addp 1301)
*
* @run main/othervm -Xcomp -XX:CompileOnly=TestAddPChainWithDifferentBase TestAddPChainWithDifferentBase
*
*/
public class TestAddPChainWithDifferentBase {
static int x;
static int iArrFld[] = new int[400];
public static void main(String[] strArr) {
test();
}
static void test() {
int i6, i7 = 9, i8, i9 = 138;
for (i6 = 7; i6 > 1; i6 -= 3) {
for (i8 = i6; i8 < 4; i8++) {
try {
iArrFld[i8] = (52691 / i8);
i7 = (iArrFld[i8 + 1] % i9);
i7 = (412419036 / iArrFld[i8]);
} catch (ArithmeticException a_e) {
}
i9 += 13;
}
}
x = i7;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021, 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 8256934
* @summary Sinking of nodes in partial peeling creates too many clones resulting in a live node limit exceeded assertion failure.
* @requires vm.compiler2.enabled
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,compiler.loopopts.TestPartialPeelingSinkNodes::test
* compiler.loopopts.TestPartialPeelingSinkNodes
*/
package compiler.loopopts;
public class TestPartialPeelingSinkNodes {
static int i5 = 168, iFld = 2, x, y;
static boolean b = false, b2 = false;
public static void main(String[] strArr) {
test();
}
// The algorithm in partial peeling creates ~90000 nodes for this method which triggers the assertion failure.
public static void test() {
for (int i = 0; i < 2480; i++) {
int i2 = -37052, i3 = 39651, i4 = -37052;
int i5 = 168, i6 = -133, i7 = 1, i8 = -10;
double d = -20.82293;
float fArr[] = new float[400];
for (int j = 0; j < 400; j++) {
fArr[j] = (j % 2 == 0) ? 0.300F + j : 0.300F - j;
}
while (--i5 > 0) {
i6 = 1;
do {
i4 += (((i6 * i2) + i3) - i3);
i2 += i4;
} while (++i6 < 9);
i3 -= i4;
for (i7 = 1; i7 < 18; i7++) {
i4 = i5;
d -= i4;
i2 -= i8;
i2 = i8;
}
}
}
}
}

View File

@ -122,11 +122,12 @@ public class TestNewRatioFlag {
public static void verifyDefNewNewRatio(int expectedRatio) {
long initEden = HeapRegionUsageTool.getEdenUsage().getInit();
long initSurv = HeapRegionUsageTool.getSurvivorUsage().getInit();
long initOld = HeapRegionUsageTool.getOldUsage().getInit();
long initHeap = HeapRegionUsageTool.getHeapUsage().getInit();
long newSize = initEden + 2 * initSurv;
long expectedNewSize = HeapRegionUsageTool.alignDown(initOld / expectedRatio,
// See GenArguments::scale_by_NewRatio_aligned for calculation in the JVM.
long expectedNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1),
wb.getHeapSpaceAlignment());
if (expectedNewSize != newSize) {
@ -143,11 +144,12 @@ public class TestNewRatioFlag {
public static void verifyPSNewRatio(int expectedRatio) {
long initEden = HeapRegionUsageTool.getEdenUsage().getInit();
long initSurv = HeapRegionUsageTool.getSurvivorUsage().getInit();
long initOld = HeapRegionUsageTool.getOldUsage().getInit();
long initHeap = HeapRegionUsageTool.getHeapUsage().getInit();
long newSize = initEden + 2 * initSurv;
long alignedDownNewSize = HeapRegionUsageTool.alignDown(initOld / expectedRatio,
// See GenArguments::scale_by_NewRatio_aligned for calculation in the JVM.
long alignedDownNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1),
wb.getHeapSpaceAlignment());
long expectedNewSize = HeapRegionUsageTool.alignUp(alignedDownNewSize,
wb.psVirtualSpaceAlignment());

View File

@ -822,6 +822,8 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 gener
jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all
jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64
jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64
jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java 8263461 linux-x64
jdk/jfr/api/consumer/streaming/TestLatestEvent.java 8268297 windows-x64
############################################################################

View File

@ -278,6 +278,7 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
@Test(dataProvider = "variants")
public void test(String uri, boolean sameClient) throws Exception {
checkSkip();
System.out.println("Request to " + uri);
HttpClient client = newHttpClient(sameClient);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, 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
@ -150,7 +150,7 @@ public class DummyWebSocketServer implements Closeable {
err.println("Error in connection: " + channel + ", " + e);
} finally {
err.println("Closed: " + channel);
close(channel);
closeChannel(channel);
readReady.countDown();
}
}
@ -184,6 +184,10 @@ public class DummyWebSocketServer implements Closeable {
}
}
protected void closeChannel(SocketChannel channel) {
close(channel);
}
protected void write(SocketChannel ch) throws IOException { }
protected final void serve(SocketChannel channel)

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* -Djdk.internal.httpclient.debug=true
* -Djdk.internal.httpclient.websocket.debug=true
* PendingBinaryPingClose
@ -48,6 +49,7 @@ public class PendingBinaryPingClose extends PendingOperations {
public void pendingBinaryPingClose(boolean last) throws Exception {
repeatable(() -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* -Djdk.internal.httpclient.debug=true
* -Djdk.internal.httpclient.websocket.debug=true
* PendingBinaryPongClose
@ -50,6 +51,7 @@ public class PendingBinaryPongClose extends PendingOperations {
public void pendingBinaryPongClose(boolean last) throws Exception {
repeatable(() -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* PendingPingBinaryClose
*/
@ -50,6 +51,7 @@ public class PendingPingBinaryClose extends PendingOperations {
public void pendingPingBinaryClose(boolean last) throws Exception {
repeatable( () -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* PendingPingTextClose
*/
@ -52,6 +53,7 @@ public class PendingPingTextClose extends PendingOperations {
try {
repeatable(() -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* PendingPongBinaryClose
*/
@ -50,6 +51,7 @@ public class PendingPongBinaryClose extends PendingOperations {
public void pendingPongBinaryClose(boolean last) throws Exception {
repeatable( () -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -25,6 +25,7 @@
* @test
* @build DummyWebSocketServer
* @run testng/othervm
* -Djdk.httpclient.sendBufferSize=8192
* PendingPongTextClose
*/
@ -50,6 +51,7 @@ public class PendingPongTextClose extends PendingOperations {
public void pendingPongTextClose(boolean last) throws Exception {
repeatable( () -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -27,6 +27,7 @@
* @run testng/othervm
* -Djdk.internal.httpclient.debug=true
* -Djdk.internal.httpclient.websocket.debug=true
* -Djdk.httpclient.sendBufferSize=8192
* PendingTextPongClose
*/
@ -49,6 +50,7 @@ public class PendingTextPongClose extends PendingOperations {
public void pendingTextPongClose(boolean last) throws Exception {
repeatable(() -> {
server = Support.notReadingServer();
server.setReceiveBufferSize(1024);
server.open();
webSocket = httpClient().newWebSocketBuilder()
.buildAsync(server.getURI(), new WebSocket.Listener() { })

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -136,17 +136,65 @@ public class Support {
*/
public static DummyWebSocketServer notReadingServer() {
return new DummyWebSocketServer() {
volatile Thread reader;
@Override
protected void read(SocketChannel ch) throws IOException {
reader = Thread.currentThread();
try {
System.out.println("Not reading server waiting");
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
throw new IOException(e);
}
}
@Override
protected void closeChannel(SocketChannel channel) {
try {
long read = drain(channel);
System.out.printf("Not reading server drained %s bytes%n", read);
} catch (IOException io) {
System.out.println("Not reading server failed to drain channel: " + io);
}
super.closeChannel(channel);
}
@Override
public void close() {
super.close();
Thread thread = reader;
if (thread != null && thread.isAlive() && thread != Thread.currentThread()) {
try {
thread.join();
System.out.println("Not reading server: closed");
} catch (InterruptedException x) {
System.out.println("Not reading server: close interrupted: " + x);
}
}
}
};
}
static long drain(SocketChannel channel) throws IOException {
System.out.println("Not reading server: draining socket");
var blocking = channel.isBlocking();
if (blocking) channel.configureBlocking(false);
long count = 0;
try {
ByteBuffer buffer = ByteBuffer.allocateDirect(8 * 1024);
int read;
while ((read = channel.read(buffer)) > 0) {
count += read;
buffer.clear();
}
return count;
} finally {
if (blocking != channel.isBlocking()) {
channel.configureBlocking(blocking);
}
}
}
public static DummyWebSocketServer writingServer(int... data) {
byte[] copy = new byte[data.length];
for (int i = 0; i < data.length; i++) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@ -76,8 +76,9 @@ public class WSHandshakeExceptionTest {
String httpsURI;
String httpNonUtf8URI;
String httpsNonUtf8URI;
HttpClient sharedClient;
static final int ITERATION_COUNT = 10;
static final int ITERATION_COUNT = 4;
// a shared executor helps reduce the amount of threads created by the test
static final ExecutorService executor = Executors.newCachedThreadPool();
@ -106,11 +107,16 @@ public class WSHandshakeExceptionTest {
@Test(dataProvider = "variants")
public void test(String uri, boolean sameClient) {
HttpClient client = null;
HttpClient client = sharedClient;
boolean pause;
for (int i = 0; i < ITERATION_COUNT; i++) {
System.out.printf("iteration %s%n", i);
if (!sameClient || client == null)
if (!sameClient || client == null) {
pause = client != null;
client = newHttpClient();
if (pause) gc(10); // give some time to gc
}
if (sharedClient == null) sharedClient = client;
try {
client.newWebSocketBuilder()
@ -143,6 +149,15 @@ public class WSHandshakeExceptionTest {
}
}
static void gc(long ms) {
System.gc();
try {
Thread.sleep(ms);
} catch (InterruptedException x) {
// OK
}
}
@BeforeTest
public void setup() throws Exception {
sslContext = new SimpleSSLContext().get();
@ -168,6 +183,8 @@ public class WSHandshakeExceptionTest {
@AfterTest
public void teardown() {
sharedClient = null;
gc(100);
httpTestServer.stop(0);
httpsTestServer.stop(0);
executor.shutdownNow();

View File

@ -404,6 +404,8 @@ public class WebSocketProxyTest {
@BeforeMethod
public void breakBetweenTests() {
System.gc();
try {Thread.sleep(100); } catch (InterruptedException x) { /* OK */ }
System.out.println("\n-------\n");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, 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
@ -123,7 +123,7 @@ public class ToolProviderTest extends TestRunner {
String out = swOut.toString();
String err = swErr.toString();
if (!out.contains("Loading")) {
if (!err.contains("Loading")) {
error("stdout: unexpected output");
}
if (!err.contains("illegal character")) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, 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
@ -155,22 +155,22 @@ public class TestLocaleOption extends TestRunner {
private void testHelloWorld(Path base, Locale defaultLocale, Locale localeOption) throws Exception {
Path apiDir = base.resolve("api");
String stdOut = javadoc(defaultLocale,
String stdErr = javadoc(defaultLocale,
localeOption,
"-sourcepath", srcDir.toString(),
"-d", apiDir.toString(),
"p")
.writeAll()
.getOutput(Task.OutputKind.STDOUT);
.getOutput(Task.OutputKind.STDERR);
// check console messages
if (Objects.equals(defaultLocale, ALLCAPS)) {
checkContains(stdOut,
checkContains(stdErr,
"""
LOADING SOURCE FILES FOR PACKAGE p...
CONSTRUCTING JAVADOC INFORMATION...""");
} else {
checkContains(stdOut,
checkContains(stdErr,
"""
Loading source files for package p...
Constructing Javadoc information...""");

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2021, 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 8268774
* @summary Residual logging output written to STDOUT, not STDERR
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @build toolbox.ToolBox javadoc.tester.*
* @run main TestToolStreams
*/
import java.io.IOException;
import java.nio.file.Path;
import javadoc.tester.JavadocTester;
import toolbox.ToolBox;
// See also TestReporterStreams for testing doclet/reporter use of streams
public class TestToolStreams extends JavadocTester {
public static void main(String... args) throws Exception {
TestToolStreams tester = new TestToolStreams();
tester.runTests(m -> new Object[]{Path.of(m.getName())});
}
ToolBox tb = new ToolBox();
TestToolStreams() throws IOException {
tb.writeJavaFiles(Path.of("src"),
"""
package p1;
/** Comment 1. */
public class C1 { }""",
"""
package p2;
/** Comment 2. */
public class C2 { }""");
}
/**
* Tests the entry point used by the DocumentationTool API and JavadocTester, in which
* all output is written to a single specified writer.
*/
@Test
public void testSingleStream(Path base) {
test(base, false, Output.OUT, Output.OUT);
}
/**
* Tests the entry point used by the launcher, in which output is written to
* writers that wrap {@code System.out} and {@code System.err}.
*/
@Test
public void testStandardStreams(Path base) {
test(base, true, Output.STDOUT, Output.STDERR);
}
void test(Path base, boolean useStdStreams, Output stdOut, Output stdErr) {
setOutputDirectoryCheck(DirectoryCheck.NONE);
setUseStandardStreams(useStdStreams);
javadoc("--help");
checkExit(Exit.OK);
if (stdOut != stdErr) {
checkIsEmpty(stdErr);
}
checkOutput(stdOut, true,
"Usage:");
javadoc("-d", base.resolve("out").toString(),
"-sourcepath", "src",
"-verbose", // Note: triggers lots of javac messages as well as the javadoc time-taken message
"p1",
Path.of("src").resolve("p2").resolve("C2.java").toString());
checkExit(Exit.OK);
if (stdOut != stdErr) {
checkIsEmpty(stdOut);
}
checkOutput(stdErr, true,
"Loading source file src/p2/C2.java...".replace("/", FS),
"Loading source files for package p1...",
"Constructing Javadoc information",
"[done in ", " ms]"
);
}
void checkIsEmpty(Output out) {
checking("no output to " + out);
String s = getOutput(out);
if (s.isEmpty()) {
passed("no output written to " + out);
} else {
failed(out + " is not empty");
}
}
}