# HG changeset patch
# User prr
# Date 1522427044 25200
# Node ID f9e81b6bfc20e46ee8681e21ebeb89bd936f5a5c
# Parent 5daa8ef1708997a5611179494b5756a40446f54e# Parent 814bd31f8da0318a0c8c95067d29217282df94e3
Merge
diff -r 5daa8ef17089 -r f9e81b6bfc20 make/CompileToolsHotspot.gmk
--- a/make/CompileToolsHotspot.gmk Thu Mar 29 17:52:32 2018 +0530
+++ b/make/CompileToolsHotspot.gmk Fri Mar 30 09:24:04 2018 -0700
@@ -120,6 +120,7 @@
SRC := \
$(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.collections/src \
+ $(SRC_DIR)/org.graalvm.compiler.bytecode/src \
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
$(SRC_DIR)/org.graalvm.compiler.code/src \
diff -r 5daa8ef17089 -r f9e81b6bfc20 make/autoconf/hotspot.m4
--- a/make/autoconf/hotspot.m4 Thu Mar 29 17:52:32 2018 +0530
+++ b/make/autoconf/hotspot.m4 Fri Mar 30 09:24:04 2018 -0700
@@ -343,11 +343,10 @@
fi
INCLUDE_GRAAL="true"
else
- # By default enable graal build on linux-x64 or where AOT is available.
+ # By default enable graal build on x64 or where AOT is available.
# graal build requires jvmci.
if test "x$JVM_FEATURES_jvmci" = "xjvmci" && \
- (test "x$OPENJDK_TARGET_CPU" = "xx86_64" && \
- test "x$OPENJDK_TARGET_OS" = "xlinux" || \
+ (test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
test "x$ENABLE_AOT" = "xtrue") ; then
AC_MSG_RESULT([yes])
JVM_FEATURES_graal="graal"
diff -r 5daa8ef17089 -r f9e81b6bfc20 make/lib/Lib-java.base.gmk
--- a/make/lib/Lib-java.base.gmk Thu Mar 29 17:52:32 2018 +0530
+++ b/make/lib/Lib-java.base.gmk Fri Mar 30 09:24:04 2018 -0700
@@ -159,6 +159,7 @@
ifeq ($(STATIC_BUILD), false)
LIBJSIG_SRC_DIR := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjsig
+ LIBJSIG_MAPFILE := $(wildcard $(TOPDIR)/make/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
ifeq ($(OPENJDK_TARGET_OS), linux)
# FIXME: This is probably not what we want to do, but keep it now for compatibility.
@@ -174,6 +175,7 @@
LIBS_linux := $(LIBDL), \
LIBS_solaris := $(LIBDL), \
LIBS_aix := $(LIBDL), \
+ MAPFILE := $(LIBJSIG_MAPFILE), \
))
TARGETS += $(BUILD_LIBJSIG)
diff -r 5daa8ef17089 -r f9e81b6bfc20 make/mapfiles/libjsig/mapfile-vers-solaris
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mapfiles/libjsig/mapfile-vers-solaris Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+ global:
+ JVM_begin_signal_setting;
+ JVM_end_signal_setting;
+ JVM_get_libjsig_version;
+ JVM_get_signal_action;
+ sigaction;
+ signal;
+ sigset;
+ local:
+ *;
+};
diff -r 5daa8ef17089 -r f9e81b6bfc20 make/nb_native/nbproject/configurations.xml
--- a/make/nb_native/nbproject/configurations.xml Thu Mar 29 17:52:32 2018 +0530
+++ b/make/nb_native/nbproject/configurations.xml Fri Mar 30 09:24:04 2018 -0700
@@ -2480,7 +2480,7 @@
jvmtiClassFileReconstituter.hpp
jvmtiCodeBlobEvents.cpp
jvmtiCodeBlobEvents.hpp
- jvmtiEnter.hpp
+ jvmtiEnter.inline.hpp
jvmtiEnv.cpp
jvmtiEnvBase.cpp
jvmtiEnvBase.hpp
@@ -13398,7 +13398,7 @@
tool="3"
flavor2="0">
- -
@@ -27175,7 +27175,7 @@
tool="3"
flavor2="0">
- -
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/aarch64.ad
--- a/src/hotspot/cpu/aarch64/aarch64.ad Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/aarch64.ad Fri Mar 30 09:24:04 2018 -0700
@@ -996,7 +996,7 @@
source_hpp %{
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "opto/addnode.hpp"
class CallStubImpl {
@@ -5845,8 +5845,8 @@
operand immByteMapBase()
%{
// Get base of card map
- predicate(Universe::heap()->barrier_set()->is_a(BarrierSet::CardTableModRef) &&
- (jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base());
+ predicate(Universe::heap()->barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
+ (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base());
match(ConP);
op_cost(0);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/assembler_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -36,7 +36,7 @@
#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
// for the moment we reuse the logical/floating point immediate encode
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,10 +34,11 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciInstance.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_aarch64.inline.hpp"
@@ -2174,8 +2175,8 @@
__ stp(length, src_pos, Address(sp, 2*BytesPerWord));
__ str(src, Address(sp, 4*BytesPerWord));
- address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
address copyfunc_addr = StubRoutines::generic_arraycopy();
+ assert(copyfunc_addr != NULL, "generic arraycopy stub required");
// The arguments are in java calling convention so we shift them
// to C convention
@@ -2188,17 +2189,12 @@
assert_different_registers(c_rarg3, j_rarg4);
__ mov(c_rarg3, j_rarg3);
__ mov(c_rarg4, j_rarg4);
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ mov(rscratch1, RuntimeAddress(C_entry));
- __ blrt(rscratch1, 5, 0, 1);
- } else {
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
- }
+ if (PrintC1Statistics) {
+ __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+ }
#endif
- __ far_call(RuntimeAddress(copyfunc_addr));
- }
+ __ far_call(RuntimeAddress(copyfunc_addr));
__ cbz(r0, *stub->continuation());
@@ -2208,14 +2204,12 @@
__ ldp(length, src_pos, Address(sp, 2*BytesPerWord));
__ ldr(src, Address(sp, 4*BytesPerWord));
- if (copyfunc_addr != NULL) {
- // r0 is -1^K where K == partial copied count
- __ eonw(rscratch1, r0, 0);
- // adjust length down and src/end pos up by partial copied count
- __ subw(length, length, rscratch1);
- __ addw(src_pos, src_pos, rscratch1);
- __ addw(dst_pos, dst_pos, rscratch1);
- }
+ // r0 is -1^K where K == partial copied count
+ __ eonw(rscratch1, r0, 0);
+ // adjust length down and src/end pos up by partial copied count
+ __ subw(length, length, rscratch1);
+ __ addw(src_pos, src_pos, rscratch1);
+ __ addw(dst_pos, dst_pos, rscratch1);
__ b(*stub->entry());
__ bind(*stub->continuation());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "c1/c1_Runtime1.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp
--- a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -65,7 +65,7 @@
// Peephole and CISC spilling both break the graph, and so makes the
// scheduler sick.
define_pd_global(bool, OptoPeephole, false);
-define_pd_global(bool, UseCISCSpill, true);
+define_pd_global(bool, UseCISCSpill, false);
define_pd_global(bool, OptoScheduling, false);
define_pd_global(bool, OptoBundling, false);
define_pd_global(bool, OptoRegScheduling, false);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/frame_aarch64.hpp
--- a/src/hotspot/cpu/aarch64/frame_aarch64.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -158,4 +158,6 @@
// deoptimization support
void interpreter_frame_set_last_sp(intptr_t* sp);
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_AARCH64_VM_FRAME_AARCH64_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp
--- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -227,9 +227,6 @@
}
-inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
-
-
// Entry frames
inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/thread.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, RegSet saved_regs) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+ if (!dest_uninitialized) {
+ __ push(saved_regs, sp);
+ if (count == c_rarg0) {
+ if (addr == c_rarg1) {
+ // exactly backwards!!
+ __ mov(rscratch1, c_rarg0);
+ __ mov(c_rarg0, c_rarg1);
+ __ mov(c_rarg1, rscratch1);
+ } else {
+ __ mov(c_rarg1, count);
+ __ mov(c_rarg0, addr);
+ }
+ } else {
+ __ mov(c_rarg0, addr);
+ __ mov(c_rarg1, count);
+ }
+ if (UseCompressedOops) {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry), 2);
+ } else {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry), 2);
+ }
+ __ pop(saved_regs, sp);
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register start, Register end, Register scratch, RegSet saved_regs) {
+ __ push(saved_regs, sp);
+ // must compute element count unless barrier set interface is changed (other platforms supply count)
+ assert_different_registers(start, end, scratch);
+ __ lea(scratch, Address(end, BytesPerHeapOop));
+ __ sub(scratch, scratch, start); // subtract start to get #bytes
+ __ lsr(scratch, scratch, LogBytesPerHeapOop); // convert to element count
+ __ mov(c_rarg0, start);
+ __ mov(c_rarg1, scratch);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry), 2);
+ __ pop(saved_regs, sp);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_AARCH64_GC_G1_G1BARRIERSETASSEMBLER_AARCH64_HPP
+#define CPU_AARCH64_GC_G1_G1BARRIERSETASSEMBLER_AARCH64_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, RegSet saved_regs);
+ void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register start, Register end, Register tmp, RegSet saved_regs);
+};
+
+#endif // CPU_AARCH64_GC_G1_G1BARRIERSETASSEMBLER_AARCH64_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP
+#define CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class BarrierSetAssembler: public CHeapObj {
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, RegSet saved_regs) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register start, Register end, Register tmp, RegSet saved_regs) {}
+};
+
+#endif // CPU_AARCH64_GC_SHARED_BARRIERSETASSEMBLER_AARCH64_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register start, Register end, Register scratch, RegSet saved_regs) {
+
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+
+ Label L_loop;
+
+ __ lsr(start, start, CardTable::card_shift);
+ __ lsr(end, end, CardTable::card_shift);
+ __ sub(end, end, start); // number of bytes to copy
+
+ const Register count = end; // 'end' register contains bytes count now
+ __ load_byte_map_base(scratch);
+ __ add(start, start, scratch);
+ if (UseConcMarkSweepGC) {
+ __ membar(__ StoreStore);
+ }
+ __ bind(L_loop);
+ __ strb(zr, Address(start, count));
+ __ subs(count, count, 1);
+ __ br(Assembler::GE, L_loop);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_AARCH64_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_AARCH64_HPP
+#define CPU_AARCH64_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_AARCH64_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register start, Register end, Register tmp, RegSet saved_regs);
+};
+
+#endif // #ifndef CPU_AARCH64_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_AARCH64_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, RegSet saved_regs) {
+
+ if (is_oop) {
+ gen_write_ref_array_pre_barrier(masm, decorators, addr, count, saved_regs);
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register start, Register end, Register tmp,
+ RegSet saved_regs) {
+ if (is_oop) {
+ gen_write_ref_array_post_barrier(masm, decorators, start, end, tmp, saved_regs);
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP
+#define CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, RegSet saved_regs) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register start, Register end, Register tmp, RegSet saved_regs) {}
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, RegSet saved_regs);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register start, Register end, Register tmp, RegSet saved_regs);
+};
+
+#endif // CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -36,6 +36,7 @@
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
*/
#include "precompiled.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -32,7 +33,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
@@ -42,6 +43,14 @@
Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; }
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
+ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+ _num_int_args = (method->is_static() ? 1 : 0);
+ _num_fp_args = 0;
+ _stack_offset = 0;
+}
+
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp
--- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,8 +26,8 @@
#ifndef CPU_AARCH64_VM_INTERPRETERRT_AARCH64_HPP
#define CPU_AARCH64_VM_INTERPRETERRT_AARCH64_HPP
-#include "asm/macroAssembler.hpp"
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
// native method calls
@@ -47,12 +47,7 @@
public:
// Creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
- _num_int_args = (method->is_static() ? 1 : 0);
- _num_fp_args = 0;
- _stack_offset = 0;
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// Code generation
void generate(uint64_t fingerprint);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_aarch64.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,7 @@
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
@@ -42,7 +42,7 @@
#include "opto/node.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.hpp"
@@ -3618,10 +3618,10 @@
// register obj is destroyed afterwards.
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableModRef,
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet,
"Wrong barrier set kind");
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
@@ -4129,7 +4129,7 @@
DirtyCardQueue::byte_offset_of_buf()));
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
@@ -4515,7 +4515,7 @@
void MacroAssembler::load_byte_map_base(Register reg) {
jbyte *byte_map_base =
- ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base();
+ ((CardTableBarrierSet*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base();
if (is_valid_AArch64_address((address)byte_map_base)) {
// Strictly speaking the byte_map_base isn't an address at all,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -79,8 +79,8 @@
void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
- // Maximum size of class area in Metaspace when compressed
- uint64_t use_XOR_for_compressed_class_base;
+ // True if an XOR can be used to expand narrow klass references.
+ bool use_XOR_for_compressed_class_base;
public:
MacroAssembler(CodeBuffer* code) : Assembler(code) {
@@ -88,7 +88,7 @@
= (operand_valid_for_logical_immediate(false /*is32*/,
(uint64_t)Universe::narrow_klass_base())
&& ((uint64_t)Universe::narrow_klass_base()
- > (1u << log2_intptr(CompressedClassSpaceSize))));
+ > (1UL << log2_intptr(Universe::narrow_klass_range()))));
}
// These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -30,6 +30,7 @@
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/runtime_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/runtime_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/runtime_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "code/vmreg.hpp"
#include "interpreter/interpreter.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,6 +34,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,8 +26,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/instanceOop.hpp"
@@ -620,111 +620,6 @@
void array_overlap_test(Label& L_no_overlap, Address::sxtw sf) { __ b(L_no_overlap); }
- // Generate code for an array write pre barrier
- //
- // addr - starting address
- // count - element count
- // tmp - scratch register
- // saved_regs - registers to be saved before calling static_write_ref_array_pre
- //
- // Callers must specify which registers to preserve in saved_regs.
- // Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
- //
- void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized, RegSet saved_regs) {
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target in uninitialized
- if (!dest_uninitialized) {
- __ push(saved_regs, sp);
- if (count == c_rarg0) {
- if (addr == c_rarg1) {
- // exactly backwards!!
- __ mov(rscratch1, c_rarg0);
- __ mov(c_rarg0, c_rarg1);
- __ mov(c_rarg1, rscratch1);
- } else {
- __ mov(c_rarg1, count);
- __ mov(c_rarg0, addr);
- }
- } else {
- __ mov(c_rarg0, addr);
- __ mov(c_rarg1, count);
- }
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
- __ pop(saved_regs, sp);
- break;
- case BarrierSet::CardTableModRef:
- break;
- default:
- ShouldNotReachHere();
-
- }
- }
- }
-
- //
- // Generate code for an array write post barrier
- //
- // Input:
- // start - register containing starting address of destination array
- // end - register containing ending address of destination array
- // scratch - scratch register
- // saved_regs - registers to be saved before calling static_write_ref_array_post
- //
- // The input registers are overwritten.
- // The ending address is inclusive.
- // Callers must specify which registers to preserve in saved_regs.
- // Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
- void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch, RegSet saved_regs) {
- assert_different_registers(start, end, scratch);
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
-
- {
- __ push(saved_regs, sp);
- // must compute element count unless barrier set interface is changed (other platforms supply count)
- assert_different_registers(start, end, scratch);
- __ lea(scratch, Address(end, BytesPerHeapOop));
- __ sub(scratch, scratch, start); // subtract start to get #bytes
- __ lsr(scratch, scratch, LogBytesPerHeapOop); // convert to element count
- __ mov(c_rarg0, start);
- __ mov(c_rarg1, scratch);
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
- __ pop(saved_regs, sp);
- }
- break;
- case BarrierSet::CardTableModRef:
- {
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
- CardTable* ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
-
- Label L_loop;
-
- __ lsr(start, start, CardTable::card_shift);
- __ lsr(end, end, CardTable::card_shift);
- __ sub(end, end, start); // number of bytes to copy
-
- const Register count = end; // 'end' register contains bytes count now
- __ load_byte_map_base(scratch);
- __ add(start, start, scratch);
- if (UseConcMarkSweepGC) {
- __ membar(__ StoreStore);
- }
- __ BIND(L_loop);
- __ strb(zr, Address(start, count));
- __ subs(count, count, 1);
- __ br(Assembler::GE, L_loop);
- }
- break;
- default:
- ShouldNotReachHere();
-
- }
- }
-
// The inner part of zero_words(). This is the bulk operation,
// zeroing words in blocks, possibly using DC ZVA to do it. The
// caller is responsible for zeroing the last few words.
@@ -1456,20 +1351,33 @@
BLOCK_COMMENT("Entry:");
}
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, is_oop, d, count, saved_reg);
+
if (is_oop) {
- gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_reg);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp);
}
copy_memory(aligned, s, d, count, rscratch1, size);
+
if (is_oop) {
__ pop(RegSet::of(d, count), sp);
if (VerifyOops)
verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
- gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
}
+
+ bs->arraycopy_epilogue(_masm, decorators, is_oop, d, count, rscratch1, RegSet());
+
__ leave();
__ mov(r0, zr); // return 0
__ ret(lr);
@@ -1517,8 +1425,18 @@
__ cmp(rscratch1, count, Assembler::LSL, exact_log2(size));
__ br(Assembler::HS, nooverlap_target);
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, is_oop, d, count, saved_regs);
+
if (is_oop) {
- gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_regs);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp);
}
@@ -1529,8 +1447,8 @@
verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
- gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
}
+ bs->arraycopy_epilogue(_masm, decorators, is_oop, d, count, rscratch1, RegSet());
__ leave();
__ mov(r0, zr); // return 0
__ ret(lr);
@@ -1871,7 +1789,14 @@
}
#endif //ASSERT
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized, wb_pre_saved_regs);
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+ bool is_oop = true;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, is_oop, to, count, wb_pre_saved_regs);
// save the original count
__ mov(count_save, count);
@@ -1915,7 +1840,7 @@
__ BIND(L_do_card_marks);
__ add(to, to, -heapOopSize); // make an inclusive end pointer
- gen_write_ref_array_post_barrier(start_to, to, rscratch1, wb_post_saved_regs);
+ bs->arraycopy_epilogue(_masm, decorators, is_oop, start_to, to, rscratch1, wb_post_saved_regs);
__ bind(L_done_pop);
__ pop(RegSet::of(r18, r19, r20, r21), sp);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,6 +35,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -184,7 +185,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
if (val == noreg) {
__ store_heap_oop_null(obj);
@@ -1904,7 +1905,8 @@
in_bytes(InvocationCounter::counter_offset()));
const Address mask(r1, in_bytes(MethodData::backedge_mask_offset()));
__ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
- r0, rscratch1, false, Assembler::EQ, &backedge_counter_overflow);
+ r0, rscratch1, false, Assembler::EQ,
+ UseOnStackReplacement ? &backedge_counter_overflow : &dispatch);
__ b(dispatch);
}
__ bind(no_mdo);
@@ -1912,7 +1914,8 @@
__ ldr(rscratch1, Address(rmethod, Method::method_counters_offset()));
const Address mask(rscratch1, in_bytes(MethodCounters::backedge_mask_offset()));
__ increment_mask_and_jump(Address(rscratch1, be_offset), increment, mask,
- r0, rscratch2, false, Assembler::EQ, &backedge_counter_overflow);
+ r0, rscratch2, false, Assembler::EQ,
+ UseOnStackReplacement ? &backedge_counter_overflow : &dispatch);
} else { // not TieredCompilation
// increment counter
__ ldr(rscratch2, Address(rmethod, Method::method_counters_offset()));
@@ -1960,8 +1963,8 @@
}
}
}
+ __ bind(dispatch);
}
- __ bind(dispatch);
// Pre-load the next target bytecode into rscratch1
__ load_unsigned_byte(rscratch1, Address(rbcp, 0));
@@ -1981,7 +1984,7 @@
__ b(dispatch);
}
- if (TieredCompilation || UseOnStackReplacement) {
+ if (UseOnStackReplacement) {
// invocation counter overflow
__ bind(backedge_counter_overflow);
__ neg(r2, r2);
@@ -1991,11 +1994,6 @@
CAST_FROM_FN_PTR(address,
InterpreterRuntime::frequency_counter_overflow),
r2);
- if (!UseOnStackReplacement)
- __ b(dispatch);
- }
-
- if (UseOnStackReplacement) {
__ load_unsigned_byte(r1, Address(rbcp, 0)); // restore target bytecode
// r0: osr nmethod (osr ok) or NULL (osr not possible)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/assembler_arm.cpp
--- a/src/hotspot/cpu/arm/assembler_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/assembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
@@ -35,7 +35,7 @@
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/assembler_arm_32.cpp
--- a/src/hotspot/cpu/arm/assembler_arm_32.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/assembler_arm_32.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
@@ -35,7 +35,7 @@
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/assembler_arm_64.cpp
--- a/src/hotspot/cpu/arm/assembler_arm_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/assembler_arm_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
@@ -35,7 +35,7 @@
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/c1_Defs_arm.hpp
--- a/src/hotspot/cpu/arm/c1_Defs_arm.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_Defs_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -79,7 +79,7 @@
#else
#define PATCHED_ADDR (204)
#endif
-#define CARDTABLEMODREF_POST_BARRIER_HELPER
+#define CARDTABLEBARRIERSET_POST_BARRIER_HELPER
#define GENERATE_ADDRESS_IS_PREFERRED
#endif // CPU_ARM_VM_C1_DEFS_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,10 +31,11 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciInstance.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "nativeInst_arm.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_arm.inline.hpp"
@@ -2777,17 +2778,14 @@
#endif // AARCH64
address copyfunc_addr = StubRoutines::generic_arraycopy();
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ call(CAST_FROM_FN_PTR(address, Runtime1::arraycopy));
- } else {
+ assert(copyfunc_addr != NULL, "generic arraycopy stub required");
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ inc_counter((address)&Runtime1::_generic_arraycopystub_cnt, tmp, tmp2);
- }
+ if (PrintC1Statistics) {
+ __ inc_counter((address)&Runtime1::_generic_arraycopystub_cnt, tmp, tmp2);
+ }
#endif // !PRODUCT
- // the stub is in the code cache so close enough
- __ call(copyfunc_addr, relocInfo::runtime_call_type);
- }
+ // the stub is in the code cache so close enough
+ __ call(copyfunc_addr, relocInfo::runtime_call_type);
#ifdef AARCH64
__ raw_pop(length, ZR);
@@ -2797,15 +2795,11 @@
__ cbz_32(R0, *stub->continuation());
- if (copyfunc_addr != NULL) {
- __ mvn_32(tmp, R0);
- restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only
- __ sub_32(length, length, tmp);
- __ add_32(src_pos, src_pos, tmp);
- __ add_32(dst_pos, dst_pos, tmp);
- } else {
- restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only
- }
+ __ mvn_32(tmp, R0);
+ restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only
+ __ sub_32(length, length, tmp);
+ __ add_32(src_pos, src_pos, tmp);
+ __ add_32(dst_pos, dst_pos, tmp);
__ b(*stub->entry());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
--- a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,7 @@
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "vmreg_arm.inline.hpp"
@@ -497,7 +497,7 @@
#endif // AARCH64
}
-void LIRGenerator::CardTableModRef_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) {
+void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) {
assert(addr->is_register(), "must be a register at this point");
LIR_Opr tmp = FrameMap::LR_ptr_opr;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/c1_Runtime1_arm.cpp
--- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,7 @@
#include "c1/c1_Runtime1.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_arm.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/frame_arm.hpp
--- a/src/hotspot/cpu/arm/frame_arm.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/frame_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -135,4 +135,6 @@
// helper to update a map with callee-saved FP
static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr);
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_ARM_VM_FRAME_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/frame_arm.inline.hpp
--- a/src/hotspot/cpu/arm/frame_arm.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/frame_arm.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -218,9 +218,6 @@
}
-inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
-
-
// Entry frames
inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/macros.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, int callee_saved_regs) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+ if (!dest_uninitialized) {
+ assert( addr->encoding() < callee_saved_regs, "addr must be saved");
+ assert(count->encoding() < callee_saved_regs, "count must be saved");
+
+ BLOCK_COMMENT("PreBarrier");
+
+#ifdef AARCH64
+ callee_saved_regs = align_up(callee_saved_regs, 2);
+ for (int i = 0; i < callee_saved_regs; i += 2) {
+ __ raw_push(as_Register(i), as_Register(i+1));
+ }
+#else
+ RegisterSet saved_regs = RegisterSet(R0, as_Register(callee_saved_regs-1));
+ __ push(saved_regs | R9ifScratched);
+#endif // AARCH64
+
+ if (addr != R0) {
+ assert_different_registers(count, R0);
+ __ mov(R0, addr);
+ }
+#ifdef AARCH64
+ __ zero_extend(R1, count, 32); // G1BarrierSet::write_ref_array_pre_*_entry takes size_t
+#else
+ if (count != R1) {
+ __ mov(R1, count);
+ }
+#endif // AARCH64
+
+ if (UseCompressedOops) {
+ __ call(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry));
+ } else {
+ __ call(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry));
+ }
+
+#ifdef AARCH64
+ for (int i = callee_saved_regs - 2; i >= 0; i -= 2) {
+ __ raw_pop(as_Register(i), as_Register(i+1));
+ }
+#else
+ __ pop(saved_regs | R9ifScratched);
+#endif // AARCH64
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+
+ BLOCK_COMMENT("G1PostBarrier");
+ if (addr != R0) {
+ assert_different_registers(count, R0);
+ __ mov(R0, addr);
+ }
+#ifdef AARCH64
+ __ zero_extend(R1, count, 32); // G1BarrierSet::write_ref_array_post_entry takes size_t
+#else
+ if (count != R1) {
+ __ mov(R1, count);
+ }
+#if R9_IS_SCRATCHED
+ // Safer to save R9 here since callers may have been written
+ // assuming R9 survives. This is suboptimal but is not in
+ // general worth optimizing for the few platforms where R9
+ // is scratched. Note that the optimization might not be to
+ // difficult for this particular call site.
+ __ push(R9);
+#endif // !R9_IS_SCRATCHED
+#endif // !AARCH64
+ __ call(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry));
+#ifndef AARCH64
+#if R9_IS_SCRATCHED
+ __ pop(R9);
+#endif // !R9_IS_SCRATCHED
+#endif // !AARCH64
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ARM_GC_G1_G1BARRIERSETASSEMBLER_ARM_HPP
+#define CPU_ARM_GC_G1_G1BARRIERSETASSEMBLER_ARM_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, , int callee_saved_regs);
+ void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // CPU_ARM_GC_G1_G1BARRIERSETASSEMBLER_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ARM_GC_SHARED_BARRIERSETASSEMBLER_ARM_HPP
+#define CPU_ARM_GC_SHARED_BARRIERSETASSEMBLER_ARM_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class BarrierSetAssembler: public CHeapObj {
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, , int callee_saved_regs) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, Register tmp) {}
+};
+
+#endif // CPU_ARM_GC_SHARED_BARRIERSETASSEMBLER_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/globals.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+ BLOCK_COMMENT("CardTablePostBarrier");
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+
+ Label L_cardtable_loop, L_done;
+
+ __ cbz_32(count, L_done); // zero count - nothing to do
+
+ __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
+ __ sub(count, count, BytesPerHeapOop); // last addr
+
+ __ logical_shift_right(addr, addr, CardTable::card_shift);
+ __ logical_shift_right(count, count, CardTable::card_shift);
+ __ sub(count, count, addr); // nb of cards
+
+ // warning: Rthread has not been preserved
+ __ mov_address(tmp, (address) ct->byte_map_base(), symbolic_Relocation::card_table_reference);
+ __ add(addr,tmp, addr);
+
+ Register zero = __ zero_register(tmp);
+
+ __ BIND(L_cardtable_loop);
+ __ strb(zero, Address(addr, 1, post_indexed));
+ __ subs(count, count, 1);
+ __ b(L_cardtable_loop, ge);
+ __ BIND(L_done);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ARM_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ARM_HPP
+#define CPU_ARM_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ARM_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // #ifndef CPU_ARM_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, int callee_saved_regs) {
+
+ if (is_oop) {
+ gen_write_ref_array_pre_barrier(masm, decorators, addr, count, callee_saved_regs);
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, Register tmp) {
+ if (is_oop) {
+ gen_write_ref_array_post_barrier(masm, decorators, addr, count, tmp);
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP
+#define CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, , int callee_saved_regs) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {}
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, int callee_saved_regs);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/interp_masm_arm.cpp
--- a/src/hotspot/cpu/arm/interp_masm_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,9 +24,9 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.inline.hpp"
+#include "gc/shared/cardTableBarrierSet.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interp_masm_arm.hpp"
#include "interpreter/interpreter.hpp"
@@ -40,6 +40,7 @@
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#if INCLUDE_ALL_GCS
@@ -411,10 +412,10 @@
void InterpreterMacroAssembler::store_check_part1(Register card_table_base) {
// Check barrier set type (should be card table) and element size
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableModRef,
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet,
"Wrong barrier set kind");
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code");
@@ -473,7 +474,7 @@
#ifdef AARCH64
strb(ZR, card_table_addr);
#else
- CardTableModRefBS* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
+ CardTableBarrierSet* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
CardTable* ct = ctbs->card_table();
if ((((uintptr_t)ct->byte_map_base() & 0xff) == 0)) {
// Card table is aligned so the lowest byte of the table address base is zero.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/interpreterRT_arm.cpp
--- a/src/hotspot/cpu/arm/interpreterRT_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/interpreterRT_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -31,11 +32,26 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
+Interpreter::SignatureHandlerGenerator::SignatureHandlerGenerator(
+ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+ _abi_offset = 0;
+ _ireg = is_static() ? 2 : 1;
+#ifdef __ABI_HARD__
+#ifdef AARCH64
+ _freg = 0;
+#else
+ _fp_slot = 0;
+ _single_fpr_slot = 0;
+#endif
+#endif
+}
+
#ifdef SHARING_FAST_NATIVE_FINGERPRINTS
// mapping from SignatureIterator param to (common) type of parsing
static const u1 shared_type[] = {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/interpreterRT_arm.hpp
--- a/src/hotspot/cpu/arm/interpreterRT_arm.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/interpreterRT_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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,8 +25,6 @@
#ifndef CPU_ARM_VM_INTERPRETERRT_ARM_HPP
#define CPU_ARM_VM_INTERPRETERRT_ARM_HPP
-#include "memory/allocation.hpp"
-
// native method calls
class SignatureHandlerGenerator: public NativeSignatureIterator {
@@ -56,23 +54,10 @@
#endif
public:
// Creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
- _abi_offset = 0;
- _ireg = is_static() ? 2 : 1;
-#ifdef __ABI_HARD__
-#ifdef AARCH64
- _freg = 0;
-#else
- _fp_slot = 0;
- _single_fpr_slot = 0;
-#endif
-#endif
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// Code generation
void generate(uint64_t fingerprint);
-
};
#ifndef AARCH64
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp
--- a/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_arm.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/macroAssembler_arm.cpp
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,14 +30,14 @@
#include "code/nativeInst.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "oops/klass.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -2267,7 +2267,7 @@
DirtyCardQueue::byte_offset_of_buf()));
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
Label done;
Label runtime;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/methodHandles_arm.cpp
--- a/src/hotspot/cpu/arm/methodHandles_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -34,6 +34,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/runtime_arm.cpp
--- a/src/hotspot/cpu/arm/runtime_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/runtime_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "memory/resourceArea.hpp"
#include "nativeInst_arm.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/stubGenerator_arm.cpp
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,8 +25,8 @@
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "assembler_arm.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_arm.hpp"
#include "oops/instanceOop.hpp"
@@ -2855,148 +2855,6 @@
return start;
}
-#if INCLUDE_ALL_GCS
- //
- // Generate pre-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count, 32-bit int
- // callee_saved_regs -
- // the call must preserve this number of registers: R0, R1, ..., R[callee_saved_regs-1]
- //
- // callee_saved_regs must include addr and count
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) except for callee_saved_regs.
- void gen_write_ref_array_pre_barrier(Register addr, Register count, int callee_saved_regs) {
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- assert( addr->encoding() < callee_saved_regs, "addr must be saved");
- assert(count->encoding() < callee_saved_regs, "count must be saved");
-
- BLOCK_COMMENT("PreBarrier");
-
-#ifdef AARCH64
- callee_saved_regs = align_up(callee_saved_regs, 2);
- for (int i = 0; i < callee_saved_regs; i += 2) {
- __ raw_push(as_Register(i), as_Register(i+1));
- }
-#else
- RegisterSet saved_regs = RegisterSet(R0, as_Register(callee_saved_regs-1));
- __ push(saved_regs | R9ifScratched);
-#endif // AARCH64
-
- if (addr != R0) {
- assert_different_registers(count, R0);
- __ mov(R0, addr);
- }
-#ifdef AARCH64
- __ zero_extend(R1, count, 32); // BarrierSet::static_write_ref_array_pre takes size_t
-#else
- if (count != R1) {
- __ mov(R1, count);
- }
-#endif // AARCH64
-
- __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
-
-#ifdef AARCH64
- for (int i = callee_saved_regs - 2; i >= 0; i -= 2) {
- __ raw_pop(as_Register(i), as_Register(i+1));
- }
-#else
- __ pop(saved_regs | R9ifScratched);
-#endif // AARCH64
- }
- case BarrierSet::CardTableModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
-#endif // INCLUDE_ALL_GCS
-
- //
- // Generate post-write barrier for array.
- //
- // Input:
- // addr - register containing starting address (can be scratched)
- // count - register containing element count, 32-bit int (can be scratched)
- // tmp - scratch register
- //
- // Note: LR can be scratched but might be equal to addr, count or tmp
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
- void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp) {
- assert_different_registers(addr, count, tmp);
- BarrierSet* bs = Universe::heap()->barrier_set();
-
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- BLOCK_COMMENT("G1PostBarrier");
- if (addr != R0) {
- assert_different_registers(count, R0);
- __ mov(R0, addr);
- }
-#ifdef AARCH64
- __ zero_extend(R1, count, 32); // BarrierSet::static_write_ref_array_post takes size_t
-#else
- if (count != R1) {
- __ mov(R1, count);
- }
-#if R9_IS_SCRATCHED
- // Safer to save R9 here since callers may have been written
- // assuming R9 survives. This is suboptimal but is not in
- // general worth optimizing for the few platforms where R9
- // is scratched. Note that the optimization might not be to
- // difficult for this particular call site.
- __ push(R9);
-#endif
-#endif // !AARCH64
- __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));
-#ifndef AARCH64
-#if R9_IS_SCRATCHED
- __ pop(R9);
-#endif
-#endif // !AARCH64
- }
- break;
- case BarrierSet::CardTableModRef:
- {
- BLOCK_COMMENT("CardTablePostBarrier");
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
- CardTable* ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
-
- Label L_cardtable_loop, L_done;
-
- __ cbz_32(count, L_done); // zero count - nothing to do
-
- __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
- __ sub(count, count, BytesPerHeapOop); // last addr
-
- __ logical_shift_right(addr, addr, CardTable::card_shift);
- __ logical_shift_right(count, count, CardTable::card_shift);
- __ sub(count, count, addr); // nb of cards
-
- // warning: Rthread has not been preserved
- __ mov_address(tmp, (address) ct->byte_map_base(), symbolic_Relocation::card_table_reference);
- __ add(addr,tmp, addr);
-
- Register zero = __ zero_register(tmp);
-
- __ BIND(L_cardtable_loop);
- __ strb(zero, Address(addr, 1, post_indexed));
- __ subs(count, count, 1);
- __ b(L_cardtable_loop, ge);
- __ BIND(L_done);
- }
- break;
- default:
- ShouldNotReachHere();
- }
- }
// Generates pattern of code to be placed after raw data copying in generate_oop_copy
// Includes return from arraycopy stub.
@@ -3007,7 +2865,7 @@
// count: total number of copied elements, 32-bit int
//
// Blows all volatile (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) and 'to', 'count', 'tmp' registers.
- void oop_arraycopy_stub_epilogue_helper(Register to, Register count, Register tmp, bool status, bool forward) {
+ void oop_arraycopy_stub_epilogue_helper(Register to, Register count, Register tmp, bool status, bool forward, DecoratorSet decorators) {
assert_different_registers(to, count, tmp);
if (forward) {
@@ -3018,7 +2876,8 @@
// 'to' is the beginning of the region
- gen_write_ref_array_post_barrier(to, count, tmp);
+ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->arraycopy_epilogue(this, decorators, true, to, count, tmp);
if (status) {
__ mov(R0, 0); // OK
@@ -3086,9 +2945,16 @@
__ push(LR);
#endif // AARCH64
-#if INCLUDE_ALL_GCS
- gen_write_ref_array_pre_barrier(to, count, callee_saved_regs);
-#endif // INCLUDE_ALL_GCS
+ DecoratorSet decorators = 0;
+ if (disjoint) {
+ decorators |= ARRAYCOPY_DISJOINT;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);
// save arguments for barrier generation (after the pre barrier)
__ mov(saved_count, count);
@@ -3146,12 +3012,12 @@
}
assert(small_copy_limit >= count_required_to_align + min_copy, "first loop might exhaust count");
- oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward);
+ oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward, decorators);
{
copy_small_array(from, to, count, tmp1, noreg, bytes_per_count, forward, L_small_array);
- oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward);
+ oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward, decorators);
}
if (!to_is_aligned) {
@@ -3165,7 +3031,7 @@
int min_copy_shifted = align_dst_and_generate_shifted_copy_loop(from, to, count, bytes_per_count, forward);
assert (small_copy_limit >= count_required_to_align + min_copy_shifted, "first loop might exhaust count");
- oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward);
+ oop_arraycopy_stub_epilogue_helper(to, saved_count, /* tmp */ tmp1, status, forward, decorators);
}
return start;
@@ -3336,7 +3202,7 @@
const int callee_saved_regs = AARCH64_ONLY(5) NOT_AARCH64(4); // LR saved differently
- Label load_element, store_element, do_card_marks, fail;
+ Label load_element, store_element, do_epilogue, fail;
BLOCK_COMMENT("Entry:");
@@ -3351,9 +3217,10 @@
pushed+=1;
#endif // AARCH64
-#if INCLUDE_ALL_GCS
- gen_write_ref_array_pre_barrier(to, count, callee_saved_regs);
-#endif // INCLUDE_ALL_GCS
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+
+ BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);
#ifndef AARCH64
const RegisterSet caller_saved_regs = RegisterSet(R4,R6) | RegisterSet(R8,R9) | altFP_7_11;
@@ -3399,7 +3266,7 @@
__ subs_32(count,count,1);
__ str(R5, Address(to, BytesPerHeapOop, post_indexed)); // store the oop
}
- __ b(do_card_marks, eq); // count exhausted
+ __ b(do_epilogue, eq); // count exhausted
// ======== loop entry is here ========
__ BIND(load_element);
@@ -3421,7 +3288,7 @@
// Note: fail marked by the fact that count differs from saved_count
- __ BIND(do_card_marks);
+ __ BIND(do_epilogue);
Register copied = AARCH64_ONLY(R20) NOT_AARCH64(R4); // saved
Label L_not_copied;
@@ -3431,7 +3298,7 @@
__ sub(to, to, AsmOperand(copied, lsl, LogBytesPerHeapOop)); // initial to value
__ mov(R12, copied); // count arg scratched by post barrier
- gen_write_ref_array_post_barrier(to, R12, R3);
+ bs->arraycopy_epilogue(this, decorators, true, to, R12, R3);
assert_different_registers(R3,R12,LR,copied,saved_count);
inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R3, R12);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/arm/templateTable_arm.cpp
--- a/src/hotspot/cpu/arm/templateTable_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/arm/templateTable_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,6 +34,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -228,7 +229,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
if (is_null) {
__ store_heap_oop_null(new_val, obj);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/assembler_ppc.cpp
--- a/src/hotspot/cpu/ppc/assembler_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/assembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,13 +25,13 @@
#include "precompiled.hpp"
#include "asm/assembler.inline.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,9 +33,10 @@
#include "ci/ciInstance.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "nativeInst_ppc.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -1858,34 +1859,31 @@
if (op->expected_type() == NULL) {
assert(src->is_nonvolatile() && src_pos->is_nonvolatile() && dst->is_nonvolatile() && dst_pos->is_nonvolatile() &&
length->is_nonvolatile(), "must preserve");
+ address copyfunc_addr = StubRoutines::generic_arraycopy();
+ assert(copyfunc_addr != NULL, "generic arraycopy stub required");
+
// 3 parms are int. Convert to long.
__ mr(R3_ARG1, src);
__ extsw(R4_ARG2, src_pos);
__ mr(R5_ARG3, dst);
__ extsw(R6_ARG4, dst_pos);
__ extsw(R7_ARG5, length);
- address copyfunc_addr = StubRoutines::generic_arraycopy();
-
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated.
- address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
- __ call_c_with_frame_resize(entry, frame_resize);
- } else {
+
#ifndef PRODUCT
- if (PrintC1Statistics) {
- address counter = (address)&Runtime1::_generic_arraycopystub_cnt;
- int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true);
- __ lwz(R11_scratch1, simm16_offs, tmp);
- __ addi(R11_scratch1, R11_scratch1, 1);
- __ stw(R11_scratch1, simm16_offs, tmp);
- }
+ if (PrintC1Statistics) {
+ address counter = (address)&Runtime1::_generic_arraycopystub_cnt;
+ int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true);
+ __ lwz(R11_scratch1, simm16_offs, tmp);
+ __ addi(R11_scratch1, R11_scratch1, 1);
+ __ stw(R11_scratch1, simm16_offs, tmp);
+ }
#endif
- __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0);
-
- __ nand(tmp, R3_RET, R3_RET);
- __ subf(length, tmp, length);
- __ add(src_pos, tmp, src_pos);
- __ add(dst_pos, tmp, dst_pos);
- }
+ __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0);
+
+ __ nand(tmp, R3_RET, R3_RET);
+ __ subf(length, tmp, length);
+ __ add(src_pos, tmp, src_pos);
+ __ add(dst_pos, tmp, dst_pos);
__ cmpwi(CCR0, R3_RET, 0);
__ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::less), *stub->entry());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp
--- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "c1/c1_Runtime1.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_ppc.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/frame_ppc.hpp
--- a/src/hotspot/cpu/ppc/frame_ppc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/frame_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -425,4 +425,6 @@
pc_return_offset = 0
};
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_PPC_VM_FRAME_PPC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/frame_ppc.inline.hpp
--- a/src/hotspot/cpu/ppc/frame_ppc.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/frame_ppc.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -179,10 +179,6 @@
return (intptr_t*)interpreter_frame_monitor_end() - 1;
}
-inline jint frame::interpreter_frame_expression_stack_direction() {
- return -1;
-}
-
// top of expression stack
inline intptr_t* frame::interpreter_frame_tos_address() const {
return ((intptr_t*) get_ijava_state()->esp) + Interpreter::stackElementWords;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/thread.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register from, Register to, Register count,
+ Register preserve1, Register preserve2) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+ // With G1, don't generate the call if we statically know that the target in uninitialized
+ if (!dest_uninitialized) {
+ int spill_slots = 3;
+ if (preserve1 != noreg) { spill_slots++; }
+ if (preserve2 != noreg) { spill_slots++; }
+ const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
+ Label filtered;
+
+ // Is marking active?
+ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+ __ lwz(R0, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
+ } else {
+ guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+ __ lbz(R0, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
+ }
+ __ cmpdi(CCR0, R0, 0);
+ __ beq(CCR0, filtered);
+
+ __ save_LR_CR(R0);
+ __ push_frame(frame_size, R0);
+ int slot_nr = 0;
+ __ std(from, frame_size - (++slot_nr) * wordSize, R1_SP);
+ __ std(to, frame_size - (++slot_nr) * wordSize, R1_SP);
+ __ std(count, frame_size - (++slot_nr) * wordSize, R1_SP);
+ if (preserve1 != noreg) { __ std(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
+ if (preserve2 != noreg) { __ std(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
+
+ if (UseCompressedOops) {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry), to, count);
+ } else {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry), to, count);
+ }
+
+ slot_nr = 0;
+ __ ld(from, frame_size - (++slot_nr) * wordSize, R1_SP);
+ __ ld(to, frame_size - (++slot_nr) * wordSize, R1_SP);
+ __ ld(count, frame_size - (++slot_nr) * wordSize, R1_SP);
+ if (preserve1 != noreg) { __ ld(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
+ if (preserve2 != noreg) { __ ld(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
+ __ addi(R1_SP, R1_SP, frame_size); // pop_frame()
+ __ restore_LR_CR(R0);
+
+ __ bind(filtered);
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register preserve) {
+ int spill_slots = (preserve != noreg) ? 1 : 0;
+ const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
+
+ __ save_LR_CR(R0);
+ __ push_frame(frame_size, R0);
+ if (preserve != noreg) { __ std(preserve, frame_size - 1 * wordSize, R1_SP); }
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry), addr, count);
+ if (preserve != noreg) { __ ld(preserve, frame_size - 1 * wordSize, R1_SP); }
+ __ addi(R1_SP, R1_SP, frame_size); // pop_frame();
+ __ restore_LR_CR(R0);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_PPC_GC_G1_G1BARRIERSETASSEMBLER_PPC_HPP
+#define CPU_PPC_GC_G1_G1BARRIERSETASSEMBLER_PPC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register from, Register to, Register count,
+ Register preserve1, Register preserve2);
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve);
+};
+
+#endif // CPU_PPC_GC_G1_G1BARRIERSETASSEMBLER_PPC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_PPC_GC_SHARED_BARRIERSETASSEMBLER_PPC_HPP
+#define CPU_PPC_GC_SHARED_BARRIERSETASSEMBLER_PPC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class InterpreterMacroAssembler;
+
+class BarrierSetAssembler: public CHeapObj {
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count, Register preserve1, Register preserve2) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, Register preserve) {}
+};
+
+#endif // CPU_PPC_GC_SHARED_BARRIERSETASSEMBLER_PPC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr,
+ Register count, Register preserve) {
+ CardTableBarrierSet* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+ assert_different_registers(addr, count, R0);
+
+ Label Lskip_loop, Lstore_loop;
+
+ if (UseConcMarkSweepGC) { __ membar(Assembler::StoreStore); }
+
+ __ sldi_(count, count, LogBytesPerHeapOop);
+ __ beq(CCR0, Lskip_loop); // zero length
+ __ addi(count, count, -BytesPerHeapOop);
+ __ add(count, addr, count);
+ // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
+ __ srdi(addr, addr, CardTable::card_shift);
+ __ srdi(count, count, CardTable::card_shift);
+ __ subf(count, addr, count);
+ __ add_const_optimized(addr, addr, (address)ct->byte_map_base(), R0);
+ __ addi(count, count, 1);
+ __ li(R0, 0);
+ __ mtctr(count);
+ // Byte store loop
+ __ bind(Lstore_loop);
+ __ stb(R0, 0, addr);
+ __ addi(addr, addr, 1);
+ __ bdnz(Lstore_loop);
+ __ bind(Lskip_loop);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_PPC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_PPC_HPP
+#define CPU_PPC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_PPC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr,
+ Register count, Register preserve);
+};
+
+#endif // CPU_PPC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_PPC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count, Register preserve1, Register preserve2) {
+ if (type == T_OBJECT) {
+ gen_write_ref_array_pre_barrier(masm, decorators, src, dst, count, preserve1, preserve2);
+
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ if (!checkcast) {
+ assert_different_registers(dst, count, R9_ARG7, R10_ARG8);
+ // Save some arguments for epilogue, e.g. disjoint_long_copy_core destroys them.
+ __ mr(R9_ARG7, dst);
+ __ mr(R10_ARG8, count);
+ }
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, Register preserve) {
+ if (type == T_OBJECT) {
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ if (!checkcast) {
+ gen_write_ref_array_post_barrier(masm, decorators, R9_ARG7, R10_ARG8, preserve);
+ } else {
+ gen_write_ref_array_post_barrier(masm, decorators, dst, count, preserve);
+ }
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP
+#define CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register from, Register to, Register count,
+ Register preserve1, Register preserve2) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve) {}
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count, Register preserve1, Register preserve2);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, Register preserve);
+};
+
+#endif // CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,6 +29,7 @@
#include "interp_masm_ppc.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "prims/jvmtiThreadState.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/interpreterRT_ppc.cpp
--- a/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/assembler.inline.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -33,7 +34,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
@@ -46,6 +47,12 @@
// Implementation of SignatureHandlerGenerator
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
+ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+ _num_used_fp_arg_regs = 0;
+}
+
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
Argument jni_arg(jni_offset());
Register r = jni_arg.is_register() ? jni_arg.as_register() : R0;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/interpreterRT_ppc.hpp
--- a/src/hotspot/cpu/ppc/interpreterRT_ppc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/interpreterRT_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,8 +26,8 @@
#ifndef CPU_PPC_VM_INTERPRETERRT_PPC_HPP
#define CPU_PPC_VM_INTERPRETERRT_PPC_HPP
-#include "asm/macroAssembler.hpp"
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
// native method calls
@@ -45,10 +45,7 @@
public:
// Creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
- _num_used_fp_arg_regs = 0;
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// Code generation
void generate(uint64_t fingerprint);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/jvmciCodeInstaller_ppc.cpp
--- a/src/hotspot/cpu/ppc/jvmciCodeInstaller_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/jvmciCodeInstaller_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_ppc.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
@@ -35,7 +35,7 @@
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
@@ -3036,9 +3036,9 @@
// Write the card table byte if needed.
void MacroAssembler::card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp) {
- CardTableModRefBS* bs =
- barrier_set_cast(Universe::heap()->barrier_set());
- assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
+ CardTableBarrierSet* bs =
+ barrier_set_cast(Universe::heap()->barrier_set());
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet, "wrong barrier");
CardTable* ct = bs->card_table();
#ifdef ASSERT
cmpdi(CCR0, Rnew_val, 0);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/methodHandles_ppc.cpp
--- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -31,6 +31,8 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "utilities/preserveException.hpp"
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/ppc.ad
--- a/src/hotspot/cpu/ppc/ppc.ad Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/ppc.ad Fri Mar 30 09:24:04 2018 -0700
@@ -1274,12 +1274,12 @@
return offsets;
}
const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
-
+
// Emit the trampoline stub which will be related to the branch-and-link below.
CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
__ relocate(rtype);
-
+
// Note: At this point we do not have the address of the trampoline
// stub, and the entry point might be too far away for bl, so __ pc()
// serves as dummy and the bl will be patched later.
@@ -1526,7 +1526,7 @@
// Save return pc.
___(std) std(return_pc, _abi(lr), callers_sp);
}
-
+
C->set_frame_complete(cbuf.insts_size());
}
#undef ___
@@ -2695,13 +2695,13 @@
ciEnv::current()->record_out_of_memory_failure();
return;
}
-
+
// Get the constant's TOC offset.
toc_offset = __ offset_to_method_toc(const_toc_addr);
-
+
// Keep the current instruction offset in mind.
((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
-
+
__ ld($dst$$Register, toc_offset, $toc$$Register);
%}
@@ -2819,7 +2819,7 @@
MachNode *_last;
} loadConLReplicatedNodesTuple;
-loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
+loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
vecXOper *dst, immI_0Oper *zero,
OptoReg::Name reg_second, OptoReg::Name reg_first,
OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
@@ -3158,7 +3158,7 @@
Label skip_storestore;
#if 0 // TODO: PPC port
- // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the
+ // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the
// StoreStore barrier conditionally.
__ lwz(R0, 0, $releaseFieldAddr$$Register);
__ cmpwi($crx$$CondRegister, R0, 0);
@@ -6852,7 +6852,7 @@
// Card-mark for CMS garbage collection.
// This cardmark does an optimization so that it must not always
// do a releasing store. For this, it gets the address of
-// CMSCollectorCardTableModRefBSExt::_requires_release as input.
+// CMSCollectorCardTableBarrierSetBSExt::_requires_release as input.
// (Using releaseFieldAddr in the match rule is a hack.)
instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
match(Set mem (StoreCM mem releaseFieldAddr));
@@ -6871,7 +6871,7 @@
// Card-mark for CMS garbage collection.
// This cardmark does an optimization so that it must not always
// do a releasing store. For this, it needs the constant address of
-// CMSCollectorCardTableModRefBSExt::_requires_release.
+// CMSCollectorCardTableBarrierSetBSExt::_requires_release.
// This constant address is split off here by expand so we can use
// adlc / matcher functionality to load it from the constant section.
instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{
@@ -6879,7 +6879,7 @@
predicate(UseConcMarkSweepGC);
expand %{
- immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %}
+ immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %}
iRegLdst releaseFieldAddress;
flagsReg crx;
loadConL_Ex(releaseFieldAddress, baseImm);
@@ -13665,7 +13665,7 @@
instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
effect(DEF temp1, USE src);
-
+
size(4);
ins_encode %{
__ mtvsrwz($temp1$$VectorSRegister, $src$$Register);
@@ -13678,7 +13678,7 @@
size(4);
ins_encode %{
- __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant);
+ __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant);
%}
ins_pipe(pipe_class_default);
%}
@@ -13843,7 +13843,7 @@
expand %{
iRegLdst tmpL;
vecX tmpV;
- immI8 zero %{ (int) 0 %}
+ immI8 zero %{ (int) 0 %}
moveReg(tmpL, src);
repl48(tmpL);
repl32(tmpL);
@@ -13915,10 +13915,10 @@
predicate(n->as_Vector()->length() == 4);
ins_cost(2 * DEFAULT_COST);
- expand %{
+ expand %{
iRegLdst tmpL;
vecX tmpV;
- immI8 zero %{ (int) 0 %}
+ immI8 zero %{ (int) 0 %}
moveReg(tmpL, src);
repl32(tmpL);
mtvsrd(tmpV, tmpL);
@@ -14057,7 +14057,7 @@
iRegIdst tmpI;
iRegLdst tmpL;
vecX tmpV;
- immI8 zero %{ (int) 0 %}
+ immI8 zero %{ (int) 0 %}
moveF2I_reg_stack(tmpS, src); // Move float to stack.
moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
@@ -14096,7 +14096,7 @@
iRegLdst tmpL;
iRegLdst tmp;
vecX tmpV;
- immI8 zero %{ (int) 0 %}
+ immI8 zero %{ (int) 0 %}
moveD2L_reg_stack(tmpS, src);
moveD2L_stack_reg(tmpL, tmpS);
mtvsrd(tmpV, tmpL);
@@ -14132,7 +14132,7 @@
predicate(false);
effect(DEF dst, USE src);
- format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%}
+ format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%}
size(4);
ins_encode %{
__ mtvsrd($dst$$VectorSRegister, $src$$Register);
@@ -14147,7 +14147,7 @@
size(4);
ins_encode %{
__ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant);
- %}
+ %}
ins_pipe(pipe_class_default);
%}
@@ -14158,7 +14158,7 @@
size(4);
ins_encode %{
__ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant);
- %}
+ %}
ins_pipe(pipe_class_default);
%}
@@ -14167,8 +14167,8 @@
predicate(n->as_Vector()->length() == 2);
expand %{
vecX tmpV;
- immI8 zero %{ (int) 0 %}
- mtvsrd(tmpV, src);
+ immI8 zero %{ (int) 0 %}
+ mtvsrd(tmpV, src);
xxpermdi(dst, tmpV, tmpV, zero);
%}
%}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/runtime_ppc.cpp
--- a/src/hotspot/cpu/ppc/runtime_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/runtime_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,7 +33,7 @@
#include "memory/resourceArea.hpp"
#include "nativeInst_ppc.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,10 +29,12 @@
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "frame_ppc.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/stubGenerator_ppc.cpp
--- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,8 +25,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_ppc.hpp"
#include "oops/instanceOop.hpp"
@@ -612,137 +612,6 @@
#undef __
#define __ _masm->
- // Generate G1 pre-write barrier for array.
- //
- // Input:
- // from - register containing src address (only needed for spilling)
- // to - register containing starting address
- // count - register containing element count
- // tmp - scratch register
- //
- // Kills:
- // nothing
- //
- void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1,
- Register preserve1 = noreg, Register preserve2 = noreg) {
- BarrierSet* const bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target in uninitialized
- if (!dest_uninitialized) {
- int spill_slots = 3;
- if (preserve1 != noreg) { spill_slots++; }
- if (preserve2 != noreg) { spill_slots++; }
- const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
- Label filtered;
-
- // Is marking active?
- if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
- __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
- } else {
- guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
- __ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
- }
- __ cmpdi(CCR0, Rtmp1, 0);
- __ beq(CCR0, filtered);
-
- __ save_LR_CR(R0);
- __ push_frame(frame_size, R0);
- int slot_nr = 0;
- __ std(from, frame_size - (++slot_nr) * wordSize, R1_SP);
- __ std(to, frame_size - (++slot_nr) * wordSize, R1_SP);
- __ std(count, frame_size - (++slot_nr) * wordSize, R1_SP);
- if (preserve1 != noreg) { __ std(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
- if (preserve2 != noreg) { __ std(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
-
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), to, count);
-
- slot_nr = 0;
- __ ld(from, frame_size - (++slot_nr) * wordSize, R1_SP);
- __ ld(to, frame_size - (++slot_nr) * wordSize, R1_SP);
- __ ld(count, frame_size - (++slot_nr) * wordSize, R1_SP);
- if (preserve1 != noreg) { __ ld(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
- if (preserve2 != noreg) { __ ld(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
- __ addi(R1_SP, R1_SP, frame_size); // pop_frame()
- __ restore_LR_CR(R0);
-
- __ bind(filtered);
- }
- break;
- case BarrierSet::CardTableModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
-
- // Generate CMS/G1 post-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count
- // tmp - scratch register
- //
- // The input registers and R0 are overwritten.
- //
- void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp, Register preserve = noreg) {
- BarrierSet* const bs = Universe::heap()->barrier_set();
-
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- int spill_slots = (preserve != noreg) ? 1 : 0;
- const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
-
- __ save_LR_CR(R0);
- __ push_frame(frame_size, R0);
- if (preserve != noreg) { __ std(preserve, frame_size - 1 * wordSize, R1_SP); }
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
- if (preserve != noreg) { __ ld(preserve, frame_size - 1 * wordSize, R1_SP); }
- __ addi(R1_SP, R1_SP, frame_size); // pop_frame();
- __ restore_LR_CR(R0);
- }
- break;
- case BarrierSet::CardTableModRef:
- {
- Label Lskip_loop, Lstore_loop;
- if (UseConcMarkSweepGC) {
- // TODO PPC port: contribute optimization / requires shared changes
- __ release();
- }
-
- CardTableModRefBS* const ctbs = barrier_set_cast(bs);
- CardTable* const ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- assert_different_registers(addr, count, tmp);
-
- __ sldi(count, count, LogBytesPerHeapOop);
- __ addi(count, count, -BytesPerHeapOop);
- __ add(count, addr, count);
- // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
- __ srdi(addr, addr, CardTable::card_shift);
- __ srdi(count, count, CardTable::card_shift);
- __ subf(count, addr, count);
- assert_different_registers(R0, addr, count, tmp);
- __ load_const(tmp, (address)ct->byte_map_base());
- __ addic_(count, count, 1);
- __ beq(CCR0, Lskip_loop);
- __ li(R0, 0);
- __ mtctr(count);
- // Byte store loop
- __ bind(Lstore_loop);
- __ stbx(R0, tmp, addr);
- __ addi(addr, addr, 1);
- __ bdnz(Lstore_loop);
- __ bind(Lskip_loop);
- }
- break;
- case BarrierSet::ModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
// Support for void zero_words_aligned8(HeapWord* to, size_t count)
//
@@ -2155,11 +2024,16 @@
STUB_ENTRY(arrayof_oop_disjoint_arraycopy) :
STUB_ENTRY(oop_disjoint_arraycopy);
- gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
-
- // Save arguments.
- __ mr(R9_ARG7, R4_ARG2);
- __ mr(R10_ARG8, R5_ARG3);
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
if (UseCompressedOops) {
array_overlap_test(nooverlap_target, 2);
@@ -2169,7 +2043,7 @@
generate_conjoint_long_copy_core(aligned);
}
- gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
__ li(R3_RET, 0); // return 0
__ blr();
return start;
@@ -2188,12 +2062,17 @@
StubCodeMark mark(this, "StubRoutines", name);
address start = __ function_entry();
assert_positive_int(R5_ARG3);
- gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
-
- // save some arguments, disjoint_long_copy_core destroys them.
- // needed for post barrier
- __ mr(R9_ARG7, R4_ARG2);
- __ mr(R10_ARG8, R5_ARG3);
+
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
if (UseCompressedOops) {
generate_disjoint_int_copy_core(aligned);
@@ -2201,7 +2080,7 @@
generate_disjoint_long_copy_core(aligned);
}
- gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
__ li(R3_RET, 0); // return 0
__ blr();
@@ -2280,11 +2159,17 @@
}
#endif
- gen_write_ref_array_pre_barrier(R3_from, R4_to, R5_count, dest_uninitialized, R12_tmp, /* preserve: */ R6_ckoff, R7_ckval);
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_from, R4_to, R5_count, /* preserve: */ R6_ckoff, R7_ckval);
//inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
- Label load_element, store_element, store_null, success, do_card_marks;
+ Label load_element, store_element, store_null, success, do_epilogue;
__ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
__ li(R8_offset, 0); // Offset from start of arrays.
__ li(R2_minus1, -1);
@@ -2328,15 +2213,15 @@
// and report their number to the caller.
__ subf_(R5_count, R9_remain, R5_count);
__ nand(R3_RET, R5_count, R5_count); // report (-1^K) to caller
- __ bne(CCR0, do_card_marks);
+ __ bne(CCR0, do_epilogue);
__ blr();
__ bind(success);
__ li(R3_RET, 0);
- __ bind(do_card_marks);
- // Store check on R4_to[0..R5_count-1].
- gen_write_ref_array_post_barrier(R4_to, R5_count, R12_tmp, /* preserve: */ R3_RET);
+ __ bind(do_epilogue);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_to, R5_count, /* preserve */ R3_RET);
+
__ blr();
return start;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,6 +34,8 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -103,7 +105,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
Label Lnull, Ldone;
if (Rval != noreg) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/assembler_s390.cpp
--- a/src/hotspot/cpu/s390/assembler_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/assembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,11 +28,11 @@
#include "compiler/disassembler.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,9 +33,10 @@
#include "ci/ciInstance.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "nativeInst_s390.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_s390.inline.hpp"
@@ -631,7 +632,7 @@
};
// Index register is normally not supported, but for
- // LIRGenerator::CardTableModRef_post_barrier we make an exception.
+ // LIRGenerator::CardTableBarrierSet_post_barrier we make an exception.
if (type == T_BYTE && dest->as_address_ptr()->index()->is_valid()) {
__ load_const_optimized(Z_R0_scratch, (int8_t)(c->as_jint()));
store_offset = __ offset();
@@ -1895,6 +1896,15 @@
// If we don't know anything, just go through the generic arraycopy.
if (default_type == NULL) {
+ address copyfunc_addr = StubRoutines::generic_arraycopy();
+
+ if (copyfunc_addr == NULL) {
+ // Take a slow path for generic arraycopy.
+ __ branch_optimized(Assembler::bcondAlways, *stub->entry());
+ __ bind(*stub->continuation());
+ return;
+ }
+
Label done;
// Save outgoing arguments in callee saved registers (C convention) in case
// a call to System.arraycopy is needed.
@@ -1915,10 +1925,6 @@
__ z_lgfr(dst_pos, dst_pos);
__ z_lgfr(length, length);
- address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
-
- address copyfunc_addr = StubRoutines::generic_arraycopy();
-
// Pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint.
// The arguments are in the corresponding registers.
@@ -1927,25 +1933,19 @@
assert(Z_ARG3 == dst, "assumption");
assert(Z_ARG4 == dst_pos, "assumption");
assert(Z_ARG5 == length, "assumption");
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated.
- emit_call_c(C_entry);
- } else {
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_generic_arraycopystub_cnt);
- __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
- }
+ if (PrintC1Statistics) {
+ __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_generic_arraycopystub_cnt);
+ __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+ }
#endif
- emit_call_c(copyfunc_addr);
- }
+ emit_call_c(copyfunc_addr);
CHECK_BAILOUT();
__ compare32_and_branch(Z_RET, (intptr_t)0, Assembler::bcondEqual, *stub->continuation());
- if (copyfunc_addr != NULL) {
- __ z_lgr(tmp, Z_RET);
- __ z_xilf(tmp, -1);
- }
+ __ z_lgr(tmp, Z_RET);
+ __ z_xilf(tmp, -1);
// Restore values from callee saved registers so they are where the stub
// expects them.
@@ -1955,11 +1955,9 @@
__ lgr_if_needed(dst_pos, callee_saved_dst_pos);
__ lgr_if_needed(length, callee_saved_length);
- if (copyfunc_addr != NULL) {
- __ z_sr(length, tmp);
- __ z_ar(src_pos, tmp);
- __ z_ar(dst_pos, tmp);
- }
+ __ z_sr(length, tmp);
+ __ z_ar(src_pos, tmp);
+ __ z_ar(dst_pos, tmp);
__ branch_optimized(Assembler::bcondAlways, *stub->entry());
__ bind(*stub->continuation());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
--- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "c1/c1_Runtime1.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_s390.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/frame_s390.hpp
--- a/src/hotspot/cpu/s390/frame_s390.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/frame_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -549,4 +549,6 @@
pc_return_offset = 0,
};
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_S390_VM_FRAME_S390_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/frame_s390.inline.hpp
--- a/src/hotspot/cpu/s390/frame_s390.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/frame_s390.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -175,10 +175,6 @@
return (intptr_t*)interpreter_frame_monitor_end() - 1;
}
-inline jint frame::interpreter_frame_expression_stack_direction() {
- return -1;
-}
-
inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
return &interpreter_frame_tos_address()[offset];
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "registerSaver_s390.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/thread.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+#define BLOCK_COMMENT(str) if (PrintAssembly) __ block_comment(str)
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+
+ // With G1, don't generate the call if we statically know that the target is uninitialized.
+ if (!dest_uninitialized) {
+ // Is marking active?
+ Label filtered;
+ assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
+ assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
+ Register Rtmp1 = Z_R0_scratch;
+ const int active_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_active());
+ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+ __ load_and_test_int(Rtmp1, Address(Z_thread, active_offset));
+ } else {
+ guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+ __ load_and_test_byte(Rtmp1, Address(Z_thread, active_offset));
+ }
+ __ z_bre(filtered); // Activity indicator is zero, so there is no marking going on currently.
+
+ RegisterSaver::save_live_registers(masm, RegisterSaver::arg_registers); // Creates frame.
+
+ if (UseCompressedOops) {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry), addr, count);
+ } else {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry), addr, count);
+ }
+
+ RegisterSaver::restore_live_registers(masm, RegisterSaver::arg_registers);
+
+ __ bind(filtered);
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, bool do_return) {
+ address entry_point = CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry);
+ if (!do_return) {
+ assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
+ assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
+ RegisterSaver::save_live_registers(masm, RegisterSaver::arg_registers); // Creates frame.
+ __ call_VM_leaf(entry_point, addr, count);
+ RegisterSaver::restore_live_registers(masm, RegisterSaver::arg_registers);
+ } else {
+ // Tail call: call c and return to stub caller.
+ __ lgr_if_needed(Z_ARG1, addr);
+ __ lgr_if_needed(Z_ARG2, count);
+ __ load_const(Z_R1, entry_point);
+ __ z_br(Z_R1); // Branch without linking, callee will return to stub caller.
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_S390_GC_G1_G1BARRIERSETASSEMBLER_S390_HPP
+#define CPU_S390_GC_G1_G1BARRIERSETASSEMBLER_S390_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+ protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count);
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, bool do_return);
+};
+
+#endif // CPU_S390_GC_G1_G1BARRIERSETASSEMBLER_S390_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_S390_GC_G1_BARRIERSETASSEMBLER_S390_HPP
+#define CPU_S390_GC_G1_BARRIERSETASSEMBLER_S390_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class InterpreterMacroAssembler;
+
+class BarrierSetAssembler: public CHeapObj {
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, bool do_return = false);
+};
+
+#endif // CPU_S390_GC_G1_BARRIERSETASSEMBLER_S390_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+#define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
+ bool do_return) {
+ CardTableBarrierSet* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+
+ NearLabel doXC, done;
+ assert_different_registers(Z_R0, Z_R1, addr, count);
+
+ // Nothing to do if count <= 0.
+ if (!do_return) {
+ __ compare64_and_branch(count, (intptr_t) 0, Assembler::bcondNotHigh, done);
+ } else {
+ __ z_ltgr(count, count);
+ __ z_bcr(Assembler::bcondNotPositive, Z_R14);
+ }
+
+ // Note: We can't combine the shifts. We could lose a carry
+ // from calculating the array end address.
+ // count = (count-1)*BytesPerHeapOop + addr
+ // Count holds addr of last oop in array then.
+ __ z_sllg(count, count, LogBytesPerHeapOop);
+ __ add2reg_with_index(count, -BytesPerHeapOop, count, addr);
+
+ // Get base address of card table.
+ __ load_const_optimized(Z_R1, (address)ct->byte_map_base());
+
+ // count = (count>>shift) - (addr>>shift)
+ __ z_srlg(addr, addr, CardTable::card_shift);
+ __ z_srlg(count, count, CardTable::card_shift);
+
+ // Prefetch first elements of card table for update.
+ if (VM_Version::has_Prefetch()) {
+ __ z_pfd(0x02, 0, addr, Z_R1);
+ }
+
+ // Special case: clear just one byte.
+ __ clear_reg(Z_R0, true, false); // Used for doOneByte.
+ __ z_sgr(count, addr); // Count = n-1 now, CC used for brc below.
+ __ z_stc(Z_R0, 0, addr, Z_R1); // Must preserve CC from z_sgr.
+ if (!do_return) {
+ __ z_brz(done);
+ } else {
+ __ z_bcr(Assembler::bcondZero, Z_R14);
+ }
+
+ __ z_cghi(count, 255);
+ __ z_brnh(doXC);
+
+ // MVCLE: clear a long area.
+ // Start addr of card table range = base + addr.
+ // # bytes in card table range = (count + 1)
+ __ add2reg_with_index(Z_R0, 0, Z_R1, addr);
+ __ add2reg(Z_R1, 1, count);
+
+ // dirty hack:
+ // There are just two callers. Both pass
+ // count in Z_ARG3 = Z_R4
+ // addr in Z_ARG2 = Z_R3
+ // ==> use Z_ARG2 as src len reg = 0
+ // Z_ARG1 as src addr (ignored)
+ assert(count == Z_ARG3, "count: unexpected register number");
+ assert(addr == Z_ARG2, "addr: unexpected register number");
+ __ clear_reg(Z_ARG2, true, false);
+
+ __ MacroAssembler::move_long_ext(Z_R0, Z_ARG1, 0);
+
+ if (!do_return) {
+ __ z_bru(done);
+ } else {
+ __ z_bcr(Assembler::bcondAlways, Z_R14);
+ }
+
+ // XC: clear a short area.
+ Label XC_template; // Instr template, never exec directly!
+ __ bind(XC_template);
+ __ z_xc(0, 0, addr, 0, addr);
+
+ __ bind(doXC);
+ // start addr of card table range = base + addr
+ // end addr of card table range = base + addr + count
+ __ add2reg_with_index(addr, 0, Z_R1, addr);
+
+ if (VM_Version::has_ExecuteExtensions()) {
+ __ z_exrl(count, XC_template); // Execute XC with var. len.
+ } else {
+ __ z_larl(Z_R1, XC_template);
+ __ z_ex(count, 0, Z_R0, Z_R1); // Execute XC with var. len.
+ }
+ if (do_return) {
+ __ z_br(Z_R14);
+ }
+
+ __ bind(done);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
+ bool do_return);
+};
+
+#endif // CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
+ bool do_return) {
+ if (do_return) { __ z_br(Z_R14); }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {
+ if (type == T_OBJECT || type == T_ARRAY) {
+ gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, bool do_return) {
+ if (type == T_OBJECT || type == T_ARRAY) {
+ gen_write_ref_array_post_barrier(masm, decorators, dst, count, do_return);
+ } else {
+ if (do_return) { __ z_br(Z_R14); }
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
+ bool do_return);
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register dst, Register count, bool do_return = false);
+};
+
+#endif // CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/interp_masm_s390.cpp
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -36,6 +36,7 @@
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/interpreterRT_s390.cpp
--- a/src/hotspot/cpu/s390/interpreterRT_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/interpreterRT_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -32,7 +33,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
// Access macros for Java and C arguments.
@@ -64,6 +65,11 @@
}
// Implementation of SignatureHandlerGenerator
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
+ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+ _fp_arg_nr = 0;
+}
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
int int_arg_nr = jni_offset() - _fp_arg_nr;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/interpreterRT_s390.hpp
--- a/src/hotspot/cpu/s390/interpreterRT_s390.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/interpreterRT_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,8 @@
#ifndef CPU_S390_VM_INTERPRETERRT_S390_HPP
#define CPU_S390_VM_INTERPRETERRT_S390_HPP
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
static int binary_search(int key, LookupswitchPair* array, int n);
@@ -51,10 +52,7 @@
public:
// creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
- _fp_arg_nr = 0;
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// code generation
void generate(uint64_t fingerprint);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp
--- a/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -34,6 +34,7 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_s390.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/macroAssembler_s390.cpp
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,7 @@
#include "gc/shared/cardTable.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/klass.inline.hpp"
@@ -41,7 +41,7 @@
#include "registerSaver_s390.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
@@ -3505,9 +3505,9 @@
// Write to card table for modification at store_addr - register is destroyed afterwards.
void MacroAssembler::card_write_barrier_post(Register store_addr, Register tmp) {
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
- assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet, "wrong barrier");
assert_different_registers(store_addr, tmp);
z_srlg(store_addr, store_addr, CardTable::card_shift);
load_absolute_address(tmp, (address)ct->byte_map_base());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/methodHandles_s390.cpp
--- a/src/hotspot/cpu/s390/methodHandles_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -31,6 +31,8 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "utilities/preserveException.hpp"
#ifdef PRODUCT
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/runtime_s390.cpp
--- a/src/hotspot/cpu/s390/runtime_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/runtime_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "memory/resourceArea.hpp"
#include "nativeInst_s390.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/sharedRuntime_s390.cpp
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,11 +28,13 @@
#include "code/debugInfoRec.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
#include "registerSaver_s390.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/stubGenerator_s390.cpp
--- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,8 +26,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "registerSaver_s390.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
#include "nativeInst_s390.hpp"
@@ -686,188 +686,6 @@
return start;
}
- // Generate pre-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count
- //
- // The input registers are overwritten.
- void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
-
- BarrierSet* const bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target is uninitialized.
- if (!dest_uninitialized) {
- // Is marking active?
- Label filtered;
- assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
- assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
- Register Rtmp1 = Z_R0_scratch;
- const int active_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_active());
- if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
- __ load_and_test_int(Rtmp1, Address(Z_thread, active_offset));
- } else {
- guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
- __ load_and_test_byte(Rtmp1, Address(Z_thread, active_offset));
- }
- __ z_bre(filtered); // Activity indicator is zero, so there is no marking going on currently.
-
- // __ push_frame_abi160(0); // implicitly done in save_live_registers()
- (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers);
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), addr, count);
- (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers);
- // __ pop_frame(); // implicitly done in restore_live_registers()
-
- __ bind(filtered);
- }
- break;
- case BarrierSet::CardTableModRef:
- case BarrierSet::ModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
-
- // Generate post-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count
- //
- // The input registers are overwritten.
- void gen_write_ref_array_post_barrier(Register addr, Register count, bool branchToEnd) {
- BarrierSet* const bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- if (branchToEnd) {
- assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
- assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
- // __ push_frame_abi160(0); // implicitly done in save_live_registers()
- (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers);
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
- (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers);
- // __ pop_frame(); // implicitly done in restore_live_registers()
- } else {
- // Tail call: call c and return to stub caller.
- address entry_point = CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post);
- __ lgr_if_needed(Z_ARG1, addr);
- __ lgr_if_needed(Z_ARG2, count);
- __ load_const(Z_R1, entry_point);
- __ z_br(Z_R1); // Branch without linking, callee will return to stub caller.
- }
- }
- break;
- case BarrierSet::CardTableModRef:
- // These cases formerly known as
- // void array_store_check(Register addr, Register count, bool branchToEnd).
- {
- NearLabel doXC, done;
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
- CardTable* ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- assert_different_registers(Z_R0, Z_R1, addr, count);
-
- // Nothing to do if count <= 0.
- if (branchToEnd) {
- __ compare64_and_branch(count, (intptr_t) 0, Assembler::bcondNotHigh, done);
- } else {
- __ z_ltgr(count, count);
- __ z_bcr(Assembler::bcondNotPositive, Z_R14);
- }
-
- // Note: We can't combine the shifts. We could lose a carry
- // from calculating the array end address.
- // count = (count-1)*BytesPerHeapOop + addr
- // Count holds addr of last oop in array then.
- __ z_sllg(count, count, LogBytesPerHeapOop);
- __ add2reg_with_index(count, -BytesPerHeapOop, count, addr);
-
- // Get base address of card table.
- __ load_const_optimized(Z_R1, (address)ct->byte_map_base());
-
- // count = (count>>shift) - (addr>>shift)
- __ z_srlg(addr, addr, CardTable::card_shift);
- __ z_srlg(count, count, CardTable::card_shift);
-
- // Prefetch first elements of card table for update.
- if (VM_Version::has_Prefetch()) {
- __ z_pfd(0x02, 0, addr, Z_R1);
- }
-
- // Special case: clear just one byte.
- __ clear_reg(Z_R0, true, false); // Used for doOneByte.
- __ z_sgr(count, addr); // Count = n-1 now, CC used for brc below.
- __ z_stc(Z_R0, 0, addr, Z_R1); // Must preserve CC from z_sgr.
- if (branchToEnd) {
- __ z_brz(done);
- } else {
- __ z_bcr(Assembler::bcondZero, Z_R14);
- }
-
- __ z_cghi(count, 255);
- __ z_brnh(doXC);
-
- // MVCLE: clear a long area.
- // Start addr of card table range = base + addr.
- // # bytes in card table range = (count + 1)
- __ add2reg_with_index(Z_R0, 0, Z_R1, addr);
- __ add2reg(Z_R1, 1, count);
-
- // dirty hack:
- // There are just two callers. Both pass
- // count in Z_ARG3 = Z_R4
- // addr in Z_ARG2 = Z_R3
- // ==> use Z_ARG2 as src len reg = 0
- // Z_ARG1 as src addr (ignored)
- assert(count == Z_ARG3, "count: unexpected register number");
- assert(addr == Z_ARG2, "addr: unexpected register number");
- __ clear_reg(Z_ARG2, true, false);
-
- __ MacroAssembler::move_long_ext(Z_R0, Z_ARG1, 0);
-
- if (branchToEnd) {
- __ z_bru(done);
- } else {
- __ z_bcr(Assembler::bcondAlways, Z_R14);
- }
-
- // XC: clear a short area.
- Label XC_template; // Instr template, never exec directly!
- __ bind(XC_template);
- __ z_xc(0, 0, addr, 0, addr);
-
- __ bind(doXC);
- // start addr of card table range = base + addr
- // end addr of card table range = base + addr + count
- __ add2reg_with_index(addr, 0, Z_R1, addr);
-
- if (VM_Version::has_ExecuteExtensions()) {
- __ z_exrl(count, XC_template); // Execute XC with var. len.
- } else {
- __ z_larl(Z_R1, XC_template);
- __ z_ex(count, 0, Z_R0, Z_R1); // Execute XC with var. len.
- }
- if (!branchToEnd) {
- __ z_br(Z_R14);
- }
-
- __ bind(done);
- }
- break;
- case BarrierSet::ModRef:
- if (!branchToEnd) { __ z_br(Z_R14); }
- break;
- default:
- ShouldNotReachHere();
- }
- }
-
-
// This is to test that the count register contains a positive int value.
// Required because C2 does not respect int to long conversion for stub calls.
void assert_positive_int(Register count) {
@@ -1482,11 +1300,20 @@
unsigned int start_off = __ offset(); // Remember stub start address (is rtn value).
unsigned int size = UseCompressedOops ? 4 : 8;
- gen_write_ref_array_pre_barrier(Z_ARG2, Z_ARG3, dest_uninitialized);
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, Z_ARG1, Z_ARG2, Z_ARG3);
generate_disjoint_copy(aligned, size, true, true);
- gen_write_ref_array_post_barrier(Z_ARG2, Z_ARG3, false);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, Z_ARG2, Z_ARG3, true);
return __ addr_at(start_off);
}
@@ -1565,11 +1392,20 @@
// Branch to disjoint_copy (if applicable) before pre_barrier to avoid double pre_barrier.
array_overlap_test(nooverlap_target, shift); // Branch away to nooverlap_target if disjoint.
- gen_write_ref_array_pre_barrier(Z_ARG2, Z_ARG3, dest_uninitialized);
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, Z_ARG1, Z_ARG2, Z_ARG3);
generate_conjoint_copy(aligned, size, true); // Must preserve ARG2, ARG3.
- gen_write_ref_array_post_barrier(Z_ARG2, Z_ARG3, false);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, Z_ARG2, Z_ARG3, true);
return __ addr_at(start_off);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/s390/templateTable_s390.cpp
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,6 +33,8 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -260,7 +262,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
if (val_is_null) {
__ store_heap_oop_null(val, offset, base);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,10 +31,12 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciInstance.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -1878,29 +1880,21 @@
__ mov(dst_pos, O3);
__ mov(length, O4);
address copyfunc_addr = StubRoutines::generic_arraycopy();
-
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy));
- } else {
+ assert(copyfunc_addr != NULL, "generic arraycopy stub required");
+
#ifndef PRODUCT
- if (PrintC1Statistics) {
- address counter = (address)&Runtime1::_generic_arraycopystub_cnt;
- __ inc_counter(counter, G1, G3);
- }
-#endif
- __ call_VM_leaf(tmp, copyfunc_addr);
+ if (PrintC1Statistics) {
+ address counter = (address)&Runtime1::_generic_arraycopystub_cnt;
+ __ inc_counter(counter, G1, G3);
}
-
- if (copyfunc_addr != NULL) {
- __ xor3(O0, -1, tmp);
- __ sub(length, tmp, length);
- __ add(src_pos, tmp, src_pos);
- __ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
- __ delayed()->add(dst_pos, tmp, dst_pos);
- } else {
- __ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
- __ delayed()->nop();
- }
+#endif
+ __ call_VM_leaf(tmp, copyfunc_addr);
+
+ __ xor3(O0, -1, tmp);
+ __ sub(length, tmp, length);
+ __ add(src_pos, tmp, src_pos);
+ __ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
+ __ delayed()->add(dst_pos, tmp, dst_pos);
__ bind(*stub->continuation());
return;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp
--- a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "c1/c1_Runtime1.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/frame_sparc.hpp
--- a/src/hotspot/cpu/sparc/frame_sparc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/frame_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -240,4 +240,6 @@
void interpreter_frame_set_monitors(BasicObjectLock* monitors);
public:
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_SPARC_VM_FRAME_SPARC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/frame_sparc.inline.hpp
--- a/src/hotspot/cpu/sparc/frame_sparc.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/frame_sparc.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -99,8 +99,6 @@
return (intptr_t*) sp_addr_at( ImethodDataPtr->sp_offset_in_saved_window());
}
-inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
-
// bottom(base) of the expression stack (highest address)
inline intptr_t* frame::interpreter_frame_expression_stack() const {
return (intptr_t*)interpreter_frame_monitors() - 1;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/macros.hpp"
+
+#define __ masm->
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+ // With G1, don't generate the call if we statically know that the target in uninitialized
+ if (!dest_uninitialized) {
+ Register tmp = O5;
+ assert_different_registers(addr, count, tmp);
+ Label filtered;
+ // Is marking active?
+ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+ __ ld(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
+ } else {
+ guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
+ "Assumption");
+ __ ldsb(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
+ }
+ // Is marking active?
+ __ cmp_and_br_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
+
+ __ save_frame(0);
+ // Save the necessary global regs... will be used after.
+ if (addr->is_global()) {
+ __ mov(addr, L0);
+ }
+ if (count->is_global()) {
+ __ mov(count, L1);
+ }
+ __ mov(addr->after_save(), O0);
+ // Get the count into O1
+ address slowpath = UseCompressedOops ? CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry)
+ : CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry);
+ __ call(slowpath);
+ __ delayed()->mov(count->after_save(), O1);
+ if (addr->is_global()) {
+ __ mov(L0, addr);
+ }
+ if (count->is_global()) {
+ __ mov(L1, count);
+ }
+ __ restore();
+
+ __ bind(filtered);
+ DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+ // Get some new fresh output registers.
+ __ save_frame(0);
+ __ mov(addr->after_save(), O0);
+ __ call(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry));
+ __ delayed()->mov(count->after_save(), O1);
+ __ restore();
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_SPARC_GC_G1_G1BARRIERSETASSEMBLER_SPARC_HPP
+#define CPU_SPARC_GC_G1_G1BARRIERSETASSEMBLER_SPARC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count);
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // CPU_SPARC_GC_G1_G1BARRIERSETASSEMBLER_SPARC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/shared/barrierSetAssembler_sparc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/shared/barrierSetAssembler_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_SPARC_GC_SHARED_BARRIERSETASSEMBLER_SPARC_HPP
+#define CPU_SPARC_GC_SHARED_BARRIERSETASSEMBLER_SPARC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class InterpreterMacroAssembler;
+
+class BarrierSetAssembler: public CHeapObj {
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {}
+};
+
+#endif // CPU_SPARC_GC_SHARED_BARRIERSETASSEMBLER_SPARC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/shared/cardTableBarrierSetAssembler_sparc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/shared/cardTableBarrierSetAssembler_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,72 @@
+
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+ CardTableBarrierSet* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+ assert_different_registers(addr, count, tmp);
+
+ Label L_loop, L_done;
+
+ __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
+
+ __ sll_ptr(count, LogBytesPerHeapOop, count);
+ __ sub(count, BytesPerHeapOop, count);
+ __ add(count, addr, count);
+ // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
+ __ srl_ptr(addr, CardTable::card_shift, addr);
+ __ srl_ptr(count, CardTable::card_shift, count);
+ __ sub(count, addr, count);
+ AddressLiteral rs(ct->byte_map_base());
+ __ set(rs, tmp);
+ __ BIND(L_loop);
+ __ stb(G0, tmp, addr);
+ __ subcc(count, 1, count);
+ __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
+ __ delayed()->add(addr, 1, addr);
+
+ __ BIND(L_done);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/shared/cardTableBarrierSetAssembler_sparc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/shared/cardTableBarrierSetAssembler_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_SPARC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_SPARC_HPP
+#define CPU_SPARC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_SPARC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // CPU_SPARC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_SPARC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/shared/modRefBarrierSetAssembler_sparc.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/shared/modRefBarrierSetAssembler_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {
+ if (type == T_OBJECT) {
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ if (!checkcast) {
+ // save arguments for barrier generation
+ __ mov(dst, G1);
+ __ mov(count, G5);
+ gen_write_ref_array_pre_barrier(masm, decorators, G1, G5);
+ } else {
+ gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
+ }
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {
+ if (type == T_OBJECT) {
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ if (!checkcast) {
+ // O0 is used as temp register
+ gen_write_ref_array_post_barrier(masm, decorators, G1, G5, O0);
+ } else {
+ gen_write_ref_array_post_barrier(masm, decorators, dst, count, O3);
+ }
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/gc/shared/modRefBarrierSetAssembler_sparc.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/sparc/gc/shared/modRefBarrierSetAssembler_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_SPARC_GC_SHARED_MODREFBARRIERSETASSEMBLER_SPARC_HPP
+#define CPU_SPARC_GC_SHARED_MODREFBARRIERSETASSEMBLER_SPARC_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp) {}
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count);
+};
+
+#endif // CPU_SPARC_GC_SHARED_MODREFBARRIERSETASSEMBLER_SPARC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/interp_masm_sparc.cpp
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -36,6 +36,7 @@
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/interpreterRT_sparc.cpp
--- a/src/hotspot/cpu/sparc/interpreterRT_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/interpreterRT_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -32,7 +33,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
@@ -40,6 +41,10 @@
// Implementation of SignatureHandlerGenerator
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
+ const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+}
void InterpreterRuntime::SignatureHandlerGenerator::pass_word(int size_of_arg, int offset_in_arg) {
Argument jni_arg(jni_offset() + offset_in_arg, false);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/interpreterRT_sparc.hpp
--- a/src/hotspot/cpu/sparc/interpreterRT_sparc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/interpreterRT_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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,7 +25,9 @@
#ifndef CPU_SPARC_VM_INTERPRETERRT_SPARC_HPP
#define CPU_SPARC_VM_INTERPRETERRT_SPARC_HPP
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
+
static int binary_search(int key, LookupswitchPair* array, int n);
@@ -52,9 +54,7 @@
public:
// Creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// Code generation
void generate( uint64_t fingerprint );
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp
--- a/src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"
#include "vmreg_sparc.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
@@ -35,7 +35,7 @@
#include "oops/klass.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.inline.hpp"
@@ -3729,11 +3729,11 @@
void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
// If we're writing constant NULL, we can skip the write barrier.
if (new_val == G0) return;
- CardTableModRefBS* bs =
- barrier_set_cast(Universe::heap()->barrier_set());
+ CardTableBarrierSet* bs =
+ barrier_set_cast(Universe::heap()->barrier_set());
CardTable* ct = bs->card_table();
- assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet, "wrong barrier");
card_table_write(ct->byte_map_base(), tmp, store_addr);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/methodHandles_sparc.cpp
--- a/src/hotspot/cpu/sparc/methodHandles_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/methodHandles_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -31,6 +31,8 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "utilities/preserveException.hpp"
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/runtime_sparc.cpp
--- a/src/hotspot/cpu/sparc/runtime_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/runtime_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "memory/resourceArea.hpp"
#include "nativeInst_sparc.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,10 +27,12 @@
#include "code/debugInfoRec.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/stubGenerator_sparc.cpp
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,8 +24,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/instanceOop.hpp"
@@ -823,125 +823,6 @@
__ delayed()->nop();
}
- //
- // Generate pre-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count
- // tmp - scratch register
- //
- // The input registers are overwritten.
- //
- void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target in uninitialized
- if (!dest_uninitialized) {
- Register tmp = O5;
- assert_different_registers(addr, count, tmp);
- Label filtered;
- // Is marking active?
- if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
- __ ld(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
- } else {
- guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
- "Assumption");
- __ ldsb(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
- }
- // Is marking active?
- __ cmp_and_br_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
-
- __ save_frame(0);
- // Save the necessary global regs... will be used after.
- if (addr->is_global()) {
- __ mov(addr, L0);
- }
- if (count->is_global()) {
- __ mov(count, L1);
- }
- __ mov(addr->after_save(), O0);
- // Get the count into O1
- __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
- __ delayed()->mov(count->after_save(), O1);
- if (addr->is_global()) {
- __ mov(L0, addr);
- }
- if (count->is_global()) {
- __ mov(L1, count);
- }
- __ restore();
-
- __ bind(filtered);
- DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
- }
- break;
- case BarrierSet::CardTableModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
- //
- // Generate post-write barrier for array.
- //
- // Input:
- // addr - register containing starting address
- // count - register containing element count
- // tmp - scratch register
- //
- // The input registers are overwritten.
- //
- void gen_write_ref_array_post_barrier(Register addr, Register count,
- Register tmp) {
- BarrierSet* bs = Universe::heap()->barrier_set();
-
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- // Get some new fresh output registers.
- __ save_frame(0);
- __ mov(addr->after_save(), O0);
- __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));
- __ delayed()->mov(count->after_save(), O1);
- __ restore();
- }
- break;
- case BarrierSet::CardTableModRef:
- {
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
- CardTable* ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- assert_different_registers(addr, count, tmp);
-
- Label L_loop, L_done;
-
- __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
-
- __ sll_ptr(count, LogBytesPerHeapOop, count);
- __ sub(count, BytesPerHeapOop, count);
- __ add(count, addr, count);
- // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
- __ srl_ptr(addr, CardTable::card_shift, addr);
- __ srl_ptr(count, CardTable::card_shift, count);
- __ sub(count, addr, count);
- AddressLiteral rs(ct->byte_map_base());
- __ set(rs, tmp);
- __ BIND(L_loop);
- __ stb(G0, tmp, addr);
- __ subcc(count, 1, count);
- __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
- __ delayed()->add(addr, 1, addr);
- __ BIND(L_done);
- }
- break;
- case BarrierSet::ModRef:
- break;
- default:
- ShouldNotReachHere();
- }
- }
//
// Generate main code for disjoint arraycopy
@@ -2388,18 +2269,25 @@
BLOCK_COMMENT("Entry:");
}
- // save arguments for barrier generation
- __ mov(to, G1);
- __ mov(count, G5);
- gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
+
assert_clean_int(count, O3); // Make sure 'count' is clean int.
if (UseCompressedOops) {
generate_disjoint_int_copy_core(aligned);
} else {
generate_disjoint_long_copy_core(aligned);
}
- // O0 is used as temp register
- gen_write_ref_array_post_barrier(G1, G5, O0);
+
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);
// O3, O4 are used as temp registers
inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
@@ -2438,10 +2326,16 @@
array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
- // save arguments for barrier generation
- __ mov(to, G1);
- __ mov(count, G5);
- gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
if (UseCompressedOops) {
generate_conjoint_int_copy_core(aligned);
@@ -2449,8 +2343,7 @@
generate_conjoint_long_copy_core(aligned);
}
- // O0 is used as temp register
- gen_write_ref_array_post_barrier(G1, G5, O0);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);
// O3, O4 are used as temp registers
inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
@@ -2552,9 +2445,16 @@
// caller can pass a 64-bit byte count here (from generic stub)
BLOCK_COMMENT("Entry:");
}
- gen_write_ref_array_pre_barrier(O1_to, O2_count, dest_uninitialized);
-
- Label load_element, store_element, do_card_marks, fail, done;
+
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
+
+ Label load_element, store_element, do_epilogue, fail, done;
__ addcc(O2_count, 0, G1_remain); // initialize loop index, and test it
__ brx(Assembler::notZero, false, Assembler::pt, load_element);
__ delayed()->mov(G0, O5_offset); // offset from start of arrays
@@ -2576,7 +2476,7 @@
__ deccc(G1_remain); // decrement the count
__ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop
__ inc(O5_offset, heapOopSize); // step to next offset
- __ brx(Assembler::zero, true, Assembler::pt, do_card_marks);
+ __ brx(Assembler::zero, true, Assembler::pt, do_epilogue);
__ delayed()->set(0, O0); // return -1 on success
// ======== loop entry is here ========
@@ -2600,8 +2500,8 @@
__ brx(Assembler::zero, false, Assembler::pt, done);
__ delayed()->not1(O2_count, O0); // report (-1^K) to caller
- __ BIND(do_card_marks);
- gen_write_ref_array_post_barrier(O1_to, O2_count, O3); // store check on O1[0..O2]
+ __ BIND(do_epilogue);
+ bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
__ BIND(done);
inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/sparc/templateTable_sparc.cpp
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,6 +32,8 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -90,7 +92,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
if (index == noreg ) {
assert(Assembler::is_simm13(offset), "fix this code");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/assembler_x86.cpp
--- a/src/hotspot/cpu/x86/assembler_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,13 +25,12 @@
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,10 +33,12 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciInstance.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "nativeInst_x86.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_x86.inline.hpp"
@@ -3057,9 +3059,8 @@
store_parameter(src, 4);
NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");)
- address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
-
address copyfunc_addr = StubRoutines::generic_arraycopy();
+ assert(copyfunc_addr != NULL, "generic arraycopy stub required");
// pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint
#ifdef _LP64
@@ -3077,29 +3078,21 @@
// Allocate abi space for args but be sure to keep stack aligned
__ subptr(rsp, 6*wordSize);
store_parameter(j_rarg4, 4);
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ call(RuntimeAddress(C_entry));
- } else {
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
- }
+ if (PrintC1Statistics) {
+ __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+ }
#endif
- __ call(RuntimeAddress(copyfunc_addr));
- }
+ __ call(RuntimeAddress(copyfunc_addr));
__ addptr(rsp, 6*wordSize);
#else
__ mov(c_rarg4, j_rarg4);
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ call(RuntimeAddress(C_entry));
- } else {
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
- }
+ if (PrintC1Statistics) {
+ __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+ }
#endif
- __ call(RuntimeAddress(copyfunc_addr));
- }
+ __ call(RuntimeAddress(copyfunc_addr));
#endif // _WIN64
#else
__ push(length);
@@ -3108,26 +3101,20 @@
__ push(src_pos);
__ push(src);
- if (copyfunc_addr == NULL) { // Use C version if stub was not generated
- __ call_VM_leaf(C_entry, 5); // removes pushed parameter from the stack
- } else {
#ifndef PRODUCT
- if (PrintC1Statistics) {
- __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
- }
+ if (PrintC1Statistics) {
+ __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+ }
#endif
- __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack
- }
+ __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack
#endif // _LP64
__ cmpl(rax, 0);
__ jcc(Assembler::equal, *stub->continuation());
- if (copyfunc_addr != NULL) {
- __ mov(tmp, rax);
- __ xorl(tmp, -1);
- }
+ __ mov(tmp, rax);
+ __ xorl(tmp, -1);
// Reload values from the stack so they are where the stub
// expects them.
@@ -3137,11 +3124,9 @@
__ movptr (src_pos, Address(rsp, 3*BytesPerWord));
__ movptr (src, Address(rsp, 4*BytesPerWord));
- if (copyfunc_addr != NULL) {
- __ subl(length, tmp);
- __ addl(src_pos, tmp);
- __ addl(dst_pos, tmp);
- }
+ __ subl(length, tmp);
+ __ addl(src_pos, tmp);
+ __ addl(dst_pos, tmp);
__ jmp(*stub->entry());
__ bind(*stub->continuation());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "c1/c1_Runtime1.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/compiledICHolder.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/frame_x86.hpp
--- a/src/hotspot/cpu/x86/frame_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/frame_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -154,4 +154,6 @@
// deoptimization support
void interpreter_frame_set_last_sp(intptr_t* sp);
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_X86_VM_FRAME_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/frame_x86.inline.hpp
--- a/src/hotspot/cpu/x86/frame_x86.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -223,10 +223,6 @@
return monitor_end-1;
}
-
-inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
-
-
// Entry frames
inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
+#include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/macros.hpp"
+
+#define __ masm->
+
+void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count) {
+ bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
+
+ if (!dest_uninitialized) {
+ Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
+#ifndef _LP64
+ __ push(thread);
+ __ get_thread(thread);
+#endif
+
+ Label filtered;
+ Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_active()));
+ // Is marking active?
+ if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+ __ cmpl(in_progress, 0);
+ } else {
+ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+ __ cmpb(in_progress, 0);
+ }
+
+ NOT_LP64(__ pop(thread);)
+
+ __ jcc(Assembler::equal, filtered);
+
+ __ pusha(); // push registers
+#ifdef _LP64
+ if (count == c_rarg0) {
+ if (addr == c_rarg1) {
+ // exactly backwards!!
+ __ xchgptr(c_rarg1, c_rarg0);
+ } else {
+ __ movptr(c_rarg1, count);
+ __ movptr(c_rarg0, addr);
+ }
+ } else {
+ __ movptr(c_rarg0, addr);
+ __ movptr(c_rarg1, count);
+ }
+ if (UseCompressedOops) {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry), 2);
+ } else {
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry), 2);
+ }
+#else
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry),
+ addr, count);
+#endif
+ __ popa();
+
+ __ bind(filtered);
+ }
+}
+
+void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+ __ pusha(); // push registers (overkill)
+#ifdef _LP64
+ if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
+ assert_different_registers(c_rarg1, addr);
+ __ mov(c_rarg1, count);
+ __ mov(c_rarg0, addr);
+ } else {
+ assert_different_registers(c_rarg0, count);
+ __ mov(c_rarg0, addr);
+ __ mov(c_rarg1, count);
+ }
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry), 2);
+#else
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry),
+ addr, count);
+#endif
+ __ popa();
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_X86_GC_G1_G1BARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_G1_G1BARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
+ protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count);
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp);
+};
+
+#endif // CPU_X86_GC_G1_G1BARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_X86_GC_G1_BARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_G1_BARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "memory/allocation.hpp"
+#include "oops/access.hpp"
+
+class InterpreterMacroAssembler;
+
+class BarrierSetAssembler: public CHeapObj {
+protected:
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {}
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {}
+};
+
+#endif // CPU_X86_GC_G1_BARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/collectedHeap.hpp"
+
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+#define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
+
+void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+ Register addr, Register count, Register tmp) {
+ BarrierSet *bs = Universe::heap()->barrier_set();
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
+ intptr_t disp = (intptr_t) ct->byte_map_base();
+
+ Label L_loop, L_done;
+ const Register end = count;
+ assert_different_registers(addr, end);
+
+ __ testl(count, count);
+ __ jcc(Assembler::zero, L_done); // zero count - nothing to do
+
+
+#ifdef _LP64
+ __ leaq(end, Address(addr, count, TIMES_OOP, 0)); // end == addr+count*oop_size
+ __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
+ __ shrptr(addr, CardTable::card_shift);
+ __ shrptr(end, CardTable::card_shift);
+ __ subptr(end, addr); // end --> cards count
+
+ __ mov64(tmp, disp);
+ __ addptr(addr, tmp);
+__ BIND(L_loop);
+ __ movb(Address(addr, count, Address::times_1), 0);
+ __ decrement(count);
+ __ jcc(Assembler::greaterEqual, L_loop);
+#else
+ __ lea(end, Address(addr, count, Address::times_ptr, -wordSize));
+ __ shrptr(addr, CardTable::card_shift);
+ __ shrptr(end, CardTable::card_shift);
+ __ subptr(end, addr); // end --> count
+__ BIND(L_loop);
+ Address cardtable(addr, count, Address::times_1, disp);
+ __ movb(cardtable, 0);
+ __ decrement(count);
+ __ jcc(Assembler::greaterEqual, L_loop);
+#endif
+
+__ BIND(L_done);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr,
+ Register count, Register tmp);
+};
+
+#endif // CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/modRefBarrierSetAssembler.hpp"
+
+#define __ masm->
+
+void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
+ bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
+
+ if (type == T_OBJECT || type == T_ARRAY) {
+#ifdef _LP64
+ if (!checkcast && !obj_int) {
+ // Save count for barrier
+ __ movptr(r11, count);
+ } else if (disjoint && obj_int) {
+ // Save dst in r11 in the disjoint case
+ __ movq(r11, dst);
+ }
+#else
+ if (disjoint) {
+ __ mov(rdx, dst); // save 'to'
+ }
+#endif
+ gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
+ }
+}
+
+void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count) {
+ bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
+ bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
+ bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
+ Register tmp = rax;
+
+ if (type == T_OBJECT || type == T_ARRAY) {
+#ifdef _LP64
+ if (!checkcast && !obj_int) {
+ // Save count for barrier
+ count = r11;
+ } else if (disjoint && obj_int) {
+ // Use the saved dst in the disjoint case
+ dst = r11;
+ } else if (checkcast) {
+ tmp = rscratch1;
+ }
+#else
+ if (disjoint) {
+ __ mov(dst, rdx); // restore 'to'
+ }
+#endif
+ gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp);
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+
+class ModRefBarrierSetAssembler: public BarrierSetAssembler {
+protected:
+ virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {}
+ virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp) {}
+
+public:
+ virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count);
+ virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
+ Register src, Register dst, Register count);
+};
+
+#endif // CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/interp_masm_x86.cpp
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,6 +35,7 @@
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/interpreterRT_x86.hpp
--- a/src/hotspot/cpu/x86/interpreterRT_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/interpreterRT_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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,7 +25,8 @@
#ifndef CPU_X86_VM_INTERPRETERRT_X86_HPP
#define CPU_X86_VM_INTERPRETERRT_X86_HPP
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
// native method calls
@@ -55,19 +56,7 @@
public:
// Creation
- SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
- _masm = new MacroAssembler(buffer);
-#ifdef AMD64
-#ifdef _WIN64
- _num_args = (method->is_static() ? 1 : 0);
- _stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address
-#else
- _num_int_args = (method->is_static() ? 1 : 0);
- _num_fp_args = 0;
- _stack_offset = wordSize; // don't overwrite return address
-#endif // _WIN64
-#endif // AMD64
- }
+ SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
// Code generation
void generate(uint64_t fingerprint);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/interpreterRT_x86_32.cpp
--- a/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -31,7 +32,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
@@ -39,6 +40,21 @@
// Implementation of SignatureHandlerGenerator
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) :
+ NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+#ifdef AMD64
+#ifdef _WIN64
+ _num_args = (method->is_static() ? 1 : 0);
+ _stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address
+#else
+ _num_int_args = (method->is_static() ? 1 : 0);
+ _num_fp_args = 0;
+ _stack_offset = wordSize; // don't overwrite return address
+#endif // _WIN64
+#endif // AMD64
+}
+
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
move(offset(), jni_offset() + 1);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/interpreterRT_x86_64.cpp
--- a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
@@ -31,13 +32,28 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
// Implementation of SignatureHandlerGenerator
+InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) :
+ NativeSignatureIterator(method) {
+ _masm = new MacroAssembler(buffer);
+#ifdef AMD64
+#ifdef _WIN64
+ _num_args = (method->is_static() ? 1 : 0);
+ _stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address
+#else
+ _num_int_args = (method->is_static() ? 1 : 0);
+ _num_fp_args = 0;
+ _stack_offset = wordSize; // don't overwrite return address
+#endif // _WIN64
+#endif // AMD64
+}
+
Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; }
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp
--- a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "compiler/disassembler.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "jvmci/jvmciEnv.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/macroAssembler_x86.cpp
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "asm/assembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
@@ -36,7 +36,7 @@
#include "oops/klass.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
@@ -5409,8 +5409,8 @@
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
DirtyCardQueue::byte_offset_of_buf()));
- CardTableModRefBS* ctbs =
- barrier_set_cast(Universe::heap()->barrier_set());
+ CardTableBarrierSet* ctbs =
+ barrier_set_cast(Universe::heap()->barrier_set());
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
@@ -5497,10 +5497,10 @@
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableModRef,
+ assert(bs->kind() == BarrierSet::CardTableBarrierSet,
"Wrong barrier set kind");
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/methodHandles_x86.cpp
--- a/src/hotspot/cpu/x86/methodHandles_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,6 +31,8 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "utilities/preserveException.hpp"
#define __ _masm->
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/runtime_x86_32.cpp
--- a/src/hotspot/cpu/x86/runtime_x86_32.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/runtime_x86_32.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,6 @@
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/runtime_x86_64.cpp
--- a/src/hotspot/cpu/x86/runtime_x86_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/runtime_x86_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,6 @@
#include "code/vmreg.hpp"
#include "interpreter/interpreter.hpp"
#include "opto/runtime.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframeArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,10 +28,12 @@
#include "code/debugInfoRec.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,10 +32,12 @@
#include "code/icBuffer.hpp"
#include "code/nativeInst.hpp"
#include "code/vtableStubs.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,8 +25,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/instanceOop.hpp"
@@ -668,107 +668,6 @@
return start;
}
- //
- // Generate pre-barrier for array stores
- //
- // Input:
- // start - starting address
- // count - element count
- void gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
- assert_different_registers(start, count);
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
-#if INCLUDE_ALL_GCS
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target in uninitialized
- if (!uninitialized_target) {
- Register thread = rax;
- Label filtered;
- __ push(thread);
- __ get_thread(thread);
- Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_active()));
- // Is marking active?
- if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
- __ cmpl(in_progress, 0);
- } else {
- assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
- __ cmpb(in_progress, 0);
- }
- __ pop(thread);
- __ jcc(Assembler::equal, filtered);
-
- __ pusha(); // push registers
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
- start, count);
- __ popa();
-
- __ bind(filtered);
- }
- break;
-#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
- break;
- default :
- ShouldNotReachHere();
-
- }
- }
-
-
- //
- // Generate a post-barrier for an array store
- //
- // start - starting address
- // count - element count
- //
- // The two input registers are overwritten.
- //
- void gen_write_ref_array_post_barrier(Register start, Register count) {
- BarrierSet* bs = Universe::heap()->barrier_set();
- assert_different_registers(start, count);
- switch (bs->kind()) {
-#if INCLUDE_ALL_GCS
- case BarrierSet::G1BarrierSet:
- {
- __ pusha(); // push registers
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post),
- start, count);
- __ popa();
- }
- break;
-#endif // INCLUDE_ALL_GCS
-
- case BarrierSet::CardTableModRef:
- {
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
- CardTable* ct = ctbs->card_table();
- assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
-
- Label L_loop;
- const Register end = count; // elements count; end == start+count-1
- assert_different_registers(start, end);
-
- __ lea(end, Address(start, count, Address::times_ptr, -wordSize));
- __ shrptr(start, CardTable::card_shift);
- __ shrptr(end, CardTable::card_shift);
- __ subptr(end, start); // end --> count
- __ BIND(L_loop);
- intptr_t disp = (intptr_t) ct->byte_map_base();
- Address cardtable(start, count, Address::times_1, disp);
- __ movb(cardtable, 0);
- __ decrement(count);
- __ jcc(Assembler::greaterEqual, L_loop);
- }
- break;
- case BarrierSet::ModRef:
- break;
- default :
- ShouldNotReachHere();
-
- }
- }
-
// Copy 64 bytes chunks
//
@@ -936,9 +835,18 @@
if (t == T_OBJECT) {
__ testl(count, count);
__ jcc(Assembler::zero, L_0_count);
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
- __ mov(saved_to, to); // save 'to'
+ }
+
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
__ subptr(to, from); // to --> to_from
__ cmpl(count, 2<arraycopy_epilogue(_masm, decorators, t, from, to, count);
+
if (t == T_OBJECT) {
- __ movl(count, Address(rsp, 12+12)); // reread 'count'
- __ mov(to, saved_to); // restore 'to'
- gen_write_ref_array_post_barrier(to, count);
__ BIND(L_0_count);
}
inc_copy_counter_np(t);
@@ -1116,8 +1024,18 @@
if (t == T_OBJECT) {
__ testl(count, count);
__ jcc(Assembler::zero, L_0_count);
- gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
+ }
+
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
// copy from high to low
__ cmpl(count, 2<arraycopy_epilogue(_masm, decorators, t, from, to, count);
+
if (t == T_OBJECT) {
- __ movl2ptr(count, Address(rsp, 12+12)); // reread count
- gen_write_ref_array_post_barrier(to, count);
__ BIND(L_0_count);
}
inc_copy_counter_np(t);
@@ -1463,8 +1383,16 @@
Address to_element_addr(end_to, count, Address::times_ptr, 0);
Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+
+ BasicType type = T_OBJECT;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
+
// Copy from low to high addresses, indexed from the end of each array.
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
__ lea(end_from, end_from_addr);
__ lea(end_to, end_to_addr);
assert(length == count, ""); // else fix next line:
@@ -1521,7 +1449,7 @@
__ BIND(L_post_barrier);
__ movptr(to, to_arg); // reload
- gen_write_ref_array_post_barrier(to, count);
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, count);
// Common exit point (success or failure).
__ BIND(L_done);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,8 +26,8 @@
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "ci/ciUtilities.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/instanceOop.hpp"
@@ -1190,119 +1190,6 @@
#endif
}
- // Generate code for an array write pre barrier
- //
- // addr - starting address
- // count - element count
- // tmp - scratch register
- //
- // Destroy no registers!
- //
- void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- // With G1, don't generate the call if we statically know that the target in uninitialized
- if (!dest_uninitialized) {
- Label filtered;
- Address in_progress(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_active()));
- // Is marking active?
- if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
- __ cmpl(in_progress, 0);
- } else {
- assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
- __ cmpb(in_progress, 0);
- }
- __ jcc(Assembler::equal, filtered);
-
- __ pusha(); // push registers
- if (count == c_rarg0) {
- if (addr == c_rarg1) {
- // exactly backwards!!
- __ xchgptr(c_rarg1, c_rarg0);
- } else {
- __ movptr(c_rarg1, count);
- __ movptr(c_rarg0, addr);
- }
- } else {
- __ movptr(c_rarg0, addr);
- __ movptr(c_rarg1, count);
- }
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
- __ popa();
-
- __ bind(filtered);
- }
- break;
- case BarrierSet::CardTableModRef:
- break;
- default:
- ShouldNotReachHere();
-
- }
- }
-
- //
- // Generate code for an array write post barrier
- //
- // Input:
- // start - register containing starting address of destination array
- // count - elements count
- // scratch - scratch register
- //
- // The input registers are overwritten.
- //
- void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
- assert_different_registers(start, count, scratch);
- BarrierSet* bs = Universe::heap()->barrier_set();
- switch (bs->kind()) {
- case BarrierSet::G1BarrierSet:
- {
- __ pusha(); // push registers (overkill)
- if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
- assert_different_registers(c_rarg1, start);
- __ mov(c_rarg1, count);
- __ mov(c_rarg0, start);
- } else {
- assert_different_registers(c_rarg0, count);
- __ mov(c_rarg0, start);
- __ mov(c_rarg1, count);
- }
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
- __ popa();
- }
- break;
- case BarrierSet::CardTableModRef:
- {
- Label L_loop, L_done;
- const Register end = count;
-
- __ testl(count, count);
- __ jcc(Assembler::zero, L_done); // zero count - nothing to do
-
- __ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
- __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
- __ shrptr(start, CardTable::card_shift);
- __ shrptr(end, CardTable::card_shift);
- __ subptr(end, start); // end --> cards count
-
- int64_t disp = ci_card_table_address_as();
- __ mov64(scratch, disp);
- __ addptr(start, scratch);
- __ BIND(L_loop);
- __ movb(Address(start, count, Address::times_1), 0);
- __ decrement(count);
- __ jcc(Assembler::greaterEqual, L_loop);
- __ BIND(L_done);
- }
- break;
- default:
- ShouldNotReachHere();
-
- }
- }
-
// Copy big chunks forward
//
@@ -1918,7 +1805,6 @@
const Register qword_count = count;
const Register end_from = from; // source array end address
const Register end_to = to; // destination array end address
- const Register saved_to = r11; // saved destination array address
// End pointers are inclusive, and if count is not zero they point
// to the last unit copied: end_to[0] := end_from[0]
@@ -1933,10 +1819,18 @@
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
- if (is_oop) {
- __ movq(saved_to, to);
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
+
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BasicType type = is_oop ? T_OBJECT : T_INT;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
// 'from', 'to' and 'count' are now valid
__ movptr(dword_count, count);
@@ -1963,9 +1857,7 @@
__ movl(Address(end_to, 8), rax);
__ BIND(L_exit);
- if (is_oop) {
- gen_write_ref_array_post_barrier(saved_to, dword_count, rax);
- }
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count);
restore_arg_regs();
inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
__ vzeroupper();
@@ -2022,10 +1914,18 @@
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
- if (is_oop) {
- // no registers are destroyed by this call
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
+ DecoratorSet decorators = 0;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BasicType type = is_oop ? T_OBJECT : T_INT;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ // no registers are destroyed by this call
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
assert_clean_int(count, rax); // Make sure 'count' is clean int.
// 'from', 'to' and 'count' are now valid
@@ -2062,9 +1962,7 @@
copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
__ BIND(L_exit);
- if (is_oop) {
- gen_write_ref_array_post_barrier(to, dword_count, rax);
- }
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count);
restore_arg_regs();
inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
__ xorptr(rax, rax); // return 0
@@ -2102,7 +2000,6 @@
const Register qword_count = rdx; // elements count
const Register end_from = from; // source array end address
const Register end_to = rcx; // destination array end address
- const Register saved_to = to;
const Register saved_count = r11;
// End pointers are inclusive, and if count is not zero they point
// to the last unit copied: end_to[0] := end_from[0]
@@ -2120,12 +2017,18 @@
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
// 'from', 'to' and 'qword_count' are now valid
- if (is_oop) {
- // Save to and count for store barrier
- __ movptr(saved_count, qword_count);
- // no registers are destroyed by this call
- gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
+
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BasicType type = is_oop ? T_OBJECT : T_LONG;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
// Copy from low to high addresses. Use 'to' as scratch.
__ lea(end_from, Address(from, qword_count, Address::times_8, -8));
@@ -2154,10 +2057,8 @@
// Copy in multi-bytes chunks
copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
- if (is_oop) {
__ BIND(L_exit);
- gen_write_ref_array_post_barrier(saved_to, saved_count, rax);
- }
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, qword_count);
restore_arg_regs();
if (is_oop) {
inc_counter_np(SharedRuntime::_oop_array_copy_ctr); // Update counter after rscratch1 is free
@@ -2209,12 +2110,18 @@
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
// 'from', 'to' and 'qword_count' are now valid
- if (is_oop) {
- // Save to and count for store barrier
- __ movptr(saved_count, qword_count);
- // No registers are destroyed by this call
- gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
+
+ DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
}
+ if (aligned) {
+ decorators |= ARRAYCOPY_ALIGNED;
+ }
+
+ BasicType type = is_oop ? T_OBJECT : T_LONG;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
__ jmp(L_copy_bytes);
@@ -2239,10 +2146,8 @@
// Copy in multi-bytes chunks
copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
- if (is_oop) {
__ BIND(L_exit);
- gen_write_ref_array_post_barrier(to, saved_count, rax);
- }
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, qword_count);
restore_arg_regs();
if (is_oop) {
inc_counter_np(SharedRuntime::_oop_array_copy_ctr); // Update counter after rscratch1 is free
@@ -2389,7 +2294,14 @@
Address from_element_addr(end_from, count, TIMES_OOP, 0);
Address to_element_addr(end_to, count, TIMES_OOP, 0);
- gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
+ DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+ if (dest_uninitialized) {
+ decorators |= AS_DEST_NOT_INITIALIZED;
+ }
+
+ BasicType type = T_OBJECT;
+ BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+ bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
// Copy from low to high addresses, indexed from the end of each array.
__ lea(end_from, end_from_addr);
@@ -2442,7 +2354,7 @@
__ xorptr(rax, rax); // return 0 on success
__ BIND(L_post_barrier);
- gen_write_ref_array_post_barrier(to, r14_length, rscratch1);
+ bs->arraycopy_epilogue(_masm, decorators, type, from, to, r14_length);
// Common exit point (success or failure).
__ BIND(L_done);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/templateTable_x86.cpp
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,6 +33,8 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
@@ -198,7 +200,7 @@
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
{
if (val == noreg) {
__ store_heap_oop_null(obj);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/x86_32.ad
--- a/src/hotspot/cpu/x86/x86_32.ad Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/x86_32.ad Fri Mar 30 09:24:04 2018 -0700
@@ -391,7 +391,7 @@
int format) {
#ifdef ASSERT
if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
- assert(oopDesc::is_oop(cast_to_oop(d32)) && (ScavengeRootsInCode || !cast_to_oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
+ assert(oopDesc::is_oop(cast_to_oop(d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d32))), "cannot embed scavengable oops in code");
}
#endif
cbuf.relocate(cbuf.insts_mark(), rspec, format);
@@ -786,7 +786,7 @@
}
if (cbuf) {
MacroAssembler _masm(cbuf);
- // EVEX spills remain EVEX: Compressed displacemement is better than AVX on spill mem operations,
+ // EVEX spills remain EVEX: Compressed displacemement is better than AVX on spill mem operations,
// it maps more cases to single byte displacement
_masm.set_managed();
if (reg_lo+1 == reg_hi) { // double move?
@@ -976,7 +976,7 @@
dst_offset_size = (tmp_dst_offset == 0) ? 0 : ((tmp_dst_offset < 0x80) ? 1 : 4);
calc_size += 3+src_offset_size + 3+dst_offset_size;
break;
- }
+ }
case Op_VecX:
case Op_VecY:
case Op_VecZ:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/x86/x86_64.ad
--- a/src/hotspot/cpu/x86/x86_64.ad Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/x86/x86_64.ad Fri Mar 30 09:24:04 2018 -0700
@@ -669,7 +669,7 @@
if (rspec.reloc()->type() == relocInfo::oop_type &&
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
- assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
+ assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code");
}
#endif
cbuf.relocate(cbuf.insts_mark(), rspec, format);
@@ -696,7 +696,7 @@
if (rspec.reloc()->type() == relocInfo::oop_type &&
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
- assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
+ assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))),
"cannot embed scavengable oops in code");
}
#endif
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/assembler_zero.cpp
--- a/src/hotspot/cpu/zero/assembler_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/assembler_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,13 +25,13 @@
#include "precompiled.hpp"
#include "assembler_zero.inline.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/cppInterpreter_zero.cpp
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -41,7 +41,7 @@
#include "runtime/atomic.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/frame_zero.hpp
--- a/src/hotspot/cpu/zero/frame_zero.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/frame_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -75,4 +75,6 @@
char* buf,
int buflen) const;
+ static jint interpreter_frame_expression_stack_direction() { return -1; }
+
#endif // CPU_ZERO_VM_FRAME_ZERO_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/frame_zero.inline.hpp
--- a/src/hotspot/cpu/zero/frame_zero.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/frame_zero.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -130,10 +130,6 @@
return monitor_end - 1;
}
-inline jint frame::interpreter_frame_expression_stack_direction() {
- return -1;
-}
-
// Return a unique id for this frame. The id must have a value where
// we can distinguish identity and younger/older relationship. NULL
// represents an invalid (incomparable) frame.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/gc/g1/g1BarrierSetAssembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/zero/gc/g1/g1BarrierSetAssembler_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ZERO_GC_G1_G1BARRIERSETASSEMBLER_ZERO_HPP
+#define CPU_ZERO_GC_G1_G1BARRIERSETASSEMBLER_ZERO_HPP
+
+class G1BarrierSetAssembler;
+
+#endif // CPU_ZERO_GC_G1_G1BARRIERSETASSEMBLER_ZERO_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/gc/shared/barrierSetAssembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/zero/gc/shared/barrierSetAssembler_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ZERO_GC_G1_BARRIERSETASSEMBLER_ZERO_HPP
+#define CPU_ZERO_GC_G1_BARRIERSETASSEMBLER_ZERO_HPP
+
+class BarrierSetAssembler;
+
+#endif // CPU_ZERO_GC_G1_BARRIERSETASSEMBLER_ZERO_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/gc/shared/cardTableBarrierSetAssembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/zero/gc/shared/cardTableBarrierSetAssembler_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ZERO_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ZERO_HPP
+#define CPU_ZERO_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ZERO_HPP
+
+class CardTableBarrierSetAssembler;
+
+#endif // CPU_ZERO_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ZERO_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/gc/shared/modRefBarrierSetAssembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/zero/gc/shared/modRefBarrierSetAssembler_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP
+#define CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP
+
+class ModRefBarrierSetAssembler;
+
+#endif // CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/interpreterRT_zero.cpp
--- a/src/hotspot/cpu/zero/interpreterRT_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/interpreterRT_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/signature.hpp"
#include "stack_zero.inline.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/interpreterRT_zero.hpp
--- a/src/hotspot/cpu/zero/interpreterRT_zero.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/interpreterRT_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,9 @@
#ifndef CPU_ZERO_VM_INTERPRETERRT_ZERO_HPP
#define CPU_ZERO_VM_INTERPRETERRT_ZERO_HPP
-#include "memory/allocation.hpp"
+// This is included in the middle of class Interpreter.
+// Do not include files here.
+
class SignatureHandler {
public:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/methodHandles_zero.cpp
--- a/src/hotspot/cpu/zero/methodHandles_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -30,6 +30,7 @@
#include "memory/resourceArea.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/frame.inline.hpp"
#include "prims/methodHandles.hpp"
void MethodHandles::invoke_target(Method* method, TRAPS) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/sharedRuntime_zero.cpp
--- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,6 +31,7 @@
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_zero.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/cpu/zero/stack_zero.cpp
--- a/src/hotspot/cpu/zero/stack_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/cpu/zero/stack_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -24,10 +24,12 @@
*/
#include "precompiled.hpp"
+#include "interpreter/bytecodeInterpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "runtime/thread.hpp"
#include "stack_zero.hpp"
#include "stack_zero.inline.hpp"
+#include "runtime/frame.inline.hpp"
#include "utilities/align.hpp"
// Inlined causes circular inclusion with thread.hpp
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/aix/attachListener_aix.cpp
--- a/src/hotspot/os/aix/attachListener_aix.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/aix/attachListener_aix.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.inline.hpp"
#include "services/attachListener.hpp"
#include "services/dtraceAttacher.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/aix/jvm_aix.cpp
--- a/src/hotspot/os/aix/jvm_aix.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/aix/jvm_aix.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/aix/os_aix.cpp
--- a/src/hotspot/os/aix/os_aix.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/aix/os_aix.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -54,7 +54,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/bsd/attachListener_bsd.cpp
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.inline.hpp"
#include "services/attachListener.hpp"
#include "services/dtraceAttacher.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/bsd/jvm_bsd.cpp
--- a/src/hotspot/os/bsd/jvm_bsd.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/bsd/jvm_bsd.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/bsd/os_bsd.cpp
--- a/src/hotspot/os/bsd/os_bsd.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/bsd/os_bsd.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -44,7 +44,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/linux/attachListener_linux.cpp
--- a/src/hotspot/os/linux/attachListener_linux.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/linux/attachListener_linux.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,7 +23,8 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.inline.hpp"
#include "services/attachListener.hpp"
#include "services/dtraceAttacher.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/linux/jvm_linux.cpp
--- a/src/hotspot/os/linux/jvm_linux.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/linux/jvm_linux.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/linux/os_linux.cpp
--- a/src/hotspot/os/linux/os_linux.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/linux/os_linux.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -45,7 +45,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/posix/os_posix.cpp
--- a/src/hotspot/os/posix/os_posix.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/posix/os_posix.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "memory/allocation.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.hpp"
#include "services/memTracker.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/solaris/attachListener_solaris.cpp
--- a/src/hotspot/os/solaris/attachListener_solaris.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/solaris/attachListener_solaris.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.inline.hpp"
#include "services/attachListener.hpp"
#include "services/dtraceAttacher.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/solaris/jvm_solaris.cpp
--- a/src/hotspot/os/solaris/jvm_solaris.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/solaris/jvm_solaris.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/solaris/os_solaris.cpp
--- a/src/hotspot/os/solaris/os_solaris.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/solaris/os_solaris.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -44,7 +44,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/windows/attachListener_windows.cpp
--- a/src/hotspot/os/windows/attachListener_windows.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/windows/attachListener_windows.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.hpp"
#include "services/attachListener.hpp"
#include "services/dtraceAttacher.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/windows/jvm_windows.cpp
--- a/src/hotspot/os/windows/jvm_windows.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/windows/jvm_windows.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jvm.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os/windows/os_windows.cpp
--- a/src/hotspot/os/windows/os_windows.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os/windows/os_windows.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,7 +47,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -42,7 +42,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp
--- a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,19 @@
#include "runtime/frame.hpp"
#include "runtime/thread.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+
+ intptr_t* sp = last_Java_sp();
+ address pc = _anchor.last_Java_pc();
+
+ // Last_Java_pc ist not set, if we come here from compiled code.
+ if (pc == NULL)
+ pc = (address) *(sp + 2);
+
+ return frame(sp, pc);
+}
+
// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Aix/PPC.
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) {
Unimplemented();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.hpp
--- a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -32,18 +32,7 @@
}
// The `last' frame is the youngest Java frame on the thread's stack.
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-
- intptr_t* sp = last_Java_sp();
- address pc = _anchor.last_Java_pc();
-
- // Last_Java_pc ist not set, if we come here from compiled code.
- if (pc == NULL)
- pc = (address) *(sp + 2);
-
- return frame(sp, pc);
- }
+ frame pd_last_frame();
public:
void set_base_of_stack_pointer(intptr_t* base_sp) {}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,7 +39,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,12 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.hpp
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,11 +30,7 @@
_anchor.clear();
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
public:
// Mutators are highly dangerous....
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
--- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -45,7 +45,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.cpp
--- a/src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,11 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ return frame(last_Java_fp(), last_Java_sp());
+}
+
void JavaThread::cache_global_variables() {
// nothing to do
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.hpp
--- a/src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/bsd_zero/thread_bsd_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -86,10 +86,7 @@
}
private:
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- return frame(last_Java_fp(), last_Java_sp());
- }
+ frame pd_last_frame();
public:
static ByteSize last_Java_fp_offset() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -41,7 +41,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp
--- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -28,6 +28,11 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp
--- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -41,10 +41,7 @@
_anchor.clear();
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
public:
// Mutators are highly dangerous....
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_arm/copy_linux_arm.inline.hpp
--- a/src/hotspot/os_cpu/linux_arm/copy_linux_arm.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_arm/copy_linux_arm.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,20 +26,11 @@
#define OS_CPU_LINUX_ARM_VM_COPY_LINUX_ARM_INLINE_HPP
static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
-#ifdef AARCH64
_Copy_conjoint_words(from, to, count * HeapWordSize);
-#else
- // NOTE: _Copy_* functions on 32-bit ARM expect "to" and "from" arguments in reversed order
- _Copy_conjoint_words(to, from, count * HeapWordSize);
-#endif
}
static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
-#ifdef AARCH64
_Copy_disjoint_words(from, to, count * HeapWordSize);
-#else
- _Copy_disjoint_words(to, from, count * HeapWordSize);
-#endif // AARCH64
}
static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
@@ -63,11 +54,7 @@
}
static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
-#ifdef AARCH64
_Copy_conjoint_jshorts_atomic(from, to, count * BytesPerShort);
-#else
- _Copy_conjoint_jshorts_atomic(to, from, count * BytesPerShort);
-#endif
}
static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
@@ -85,7 +72,7 @@
assert(HeapWordSize == BytesPerLong, "64-bit architecture");
pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#else
- _Copy_conjoint_jlongs_atomic(to, from, count * BytesPerLong);
+ _Copy_conjoint_jlongs_atomic(from, to, count * BytesPerLong);
#endif
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_arm/linux_arm_32.s
--- a/src/hotspot/os_cpu/linux_arm/linux_arm_32.s Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_arm/linux_arm_32.s Fri Mar 30 09:24:04 2018 -0700
@@ -49,6 +49,9 @@
.globl _Copy_arrayof_conjoint_jlongs
.type _Copy_arrayof_conjoint_jlongs, %function
+from .req r0
+to .req r1
+
.text
.globl SpinPause
.type SpinPause, %function
@@ -77,7 +80,7 @@
cmp r2, #0
beq disjoint_words_finish
- pld [r1, #0]
+ pld [from, #0]
cmp r2, #12
ble disjoint_words_small
@@ -85,28 +88,28 @@
dw_f2b_loop_32:
subs r2, #32
blt dw_f2b_loop_32_finish
- ldmia r1!, {r3 - r9, ip}
+ ldmia from!, {r3 - r9, ip}
nop
- pld [r1]
- stmia r0!, {r3 - r9, ip}
+ pld [from]
+ stmia to!, {r3 - r9, ip}
bgt dw_f2b_loop_32
dw_f2b_loop_32_finish:
addlts r2, #32
beq disjoint_words_finish
cmp r2, #16
blt disjoint_words_small
- ldmia r1!, {r3 - r6}
+ ldmia from!, {r3 - r6}
subge r2, r2, #16
- stmia r0!, {r3 - r6}
+ stmia to!, {r3 - r6}
beq disjoint_words_finish
disjoint_words_small:
cmp r2, #8
- ldr r7, [r1], #4
- ldrge r8, [r1], #4
- ldrgt r9, [r1], #4
- str r7, [r0], #4
- strge r8, [r0], #4
- strgt r9, [r0], #4
+ ldr r7, [from], #4
+ ldrge r8, [from], #4
+ ldrgt r9, [from], #4
+ str r7, [to], #4
+ strge r8, [to], #4
+ strgt r9, [to], #4
disjoint_words_finish:
ldmia sp!, {r3 - r9, ip}
@@ -122,72 +125,72 @@
cmp r2, #0
beq conjoint_words_finish
- pld [r1, #0]
+ pld [from, #0]
cmp r2, #12
ble conjoint_words_small
- subs r3, r0, r1
+ subs r3, to, from
cmphi r2, r3
bhi cw_b2f_copy
.align 3
cw_f2b_loop_32:
subs r2, #32
blt cw_f2b_loop_32_finish
- ldmia r1!, {r3 - r9, ip}
+ ldmia from!, {r3 - r9, ip}
nop
- pld [r1]
- stmia r0!, {r3 - r9, ip}
+ pld [from]
+ stmia to!, {r3 - r9, ip}
bgt cw_f2b_loop_32
cw_f2b_loop_32_finish:
addlts r2, #32
beq conjoint_words_finish
cmp r2, #16
blt conjoint_words_small
- ldmia r1!, {r3 - r6}
+ ldmia from!, {r3 - r6}
subge r2, r2, #16
- stmia r0!, {r3 - r6}
+ stmia to!, {r3 - r6}
beq conjoint_words_finish
conjoint_words_small:
cmp r2, #8
- ldr r7, [r1], #4
- ldrge r8, [r1], #4
- ldrgt r9, [r1], #4
- str r7, [r0], #4
- strge r8, [r0], #4
- strgt r9, [r0], #4
+ ldr r7, [from], #4
+ ldrge r8, [from], #4
+ ldrgt r9, [from], #4
+ str r7, [to], #4
+ strge r8, [to], #4
+ strgt r9, [to], #4
b conjoint_words_finish
# Src and dest overlap, copy in a descending order
cw_b2f_copy:
- add r1, r2
- pld [r1, #-32]
- add r0, r2
+ add from, r2
+ pld [from, #-32]
+ add to, r2
.align 3
cw_b2f_loop_32:
subs r2, #32
blt cw_b2f_loop_32_finish
- ldmdb r1!, {r3-r9,ip}
+ ldmdb from!, {r3-r9,ip}
nop
- pld [r1, #-32]
- stmdb r0!, {r3-r9,ip}
+ pld [from, #-32]
+ stmdb to!, {r3-r9,ip}
bgt cw_b2f_loop_32
cw_b2f_loop_32_finish:
addlts r2, #32
beq conjoint_words_finish
cmp r2, #16
blt cw_b2f_copy_small
- ldmdb r1!, {r3 - r6}
+ ldmdb from!, {r3 - r6}
subge r2, r2, #16
- stmdb r0!, {r3 - r6}
+ stmdb to!, {r3 - r6}
beq conjoint_words_finish
cw_b2f_copy_small:
cmp r2, #8
- ldr r7, [r1, #-4]!
- ldrge r8, [r1, #-4]!
- ldrgt r9, [r1, #-4]!
- str r7, [r0, #-4]!
- strge r8, [r0, #-4]!
- strgt r9, [r0, #-4]!
+ ldr r7, [from, #-4]!
+ ldrge r8, [from, #-4]!
+ ldrgt r9, [from, #-4]!
+ str r7, [to, #-4]!
+ strge r8, [to, #-4]!
+ strgt r9, [to, #-4]!
conjoint_words_finish:
ldmia sp!, {r3 - r9, ip}
@@ -202,15 +205,15 @@
cmp r2, #0
beq conjoint_shorts_finish
- subs r3, r0, r1
+ subs r3, to, from
cmphi r2, r3
bhi cs_b2f_copy
- pld [r1]
+ pld [from]
- ands r3, r0, #3
+ ands r3, to, #3
bne cs_f2b_dest_u
- ands r3, r1, #3
+ ands r3, from, #3
bne cs_f2b_src_u
# Aligned source address
@@ -218,10 +221,10 @@
cs_f2b_loop_32:
subs r2, #32
blt cs_f2b_loop_32_finish
- ldmia r1!, {r3 - r9, ip}
+ ldmia from!, {r3 - r9, ip}
nop
- pld [r1]
- stmia r0!, {r3 - r9, ip}
+ pld [from]
+ stmia to!, {r3 - r9, ip}
bgt cs_f2b_loop_32
cs_f2b_loop_32_finish:
addlts r2, #32
@@ -230,32 +233,32 @@
.align 3
cs_f2b_8_loop:
beq cs_f2b_4
- ldmia r1!, {r4-r5}
+ ldmia from!, {r4-r5}
subs r6, #1
- stmia r0!, {r4-r5}
+ stmia to!, {r4-r5}
bgt cs_f2b_8_loop
cs_f2b_4:
ands r2, #7
beq conjoint_shorts_finish
cmp r2, #4
- ldrh r3, [r1], #2
- ldrgeh r4, [r1], #2
- ldrgth r5, [r1], #2
- strh r3, [r0], #2
- strgeh r4, [r0], #2
- strgth r5, [r0], #2
+ ldrh r3, [from], #2
+ ldrgeh r4, [from], #2
+ ldrgth r5, [from], #2
+ strh r3, [to], #2
+ strgeh r4, [to], #2
+ strgth r5, [to], #2
b conjoint_shorts_finish
# Destination not aligned
cs_f2b_dest_u:
- ldrh r3, [r1], #2
+ ldrh r3, [from], #2
subs r2, #2
- strh r3, [r0], #2
+ strh r3, [to], #2
beq conjoint_shorts_finish
# Check to see if source is not aligned ether
- ands r3, r1, #3
+ ands r3, from, #3
beq cs_f2b_loop_32
cs_f2b_src_u:
@@ -263,153 +266,153 @@
blt cs_f2b_8_u
# Load 2 first bytes to r7 and make src ptr word aligned
- bic r1, #3
- ldr r7, [r1], #4
+ bic from, #3
+ ldr r7, [from], #4
# Destination aligned, source not
mov r8, r2, lsr #4
.align 3
cs_f2b_16_u_loop:
mov r3, r7, lsr #16
- ldmia r1!, {r4 - r7}
+ ldmia from!, {r4 - r7}
orr r3, r3, r4, lsl #16
mov r4, r4, lsr #16
- pld [r1]
+ pld [from]
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
- stmia r0!, {r3 - r6}
+ stmia to!, {r3 - r6}
subs r8, #1
bgt cs_f2b_16_u_loop
ands r2, #0xf
beq conjoint_shorts_finish
- sub r1, #2
+ sub from, #2
cs_f2b_8_u:
cmp r2, #8
blt cs_f2b_4_u
- ldrh r4, [r1], #2
- ldr r5, [r1], #4
- ldrh r6, [r1], #2
+ ldrh r4, [from], #2
+ ldr r5, [from], #4
+ ldrh r6, [from], #2
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
subs r2, #8
- stmia r0!, {r4 - r5}
+ stmia to!, {r4 - r5}
cs_f2b_4_u:
beq conjoint_shorts_finish
cmp r2, #4
- ldrh r3, [r1], #2
- ldrgeh r4, [r1], #2
- ldrgth r5, [r1], #2
- strh r3, [r0], #2
- strgeh r4, [r0], #2
- strgth r5, [r0], #2
+ ldrh r3, [from], #2
+ ldrgeh r4, [from], #2
+ ldrgth r5, [from], #2
+ strh r3, [to], #2
+ strgeh r4, [to], #2
+ strgth r5, [to], #2
b conjoint_shorts_finish
# Src and dest overlap, copy in a descending order
cs_b2f_copy:
- add r1, r2
- pld [r1, #-32]
- add r0, r2
+ add from, r2
+ pld [from, #-32]
+ add to, r2
- ands r3, r0, #3
+ ands r3, to, #3
bne cs_b2f_dest_u
- ands r3, r1, #3
+ ands r3, from, #3
bne cs_b2f_src_u
.align 3
cs_b2f_loop_32:
subs r2, #32
blt cs_b2f_loop_32_finish
- ldmdb r1!, {r3-r9,ip}
+ ldmdb from!, {r3-r9,ip}
nop
- pld [r1, #-32]
- stmdb r0!, {r3-r9,ip}
+ pld [from, #-32]
+ stmdb to!, {r3-r9,ip}
bgt cs_b2f_loop_32
cs_b2f_loop_32_finish:
addlts r2, #32
beq conjoint_shorts_finish
cmp r2, #24
blt cs_b2f_16
- ldmdb r1!, {r3-r8}
+ ldmdb from!, {r3-r8}
sub r2, #24
- stmdb r0!, {r3-r8}
+ stmdb to!, {r3-r8}
beq conjoint_shorts_finish
cs_b2f_16:
cmp r2, #16
blt cs_b2f_8
- ldmdb r1!, {r3-r6}
+ ldmdb from!, {r3-r6}
sub r2, #16
- stmdb r0!, {r3-r6}
+ stmdb to!, {r3-r6}
beq conjoint_shorts_finish
cs_b2f_8:
cmp r2, #8
blt cs_b2f_all_copy
- ldmdb r1!, {r3-r4}
+ ldmdb from!, {r3-r4}
sub r2, #8
- stmdb r0!, {r3-r4}
+ stmdb to!, {r3-r4}
beq conjoint_shorts_finish
cs_b2f_all_copy:
cmp r2, #4
- ldrh r3, [r1, #-2]!
- ldrgeh r4, [r1, #-2]!
- ldrgth r5, [r1, #-2]!
- strh r3, [r0, #-2]!
- strgeh r4, [r0, #-2]!
- strgth r5, [r0, #-2]!
+ ldrh r3, [from, #-2]!
+ ldrgeh r4, [from, #-2]!
+ ldrgth r5, [from, #-2]!
+ strh r3, [to, #-2]!
+ strgeh r4, [to, #-2]!
+ strgth r5, [to, #-2]!
b conjoint_shorts_finish
# Destination not aligned
cs_b2f_dest_u:
- ldrh r3, [r1, #-2]!
- strh r3, [r0, #-2]!
+ ldrh r3, [from, #-2]!
+ strh r3, [to, #-2]!
sub r2, #2
# Check source alignment as well
- ands r3, r1, #3
+ ands r3, from, #3
beq cs_b2f_loop_32
# Source not aligned
cs_b2f_src_u:
- bic r1, #3
+ bic from, #3
.align 3
cs_b2f_16_loop_u:
subs r2, #16
blt cs_b2f_16_loop_u_finished
- ldr r7, [r1]
+ ldr r7, [from]
mov r3, r7
- ldmdb r1!, {r4 - r7}
+ ldmdb from!, {r4 - r7}
mov r4, r4, lsr #16
orr r4, r4, r5, lsl #16
- pld [r1, #-32]
+ pld [from, #-32]
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
mov r7, r7, lsr #16
orr r7, r7, r3, lsl #16
- stmdb r0!, {r4 - r7}
+ stmdb to!, {r4 - r7}
bgt cs_b2f_16_loop_u
beq conjoint_shorts_finish
cs_b2f_16_loop_u_finished:
addlts r2, #16
- ldr r3, [r1]
+ ldr r3, [from]
cmp r2, #10
blt cs_b2f_2_u_loop
- ldmdb r1!, {r4 - r5}
+ ldmdb from!, {r4 - r5}
mov r6, r4, lsr #16
orr r6, r6, r5, lsl #16
mov r7, r5, lsr #16
orr r7, r7, r3, lsl #16
- stmdb r0!, {r6-r7}
+ stmdb to!, {r6-r7}
sub r2, #8
.align 3
cs_b2f_2_u_loop:
subs r2, #2
- ldrh r3, [r1], #-2
- strh r3, [r0, #-2]!
+ ldrh r3, [from], #-2
+ strh r3, [to, #-2]!
bgt cs_b2f_2_u_loop
conjoint_shorts_finish:
@@ -440,21 +443,21 @@
cmp r2, #0
beq conjoint_longs_finish
- pld [r1, #0]
+ pld [from, #0]
cmp r2, #24
ble conjoint_longs_small
- subs r3, r0, r1
+ subs r3, to, from
cmphi r2, r3
bhi cl_b2f_copy
.align 3
cl_f2b_loop_32:
subs r2, #32
blt cl_f2b_loop_32_finish
- ldmia r1!, {r3 - r9, ip}
+ ldmia from!, {r3 - r9, ip}
nop
- pld [r1]
- stmia r0!, {r3 - r9, ip}
+ pld [from]
+ stmia to!, {r3 - r9, ip}
bgt cl_f2b_loop_32
cl_f2b_loop_32_finish:
addlts r2, #32
@@ -463,31 +466,31 @@
cmp r2, #16
blt cl_f2b_copy_8
bgt cl_f2b_copy_24
- ldmia r1!, {r3 - r6}
- stmia r0!, {r3 - r6}
+ ldmia from!, {r3 - r6}
+ stmia to!, {r3 - r6}
b conjoint_longs_finish
cl_f2b_copy_8:
- ldmia r1!, {r3 - r4}
- stmia r0!, {r3 - r4}
+ ldmia from!, {r3 - r4}
+ stmia to!, {r3 - r4}
b conjoint_longs_finish
cl_f2b_copy_24:
- ldmia r1!, {r3 - r8}
- stmia r0!, {r3 - r8}
+ ldmia from!, {r3 - r8}
+ stmia to!, {r3 - r8}
b conjoint_longs_finish
# Src and dest overlap, copy in a descending order
cl_b2f_copy:
- add r1, r2
- pld [r1, #-32]
- add r0, r2
+ add from, r2
+ pld [from, #-32]
+ add to, r2
.align 3
cl_b2f_loop_32:
subs r2, #32
blt cl_b2f_loop_32_finish
- ldmdb r1!, {r3 - r9, ip}
+ ldmdb from!, {r3 - r9, ip}
nop
- pld [r1]
- stmdb r0!, {r3 - r9, ip}
+ pld [from]
+ stmdb to!, {r3 - r9, ip}
bgt cl_b2f_loop_32
cl_b2f_loop_32_finish:
addlts r2, #32
@@ -495,16 +498,16 @@
cmp r2, #16
blt cl_b2f_copy_8
bgt cl_b2f_copy_24
- ldmdb r1!, {r3 - r6}
- stmdb r0!, {r3 - r6}
+ ldmdb from!, {r3 - r6}
+ stmdb to!, {r3 - r6}
b conjoint_longs_finish
cl_b2f_copy_8:
- ldmdb r1!, {r3 - r4}
- stmdb r0!, {r3 - r4}
+ ldmdb from!, {r3 - r4}
+ stmdb to!, {r3 - r4}
b conjoint_longs_finish
cl_b2f_copy_24:
- ldmdb r1!, {r3 - r8}
- stmdb r0!, {r3 - r8}
+ ldmdb from!, {r3 - r8}
+ stmdb to!, {r3 - r8}
conjoint_longs_finish:
ldmia sp!, {r3 - r9, ip}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,7 +39,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
--- a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,13 +23,28 @@
*/
#include "precompiled.hpp"
-#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.inline.hpp"
+#include "gc/shared/cardTableBarrierSet.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+#ifdef AARCH64
+ assert (_anchor.last_Java_pc() != NULL, "pc should be stored");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+#else
+ if (_anchor.last_Java_pc() != NULL) {
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+ } else {
+ // This will pick up pc from sp
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
+ }
+#endif // AARCH64
+}
+
void JavaThread::cache_global_variables() {
BarrierSet* bs = Universe::heap()->barrier_set();
@@ -42,8 +57,8 @@
_heap_top_addr = NULL;
}
- if (bs->is_a(BarrierSet::CardTableModRef)) {
- _card_table_base = (address) (barrier_set_cast(bs)->card_table()->byte_map_base());
+ if (bs->is_a(BarrierSet::CardTableBarrierSet)) {
+ _card_table_base = (address) (barrier_set_cast(bs)->card_table()->byte_map_base());
} else {
_card_table_base = NULL;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_arm/thread_linux_arm.hpp
--- a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -37,20 +37,7 @@
_in_top_frame_unsafe_section = NULL;
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-#ifdef AARCH64
- assert (_anchor.last_Java_pc() != NULL, "pc should be stored");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-#else
- if (_anchor.last_Java_pc() != NULL) {
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- } else {
- // This will pick up pc from sp
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
- }
-#endif // AARCH64
- }
+ frame pd_last_frame();
public:
intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -41,7 +41,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp
--- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -24,9 +24,23 @@
*/
#include "precompiled.hpp"
-#include "runtime/frame.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/thread.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+
+ intptr_t* sp = last_Java_sp();
+ address pc = _anchor.last_Java_pc();
+
+ // Last_Java_pc ist not set, if we come here from compiled code.
+ if (pc == NULL) {
+ pc = (address) *(sp + 2);
+ }
+
+ return frame(sp, pc);
+}
+
// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/PPC.
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) {
Unimplemented();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.hpp
--- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -33,19 +33,7 @@
}
// The `last' frame is the youngest Java frame on the thread's stack.
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-
- intptr_t* sp = last_Java_sp();
- address pc = _anchor.last_Java_pc();
-
- // Last_Java_pc ist not set, if we come here from compiled code.
- if (pc == NULL) {
- pc = (address) *(sp + 2);
- }
-
- return frame(sp, pc);
- }
+ frame pd_last_frame();
public:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -44,7 +44,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp
--- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -24,9 +24,23 @@
*/
#include "precompiled.hpp"
-#include "runtime/frame.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/thread.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+
+ intptr_t* sp = last_Java_sp();
+ address pc = _anchor.last_Java_pc();
+
+ // Last_Java_pc ist not set if we come here from compiled code.
+ if (pc == NULL) {
+ pc = (address) *(sp + 14);
+ }
+
+ return frame(sp, pc);
+}
+
// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/S390x.
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) {
Unimplemented();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_s390/thread_linux_s390.hpp
--- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -33,19 +33,7 @@
}
// The `last' frame is the youngest Java frame on the thread's stack.
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-
- intptr_t* sp = last_Java_sp();
- address pc = _anchor.last_Java_pc();
-
- // Last_Java_pc ist not set if we come here from compiled code.
- if (pc == NULL) {
- pc = (address) *(sp + 14);
- }
-
- return frame(sp, pc);
- }
+ frame pd_last_frame();
public:
void set_base_of_stack_pointer(intptr_t* base_sp) {}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -40,7 +40,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.cpp
--- a/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,14 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ assert(_anchor.walkable(), "thread has not dumped its register windows yet");
+
+ assert(_anchor.last_Java_pc() != NULL, "Ack no pc!");
+ return frame(last_Java_sp(), frame::unpatchable, _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.hpp
--- a/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,13 +32,7 @@
_base_of_stack_pointer = NULL;
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- assert(_anchor.walkable(), "thread has not dumped its register windows yet");
-
- assert(_anchor.last_Java_pc() != NULL, "Ack no pc!");
- return frame(last_Java_sp(), frame::unpatchable, _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
// Sometimes the trap handler needs to record both PC and NPC.
// This is a SPARC-specific companion to Thread::set_saved_exception_pc.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,7 +39,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,12 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_x86/thread_linux_x86.hpp
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,11 +30,7 @@
_anchor.clear();
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
public:
// Mutators are highly dangerous....
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -40,7 +40,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp
--- a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,11 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ return frame(last_Java_fp(), last_Java_sp());
+}
+
void JavaThread::cache_global_variables() {
// nothing to do
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp
--- a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -86,10 +86,7 @@
}
private:
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- return frame(last_Java_fp(), last_Java_sp());
- }
+ frame pd_last_frame();
public:
static ByteSize last_Java_fp_offset() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp
--- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -41,7 +41,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.cpp
--- a/src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,14 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ assert(_anchor.walkable(), "thread has not dumped its register windows yet");
+
+ assert(_anchor.last_Java_pc() != NULL, "Ack no pc!");
+ return frame(last_Java_sp(), frame::unpatchable, _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.hpp
--- a/src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_sparc/thread_solaris_sparc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -31,13 +31,7 @@
_base_of_stack_pointer = NULL;
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- assert(_anchor.walkable(), "thread has not dumped its register windows yet");
-
- assert(_anchor.last_Java_pc() != NULL, "Ack no pc!");
- return frame(last_Java_sp(), frame::unpatchable, _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
// Sometimes the trap handler needs to record both PC and NPC.
// This is a SPARC-specific companion to Thread::set_saved_exception_pc.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -40,7 +40,7 @@
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.cpp
--- a/src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,12 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.hpp
--- a/src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/solaris_x86/thread_solaris_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -28,11 +28,7 @@
private:
void pd_initialize() { _anchor.clear(); }
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
public:
// Mutators are highly dangerous....
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp
--- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -40,7 +40,7 @@
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,12 @@
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+frame JavaThread::pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/os_cpu/windows_x86/thread_windows_x86.hpp
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,11 +30,7 @@
_anchor.clear();
}
- frame pd_last_frame() {
- assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
- vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
- return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
- }
+ frame pd_last_frame();
public:
// Mutators are highly dangerous....
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/adlc/main.cpp
--- a/src/hotspot/share/adlc/main.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/adlc/main.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -228,6 +228,7 @@
AD.addInclude(AD._CPP_file, "opto/regmask.hpp");
AD.addInclude(AD._CPP_file, "opto/runtime.hpp");
AD.addInclude(AD._CPP_file, "runtime/biasedLocking.hpp");
+ AD.addInclude(AD._CPP_file, "runtime/safepointMechanism.hpp");
AD.addInclude(AD._CPP_file, "runtime/sharedRuntime.hpp");
AD.addInclude(AD._CPP_file, "runtime/stubRoutines.hpp");
AD.addInclude(AD._CPP_file, "utilities/growableArray.hpp");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/aot/aotCodeHeap.cpp
--- a/src/hotspot/share/aot/aotCodeHeap.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,10 +25,10 @@
#include "aot/aotCodeHeap.hpp"
#include "aot/aotLoader.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaAssertions.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/shared/gcLocker.hpp"
#include "interpreter/abstractInterpreter.hpp"
@@ -36,6 +36,7 @@
#include "jvmci/jvmciRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/method.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vm_operations.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/aot/aotCompiledMethod.cpp
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,12 +30,13 @@
#include "code/compiledIC.hpp"
#include "code/nativeInst.hpp"
#include "compiler/compilerOracle.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/gcLocker.hpp"
#include "jvmci/compilerRuntime.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "oops/method.inline.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
@@ -70,6 +71,10 @@
}
#endif
+address* AOTCompiledMethod::orig_pc_addr(const frame* fr) {
+ return (address*) ((address)fr->unextended_sp() + _meta->orig_pc_offset());
+}
+
bool AOTCompiledMethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) {
return false;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/aot/aotCompiledMethod.hpp
--- a/src/hotspot/share/aot/aotCompiledMethod.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/aot/aotCompiledMethod.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -117,7 +117,7 @@
const int _method_index;
oop _oop; // method()->method_holder()->klass_holder()
- address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _meta->orig_pc_offset()); }
+ address* orig_pc_addr(const frame* fr);
bool make_not_entrant_helper(int new_state);
public:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_Compiler.cpp
--- a/src/hotspot/share/c1/c1_Compiler.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_Compiler.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -38,7 +38,7 @@
#include "memory/resourceArea.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/bitMap.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_FrameMap.hpp
--- a/src/hotspot/share/c1/c1_FrameMap.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_FrameMap.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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,7 +25,7 @@
#ifndef SHARE_VM_C1_C1_FRAMEMAP_HPP
#define SHARE_VM_C1_C1_FRAMEMAP_HPP
-#include "asm/assembler.hpp"
+#include "asm/macroAssembler.hpp"
#include "c1/c1_Defs.hpp"
#include "c1/c1_LIR.hpp"
#include "code/vmreg.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_GraphBuilder.cpp
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,6 +32,7 @@
#include "ci/ciField.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciMemberName.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/bytecode.hpp"
#include "memory/resourceArea.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_LIRAssembler.cpp
--- a/src/hotspot/share/c1/c1_LIRAssembler.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,6 +30,7 @@
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_ValueStack.hpp"
#include "ci/ciInstance.hpp"
+#include "gc/shared/collectedHeap.hpp"
#include "runtime/os.hpp"
void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_LIRGenerator.cpp
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,8 @@
#include "ci/ciObjArray.hpp"
#include "ci/ciUtilities.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/collectedHeap.hpp"
#include "runtime/arguments.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
@@ -1460,10 +1461,10 @@
switch (_bs->kind()) {
#if INCLUDE_ALL_GCS
case BarrierSet::G1BarrierSet:
- G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
+ G1BarrierSet_pre_barrier(addr_opr, pre_val, do_load, patch, info);
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
// No pre barriers
break;
default :
@@ -1476,11 +1477,11 @@
switch (_bs->kind()) {
#if INCLUDE_ALL_GCS
case BarrierSet::G1BarrierSet:
- G1SATBCardTableModRef_post_barrier(addr, new_val);
+ G1BarrierSet_post_barrier(addr, new_val);
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableModRef:
- CardTableModRef_post_barrier(addr, new_val);
+ case BarrierSet::CardTableBarrierSet:
+ CardTableBarrierSet_post_barrier(addr, new_val);
break;
default :
ShouldNotReachHere();
@@ -1490,8 +1491,8 @@
////////////////////////////////////////////////////////////////////////
#if INCLUDE_ALL_GCS
-void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
- bool do_load, bool patch, CodeEmitInfo* info) {
+void LIRGenerator::G1BarrierSet_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
+ bool do_load, bool patch, CodeEmitInfo* info) {
// First we test whether marking is in progress.
BasicType flag_type;
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
@@ -1545,7 +1546,7 @@
__ branch_destination(slow->continuation());
}
-void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
+void LIRGenerator::G1BarrierSet_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
// If the "new_val" is a constant NULL, no barrier is necessary.
if (new_val->is_constant() &&
new_val->as_constant_ptr()->as_jobject() == NULL) return;
@@ -1609,7 +1610,7 @@
#endif // INCLUDE_ALL_GCS
////////////////////////////////////////////////////////////////////////
-void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
+void LIRGenerator::CardTableBarrierSet_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
LIR_Const* card_table_base = new LIR_Const(ci_card_table_address());
if (addr->is_address()) {
LIR_Address* address = addr->as_address_ptr();
@@ -1626,8 +1627,8 @@
}
assert(addr->is_register(), "must be a register at this point");
-#ifdef CARDTABLEMODREF_POST_BARRIER_HELPER
- CardTableModRef_post_barrier_helper(addr, card_table_base);
+#ifdef CARDTABLEBARRIERSET_POST_BARRIER_HELPER
+ CardTableBarrierSet_post_barrier_helper(addr, card_table_base);
#else
LIR_Opr tmp = new_pointer_register();
if (TwoOperandLIRForm) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_LIRGenerator.hpp
--- a/src/hotspot/share/c1/c1_LIRGenerator.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRGenerator.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -275,15 +275,15 @@
// specific implementations
// pre barriers
- void G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
- bool do_load, bool patch, CodeEmitInfo* info);
+ void G1BarrierSet_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
+ bool do_load, bool patch, CodeEmitInfo* info);
// post barriers
- void G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
- void CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
-#ifdef CARDTABLEMODREF_POST_BARRIER_HELPER
- void CardTableModRef_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base);
+ void G1BarrierSet_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
+ void CardTableBarrierSet_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
+#ifdef CARDTABLEBARRIERSET_POST_BARRIER_HELPER
+ void CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base);
#endif
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_Runtime1.cpp
--- a/src/hotspot/share/c1/c1_Runtime1.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -53,11 +53,12 @@
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threadCritical.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/copy.hpp"
@@ -1358,67 +1359,6 @@
JRT_END
-// Array copy return codes.
-enum {
- ac_failed = -1, // arraycopy failed
- ac_ok = 0 // arraycopy succeeded
-};
-
-
-// Below length is the # elements copied.
-template int obj_arraycopy_work(oopDesc* src, T* src_addr,
- oopDesc* dst, T* dst_addr,
- int length) {
- if (src == dst) {
- // same object, no check
- HeapAccess<>::oop_arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length);
- return ac_ok;
- } else {
- Klass* bound = ObjArrayKlass::cast(dst->klass())->element_klass();
- Klass* stype = ObjArrayKlass::cast(src->klass())->element_klass();
- if (stype == bound || stype->is_subtype_of(bound)) {
- // Elements are guaranteed to be subtypes, so no check necessary
- HeapAccess::oop_arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length);
- return ac_ok;
- }
- }
- return ac_failed;
-}
-
-// fast and direct copy of arrays; returning -1, means that an exception may be thrown
-// and we did not copy anything
-JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length))
-#ifndef PRODUCT
- _generic_arraycopy_cnt++; // Slow-path oop array copy
-#endif
-
- if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed;
- if (!dst->is_array() || !src->is_array()) return ac_failed;
- if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed;
- if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed;
-
- if (length == 0) return ac_ok;
- if (src->is_typeArray()) {
- Klass* klass_oop = src->klass();
- if (klass_oop != dst->klass()) return ac_failed;
- TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop);
- klass->copy_array(arrayOop(src), src_pos, arrayOop(dst), dst_pos, length, Thread::current());
- return ac_ok;
- } else if (src->is_objArray() && dst->is_objArray()) {
- if (UseCompressedOops) {
- narrowOop *src_addr = objArrayOop(src)->obj_at_addr(src_pos);
- narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos);
- return obj_arraycopy_work(src, src_addr, dst, dst_addr, length);
- } else {
- oop *src_addr = objArrayOop(src)->obj_at_addr(src_pos);
- oop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos);
- return obj_arraycopy_work(src, src_addr, dst, dst_addr, length);
- }
- }
- return ac_failed;
-JRT_END
-
-
JRT_LEAF(int, Runtime1::is_instance_of(oopDesc* mirror, oopDesc* obj))
// had to return int instead of bool, otherwise there may be a mismatch
// between the C calling convention and the Java one.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/c1/c1_Runtime1.hpp
--- a/src/hotspot/share/c1/c1_Runtime1.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/c1/c1_Runtime1.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -186,7 +186,6 @@
#endif
// directly accessible leaf routine
- static int arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length);
static int is_instance_of(oopDesc* mirror, oopDesc* obj);
static void predicate_failed_trap(JavaThread* thread);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciArray.cpp
--- a/src/hotspot/share/ci/ciArray.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciArray.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciBaseObject.hpp
--- a/src/hotspot/share/ci/ciBaseObject.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciBaseObject.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,6 @@
#include "ci/ciClassList.hpp"
#include "memory/allocation.hpp"
-#include "runtime/handles.hpp"
#include "runtime/jniHandles.hpp"
// ciBaseObject
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciCallSite.cpp
--- a/src/hotspot/share/ci/ciCallSite.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciCallSite.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "ci/ciCallSite.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
// ciCallSite
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciConstantPoolCache.cpp
--- a/src/hotspot/share/ci/ciConstantPoolCache.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciConstantPoolCache.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciConstantPoolCache.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciEnv.cpp
--- a/src/hotspot/share/ci/ciEnv.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciEnv.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "ci/ciMethod.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciReplay.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciEnv.hpp
--- a/src/hotspot/share/ci/ciEnv.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciEnv.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
#include "code/dependencies.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "compiler/oopMap.hpp"
+#include "oops/methodData.hpp"
#include "runtime/thread.hpp"
class CompileTask;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciExceptionHandler.cpp
--- a/src/hotspot/share/ci/ciExceptionHandler.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciExceptionHandler.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,8 @@
#include "precompiled.hpp"
#include "ci/ciExceptionHandler.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
+#include "runtime/handles.inline.hpp"
// ciExceptionHandler
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciField.cpp
--- a/src/hotspot/share/ci/ciField.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciField.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,13 +25,14 @@
#include "precompiled.hpp"
#include "ci/ciField.hpp"
#include "ci/ciInstanceKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldDescriptor.hpp"
+#include "runtime/handles.inline.hpp"
// ciField
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciField.hpp
--- a/src/hotspot/share/ci/ciField.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciField.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,6 +29,7 @@
#include "ci/ciConstant.hpp"
#include "ci/ciFlags.hpp"
#include "ci/ciInstance.hpp"
+#include "ci/ciUtilities.hpp"
// ciField
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciInstance.cpp
--- a/src/hotspot/share/ci/ciInstance.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciInstance.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "ci/ciField.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciInstanceKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "oops/oop.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciInstanceKlass.cpp
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "ci/ciField.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciInstanceKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
@@ -34,6 +34,7 @@
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.hpp"
#include "runtime/fieldDescriptor.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
// ciInstanceKlass
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciKlass.cpp
--- a/src/hotspot/share/ci/ciKlass.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciKlass.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciSymbol.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "oops/oop.inline.hpp"
// ciKlass
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMemberName.cpp
--- a/src/hotspot/share/ci/ciMemberName.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMemberName.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciClassList.hpp"
#include "ci/ciMemberName.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaClasses.hpp"
// ------------------------------------------------------------------
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMetadata.cpp
--- a/src/hotspot/share/ci/ciMetadata.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMetadata.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciObject.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
// ------------------------------------------------------------------
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMethod.cpp
--- a/src/hotspot/share/ci/ciMethod.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMethod.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "ci/ciStreams.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciReplay.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/methodLiveness.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMethodData.cpp
--- a/src/hotspot/share/ci/ciMethodData.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMethodData.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "ci/ciMetadata.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/deoptimization.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMethodHandle.cpp
--- a/src/hotspot/share/ci/ciMethodHandle.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMethodHandle.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciClassList.hpp"
#include "ci/ciMethodHandle.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaClasses.hpp"
// ------------------------------------------------------------------
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMethodType.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/ci/ciMethodType.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "ci/ciInstance.hpp"
+#include "ci/ciMethodType.hpp"
+#include "ci/ciUtilities.inline.hpp"
+#include "classfile/javaClasses.hpp"
+
+ciType* ciMethodType::class_to_citype(oop klass_oop) const {
+ if (java_lang_Class::is_primitive(klass_oop)) {
+ BasicType bt = java_lang_Class::primitive_type(klass_oop);
+ return ciType::make(bt);
+ } else {
+ Klass* k = java_lang_Class::as_Klass(klass_oop);
+ return CURRENT_ENV->get_klass(k);
+ }
+}
+
+ciType* ciMethodType::rtype() const {
+ GUARDED_VM_ENTRY(
+ oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
+ return class_to_citype(rtype);
+ )
+}
+
+int ciMethodType::ptype_count() const {
+ GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_count(get_oop());)
+}
+
+int ciMethodType::ptype_slot_count() const {
+ GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
+}
+
+ciType* ciMethodType::ptype_at(int index) const {
+ GUARDED_VM_ENTRY(
+ oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
+ return class_to_citype(ptype);
+ )
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciMethodType.hpp
--- a/src/hotspot/share/ci/ciMethodType.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciMethodType.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,23 +26,13 @@
#define SHARE_VM_CI_CIMETHODTYPE_HPP
#include "ci/ciInstance.hpp"
-#include "ci/ciUtilities.hpp"
-#include "classfile/javaClasses.hpp"
// ciMethodType
//
// The class represents a java.lang.invoke.MethodType object.
class ciMethodType : public ciInstance {
private:
- ciType* class_to_citype(oop klass_oop) const {
- if (java_lang_Class::is_primitive(klass_oop)) {
- BasicType bt = java_lang_Class::primitive_type(klass_oop);
- return ciType::make(bt);
- } else {
- Klass* k = java_lang_Class::as_Klass(klass_oop);
- return CURRENT_ENV->get_klass(k);
- }
- }
+ ciType* class_to_citype(oop klass_oop) const;
public:
ciMethodType(instanceHandle h_i) : ciInstance(h_i) {}
@@ -50,27 +40,12 @@
// What kind of ciObject is this?
bool is_method_type() const { return true; }
- ciType* rtype() const {
- GUARDED_VM_ENTRY(
- oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
- return class_to_citype(rtype);
- )
- }
-
- int ptype_count() const {
- GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_count(get_oop());)
- }
+ ciType* rtype() const;
- int ptype_slot_count() const {
- GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
- }
+ int ptype_count() const;
+ int ptype_slot_count() const ;
- ciType* ptype_at(int index) const {
- GUARDED_VM_ENTRY(
- oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
- return class_to_citype(ptype);
- )
- }
+ ciType* ptype_at(int index) const;
};
#endif // SHARE_VM_CI_CIMETHODTYPE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciNullObject.cpp
--- a/src/hotspot/share/ci/ciNullObject.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciNullObject.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciNullObject.hpp"
+#include "ci/ciUtilities.hpp"
// ciNullObject
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciNullObject.hpp
--- a/src/hotspot/share/ci/ciNullObject.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciNullObject.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,6 @@
#include "ci/ciClassList.hpp"
#include "ci/ciObject.hpp"
-#include "ci/ciUtilities.hpp"
// ciNullObject
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciObjArray.cpp
--- a/src/hotspot/share/ci/ciObjArray.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciObjArray.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciObjArray.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
// ciObjArray
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciObjArrayKlass.cpp
--- a/src/hotspot/share/ci/ciObjArrayKlass.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciObjArrayKlass.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciSymbol.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "oops/objArrayKlass.hpp"
// ciObjArrayKlass
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciObject.cpp
--- a/src/hotspot/share/ci/ciObject.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciObject.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciObject.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
@@ -207,7 +207,7 @@
int flags = 0;
if (x != NULL) {
assert(Universe::heap()->is_in_reserved(x), "must be");
- if (x->is_scavengable())
+ if (Universe::heap()->is_scavengable(x))
flags |= SCAVENGABLE_FLAG;
}
_ident |= flags;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciObjectFactory.cpp
--- a/src/hotspot/share/ci/ciObjectFactory.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciObjectFactory.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,13 +39,14 @@
#include "ci/ciSymbol.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldType.hpp"
+#include "runtime/handles.inline.hpp"
#include "utilities/macros.hpp"
// ciObjectFactory
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciReplay.cpp
--- a/src/hotspot/share/ci/ciReplay.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciReplay.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "ci/ciReplay.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciSignature.cpp
--- a/src/hotspot/share/ci/ciSignature.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciSignature.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciMethodType.hpp"
#include "ci/ciSignature.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciSignature.hpp
--- a/src/hotspot/share/ci/ciSignature.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciSignature.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,6 +27,7 @@
#include "ci/ciClassList.hpp"
#include "ci/ciSymbol.hpp"
+#include "interpreter/bytecodes.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciStreams.cpp
--- a/src/hotspot/share/ci/ciStreams.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciStreams.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,8 @@
#include "ci/ciConstant.hpp"
#include "ci/ciField.hpp"
#include "ci/ciStreams.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
+#include "runtime/handles.inline.hpp"
// ciExceptionHandlerStream
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciSymbol.cpp
--- a/src/hotspot/share/ci/ciSymbol.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciSymbol.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciSymbol.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "memory/oopFactory.hpp"
// ------------------------------------------------------------------
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciType.cpp
--- a/src/hotspot/share/ci/ciType.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciType.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciType.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciTypeArray.cpp
--- a/src/hotspot/share/ci/ciTypeArray.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciTypeArray.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciTypeArray.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
// ciTypeArray
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciTypeArrayKlass.cpp
--- a/src/hotspot/share/ci/ciTypeArrayKlass.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciTypeArrayKlass.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciTypeArrayKlass.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
// ciTypeArrayKlass
//
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciUtilities.cpp
--- a/src/hotspot/share/ci/ciUtilities.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciUtilities.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,8 +24,9 @@
#include "precompiled.hpp"
#include "ci/ciUtilities.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/cardTable.hpp"
+#include "gc/shared/collectedHeap.hpp"
#include "memory/universe.hpp"
// ciUtilities
@@ -51,7 +52,7 @@
// card_table_base
jbyte *ci_card_table_address() {
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust users of this code");
return ct->byte_map_base();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciUtilities.hpp
--- a/src/hotspot/share/ci/ciUtilities.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/ci/ciUtilities.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,45 +26,11 @@
#define SHARE_VM_CI_CIUTILITIES_HPP
#include "ci/ciEnv.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "utilities/globalDefinitions.hpp"
// The following routines and definitions are used internally in the
// compiler interface.
-
-// Add a ci native entry wrapper?
-
-// Bring the compilation thread into the VM state.
-#define VM_ENTRY_MARK \
- CompilerThread* thread=CompilerThread::current(); \
- ThreadInVMfromNative __tiv(thread); \
- ResetNoHandleMark rnhm; \
- HandleMarkCleaner __hm(thread); \
- Thread* THREAD = thread; \
- debug_only(VMNativeEntryWrapper __vew;)
-
-
-
-// Bring the compilation thread into the VM state. No handle mark.
-#define VM_QUICK_ENTRY_MARK \
- CompilerThread* thread=CompilerThread::current(); \
- ThreadInVMfromNative __tiv(thread); \
-/* \
- * [TODO] The NoHandleMark line does nothing but declare a function prototype \
- * The NoHandkeMark constructor is NOT executed. If the ()'s are \
- * removed, causes the NoHandleMark assert to trigger. \
- * debug_only(NoHandleMark __hm();) \
- */ \
- Thread* THREAD = thread; \
- debug_only(VMNativeEntryWrapper __vew;)
-
-
-#define EXCEPTION_CONTEXT \
- CompilerThread* thread=CompilerThread::current(); \
- Thread* THREAD = thread;
-
-
#define CURRENT_ENV \
ciEnv::current()
@@ -78,36 +44,6 @@
#define ASSERT_IN_VM \
assert(IS_IN_VM, "must be in vm state");
-#define GUARDED_VM_ENTRY(action) \
- {if (IS_IN_VM) { action } else { VM_ENTRY_MARK; { action }}}
-
-#define GUARDED_VM_QUICK_ENTRY(action) \
- {if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}}
-
-// Redefine this later.
-#define KILL_COMPILE_ON_FATAL_(result) \
- THREAD); \
- if (HAS_PENDING_EXCEPTION) { \
- if (PENDING_EXCEPTION->klass() == \
- SystemDictionary::ThreadDeath_klass()) { \
- /* Kill the compilation. */ \
- fatal("unhandled ci exception"); \
- return (result); \
- } \
- CLEAR_PENDING_EXCEPTION; \
- return (result); \
- } \
- (void)(0
-
-#define KILL_COMPILE_ON_ANY \
- THREAD); \
- if (HAS_PENDING_EXCEPTION) { \
- fatal("unhandled ci exception"); \
- CLEAR_PENDING_EXCEPTION; \
- } \
-(void)(0
-
-
inline const char* bool_to_str(bool b) {
return ((b) ? "true" : "false");
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/ci/ciUtilities.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/ci/ciUtilities.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_CI_CIUTILITIES_INLINE_HPP
+#define SHARE_VM_CI_CIUTILITIES_INLINE_HPP
+
+#include "ci/ciUtilities.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+
+// Add a ci native entry wrapper?
+
+// Bring the compilation thread into the VM state.
+#define VM_ENTRY_MARK \
+ CompilerThread* thread=CompilerThread::current(); \
+ ThreadInVMfromNative __tiv(thread); \
+ ResetNoHandleMark rnhm; \
+ HandleMarkCleaner __hm(thread); \
+ Thread* THREAD = thread; \
+ debug_only(VMNativeEntryWrapper __vew;)
+
+
+
+// Bring the compilation thread into the VM state. No handle mark.
+#define VM_QUICK_ENTRY_MARK \
+ CompilerThread* thread=CompilerThread::current(); \
+ ThreadInVMfromNative __tiv(thread); \
+/* \
+ * [TODO] The NoHandleMark line does nothing but declare a function prototype \
+ * The NoHandkeMark constructor is NOT executed. If the ()'s are \
+ * removed, causes the NoHandleMark assert to trigger. \
+ * debug_only(NoHandleMark __hm();) \
+ */ \
+ Thread* THREAD = thread; \
+ debug_only(VMNativeEntryWrapper __vew;)
+
+
+#define EXCEPTION_CONTEXT \
+ CompilerThread* thread=CompilerThread::current(); \
+ Thread* THREAD = thread;
+
+
+#define GUARDED_VM_ENTRY(action) \
+ {if (IS_IN_VM) { action } else { VM_ENTRY_MARK; { action }}}
+
+#define GUARDED_VM_QUICK_ENTRY(action) \
+ {if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}}
+
+// Redefine this later.
+#define KILL_COMPILE_ON_FATAL_(result) \
+ THREAD); \
+ if (HAS_PENDING_EXCEPTION) { \
+ if (PENDING_EXCEPTION->klass() == \
+ SystemDictionary::ThreadDeath_klass()) { \
+ /* Kill the compilation. */ \
+ fatal("unhandled ci exception"); \
+ return (result); \
+ } \
+ CLEAR_PENDING_EXCEPTION; \
+ return (result); \
+ } \
+ (void)(0
+
+#define KILL_COMPILE_ON_ANY \
+ THREAD); \
+ if (HAS_PENDING_EXCEPTION) { \
+ fatal("unhandled ci exception"); \
+ CLEAR_PENDING_EXCEPTION; \
+ } \
+(void)(0
+
+#endif // SHARE_VM_CI_CIUTILITIES_INLINE_HPP
+
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classFileParser.cpp
--- a/src/hotspot/share/classfile/classFileParser.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classFileParser.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -58,6 +58,7 @@
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/perfData.hpp"
#include "runtime/reflection.hpp"
@@ -770,6 +771,13 @@
} // end of for
}
+Handle ClassFileParser::clear_cp_patch_at(int index) {
+ Handle patch = cp_patch_at(index);
+ _cp_patches->at_put(index, Handle());
+ assert(!has_cp_patch_at(index), "");
+ return patch;
+}
+
void ClassFileParser::patch_class(ConstantPool* cp, int class_index, Klass* k, Symbol* name) {
int name_index = _orig_cp_size + _num_patched_klasses;
int resolved_klass_index = _first_patched_klass_resolved_index + _num_patched_klasses;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classFileParser.hpp
--- a/src/hotspot/share/classfile/classFileParser.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classFileParser.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_CLASSFILE_CLASSFILEPARSER_HPP
#include "memory/referenceType.hpp"
-#include "runtime/handles.inline.hpp"
+#include "oops/annotations.hpp"
#include "oops/constantPool.hpp"
#include "oops/typeArrayOop.hpp"
#include "utilities/accessFlags.hpp"
@@ -434,12 +434,7 @@
return _cp_patches->at(index);
}
- Handle clear_cp_patch_at(int index) {
- Handle patch = cp_patch_at(index);
- _cp_patches->at_put(index, Handle());
- assert(!has_cp_patch_at(index), "");
- return patch;
- }
+ Handle clear_cp_patch_at(int index);
void patch_class(ConstantPool* cp, int class_index, Klass* k, Symbol* name);
void patch_constant_pool(ConstantPool* cp,
@@ -530,7 +525,7 @@
const GrowableArray* cp_patches() const { return _cp_patches; }
ClassLoaderData* loader_data() const { return _loader_data; }
const Symbol* class_name() const { return _class_name; }
- const Klass* super_klass() const { return _super_klass; }
+ const InstanceKlass* super_klass() const { return _super_klass; }
ReferenceType reference_type() const { return _rt; }
AccessFlags access_flags() const { return _access_flags; }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classListParser.cpp
--- a/src/hotspot/share/classfile/classListParser.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classListParser.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -31,6 +31,8 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/fieldType.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classLoader.cpp
--- a/src/hotspot/share/classfile/classLoader.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classLoader.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -61,7 +61,7 @@
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classLoaderData.cpp
--- a/src/hotspot/share/classfile/classLoaderData.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -610,6 +610,21 @@
return new Dictionary(this, size, resizable);
}
+// Tell the GC to keep this klass alive while iterating ClassLoaderDataGraph
+oop ClassLoaderData::holder_phantom() {
+ // A klass that was previously considered dead can be looked up in the
+ // CLD/SD, and its _java_mirror or _class_loader can be stored in a root
+ // or a reachable object making it alive again. The SATB part of G1 needs
+ // to get notified about this potential resurrection, otherwise the marking
+ // might not find the object.
+ if (!keep_alive()) {
+ oop* o = is_anonymous() ? _klasses->java_mirror_handle().ptr_raw() : &_class_loader;
+ return RootAccess::oop_load(o);
+ } else {
+ return NULL;
+ }
+}
+
// Unloading support
oop ClassLoaderData::keep_alive_object() const {
assert_locked_or_safepoint(_metaspace_lock);
@@ -1048,26 +1063,34 @@
}
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->classes_do(klass_closure);
}
}
void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->classes_do(f);
}
}
void ClassLoaderDataGraph::methods_do(void f(Method*)) {
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->methods_do(f);
}
}
void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) {
assert_locked_or_safepoint(Module_lock);
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->modules_do(f);
}
}
@@ -1084,7 +1107,9 @@
void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
assert_locked_or_safepoint(Module_lock);
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->packages_do(f);
}
}
@@ -1100,7 +1125,9 @@
}
void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
+ Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ Handle holder(thread, cld->holder_phantom());
cld->loaded_classes_do(klass_closure);
}
}
@@ -1121,21 +1148,27 @@
// Walk classes in the loaded class dictionaries in various forms.
// Only walks the classes defined in this class loader.
void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*)) {
+ Thread* thread = Thread::current();
FOR_ALL_DICTIONARY(cld) {
+ Handle holder(thread, cld->holder_phantom());
cld->dictionary()->classes_do(f);
}
}
// Only walks the classes defined in this class loader.
void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS) {
+ Thread* thread = Thread::current();
FOR_ALL_DICTIONARY(cld) {
+ Handle holder(thread, cld->holder_phantom());
cld->dictionary()->classes_do(f, CHECK);
}
}
// Walks all entries in the dictionary including entries initiated by this class loader.
void ClassLoaderDataGraph::dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) {
+ Thread* thread = Thread::current();
FOR_ALL_DICTIONARY(cld) {
+ Handle holder(thread, cld->holder_phantom());
cld->dictionary()->all_entries_do(f);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/classLoaderData.hpp
--- a/src/hotspot/share/classfile/classLoaderData.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -288,6 +288,7 @@
void unload();
bool keep_alive() const { return _keep_alive > 0; }
+ oop holder_phantom();
void classes_do(void f(Klass*));
void loaded_classes_do(KlassClosure* klass_closure);
void classes_do(void f(InstanceKlass*));
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/javaClasses.cpp
--- a/src/hotspot/share/classfile/javaClasses.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -50,14 +50,15 @@
#include "oops/typeArrayOop.inline.hpp"
#include "prims/resolvedMethodTable.hpp"
#include "runtime/fieldDescriptor.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/preserveException.hpp"
@@ -1866,12 +1867,8 @@
oop java_lang_Throwable::unassigned_stacktrace() {
InstanceKlass* ik = SystemDictionary::Throwable_klass();
- address addr = ik->static_field_addr(static_unassigned_stacktrace_offset);
- if (UseCompressedOops) {
- return oopDesc::load_decode_heap_oop((narrowOop *)addr);
- } else {
- return oopDesc::load_decode_heap_oop((oop*)addr);
- }
+ oop base = ik->static_field_base_raw();
+ return base->obj_field(static_unassigned_stacktrace_offset);
}
oop java_lang_Throwable::backtrace(oop throwable) {
@@ -3547,14 +3544,14 @@
jlong java_lang_ref_SoftReference::clock() {
InstanceKlass* ik = SystemDictionary::SoftReference_klass();
- jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
- return *offset;
+ oop base = ik->static_field_base_raw();
+ return base->long_field(static_clock_offset);
}
void java_lang_ref_SoftReference::set_clock(jlong value) {
InstanceKlass* ik = SystemDictionary::SoftReference_klass();
- jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
- *offset = value;
+ oop base = ik->static_field_base_raw();
+ base->long_field_put(static_clock_offset, value);
}
// Support for java_lang_invoke_DirectMethodHandle
@@ -4133,12 +4130,8 @@
bool java_lang_System::has_security_manager() {
InstanceKlass* ik = SystemDictionary::System_klass();
- address addr = ik->static_field_addr(static_security_offset);
- if (UseCompressedOops) {
- return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL;
- } else {
- return oopDesc::load_decode_heap_oop((oop*)addr) != NULL;
- }
+ oop base = ik->static_field_base_raw();
+ return !oopDesc::is_null(base->obj_field(static_security_offset));
}
int java_lang_Class::_klass_offset;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/klassFactory.cpp
--- a/src/hotspot/share/classfile/klassFactory.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/klassFactory.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2018, 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
@@ -34,6 +34,7 @@
#include "memory/resourceArea.hpp"
#include "prims/jvmtiEnvBase.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
+#include "runtime/handles.inline.hpp"
#include "trace/traceMacros.hpp"
// called during initial loading of a shared class
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/sharedClassUtil.cpp
--- a/src/hotspot/share/classfile/sharedClassUtil.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/sharedClassUtil.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -38,7 +38,7 @@
#include "oops/instanceKlass.hpp"
#include "runtime/arguments.hpp"
#include "runtime/java.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
class ManifestStream: public ResourceObj {
private:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/stackMapTable.cpp
--- a/src/hotspot/share/classfile/stackMapTable.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/stackMapTable.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -144,6 +144,20 @@
str->print_cr(" }");
}
+StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,
+ int32_t code_len, TRAPS) :
+ _verifier(v), _stream(stream),
+ _code_data(code_data), _code_length(code_len) {
+ methodHandle m = v->method();
+ if (m->has_stackmap_table()) {
+ _cp = constantPoolHandle(THREAD, m->constants());
+ _frame_count = _stream->get_u2(CHECK);
+ } else {
+ // There's no stackmap table present. Frame count and size are 0.
+ _frame_count = 0;
+ }
+}
+
int32_t StackMapReader::chop(
VerificationType* locals, int32_t length, int32_t chops) {
if (locals == NULL) return -1;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/stackMapTable.hpp
--- a/src/hotspot/share/classfile/stackMapTable.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/stackMapTable.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -142,18 +142,7 @@
public:
// Constructor
StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,
- int32_t code_len, TRAPS) :
- _verifier(v), _stream(stream),
- _code_data(code_data), _code_length(code_len) {
- methodHandle m = v->method();
- if (m->has_stackmap_table()) {
- _cp = constantPoolHandle(THREAD, m->constants());
- _frame_count = _stream->get_u2(CHECK);
- } else {
- // There's no stackmap table present. Frame count and size are 0.
- _frame_count = 0;
- }
- }
+ int32_t code_len, TRAPS);
inline int32_t get_frame_count() const { return _frame_count; }
StackMapFrame* next(StackMapFrame* pre_frame, bool first,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/systemDictionary.hpp
--- a/src/hotspot/share/classfile/systemDictionary.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,7 +34,6 @@
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "utilities/hashtable.hpp"
-#include "utilities/hashtable.inline.hpp"
// The dictionary in each ClassLoaderData stores all loaded classes, either
// initiatied by its class loader or defined by its class loader:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/classfile/verifier.cpp
--- a/src/hotspot/share/classfile/verifier.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/classfile/verifier.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -44,7 +44,7 @@
#include "oops/typeArrayOop.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/codeBlob.cpp
--- a/src/hotspot/share/code/codeBlob.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/codeBlob.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,7 @@
#include "oops/oop.inline.hpp"
#include "prims/forte.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/compiledMethod.cpp
--- a/src/hotspot/share/code/compiledMethod.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/compiledMethod.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,10 +27,12 @@
#include "code/compiledMethod.inline.hpp"
#include "code/scopeDesc.hpp"
#include "code/codeCache.hpp"
-#include "prims/methodHandles.hpp"
#include "interpreter/bytecode.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/methodData.hpp"
#include "oops/method.inline.hpp"
+#include "prims/methodHandles.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/compiledMethod.hpp
--- a/src/hotspot/share/code/compiledMethod.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/compiledMethod.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -50,13 +50,15 @@
volatile int _count;
ExceptionCache* _next;
- address pc_at(int index) { assert(index >= 0 && index < count(),""); return _pc[index]; }
- void set_pc_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
- address handler_at(int index) { assert(index >= 0 && index < count(),""); return _handler[index]; }
- void set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
- int count();
+ inline address pc_at(int index);
+ void set_pc_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
+
+ inline address handler_at(int index);
+ void set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
+
+ inline int count();
// increment_count is only called under lock, but there may be concurrent readers.
- void increment_count();
+ void increment_count();
public:
@@ -306,9 +308,9 @@
virtual address get_original_pc(const frame* fr) = 0;
// Deopt
// Return true is the PC is one would expect if the frame is being deopted.
- bool is_deopt_pc (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
+ inline bool is_deopt_pc(address pc);
bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
- bool is_deopt_entry(address pc);
+ inline bool is_deopt_entry(address pc);
virtual bool can_convert_to_zombie() = 0;
virtual const char* compile_kind() const = 0;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/compiledMethod.inline.hpp
--- a/src/hotspot/share/code/compiledMethod.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/compiledMethod.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,6 +29,8 @@
#include "code/nativeInst.hpp"
#include "runtime/frame.hpp"
+inline bool CompiledMethod::is_deopt_pc(address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
+
// When using JVMCI the address might be off by the size of a call instruction.
inline bool CompiledMethod::is_deopt_entry(address pc) {
return pc == deopt_handler_begin()
@@ -64,6 +66,16 @@
inline int ExceptionCache::count() { return OrderAccess::load_acquire(&_count); }
+address ExceptionCache::pc_at(int index) {
+ assert(index >= 0 && index < count(),"");
+ return _pc[index];
+}
+
+address ExceptionCache::handler_at(int index) {
+ assert(index >= 0 && index < count(),"");
+ return _handler[index];
+}
+
// increment_count is only called under lock, but there may be concurrent readers.
inline void ExceptionCache::increment_count() { OrderAccess::release_store(&_count, _count + 1); }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/debugInfo.cpp
--- a/src/hotspot/share/code/debugInfo.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/debugInfo.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "code/nmethod.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.hpp"
@@ -121,6 +121,10 @@
// ObjectValue
+void ObjectValue::set_value(oop value) {
+ _value = Handle(Thread::current(), value);
+}
+
void ObjectValue::read_object(DebugInfoReadStream* stream) {
_klass = read_from(stream);
assert(_klass->is_constant_oop(), "should be constant java mirror oop");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/debugInfo.hpp
--- a/src/hotspot/share/code/debugInfo.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/debugInfo.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -128,7 +128,7 @@
Handle value() const { return _value; }
bool is_visited() const { return _visited; }
- void set_value(oop value) { _value = Handle(Thread::current(), value); }
+ void set_value(oop value);
void set_visited(bool visited) { _visited = false; }
// Serialization of debugging information
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/nmethod.cpp
--- a/src/hotspot/share/code/nmethod.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/nmethod.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,7 @@
#include "jvm.h"
#include "code/codeCache.hpp"
#include "code/compiledIC.hpp"
+#include "code/compiledMethod.inline.hpp"
#include "code/dependencies.hpp"
#include "code/nativeInst.hpp"
#include "code/nmethod.hpp"
@@ -36,20 +37,25 @@
#include "compiler/compilerDirectives.hpp"
#include "compiler/directivesParser.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/bytecode.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
+#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/method.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sweeper.hpp"
+#include "runtime/vmThread.hpp"
#include "utilities/align.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
@@ -380,6 +386,10 @@
nul_chk_table_size();
}
+address* nmethod::orig_pc_addr(const frame* fr) {
+ return (address*) ((address)fr->unextended_sp() + _orig_pc_offset);
+}
+
const char* nmethod::compile_kind() const {
if (is_osr_method()) return "osr";
if (method() != NULL && is_native_method()) return "c2n";
@@ -1682,7 +1692,7 @@
{ NOT_PRODUCT(_print_nm = NULL); }
bool detected_scavenge_root() { return _detected_scavenge_root; }
virtual void do_oop(oop* p) {
- if ((*p) != NULL && (*p)->is_scavengable()) {
+ if ((*p) != NULL && Universe::heap()->is_scavengable(*p)) {
NOT_PRODUCT(maybe_print(p));
_detected_scavenge_root = true;
}
@@ -2177,7 +2187,7 @@
DebugScavengeRoot(nmethod* nm) : _nm(nm), _ok(true) { }
bool ok() { return _ok; }
virtual void do_oop(oop* p) {
- if ((*p) == NULL || !(*p)->is_scavengable()) return;
+ if ((*p) == NULL || !Universe::heap()->is_scavengable(*p)) return;
if (_ok) {
_nm->print_nmethod(true);
_ok = false;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/nmethod.hpp
--- a/src/hotspot/share/code/nmethod.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/nmethod.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -512,7 +512,7 @@
private:
ScopeDesc* scope_desc_in(address begin, address end);
- address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); }
+ address* orig_pc_addr(const frame* fr);
public:
// copying of debugging information
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/code/relocInfo_ext.cpp
--- a/src/hotspot/share/code/relocInfo_ext.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/code/relocInfo_ext.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "code/relocInfo.hpp"
#include "code/relocInfo_ext.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/universe.hpp"
#include "runtime/os.hpp"
@@ -60,7 +60,7 @@
}
case symbolic_Relocation::card_table_reference: {
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTableBarrierSet* ctbs = barrier_set_cast(bs);
CardTable* ct = ctbs->card_table();
return (address)ct->byte_map_base();
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/compileBroker.cpp
--- a/src/hotspot/share/compiler/compileBroker.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/compileBroker.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -47,12 +47,13 @@
#include "runtime/atomic.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/timerTrace.hpp"
+#include "runtime/vframe.inline.hpp"
#include "trace/tracing.hpp"
#include "utilities/debug.hpp"
#include "utilities/dtrace.hpp"
@@ -1344,11 +1345,11 @@
#if INCLUDE_JVMCI
// The number of milliseconds to wait before checking if
// JVMCI compilation has made progress.
-static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 500;
+static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 1000;
// The number of JVMCI compilation progress checks that must fail
// before unblocking a thread waiting for a blocking compilation.
-static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 5;
+static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 10;
/**
* Waits for a JVMCI compiler to complete a given task. This thread
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/compileTask.cpp
--- a/src/hotspot/share/compiler/compileTask.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/compileTask.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/handles.inline.hpp"
CompileTask* CompileTask::_task_free_list = NULL;
#ifdef ASSERT
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/compilerDirectives.cpp
--- a/src/hotspot/share/compiler/compilerDirectives.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/compilerDirectives.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "ci/ciMethod.hpp"
-#include "ci/ciUtilities.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compilerDirectives.hpp"
#include "compiler/compilerOracle.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/compilerDirectives.hpp
--- a/src/hotspot/share/compiler/compilerDirectives.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/compilerDirectives.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,6 @@
#include "ci/ciMetadata.hpp"
#include "ci/ciMethod.hpp"
-#include "ci/ciUtilities.hpp"
#include "compiler/methodMatcher.hpp"
#include "compiler/compilerOracle.hpp"
#include "utilities/exceptions.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/directivesParser.cpp
--- a/src/hotspot/share/compiler/directivesParser.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/directivesParser.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
#include "compiler/directivesParser.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
#include
void DirectivesParser::push_tmp(CompilerDirectives* dir) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/disassembler.cpp
--- a/src/hotspot/share/compiler/disassembler.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/disassembler.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "code/codeCache.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
@@ -319,7 +319,7 @@
}
BarrierSet* bs = Universe::heap()->barrier_set();
- if (bs->is_a(BarrierSet::CardTableModRef) &&
+ if (bs->is_a(BarrierSet::CardTableBarrierSet) &&
adr == ci_card_table_address_as()) {
st->print("word_map_base");
if (WizardMode) st->print(" " INTPTR_FORMAT, p2i(adr));
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/compiler/methodMatcher.hpp
--- a/src/hotspot/share/compiler/methodMatcher.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/compiler/methodMatcher.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
#define SHARE_VM_COMPILER_METHODMATCHER_HPP
#include "memory/allocation.hpp"
-#include "runtime/handles.inline.hpp"
+#include "runtime/handles.hpp"
#include "memory/resourceArea.hpp"
class MethodMatcher : public CHeapObj {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/cms/cmsCardTable.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/cms/cmsCardTable.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/cms/cmsHeap.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTableRS.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/space.inline.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/virtualspace.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/java.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/orderAccess.inline.hpp"
+#include "runtime/vmThread.hpp"
+
+void CardTableRS::
+non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
+ OopsInGenClosure* cl,
+ CardTableRS* ct,
+ uint n_threads) {
+ assert(n_threads > 0, "expected n_threads > 0");
+ assert(n_threads <= ParallelGCThreads,
+ "n_threads: %u > ParallelGCThreads: %u", n_threads, ParallelGCThreads);
+
+ // Make sure the LNC array is valid for the space.
+ jbyte** lowest_non_clean;
+ uintptr_t lowest_non_clean_base_chunk_index;
+ size_t lowest_non_clean_chunk_size;
+ get_LNC_array_for_space(sp, lowest_non_clean,
+ lowest_non_clean_base_chunk_index,
+ lowest_non_clean_chunk_size);
+
+ uint n_strides = n_threads * ParGCStridesPerThread;
+ SequentialSubTasksDone* pst = sp->par_seq_tasks();
+ // Sets the condition for completion of the subtask (how many threads
+ // need to finish in order to be done).
+ pst->set_n_threads(n_threads);
+ pst->set_n_tasks(n_strides);
+
+ uint stride = 0;
+ while (!pst->is_task_claimed(/* reference */ stride)) {
+ process_stride(sp, mr, stride, n_strides,
+ cl, ct,
+ lowest_non_clean,
+ lowest_non_clean_base_chunk_index,
+ lowest_non_clean_chunk_size);
+ }
+ if (pst->all_tasks_completed()) {
+ // Clear lowest_non_clean array for next time.
+ intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
+ uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
+ for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
+ intptr_t ind = ch - lowest_non_clean_base_chunk_index;
+ assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
+ "Bounds error");
+ lowest_non_clean[ind] = NULL;
+ }
+ }
+}
+
+void
+CardTableRS::
+process_stride(Space* sp,
+ MemRegion used,
+ jint stride, int n_strides,
+ OopsInGenClosure* cl,
+ CardTableRS* ct,
+ jbyte** lowest_non_clean,
+ uintptr_t lowest_non_clean_base_chunk_index,
+ size_t lowest_non_clean_chunk_size) {
+ // We go from higher to lower addresses here; it wouldn't help that much
+ // because of the strided parallelism pattern used here.
+
+ // Find the first card address of the first chunk in the stride that is
+ // at least "bottom" of the used region.
+ jbyte* start_card = byte_for(used.start());
+ jbyte* end_card = byte_after(used.last());
+ uintptr_t start_chunk = addr_to_chunk_index(used.start());
+ uintptr_t start_chunk_stride_num = start_chunk % n_strides;
+ jbyte* chunk_card_start;
+
+ if ((uintptr_t)stride >= start_chunk_stride_num) {
+ chunk_card_start = (jbyte*)(start_card +
+ (stride - start_chunk_stride_num) *
+ ParGCCardsPerStrideChunk);
+ } else {
+ // Go ahead to the next chunk group boundary, then to the requested stride.
+ chunk_card_start = (jbyte*)(start_card +
+ (n_strides - start_chunk_stride_num + stride) *
+ ParGCCardsPerStrideChunk);
+ }
+
+ while (chunk_card_start < end_card) {
+ // Even though we go from lower to higher addresses below, the
+ // strided parallelism can interleave the actual processing of the
+ // dirty pages in various ways. For a specific chunk within this
+ // stride, we take care to avoid double scanning or missing a card
+ // by suitably initializing the "min_done" field in process_chunk_boundaries()
+ // below, together with the dirty region extension accomplished in
+ // DirtyCardToOopClosure::do_MemRegion().
+ jbyte* chunk_card_end = chunk_card_start + ParGCCardsPerStrideChunk;
+ // Invariant: chunk_mr should be fully contained within the "used" region.
+ MemRegion chunk_mr = MemRegion(addr_for(chunk_card_start),
+ chunk_card_end >= end_card ?
+ used.end() : addr_for(chunk_card_end));
+ assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
+ assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
+
+ // This function is used by the parallel card table iteration.
+ const bool parallel = true;
+
+ DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(),
+ cl->gen_boundary(),
+ parallel);
+ ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
+
+
+ // Process the chunk.
+ process_chunk_boundaries(sp,
+ dcto_cl,
+ chunk_mr,
+ used,
+ lowest_non_clean,
+ lowest_non_clean_base_chunk_index,
+ lowest_non_clean_chunk_size);
+
+ // We want the LNC array updates above in process_chunk_boundaries
+ // to be visible before any of the card table value changes as a
+ // result of the dirty card iteration below.
+ OrderAccess::storestore();
+
+ // We want to clear the cards: clear_cl here does the work of finding
+ // contiguous dirty ranges of cards to process and clear.
+ clear_cl.do_MemRegion(chunk_mr);
+
+ // Find the next chunk of the stride.
+ chunk_card_start += ParGCCardsPerStrideChunk * n_strides;
+ }
+}
+
+void
+CardTableRS::
+process_chunk_boundaries(Space* sp,
+ DirtyCardToOopClosure* dcto_cl,
+ MemRegion chunk_mr,
+ MemRegion used,
+ jbyte** lowest_non_clean,
+ uintptr_t lowest_non_clean_base_chunk_index,
+ size_t lowest_non_clean_chunk_size)
+{
+ // We must worry about non-array objects that cross chunk boundaries,
+ // because such objects are both precisely and imprecisely marked:
+ // .. if the head of such an object is dirty, the entire object
+ // needs to be scanned, under the interpretation that this
+ // was an imprecise mark
+ // .. if the head of such an object is not dirty, we can assume
+ // precise marking and it's efficient to scan just the dirty
+ // cards.
+ // In either case, each scanned reference must be scanned precisely
+ // once so as to avoid cloning of a young referent. For efficiency,
+ // our closures depend on this property and do not protect against
+ // double scans.
+
+ uintptr_t start_chunk_index = addr_to_chunk_index(chunk_mr.start());
+ assert(start_chunk_index >= lowest_non_clean_base_chunk_index, "Bounds error.");
+ uintptr_t cur_chunk_index = start_chunk_index - lowest_non_clean_base_chunk_index;
+
+ // First, set "our" lowest_non_clean entry, which would be
+ // used by the thread scanning an adjoining left chunk with
+ // a non-array object straddling the mutual boundary.
+ // Find the object that spans our boundary, if one exists.
+ // first_block is the block possibly straddling our left boundary.
+ HeapWord* first_block = sp->block_start(chunk_mr.start());
+ assert((chunk_mr.start() != used.start()) || (first_block == chunk_mr.start()),
+ "First chunk should always have a co-initial block");
+ // Does the block straddle the chunk's left boundary, and is it
+ // a non-array object?
+ if (first_block < chunk_mr.start() // first block straddles left bdry
+ && sp->block_is_obj(first_block) // first block is an object
+ && !(oop(first_block)->is_objArray() // first block is not an array (arrays are precisely dirtied)
+ || oop(first_block)->is_typeArray())) {
+ // Find our least non-clean card, so that a left neighbor
+ // does not scan an object straddling the mutual boundary
+ // too far to the right, and attempt to scan a portion of
+ // that object twice.
+ jbyte* first_dirty_card = NULL;
+ jbyte* last_card_of_first_obj =
+ byte_for(first_block + sp->block_size(first_block) - 1);
+ jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
+ jbyte* last_card_of_cur_chunk = byte_for(chunk_mr.last());
+ jbyte* last_card_to_check =
+ (jbyte*) MIN2((intptr_t) last_card_of_cur_chunk,
+ (intptr_t) last_card_of_first_obj);
+ // Note that this does not need to go beyond our last card
+ // if our first object completely straddles this chunk.
+ for (jbyte* cur = first_card_of_cur_chunk;
+ cur <= last_card_to_check; cur++) {
+ jbyte val = *cur;
+ if (card_will_be_scanned(val)) {
+ first_dirty_card = cur; break;
+ } else {
+ assert(!card_may_have_been_dirty(val), "Error");
+ }
+ }
+ if (first_dirty_card != NULL) {
+ assert(cur_chunk_index < lowest_non_clean_chunk_size, "Bounds error.");
+ assert(lowest_non_clean[cur_chunk_index] == NULL,
+ "Write exactly once : value should be stable hereafter for this round");
+ lowest_non_clean[cur_chunk_index] = first_dirty_card;
+ }
+ } else {
+ // In this case we can help our neighbor by just asking them
+ // to stop at our first card (even though it may not be dirty).
+ assert(lowest_non_clean[cur_chunk_index] == NULL, "Write once : value should be stable hereafter");
+ jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
+ lowest_non_clean[cur_chunk_index] = first_card_of_cur_chunk;
+ }
+
+ // Next, set our own max_to_do, which will strictly/exclusively bound
+ // the highest address that we will scan past the right end of our chunk.
+ HeapWord* max_to_do = NULL;
+ if (chunk_mr.end() < used.end()) {
+ // This is not the last chunk in the used region.
+ // What is our last block? We check the first block of
+ // the next (right) chunk rather than strictly check our last block
+ // because it's potentially more efficient to do so.
+ HeapWord* const last_block = sp->block_start(chunk_mr.end());
+ assert(last_block <= chunk_mr.end(), "In case this property changes.");
+ if ((last_block == chunk_mr.end()) // our last block does not straddle boundary
+ || !sp->block_is_obj(last_block) // last_block isn't an object
+ || oop(last_block)->is_objArray() // last_block is an array (precisely marked)
+ || oop(last_block)->is_typeArray()) {
+ max_to_do = chunk_mr.end();
+ } else {
+ assert(last_block < chunk_mr.end(), "Tautology");
+ // It is a non-array object that straddles the right boundary of this chunk.
+ // last_obj_card is the card corresponding to the start of the last object
+ // in the chunk. Note that the last object may not start in
+ // the chunk.
+ jbyte* const last_obj_card = byte_for(last_block);
+ const jbyte val = *last_obj_card;
+ if (!card_will_be_scanned(val)) {
+ assert(!card_may_have_been_dirty(val), "Error");
+ // The card containing the head is not dirty. Any marks on
+ // subsequent cards still in this chunk must have been made
+ // precisely; we can cap processing at the end of our chunk.
+ max_to_do = chunk_mr.end();
+ } else {
+ // The last object must be considered dirty, and extends onto the
+ // following chunk. Look for a dirty card in that chunk that will
+ // bound our processing.
+ jbyte* limit_card = NULL;
+ const size_t last_block_size = sp->block_size(last_block);
+ jbyte* const last_card_of_last_obj =
+ byte_for(last_block + last_block_size - 1);
+ jbyte* const first_card_of_next_chunk = byte_for(chunk_mr.end());
+ // This search potentially goes a long distance looking
+ // for the next card that will be scanned, terminating
+ // at the end of the last_block, if no earlier dirty card
+ // is found.
+ assert(byte_for(chunk_mr.end()) - byte_for(chunk_mr.start()) == ParGCCardsPerStrideChunk,
+ "last card of next chunk may be wrong");
+ for (jbyte* cur = first_card_of_next_chunk;
+ cur <= last_card_of_last_obj; cur++) {
+ const jbyte val = *cur;
+ if (card_will_be_scanned(val)) {
+ limit_card = cur; break;
+ } else {
+ assert(!card_may_have_been_dirty(val), "Error: card can't be skipped");
+ }
+ }
+ if (limit_card != NULL) {
+ max_to_do = addr_for(limit_card);
+ assert(limit_card != NULL && max_to_do != NULL, "Error");
+ } else {
+ // The following is a pessimistic value, because it's possible
+ // that a dirty card on a subsequent chunk has been cleared by
+ // the time we get to look at it; we'll correct for that further below,
+ // using the LNC array which records the least non-clean card
+ // before cards were cleared in a particular chunk.
+ limit_card = last_card_of_last_obj;
+ max_to_do = last_block + last_block_size;
+ assert(limit_card != NULL && max_to_do != NULL, "Error");
+ }
+ assert(0 < cur_chunk_index+1 && cur_chunk_index+1 < lowest_non_clean_chunk_size,
+ "Bounds error.");
+ // It is possible that a dirty card for the last object may have been
+ // cleared before we had a chance to examine it. In that case, the value
+ // will have been logged in the LNC for that chunk.
+ // We need to examine as many chunks to the right as this object
+ // covers. However, we need to bound this checking to the largest
+ // entry in the LNC array: this is because the heap may expand
+ // after the LNC array has been created but before we reach this point,
+ // and the last block in our chunk may have been expanded to include
+ // the expansion delta (and possibly subsequently allocated from, so
+ // it wouldn't be sufficient to check whether that last block was
+ // or was not an object at this point).
+ uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
+ - lowest_non_clean_base_chunk_index;
+ const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
+ - lowest_non_clean_base_chunk_index;
+ if (last_chunk_index_to_check > last_chunk_index) {
+ assert(last_block + last_block_size > used.end(),
+ "Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
+ " does not exceed used.end() = " PTR_FORMAT ","
+ " yet last_chunk_index_to_check " INTPTR_FORMAT
+ " exceeds last_chunk_index " INTPTR_FORMAT,
+ p2i(last_block), p2i(last_block + last_block_size),
+ p2i(used.end()),
+ last_chunk_index_to_check, last_chunk_index);
+ assert(sp->used_region().end() > used.end(),
+ "Expansion did not happen: "
+ "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
+ p2i(sp->used_region().start()), p2i(sp->used_region().end()),
+ p2i(used.start()), p2i(used.end()));
+ last_chunk_index_to_check = last_chunk_index;
+ }
+ for (uintptr_t lnc_index = cur_chunk_index + 1;
+ lnc_index <= last_chunk_index_to_check;
+ lnc_index++) {
+ jbyte* lnc_card = lowest_non_clean[lnc_index];
+ if (lnc_card != NULL) {
+ // we can stop at the first non-NULL entry we find
+ if (lnc_card <= limit_card) {
+ limit_card = lnc_card;
+ max_to_do = addr_for(limit_card);
+ assert(limit_card != NULL && max_to_do != NULL, "Error");
+ }
+ // In any case, we break now
+ break;
+ } // else continue to look for a non-NULL entry if any
+ }
+ assert(limit_card != NULL && max_to_do != NULL, "Error");
+ }
+ assert(max_to_do != NULL, "OOPS 1 !");
+ }
+ assert(max_to_do != NULL, "OOPS 2!");
+ } else {
+ max_to_do = used.end();
+ }
+ assert(max_to_do != NULL, "OOPS 3!");
+ // Now we can set the closure we're using so it doesn't to beyond
+ // max_to_do.
+ dcto_cl->set_min_done(max_to_do);
+#ifndef PRODUCT
+ dcto_cl->set_last_bottom(max_to_do);
+#endif
+}
+
+void
+CardTableRS::
+get_LNC_array_for_space(Space* sp,
+ jbyte**& lowest_non_clean,
+ uintptr_t& lowest_non_clean_base_chunk_index,
+ size_t& lowest_non_clean_chunk_size) {
+
+ int i = find_covering_region_containing(sp->bottom());
+ MemRegion covered = _covered[i];
+ size_t n_chunks = chunks_to_cover(covered);
+
+ // Only the first thread to obtain the lock will resize the
+ // LNC array for the covered region. Any later expansion can't affect
+ // the used_at_save_marks region.
+ // (I observed a bug in which the first thread to execute this would
+ // resize, and then it would cause "expand_and_allocate" that would
+ // increase the number of chunks in the covered region. Then a second
+ // thread would come and execute this, see that the size didn't match,
+ // and free and allocate again. So the first thread would be using a
+ // freed "_lowest_non_clean" array.)
+
+ // Do a dirty read here. If we pass the conditional then take the rare
+ // event lock and do the read again in case some other thread had already
+ // succeeded and done the resize.
+ int cur_collection = CMSHeap::heap()->total_collections();
+ // Updated _last_LNC_resizing_collection[i] must not be visible before
+ // _lowest_non_clean and friends are visible. Therefore use acquire/release
+ // to guarantee this on non TSO architecures.
+ if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) {
+ MutexLocker x(ParGCRareEvent_lock);
+ // This load_acquire is here for clarity only. The MutexLocker already fences.
+ if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) {
+ if (_lowest_non_clean[i] == NULL ||
+ n_chunks != _lowest_non_clean_chunk_size[i]) {
+
+ // Should we delete the old?
+ if (_lowest_non_clean[i] != NULL) {
+ assert(n_chunks != _lowest_non_clean_chunk_size[i],
+ "logical consequence");
+ FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
+ _lowest_non_clean[i] = NULL;
+ }
+ // Now allocate a new one if necessary.
+ if (_lowest_non_clean[i] == NULL) {
+ _lowest_non_clean[i] = NEW_C_HEAP_ARRAY(CardPtr, n_chunks, mtGC);
+ _lowest_non_clean_chunk_size[i] = n_chunks;
+ _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
+ for (int j = 0; j < (int)n_chunks; j++)
+ _lowest_non_clean[i][j] = NULL;
+ }
+ }
+ // Make sure this gets visible only after _lowest_non_clean* was initialized
+ OrderAccess::release_store(&_last_LNC_resizing_collection[i], cur_collection);
+ }
+ }
+ // In any case, now do the initialization.
+ lowest_non_clean = _lowest_non_clean[i];
+ lowest_non_clean_base_chunk_index = _lowest_non_clean_base_chunk_index[i];
+ lowest_non_clean_chunk_size = _lowest_non_clean_chunk_size[i];
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,6 @@
#include "gc/shared/gcId.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/cms/parCardTableModRefBS.cpp
--- a/src/hotspot/share/gc/cms/parCardTableModRefBS.cpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,432 +0,0 @@
-/*
- * Copyright (c) 2007, 2018, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/cms/cmsHeap.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
-#include "gc/shared/cardTableRS.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "gc/shared/space.inline.hpp"
-#include "memory/allocation.inline.hpp"
-#include "memory/virtualspace.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/java.hpp"
-#include "runtime/mutexLocker.hpp"
-#include "runtime/orderAccess.inline.hpp"
-#include "runtime/vmThread.hpp"
-
-void CardTableRS::
-non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
- OopsInGenClosure* cl,
- CardTableRS* ct,
- uint n_threads) {
- assert(n_threads > 0, "expected n_threads > 0");
- assert(n_threads <= ParallelGCThreads,
- "n_threads: %u > ParallelGCThreads: %u", n_threads, ParallelGCThreads);
-
- // Make sure the LNC array is valid for the space.
- jbyte** lowest_non_clean;
- uintptr_t lowest_non_clean_base_chunk_index;
- size_t lowest_non_clean_chunk_size;
- get_LNC_array_for_space(sp, lowest_non_clean,
- lowest_non_clean_base_chunk_index,
- lowest_non_clean_chunk_size);
-
- uint n_strides = n_threads * ParGCStridesPerThread;
- SequentialSubTasksDone* pst = sp->par_seq_tasks();
- // Sets the condition for completion of the subtask (how many threads
- // need to finish in order to be done).
- pst->set_n_threads(n_threads);
- pst->set_n_tasks(n_strides);
-
- uint stride = 0;
- while (!pst->is_task_claimed(/* reference */ stride)) {
- process_stride(sp, mr, stride, n_strides,
- cl, ct,
- lowest_non_clean,
- lowest_non_clean_base_chunk_index,
- lowest_non_clean_chunk_size);
- }
- if (pst->all_tasks_completed()) {
- // Clear lowest_non_clean array for next time.
- intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
- uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
- for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
- intptr_t ind = ch - lowest_non_clean_base_chunk_index;
- assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
- "Bounds error");
- lowest_non_clean[ind] = NULL;
- }
- }
-}
-
-void
-CardTableRS::
-process_stride(Space* sp,
- MemRegion used,
- jint stride, int n_strides,
- OopsInGenClosure* cl,
- CardTableRS* ct,
- jbyte** lowest_non_clean,
- uintptr_t lowest_non_clean_base_chunk_index,
- size_t lowest_non_clean_chunk_size) {
- // We go from higher to lower addresses here; it wouldn't help that much
- // because of the strided parallelism pattern used here.
-
- // Find the first card address of the first chunk in the stride that is
- // at least "bottom" of the used region.
- jbyte* start_card = byte_for(used.start());
- jbyte* end_card = byte_after(used.last());
- uintptr_t start_chunk = addr_to_chunk_index(used.start());
- uintptr_t start_chunk_stride_num = start_chunk % n_strides;
- jbyte* chunk_card_start;
-
- if ((uintptr_t)stride >= start_chunk_stride_num) {
- chunk_card_start = (jbyte*)(start_card +
- (stride - start_chunk_stride_num) *
- ParGCCardsPerStrideChunk);
- } else {
- // Go ahead to the next chunk group boundary, then to the requested stride.
- chunk_card_start = (jbyte*)(start_card +
- (n_strides - start_chunk_stride_num + stride) *
- ParGCCardsPerStrideChunk);
- }
-
- while (chunk_card_start < end_card) {
- // Even though we go from lower to higher addresses below, the
- // strided parallelism can interleave the actual processing of the
- // dirty pages in various ways. For a specific chunk within this
- // stride, we take care to avoid double scanning or missing a card
- // by suitably initializing the "min_done" field in process_chunk_boundaries()
- // below, together with the dirty region extension accomplished in
- // DirtyCardToOopClosure::do_MemRegion().
- jbyte* chunk_card_end = chunk_card_start + ParGCCardsPerStrideChunk;
- // Invariant: chunk_mr should be fully contained within the "used" region.
- MemRegion chunk_mr = MemRegion(addr_for(chunk_card_start),
- chunk_card_end >= end_card ?
- used.end() : addr_for(chunk_card_end));
- assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
- assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
-
- // This function is used by the parallel card table iteration.
- const bool parallel = true;
-
- DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(),
- cl->gen_boundary(),
- parallel);
- ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
-
-
- // Process the chunk.
- process_chunk_boundaries(sp,
- dcto_cl,
- chunk_mr,
- used,
- lowest_non_clean,
- lowest_non_clean_base_chunk_index,
- lowest_non_clean_chunk_size);
-
- // We want the LNC array updates above in process_chunk_boundaries
- // to be visible before any of the card table value changes as a
- // result of the dirty card iteration below.
- OrderAccess::storestore();
-
- // We want to clear the cards: clear_cl here does the work of finding
- // contiguous dirty ranges of cards to process and clear.
- clear_cl.do_MemRegion(chunk_mr);
-
- // Find the next chunk of the stride.
- chunk_card_start += ParGCCardsPerStrideChunk * n_strides;
- }
-}
-
-void
-CardTableRS::
-process_chunk_boundaries(Space* sp,
- DirtyCardToOopClosure* dcto_cl,
- MemRegion chunk_mr,
- MemRegion used,
- jbyte** lowest_non_clean,
- uintptr_t lowest_non_clean_base_chunk_index,
- size_t lowest_non_clean_chunk_size)
-{
- // We must worry about non-array objects that cross chunk boundaries,
- // because such objects are both precisely and imprecisely marked:
- // .. if the head of such an object is dirty, the entire object
- // needs to be scanned, under the interpretation that this
- // was an imprecise mark
- // .. if the head of such an object is not dirty, we can assume
- // precise marking and it's efficient to scan just the dirty
- // cards.
- // In either case, each scanned reference must be scanned precisely
- // once so as to avoid cloning of a young referent. For efficiency,
- // our closures depend on this property and do not protect against
- // double scans.
-
- uintptr_t start_chunk_index = addr_to_chunk_index(chunk_mr.start());
- assert(start_chunk_index >= lowest_non_clean_base_chunk_index, "Bounds error.");
- uintptr_t cur_chunk_index = start_chunk_index - lowest_non_clean_base_chunk_index;
-
- // First, set "our" lowest_non_clean entry, which would be
- // used by the thread scanning an adjoining left chunk with
- // a non-array object straddling the mutual boundary.
- // Find the object that spans our boundary, if one exists.
- // first_block is the block possibly straddling our left boundary.
- HeapWord* first_block = sp->block_start(chunk_mr.start());
- assert((chunk_mr.start() != used.start()) || (first_block == chunk_mr.start()),
- "First chunk should always have a co-initial block");
- // Does the block straddle the chunk's left boundary, and is it
- // a non-array object?
- if (first_block < chunk_mr.start() // first block straddles left bdry
- && sp->block_is_obj(first_block) // first block is an object
- && !(oop(first_block)->is_objArray() // first block is not an array (arrays are precisely dirtied)
- || oop(first_block)->is_typeArray())) {
- // Find our least non-clean card, so that a left neighbor
- // does not scan an object straddling the mutual boundary
- // too far to the right, and attempt to scan a portion of
- // that object twice.
- jbyte* first_dirty_card = NULL;
- jbyte* last_card_of_first_obj =
- byte_for(first_block + sp->block_size(first_block) - 1);
- jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
- jbyte* last_card_of_cur_chunk = byte_for(chunk_mr.last());
- jbyte* last_card_to_check =
- (jbyte*) MIN2((intptr_t) last_card_of_cur_chunk,
- (intptr_t) last_card_of_first_obj);
- // Note that this does not need to go beyond our last card
- // if our first object completely straddles this chunk.
- for (jbyte* cur = first_card_of_cur_chunk;
- cur <= last_card_to_check; cur++) {
- jbyte val = *cur;
- if (card_will_be_scanned(val)) {
- first_dirty_card = cur; break;
- } else {
- assert(!card_may_have_been_dirty(val), "Error");
- }
- }
- if (first_dirty_card != NULL) {
- assert(cur_chunk_index < lowest_non_clean_chunk_size, "Bounds error.");
- assert(lowest_non_clean[cur_chunk_index] == NULL,
- "Write exactly once : value should be stable hereafter for this round");
- lowest_non_clean[cur_chunk_index] = first_dirty_card;
- }
- } else {
- // In this case we can help our neighbor by just asking them
- // to stop at our first card (even though it may not be dirty).
- assert(lowest_non_clean[cur_chunk_index] == NULL, "Write once : value should be stable hereafter");
- jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
- lowest_non_clean[cur_chunk_index] = first_card_of_cur_chunk;
- }
-
- // Next, set our own max_to_do, which will strictly/exclusively bound
- // the highest address that we will scan past the right end of our chunk.
- HeapWord* max_to_do = NULL;
- if (chunk_mr.end() < used.end()) {
- // This is not the last chunk in the used region.
- // What is our last block? We check the first block of
- // the next (right) chunk rather than strictly check our last block
- // because it's potentially more efficient to do so.
- HeapWord* const last_block = sp->block_start(chunk_mr.end());
- assert(last_block <= chunk_mr.end(), "In case this property changes.");
- if ((last_block == chunk_mr.end()) // our last block does not straddle boundary
- || !sp->block_is_obj(last_block) // last_block isn't an object
- || oop(last_block)->is_objArray() // last_block is an array (precisely marked)
- || oop(last_block)->is_typeArray()) {
- max_to_do = chunk_mr.end();
- } else {
- assert(last_block < chunk_mr.end(), "Tautology");
- // It is a non-array object that straddles the right boundary of this chunk.
- // last_obj_card is the card corresponding to the start of the last object
- // in the chunk. Note that the last object may not start in
- // the chunk.
- jbyte* const last_obj_card = byte_for(last_block);
- const jbyte val = *last_obj_card;
- if (!card_will_be_scanned(val)) {
- assert(!card_may_have_been_dirty(val), "Error");
- // The card containing the head is not dirty. Any marks on
- // subsequent cards still in this chunk must have been made
- // precisely; we can cap processing at the end of our chunk.
- max_to_do = chunk_mr.end();
- } else {
- // The last object must be considered dirty, and extends onto the
- // following chunk. Look for a dirty card in that chunk that will
- // bound our processing.
- jbyte* limit_card = NULL;
- const size_t last_block_size = sp->block_size(last_block);
- jbyte* const last_card_of_last_obj =
- byte_for(last_block + last_block_size - 1);
- jbyte* const first_card_of_next_chunk = byte_for(chunk_mr.end());
- // This search potentially goes a long distance looking
- // for the next card that will be scanned, terminating
- // at the end of the last_block, if no earlier dirty card
- // is found.
- assert(byte_for(chunk_mr.end()) - byte_for(chunk_mr.start()) == ParGCCardsPerStrideChunk,
- "last card of next chunk may be wrong");
- for (jbyte* cur = first_card_of_next_chunk;
- cur <= last_card_of_last_obj; cur++) {
- const jbyte val = *cur;
- if (card_will_be_scanned(val)) {
- limit_card = cur; break;
- } else {
- assert(!card_may_have_been_dirty(val), "Error: card can't be skipped");
- }
- }
- if (limit_card != NULL) {
- max_to_do = addr_for(limit_card);
- assert(limit_card != NULL && max_to_do != NULL, "Error");
- } else {
- // The following is a pessimistic value, because it's possible
- // that a dirty card on a subsequent chunk has been cleared by
- // the time we get to look at it; we'll correct for that further below,
- // using the LNC array which records the least non-clean card
- // before cards were cleared in a particular chunk.
- limit_card = last_card_of_last_obj;
- max_to_do = last_block + last_block_size;
- assert(limit_card != NULL && max_to_do != NULL, "Error");
- }
- assert(0 < cur_chunk_index+1 && cur_chunk_index+1 < lowest_non_clean_chunk_size,
- "Bounds error.");
- // It is possible that a dirty card for the last object may have been
- // cleared before we had a chance to examine it. In that case, the value
- // will have been logged in the LNC for that chunk.
- // We need to examine as many chunks to the right as this object
- // covers. However, we need to bound this checking to the largest
- // entry in the LNC array: this is because the heap may expand
- // after the LNC array has been created but before we reach this point,
- // and the last block in our chunk may have been expanded to include
- // the expansion delta (and possibly subsequently allocated from, so
- // it wouldn't be sufficient to check whether that last block was
- // or was not an object at this point).
- uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
- - lowest_non_clean_base_chunk_index;
- const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
- - lowest_non_clean_base_chunk_index;
- if (last_chunk_index_to_check > last_chunk_index) {
- assert(last_block + last_block_size > used.end(),
- "Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
- " does not exceed used.end() = " PTR_FORMAT ","
- " yet last_chunk_index_to_check " INTPTR_FORMAT
- " exceeds last_chunk_index " INTPTR_FORMAT,
- p2i(last_block), p2i(last_block + last_block_size),
- p2i(used.end()),
- last_chunk_index_to_check, last_chunk_index);
- assert(sp->used_region().end() > used.end(),
- "Expansion did not happen: "
- "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
- p2i(sp->used_region().start()), p2i(sp->used_region().end()),
- p2i(used.start()), p2i(used.end()));
- last_chunk_index_to_check = last_chunk_index;
- }
- for (uintptr_t lnc_index = cur_chunk_index + 1;
- lnc_index <= last_chunk_index_to_check;
- lnc_index++) {
- jbyte* lnc_card = lowest_non_clean[lnc_index];
- if (lnc_card != NULL) {
- // we can stop at the first non-NULL entry we find
- if (lnc_card <= limit_card) {
- limit_card = lnc_card;
- max_to_do = addr_for(limit_card);
- assert(limit_card != NULL && max_to_do != NULL, "Error");
- }
- // In any case, we break now
- break;
- } // else continue to look for a non-NULL entry if any
- }
- assert(limit_card != NULL && max_to_do != NULL, "Error");
- }
- assert(max_to_do != NULL, "OOPS 1 !");
- }
- assert(max_to_do != NULL, "OOPS 2!");
- } else {
- max_to_do = used.end();
- }
- assert(max_to_do != NULL, "OOPS 3!");
- // Now we can set the closure we're using so it doesn't to beyond
- // max_to_do.
- dcto_cl->set_min_done(max_to_do);
-#ifndef PRODUCT
- dcto_cl->set_last_bottom(max_to_do);
-#endif
-}
-
-void
-CardTableRS::
-get_LNC_array_for_space(Space* sp,
- jbyte**& lowest_non_clean,
- uintptr_t& lowest_non_clean_base_chunk_index,
- size_t& lowest_non_clean_chunk_size) {
-
- int i = find_covering_region_containing(sp->bottom());
- MemRegion covered = _covered[i];
- size_t n_chunks = chunks_to_cover(covered);
-
- // Only the first thread to obtain the lock will resize the
- // LNC array for the covered region. Any later expansion can't affect
- // the used_at_save_marks region.
- // (I observed a bug in which the first thread to execute this would
- // resize, and then it would cause "expand_and_allocate" that would
- // increase the number of chunks in the covered region. Then a second
- // thread would come and execute this, see that the size didn't match,
- // and free and allocate again. So the first thread would be using a
- // freed "_lowest_non_clean" array.)
-
- // Do a dirty read here. If we pass the conditional then take the rare
- // event lock and do the read again in case some other thread had already
- // succeeded and done the resize.
- int cur_collection = CMSHeap::heap()->total_collections();
- // Updated _last_LNC_resizing_collection[i] must not be visible before
- // _lowest_non_clean and friends are visible. Therefore use acquire/release
- // to guarantee this on non TSO architecures.
- if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) {
- MutexLocker x(ParGCRareEvent_lock);
- // This load_acquire is here for clarity only. The MutexLocker already fences.
- if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) {
- if (_lowest_non_clean[i] == NULL ||
- n_chunks != _lowest_non_clean_chunk_size[i]) {
-
- // Should we delete the old?
- if (_lowest_non_clean[i] != NULL) {
- assert(n_chunks != _lowest_non_clean_chunk_size[i],
- "logical consequence");
- FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
- _lowest_non_clean[i] = NULL;
- }
- // Now allocate a new one if necessary.
- if (_lowest_non_clean[i] == NULL) {
- _lowest_non_clean[i] = NEW_C_HEAP_ARRAY(CardPtr, n_chunks, mtGC);
- _lowest_non_clean_chunk_size[i] = n_chunks;
- _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
- for (int j = 0; j < (int)n_chunks; j++)
- _lowest_non_clean[i][j] = NULL;
- }
- }
- // Make sure this gets visible only after _lowest_non_clean* was initialized
- OrderAccess::release_store(&_last_LNC_resizing_collection[i], cur_collection);
- }
- }
- // In any case, now do the initialization.
- lowest_non_clean = _lowest_non_clean[i];
- lowest_non_clean_base_chunk_index = _lowest_non_clean_base_chunk_index[i];
- lowest_non_clean_chunk_size = _lowest_non_clean_chunk_size[i];
-}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/cms/vmCMSOperations.cpp
--- a/src/hotspot/share/gc/cms/vmCMSOperations.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/cms/vmCMSOperations.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,8 @@
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.hpp"
#include "utilities/dtrace.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1BarrierSet.cpp
--- a/src/hotspot/share/gc/g1/g1BarrierSet.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/g1/g1BarrierSet.inline.hpp"
+#include "gc/g1/g1BarrierSetAssembler.hpp"
#include "gc/g1/g1CardTable.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -32,9 +33,12 @@
#include "oops/oop.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
+#include "utilities/macros.hpp"
G1BarrierSet::G1BarrierSet(G1CardTable* card_table) :
- CardTableModRefBS(card_table, BarrierSet::FakeRtti(BarrierSet::G1BarrierSet)),
+ CardTableBarrierSet(make_barrier_set_assembler(),
+ card_table,
+ BarrierSet::FakeRtti(BarrierSet::G1BarrierSet)),
_dcqs(JavaThread::dirty_card_queue_set())
{ }
@@ -53,11 +57,26 @@
}
}
+void G1BarrierSet::write_ref_array_pre_oop_entry(oop* dst, size_t length) {
+ G1BarrierSet *bs = barrier_set_cast(BarrierSet::barrier_set());
+ bs->write_ref_array_pre(dst, length, false);
+}
+
+void G1BarrierSet::write_ref_array_pre_narrow_oop_entry(narrowOop* dst, size_t length) {
+ G1BarrierSet *bs = barrier_set_cast(BarrierSet::barrier_set());
+ bs->write_ref_array_pre(dst, length, false);
+}
+
+void G1BarrierSet::write_ref_array_post_entry(HeapWord* dst, size_t length) {
+ G1BarrierSet *bs = barrier_set_cast(BarrierSet::barrier_set());
+ bs->G1BarrierSet::write_ref_array(dst, length);
+}
+
template void
-G1BarrierSet::write_ref_array_pre_work(T* dst, int count) {
+G1BarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
if (!JavaThread::satb_mark_queue_set().is_active()) return;
T* elem_ptr = dst;
- for (int i = 0; i < count; i++, elem_ptr++) {
+ for (size_t i = 0; i < count; i++, elem_ptr++) {
T heap_oop = oopDesc::load_heap_oop(elem_ptr);
if (!oopDesc::is_null(heap_oop)) {
enqueue(oopDesc::decode_heap_oop_not_null(heap_oop));
@@ -65,13 +84,13 @@
}
}
-void G1BarrierSet::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
+void G1BarrierSet::write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized) {
if (!dest_uninitialized) {
write_ref_array_pre_work(dst, count);
}
}
-void G1BarrierSet::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
+void G1BarrierSet::write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized) {
if (!dest_uninitialized) {
write_ref_array_pre_work(dst, count);
}
@@ -167,7 +186,7 @@
void G1BarrierSet::on_thread_detach(JavaThread* thread) {
// Flush any deferred card marks, SATB buffers and dirty card queue buffers
- CardTableModRefBS::on_thread_detach(thread);
+ CardTableBarrierSet::on_thread_detach(thread);
thread->satb_mark_queue().flush();
thread->dirty_card_queue().flush();
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1BarrierSet.hpp
--- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_GC_G1_G1BARRIERSET_HPP
#define SHARE_VM_GC_G1_G1BARRIERSET_HPP
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
class DirtyCardQueueSet;
class CardTable;
@@ -34,7 +34,7 @@
// This barrier is specialized to use a logging barrier to support
// snapshot-at-the-beginning marking.
-class G1BarrierSet: public CardTableModRefBS {
+class G1BarrierSet: public CardTableBarrierSet {
friend class VMStructs;
private:
DirtyCardQueueSet& _dcqs;
@@ -49,9 +49,13 @@
static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
- template void write_ref_array_pre_work(T* dst, int count);
- virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized);
- virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized);
+ template void write_ref_array_pre_work(T* dst, size_t count);
+ virtual void write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized);
+ virtual void write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized);
+
+ static void write_ref_array_pre_oop_entry(oop* dst, size_t length);
+ static void write_ref_array_pre_narrow_oop_entry(narrowOop* dst, size_t length);
+ static void write_ref_array_post_entry(HeapWord* dst, size_t length);
template
void write_ref_field_pre(T* field);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1BarrierSetAssembler.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1BarrierSetAssembler.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_G1BARRIERSETASSEMBLER_HPP
+#define SHARE_GC_SHARED_G1BARRIERSETASSEMBLER_HPP
+
+#include "utilities/macros.hpp"
+
+#include CPU_HEADER(gc/g1/g1BarrierSetAssembler)
+
+#endif // SHARE_GC_SHARED_G1BARRIERSETASSEMBLER_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1CardCounts.cpp
--- a/src/hotspot/share/gc/g1/g1CardCounts.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CardCounts.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "gc/g1/g1CardCounts.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "services/memTracker.hpp"
#include "utilities/copy.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1CardCounts.hpp
--- a/src/hotspot/share/gc/g1/g1CardCounts.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CardCounts.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "memory/virtualspace.hpp"
#include "utilities/globalDefinitions.hpp"
-class CardTableModRefBS;
+class CardTableBarrierSet;
class G1CardCounts;
class G1CollectedHeap;
class G1RegionToSpaceMapper;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp
--- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -107,6 +107,11 @@
const int stride = MIN2(len - beg_index, (int) ObjArrayMarkingStride);
const int end_index = beg_index + stride;
+ // Push the continuation first to allow more efficient work stealing.
+ if (end_index < len) {
+ push_objarray(array, end_index);
+ }
+
array->oop_iterate_range(mark_closure(), beg_index, end_index);
if (VerifyDuringGC) {
@@ -117,10 +122,6 @@
assert(false, "Failed");
}
}
-
- if (end_index < len) {
- push_objarray(array, end_index); // Push the continuation.
- }
}
inline void G1FullGCMarker::follow_object(oop obj) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1Policy.hpp
--- a/src/hotspot/share/gc/g1/g1Policy.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -161,7 +161,7 @@
double accum_yg_surv_rate_pred(int age) const;
-protected:
+private:
G1CollectionSet* _collection_set;
double average_time_ms(G1GCPhaseTimes::GCParPhases phase) const;
double other_time_ms(double pause_time_ms) const;
@@ -171,7 +171,6 @@
double constant_other_time_ms(double pause_time_ms) const;
CollectionSetChooser* cset_chooser() const;
-private:
// The number of bytes copied during the GC.
size_t _bytes_copied_during_gc;
@@ -399,7 +398,6 @@
AgeTable _survivors_age_table;
-protected:
size_t desired_survivor_size() const;
public:
uint tenuring_threshold() const { return _tenuring_threshold; }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/g1RemSet.hpp
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -37,7 +37,7 @@
// collection set.
class BitMap;
-class CardTableModRefBS;
+class CardTableBarrierSet;
class G1BlockOffsetTable;
class CodeBlobClosure;
class G1CollectedHeap;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/sparsePRT.cpp
--- a/src/hotspot/share/gc/g1/sparsePRT.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/sparsePRT.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "gc/g1/heapRegionBounds.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/sparsePRT.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/space.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/atomic.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/sparsePRT.hpp
--- a/src/hotspot/share/gc/g1/sparsePRT.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/sparsePRT.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/g1/heapRegion.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/vmStructs_g1.hpp
--- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -73,8 +73,13 @@
#define VM_INT_CONSTANTS_G1(declare_constant, declare_constant_with_value) \
declare_constant(HeapRegionType::FreeTag) \
declare_constant(HeapRegionType::YoungMask) \
+ declare_constant(HeapRegionType::EdenTag) \
+ declare_constant(HeapRegionType::SurvTag) \
declare_constant(HeapRegionType::HumongousMask) \
declare_constant(HeapRegionType::PinnedMask) \
+ declare_constant(HeapRegionType::ArchiveMask) \
+ declare_constant(HeapRegionType::StartsHumongousTag) \
+ declare_constant(HeapRegionType::ContinuesHumongousTag) \
declare_constant(HeapRegionType::OldMask)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/g1/vm_operations_g1.cpp
--- a/src/hotspot/share/gc/g1/vm_operations_g1.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/g1/vm_operations_g1.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
void VM_G1CollectFull::doit() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/asPSOldGen.cpp
--- a/src/hotspot/share/gc/parallel/asPSOldGen.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/asPSOldGen.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psAdaptiveSizePolicy.hpp"
#include "gc/parallel/psMarkSweepDecorator.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/objectStartArray.cpp
--- a/src/hotspot/share/gc/parallel/objectStartArray.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "gc/parallel/objectStartArray.inline.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -71,7 +71,7 @@
PSCardTable* card_table = new PSCardTable(reserved_region());
card_table->initialize();
- CardTableModRefBS* const barrier_set = new CardTableModRefBS(card_table);
+ CardTableBarrierSet* const barrier_set = new CardTableBarrierSet(card_table);
barrier_set->initialize();
set_barrier_set(barrier_set);
@@ -626,8 +626,8 @@
return (ParallelScavengeHeap*)heap;
}
-CardTableModRefBS* ParallelScavengeHeap::barrier_set() {
- return barrier_set_cast(CollectedHeap::barrier_set());
+CardTableBarrierSet* ParallelScavengeHeap::barrier_set() {
+ return barrier_set_cast(CollectedHeap::barrier_set());
}
PSCardTable* ParallelScavengeHeap::card_table() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,7 @@
#include "gc/parallel/psGCAdaptivePolicyCounters.hpp"
#include "gc/parallel/psOldGen.hpp"
#include "gc/parallel/psYoungGen.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcPolicyCounters.hpp"
@@ -127,7 +127,7 @@
static GCTaskManager* const gc_task_manager() { return _gc_task_manager; }
- CardTableModRefBS* barrier_set();
+ CardTableBarrierSet* barrier_set();
PSCardTable* card_table();
AdjoiningGenerations* gens() { return _gens; }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/psCardTable.cpp
--- a/src/hotspot/share/gc/parallel/psCardTable.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psCardTable.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -392,10 +392,10 @@
// Assumes that only the base or the end changes. This allows indentification
// of the region that is being resized. The
-// CardTableModRefBS::resize_covered_region() is used for the normal case
+// CardTable::resize_covered_region() is used for the normal case
// where the covered regions are growing or shrinking at the high end.
// The method resize_covered_region_by_end() is analogous to
-// CardTableModRefBS::resize_covered_region() but
+// CardTable::resize_covered_region() but
// for regions that grow or shrink at the low end.
void PSCardTable::resize_covered_region(MemRegion new_region) {
for (int i = 0; i < _cur_covered_regions; i++) {
@@ -463,7 +463,7 @@
resize_update_covered_table(changed_region, new_region);
int ind = changed_region;
- log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
+ log_trace(gc, barrier)("CardTable::resize_covered_region: ");
log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/psOldGen.cpp
--- a/src/hotspot/share/gc/parallel/psOldGen.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psOldGen.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "gc/parallel/psCardTable.hpp"
#include "gc/parallel/psMarkSweepDecorator.hpp"
#include "gc/parallel/psOldGen.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/spaceDecorator.hpp"
#include "logging/log.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/parallel/psParallelCompact.hpp
--- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -950,19 +950,7 @@
ParCompactionManager* _cm;
};
- class AdjustKlassClosure : public KlassClosure {
- public:
- AdjustKlassClosure(ParCompactionManager* cm) {
- assert(cm != NULL, "associate ParCompactionManage should not be NULL");
- _cm = cm;
- }
- void do_klass(Klass* klass);
- private:
- ParCompactionManager* _cm;
- };
-
friend class AdjustPointerClosure;
- friend class AdjustKlassClosure;
friend class RefProcTaskProxy;
friend class PSParallelCompactTest;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSet.cpp
--- a/src/hotspot/share/gc/shared/barrierSet.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/barrierSet.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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,24 +23,6 @@
*/
#include "precompiled.hpp"
-#include "gc/shared/barrierSet.inline.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "memory/universe.hpp"
+#include "gc/shared/barrierSet.hpp"
BarrierSet* BarrierSet::_bs = NULL;
-
-// count is number of array elements being written
-void BarrierSet::static_write_ref_array_pre(HeapWord* start, size_t count) {
- assert(count <= (size_t)max_intx, "count too large");
- if (UseCompressedOops) {
- Universe::heap()->barrier_set()->write_ref_array_pre((narrowOop*)start, (int)count, false);
- } else {
- Universe::heap()->barrier_set()->write_ref_array_pre( (oop*)start, (int)count, false);
- }
-}
-
-// count is number of array elements being written
-void BarrierSet::static_write_ref_array_post(HeapWord* start, size_t count) {
- // simply delegate to instance method
- Universe::heap()->barrier_set()->write_ref_array(start, count);
-}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSet.hpp
--- a/src/hotspot/share/gc/shared/barrierSet.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,8 +31,10 @@
#include "oops/accessBackend.hpp"
#include "oops/oopsHierarchy.hpp"
#include "utilities/fakeRttiSupport.hpp"
+#include "utilities/macros.hpp"
class JavaThread;
+class BarrierSetAssembler;
// This class provides the interface between a barrier implementation and
// the rest of the system.
@@ -67,6 +69,7 @@
private:
FakeRtti _fake_rtti;
+ BarrierSetAssembler* _barrier_set_assembler;
public:
// Metafunction mapping a class derived from BarrierSet to the
@@ -87,28 +90,17 @@
// End of fake RTTI support.
protected:
- BarrierSet(const FakeRtti& fake_rtti) : _fake_rtti(fake_rtti) { }
+ BarrierSet(BarrierSetAssembler* barrier_set_assembler, const FakeRtti& fake_rtti) :
+ _fake_rtti(fake_rtti),
+ _barrier_set_assembler(barrier_set_assembler) { }
~BarrierSet() { }
+ template
+ BarrierSetAssembler* make_barrier_set_assembler() {
+ return NOT_ZERO(new BarrierSetAssemblerT()) ZERO_ONLY(NULL);
+ }
+
public:
- // Operations on arrays, or general regions (e.g., for "clone") may be
- // optimized by some barriers.
-
- // Below length is the # array elements being written
- virtual void write_ref_array_pre(oop* dst, int length,
- bool dest_uninitialized = false) {}
- virtual void write_ref_array_pre(narrowOop* dst, int length,
- bool dest_uninitialized = false) {}
- // Below count is the # array elements being written, starting
- // at the address "start", which may not necessarily be HeapWord-aligned
- inline void write_ref_array(HeapWord* start, size_t count);
-
- // Static versions, suitable for calling from generated code;
- // count is # array elements being written, starting with "start",
- // which may not necessarily be HeapWord-aligned.
- static void static_write_ref_array_pre(HeapWord* start, size_t count);
- static void static_write_ref_array_post(HeapWord* start, size_t count);
-
// Support for optimizing compilers to call the barrier set on slow path allocations
// that did not enter a TLAB. Used for e.g. ReduceInitialCardMarks.
// The allocation is safe to use iff it returns true. If not, the slow-path allocation
@@ -119,15 +111,17 @@
virtual void on_thread_detach(JavaThread* thread) {}
virtual void make_parsable(JavaThread* thread) {}
-protected:
- virtual void write_ref_array_work(MemRegion mr) = 0;
-
public:
// Print a description of the memory for the barrier set
virtual void print_on(outputStream* st) const = 0;
static void set_bs(BarrierSet* bs) { _bs = bs; }
+ BarrierSetAssembler* barrier_set_assembler() {
+ assert(_barrier_set_assembler != NULL, "should be set");
+ return _barrier_set_assembler;
+ }
+
// The AccessBarrier of a BarrierSet subclass is called by the Access API
// (cf. oops/access.hpp) to perform decorated accesses. GC implementations
// may override these default access operations by declaring an
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSet.inline.hpp
--- a/src/hotspot/share/gc/shared/barrierSet.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
-#define SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
-
-#include "gc/shared/barrierSet.hpp"
-#include "utilities/align.hpp"
-
-// count is number of array elements being written
-void BarrierSet::write_ref_array(HeapWord* start, size_t count) {
- assert(count <= (size_t)max_intx, "count too large");
- HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
- // In the case of compressed oops, start and end may potentially be misaligned;
- // so we need to conservatively align the first downward (this is not
- // strictly necessary for current uses, but a case of good hygiene and,
- // if you will, aesthetics) and the second upward (this is essential for
- // current uses) to a HeapWord boundary, so we mark all cards overlapping
- // this write. If this evolves in the future to calling a
- // logging barrier of narrow oop granularity, like the pre-barrier for G1
- // (mentioned here merely by way of example), we will need to change this
- // interface, so it is "exactly precise" (if i may be allowed the adverbial
- // redundancy for emphasis) and does not include narrow oop slots not
- // included in the original write interval.
- HeapWord* aligned_start = align_down(start, HeapWordSize);
- HeapWord* aligned_end = align_up (end, HeapWordSize);
- // If compressed oops were not being used, these should already be aligned
- assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
- "Expected heap word alignment of start and end");
- write_ref_array_work(MemRegion(aligned_start, aligned_end));
-}
-
-#endif // SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSetAssembler.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/barrierSetAssembler.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_BARRIERSETASSEMBLER_HPP
+#define SHARE_GC_SHARED_BARRIERSETASSEMBLER_HPP
+
+#include "utilities/macros.hpp"
+
+#include CPU_HEADER(gc/shared/barrierSetAssembler)
+
+#endif // SHARE_GC_SHARED_BARRIERSETASSEMBLER_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSetConfig.hpp
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -36,7 +36,7 @@
// Do something for each concrete barrier set part of the build.
#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \
- f(CardTableModRef) \
+ f(CardTableBarrierSet) \
FOR_EACH_CONCRETE_INCLUDE_ALL_GC_BARRIER_SET_DO(f)
#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp
--- a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "gc/shared/barrierSetConfig.hpp"
#include "gc/shared/modRefBarrierSet.inline.hpp"
-#include "gc/shared/cardTableModRefBS.inline.hpp"
+#include "gc/shared/cardTableBarrierSet.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1BarrierSet.inline.hpp" // G1 support
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTable.hpp
--- a/src/hotspot/share/gc/shared/cardTable.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/cardTable.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -87,7 +87,7 @@
MemRegion committed_unique_to_self(int self, MemRegion mr) const;
// Some barrier sets create tables whose elements correspond to parts of
- // the heap; the CardTableModRefBS is an example. Such barrier sets will
+ // the heap; the CardTableBarrierSet is an example. Such barrier sets will
// normally reserve space for such tables, and commit parts of the table
// "covering" parts of the heap that are committed. At most one covered
// region per generation is needed.
@@ -114,7 +114,7 @@
virtual ~CardTable();
virtual void initialize();
- // The kinds of precision a CardTableModRefBS may offer.
+ // The kinds of precision a CardTable may offer.
enum PrecisionStyle {
Precise,
ObjHeadPreciseArray
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableBarrierSet.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2000, 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/cardTableBarrierSetAssembler.hpp"
+#include "gc/shared/cardTableBarrierSet.inline.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/space.inline.hpp"
+#include "logging/log.hpp"
+#include "memory/virtualspace.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/thread.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/align.hpp"
+#include "utilities/macros.hpp"
+
+// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
+// enumerate ref fields that have been modified (since the last
+// enumeration.)
+
+CardTableBarrierSet::CardTableBarrierSet(BarrierSetAssembler* barrier_set_assembler,
+ CardTable* card_table,
+ const BarrierSet::FakeRtti& fake_rtti) :
+ ModRefBarrierSet(barrier_set_assembler,
+ fake_rtti.add_tag(BarrierSet::CardTableBarrierSet)),
+ _defer_initial_card_mark(false),
+ _card_table(card_table)
+{}
+
+CardTableBarrierSet::CardTableBarrierSet(CardTable* card_table) :
+ ModRefBarrierSet(make_barrier_set_assembler(),
+ BarrierSet::FakeRtti(BarrierSet::CardTableBarrierSet)),
+ _defer_initial_card_mark(false),
+ _card_table(card_table)
+{}
+
+void CardTableBarrierSet::initialize() {
+ initialize_deferred_card_mark_barriers();
+}
+
+CardTableBarrierSet::~CardTableBarrierSet() {
+ delete _card_table;
+}
+
+void CardTableBarrierSet::write_ref_array_work(MemRegion mr) {
+ _card_table->dirty_MemRegion(mr);
+}
+
+void CardTableBarrierSet::invalidate(MemRegion mr) {
+ _card_table->invalidate(mr);
+}
+
+void CardTableBarrierSet::print_on(outputStream* st) const {
+ _card_table->print_on(st);
+}
+
+// Helper for ReduceInitialCardMarks. For performance,
+// compiled code may elide card-marks for initializing stores
+// to a newly allocated object along the fast-path. We
+// compensate for such elided card-marks as follows:
+// (a) Generational, non-concurrent collectors, such as
+// GenCollectedHeap(ParNew,DefNew,Tenured) and
+// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
+// need the card-mark if and only if the region is
+// in the old gen, and do not care if the card-mark
+// succeeds or precedes the initializing stores themselves,
+// so long as the card-mark is completed before the next
+// scavenge. For all these cases, we can do a card mark
+// at the point at which we do a slow path allocation
+// in the old gen, i.e. in this call.
+// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
+// in addition that the card-mark for an old gen allocated
+// object strictly follow any associated initializing stores.
+// In these cases, the memRegion remembered below is
+// used to card-mark the entire region either just before the next
+// slow-path allocation by this thread or just before the next scavenge or
+// CMS-associated safepoint, whichever of these events happens first.
+// (The implicit assumption is that the object has been fully
+// initialized by this point, a fact that we assert when doing the
+// card-mark.)
+// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
+// G1 concurrent marking is in progress an SATB (pre-write-)barrier
+// is used to remember the pre-value of any store. Initializing
+// stores will not need this barrier, so we need not worry about
+// compensating for the missing pre-barrier here. Turning now
+// to the post-barrier, we note that G1 needs a RS update barrier
+// which simply enqueues a (sequence of) dirty cards which may
+// optionally be refined by the concurrent update threads. Note
+// that this barrier need only be applied to a non-young write,
+// but, like in CMS, because of the presence of concurrent refinement
+// (much like CMS' precleaning), must strictly follow the oop-store.
+// Thus, using the same protocol for maintaining the intended
+// invariants turns out, serendepitously, to be the same for both
+// G1 and CMS.
+//
+// For any future collector, this code should be reexamined with
+// that specific collector in mind, and the documentation above suitably
+// extended and updated.
+void CardTableBarrierSet::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {
+#if defined(COMPILER2) || INCLUDE_JVMCI
+ if (!ReduceInitialCardMarks) {
+ return;
+ }
+ // If a previous card-mark was deferred, flush it now.
+ flush_deferred_card_mark_barrier(thread);
+ if (new_obj->is_typeArray() || _card_table->is_in_young(new_obj)) {
+ // Arrays of non-references don't need a post-barrier.
+ // The deferred_card_mark region should be empty
+ // following the flush above.
+ assert(thread->deferred_card_mark().is_empty(), "Error");
+ } else {
+ MemRegion mr((HeapWord*)new_obj, new_obj->size());
+ assert(!mr.is_empty(), "Error");
+ if (_defer_initial_card_mark) {
+ // Defer the card mark
+ thread->set_deferred_card_mark(mr);
+ } else {
+ // Do the card mark
+ invalidate(mr);
+ }
+ }
+#endif // COMPILER2 || JVMCI
+}
+
+void CardTableBarrierSet::initialize_deferred_card_mark_barriers() {
+ // Used for ReduceInitialCardMarks (when COMPILER2 or JVMCI is used);
+ // otherwise remains unused.
+#if defined(COMPILER2) || INCLUDE_JVMCI
+ _defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers()
+ && (DeferInitialCardMark || card_mark_must_follow_store());
+#else
+ assert(_defer_initial_card_mark == false, "Who would set it?");
+#endif
+}
+
+void CardTableBarrierSet::flush_deferred_card_mark_barrier(JavaThread* thread) {
+#if defined(COMPILER2) || INCLUDE_JVMCI
+ MemRegion deferred = thread->deferred_card_mark();
+ if (!deferred.is_empty()) {
+ assert(_defer_initial_card_mark, "Otherwise should be empty");
+ {
+ // Verify that the storage points to a parsable object in heap
+ DEBUG_ONLY(oop old_obj = oop(deferred.start());)
+ assert(!_card_table->is_in_young(old_obj),
+ "Else should have been filtered in on_slowpath_allocation_exit()");
+ assert(oopDesc::is_oop(old_obj, true), "Not an oop");
+ assert(deferred.word_size() == (size_t)(old_obj->size()),
+ "Mismatch: multiple objects?");
+ }
+ write_region(deferred);
+ // "Clear" the deferred_card_mark field
+ thread->set_deferred_card_mark(MemRegion());
+ }
+ assert(thread->deferred_card_mark().is_empty(), "invariant");
+#else
+ assert(!_defer_initial_card_mark, "Should be false");
+ assert(thread->deferred_card_mark().is_empty(), "Should be empty");
+#endif
+}
+
+void CardTableBarrierSet::on_thread_detach(JavaThread* thread) {
+ // The deferred store barriers must all have been flushed to the
+ // card-table (or other remembered set structure) before GC starts
+ // processing the card-table (or other remembered set).
+ flush_deferred_card_mark_barrier(thread);
+}
+
+bool CardTableBarrierSet::card_mark_must_follow_store() const {
+ return _card_table->scanned_concurrently();
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableBarrierSet.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_HPP
+#define SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_HPP
+
+#include "gc/shared/modRefBarrierSet.hpp"
+#include "utilities/align.hpp"
+
+class CardTable;
+
+// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
+// enumerate ref fields that have been modified (since the last
+// enumeration.)
+
+// As it currently stands, this barrier is *imprecise*: when a ref field in
+// an object "o" is modified, the card table entry for the card containing
+// the head of "o" is dirtied, not necessarily the card containing the
+// modified field itself. For object arrays, however, the barrier *is*
+// precise; only the card containing the modified element is dirtied.
+// Closures used to scan dirty cards should take these
+// considerations into account.
+
+class CardTableBarrierSet: public ModRefBarrierSet {
+ // Some classes get to look at some private stuff.
+ friend class VMStructs;
+ protected:
+
+ // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
+ // or INCLUDE_JVMCI is being used
+ bool _defer_initial_card_mark;
+ CardTable* _card_table;
+
+ CardTableBarrierSet(BarrierSetAssembler* barrier_set_assembler,
+ CardTable* card_table,
+ const BarrierSet::FakeRtti& fake_rtti);
+
+ public:
+ CardTableBarrierSet(CardTable* card_table);
+ ~CardTableBarrierSet();
+
+ CardTable* card_table() const { return _card_table; }
+
+ virtual void initialize();
+
+ void write_region(MemRegion mr) {
+ invalidate(mr);
+ }
+
+ void write_ref_array_work(MemRegion mr);
+
+ public:
+ // Record a reference update. Note that these versions are precise!
+ // The scanning code has to handle the fact that the write barrier may be
+ // either precise or imprecise. We make non-virtual inline variants of
+ // these functions here for performance.
+ template
+ void write_ref_field_post(T* field, oop newVal);
+
+ virtual void invalidate(MemRegion mr);
+
+ // ReduceInitialCardMarks
+ void initialize_deferred_card_mark_barriers();
+
+ // If the CollectedHeap was asked to defer a store barrier above,
+ // this informs it to flush such a deferred store barrier to the
+ // remembered set.
+ void flush_deferred_card_mark_barrier(JavaThread* thread);
+
+ // Can a compiler initialize a new object without store barriers?
+ // This permission only extends from the creation of a new object
+ // via a TLAB up to the first subsequent safepoint. If such permission
+ // is granted for this heap type, the compiler promises to call
+ // defer_store_barrier() below on any slow path allocation of
+ // a new object for which such initializing store barriers will
+ // have been elided. G1, like CMS, allows this, but should be
+ // ready to provide a compensating write barrier as necessary
+ // if that storage came out of a non-young region. The efficiency
+ // of this implementation depends crucially on being able to
+ // answer very efficiently in constant time whether a piece of
+ // storage in the heap comes from a young region or not.
+ // See ReduceInitialCardMarks.
+ virtual bool can_elide_tlab_store_barriers() const {
+ return true;
+ }
+
+ // If a compiler is eliding store barriers for TLAB-allocated objects,
+ // we will be informed of a slow-path allocation by a call
+ // to on_slowpath_allocation_exit() below. Such a call precedes the
+ // initialization of the object itself, and no post-store-barriers will
+ // be issued. Some heap types require that the barrier strictly follows
+ // the initializing stores. (This is currently implemented by deferring the
+ // barrier until the next slow-path allocation or gc-related safepoint.)
+ // This interface answers whether a particular barrier type needs the card
+ // mark to be thus strictly sequenced after the stores.
+ virtual bool card_mark_must_follow_store() const;
+
+ virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
+ virtual void on_thread_detach(JavaThread* thread);
+
+ virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
+
+ virtual void print_on(outputStream* st) const;
+
+ template
+ class AccessBarrier: public ModRefBarrierSet::AccessBarrier {};
+};
+
+template<>
+struct BarrierSet::GetName {
+ static const BarrierSet::Name value = BarrierSet::CardTableBarrierSet;
+};
+
+template<>
+struct BarrierSet::GetType {
+ typedef ::CardTableBarrierSet type;
+};
+
+#endif // SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_INLINE_HPP
+#define SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_INLINE_HPP
+
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "runtime/orderAccess.inline.hpp"
+
+template
+inline void CardTableBarrierSet::write_ref_field_post(T* field, oop newVal) {
+ volatile jbyte* byte = _card_table->byte_for(field);
+ if (UseConcMarkSweepGC) {
+ // Perform a releasing store if using CMS so that it may
+ // scan and clear the cards concurrently during pre-cleaning.
+ OrderAccess::release_store(byte, CardTable::dirty_card_val());
+ } else {
+ *byte = CardTable::dirty_card_val();
+ }
+}
+
+#endif // SHARE_VM_GC_SHARED_CARDTABLEBARRIERSET_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableBarrierSetAssembler.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/cardTableBarrierSetAssembler.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_HPP
+#define SHARE_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_HPP
+
+#include "utilities/macros.hpp"
+
+#include CPU_HEADER(gc/shared/cardTableBarrierSetAssembler)
+
+#endif // SHARE_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableModRefBS.cpp
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2000, 2018, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/shared/cardTableModRefBS.inline.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/space.inline.hpp"
-#include "logging/log.hpp"
-#include "memory/virtualspace.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/thread.hpp"
-#include "services/memTracker.hpp"
-#include "utilities/align.hpp"
-#include "utilities/macros.hpp"
-
-// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
-// enumerate ref fields that have been modified (since the last
-// enumeration.)
-
-CardTableModRefBS::CardTableModRefBS(
- CardTable* card_table,
- const BarrierSet::FakeRtti& fake_rtti) :
- ModRefBarrierSet(fake_rtti.add_tag(BarrierSet::CardTableModRef)),
- _defer_initial_card_mark(false),
- _card_table(card_table)
-{}
-
-CardTableModRefBS::CardTableModRefBS(CardTable* card_table) :
- ModRefBarrierSet(BarrierSet::FakeRtti(BarrierSet::CardTableModRef)),
- _defer_initial_card_mark(false),
- _card_table(card_table)
-{}
-
-void CardTableModRefBS::initialize() {
- initialize_deferred_card_mark_barriers();
-}
-
-CardTableModRefBS::~CardTableModRefBS() {
- delete _card_table;
-}
-
-void CardTableModRefBS::write_ref_array_work(MemRegion mr) {
- _card_table->dirty_MemRegion(mr);
-}
-
-void CardTableModRefBS::invalidate(MemRegion mr) {
- _card_table->invalidate(mr);
-}
-
-void CardTableModRefBS::print_on(outputStream* st) const {
- _card_table->print_on(st);
-}
-
-// Helper for ReduceInitialCardMarks. For performance,
-// compiled code may elide card-marks for initializing stores
-// to a newly allocated object along the fast-path. We
-// compensate for such elided card-marks as follows:
-// (a) Generational, non-concurrent collectors, such as
-// GenCollectedHeap(ParNew,DefNew,Tenured) and
-// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
-// need the card-mark if and only if the region is
-// in the old gen, and do not care if the card-mark
-// succeeds or precedes the initializing stores themselves,
-// so long as the card-mark is completed before the next
-// scavenge. For all these cases, we can do a card mark
-// at the point at which we do a slow path allocation
-// in the old gen, i.e. in this call.
-// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
-// in addition that the card-mark for an old gen allocated
-// object strictly follow any associated initializing stores.
-// In these cases, the memRegion remembered below is
-// used to card-mark the entire region either just before the next
-// slow-path allocation by this thread or just before the next scavenge or
-// CMS-associated safepoint, whichever of these events happens first.
-// (The implicit assumption is that the object has been fully
-// initialized by this point, a fact that we assert when doing the
-// card-mark.)
-// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
-// G1 concurrent marking is in progress an SATB (pre-write-)barrier
-// is used to remember the pre-value of any store. Initializing
-// stores will not need this barrier, so we need not worry about
-// compensating for the missing pre-barrier here. Turning now
-// to the post-barrier, we note that G1 needs a RS update barrier
-// which simply enqueues a (sequence of) dirty cards which may
-// optionally be refined by the concurrent update threads. Note
-// that this barrier need only be applied to a non-young write,
-// but, like in CMS, because of the presence of concurrent refinement
-// (much like CMS' precleaning), must strictly follow the oop-store.
-// Thus, using the same protocol for maintaining the intended
-// invariants turns out, serendepitously, to be the same for both
-// G1 and CMS.
-//
-// For any future collector, this code should be reexamined with
-// that specific collector in mind, and the documentation above suitably
-// extended and updated.
-void CardTableModRefBS::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
- if (!ReduceInitialCardMarks) {
- return;
- }
- // If a previous card-mark was deferred, flush it now.
- flush_deferred_card_mark_barrier(thread);
- if (new_obj->is_typeArray() || _card_table->is_in_young(new_obj)) {
- // Arrays of non-references don't need a post-barrier.
- // The deferred_card_mark region should be empty
- // following the flush above.
- assert(thread->deferred_card_mark().is_empty(), "Error");
- } else {
- MemRegion mr((HeapWord*)new_obj, new_obj->size());
- assert(!mr.is_empty(), "Error");
- if (_defer_initial_card_mark) {
- // Defer the card mark
- thread->set_deferred_card_mark(mr);
- } else {
- // Do the card mark
- invalidate(mr);
- }
- }
-#endif // COMPILER2 || JVMCI
-}
-
-void CardTableModRefBS::initialize_deferred_card_mark_barriers() {
- // Used for ReduceInitialCardMarks (when COMPILER2 or JVMCI is used);
- // otherwise remains unused.
-#if defined(COMPILER2) || INCLUDE_JVMCI
- _defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers()
- && (DeferInitialCardMark || card_mark_must_follow_store());
-#else
- assert(_defer_initial_card_mark == false, "Who would set it?");
-#endif
-}
-
-void CardTableModRefBS::flush_deferred_card_mark_barrier(JavaThread* thread) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
- MemRegion deferred = thread->deferred_card_mark();
- if (!deferred.is_empty()) {
- assert(_defer_initial_card_mark, "Otherwise should be empty");
- {
- // Verify that the storage points to a parsable object in heap
- DEBUG_ONLY(oop old_obj = oop(deferred.start());)
- assert(!_card_table->is_in_young(old_obj),
- "Else should have been filtered in on_slowpath_allocation_exit()");
- assert(oopDesc::is_oop(old_obj, true), "Not an oop");
- assert(deferred.word_size() == (size_t)(old_obj->size()),
- "Mismatch: multiple objects?");
- }
- write_region(deferred);
- // "Clear" the deferred_card_mark field
- thread->set_deferred_card_mark(MemRegion());
- }
- assert(thread->deferred_card_mark().is_empty(), "invariant");
-#else
- assert(!_defer_initial_card_mark, "Should be false");
- assert(thread->deferred_card_mark().is_empty(), "Should be empty");
-#endif
-}
-
-void CardTableModRefBS::on_thread_detach(JavaThread* thread) {
- // The deferred store barriers must all have been flushed to the
- // card-table (or other remembered set structure) before GC starts
- // processing the card-table (or other remembered set).
- flush_deferred_card_mark_barrier(thread);
-}
-
-bool CardTableModRefBS::card_mark_must_follow_store() const {
- return _card_table->scanned_concurrently();
-}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableModRefBS.hpp
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
-#define SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
-
-#include "gc/shared/modRefBarrierSet.hpp"
-#include "utilities/align.hpp"
-
-class CardTable;
-
-// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
-// enumerate ref fields that have been modified (since the last
-// enumeration.)
-
-// As it currently stands, this barrier is *imprecise*: when a ref field in
-// an object "o" is modified, the card table entry for the card containing
-// the head of "o" is dirtied, not necessarily the card containing the
-// modified field itself. For object arrays, however, the barrier *is*
-// precise; only the card containing the modified element is dirtied.
-// Closures used to scan dirty cards should take these
-// considerations into account.
-
-class CardTableModRefBS: public ModRefBarrierSet {
- // Some classes get to look at some private stuff.
- friend class VMStructs;
- protected:
-
- // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
- // or INCLUDE_JVMCI is being used
- bool _defer_initial_card_mark;
- CardTable* _card_table;
-
- CardTableModRefBS(CardTable* card_table, const BarrierSet::FakeRtti& fake_rtti);
-
- public:
- CardTableModRefBS(CardTable* card_table);
- ~CardTableModRefBS();
-
- CardTable* card_table() const { return _card_table; }
-
- virtual void initialize();
-
- void write_region(MemRegion mr) {
- invalidate(mr);
- }
-
- protected:
- void write_ref_array_work(MemRegion mr);
-
- public:
- // Record a reference update. Note that these versions are precise!
- // The scanning code has to handle the fact that the write barrier may be
- // either precise or imprecise. We make non-virtual inline variants of
- // these functions here for performance.
- template
- void write_ref_field_post(T* field, oop newVal);
-
- virtual void invalidate(MemRegion mr);
-
- // ReduceInitialCardMarks
- void initialize_deferred_card_mark_barriers();
-
- // If the CollectedHeap was asked to defer a store barrier above,
- // this informs it to flush such a deferred store barrier to the
- // remembered set.
- void flush_deferred_card_mark_barrier(JavaThread* thread);
-
- // Can a compiler initialize a new object without store barriers?
- // This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint. If such permission
- // is granted for this heap type, the compiler promises to call
- // defer_store_barrier() below on any slow path allocation of
- // a new object for which such initializing store barriers will
- // have been elided. G1, like CMS, allows this, but should be
- // ready to provide a compensating write barrier as necessary
- // if that storage came out of a non-young region. The efficiency
- // of this implementation depends crucially on being able to
- // answer very efficiently in constant time whether a piece of
- // storage in the heap comes from a young region or not.
- // See ReduceInitialCardMarks.
- virtual bool can_elide_tlab_store_barriers() const {
- return true;
- }
-
- // If a compiler is eliding store barriers for TLAB-allocated objects,
- // we will be informed of a slow-path allocation by a call
- // to on_slowpath_allocation_exit() below. Such a call precedes the
- // initialization of the object itself, and no post-store-barriers will
- // be issued. Some heap types require that the barrier strictly follows
- // the initializing stores. (This is currently implemented by deferring the
- // barrier until the next slow-path allocation or gc-related safepoint.)
- // This interface answers whether a particular barrier type needs the card
- // mark to be thus strictly sequenced after the stores.
- virtual bool card_mark_must_follow_store() const;
-
- virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
- virtual void on_thread_detach(JavaThread* thread);
-
- virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
-
- virtual void print_on(outputStream* st) const;
-
- template
- class AccessBarrier: public ModRefBarrierSet::AccessBarrier {};
-};
-
-template<>
-struct BarrierSet::GetName {
- static const BarrierSet::Name value = BarrierSet::CardTableModRef;
-};
-
-template<>
-struct BarrierSet::GetType {
- typedef CardTableModRefBS type;
-};
-
-#endif // SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_INLINE_HPP
-#define SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_INLINE_HPP
-
-#include "gc/shared/cardTableModRefBS.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "runtime/orderAccess.inline.hpp"
-
-template
-inline void CardTableModRefBS::write_ref_field_post(T* field, oop newVal) {
- volatile jbyte* byte = _card_table->byte_for(field);
- if (UseConcMarkSweepGC) {
- // Perform a releasing store if using CMS so that it may
- // scan and clear the cards concurrently during pre-cleaning.
- OrderAccess::release_store(byte, CardTable::dirty_card_val());
- } else {
- *byte = CardTable::dirty_card_val();
- }
-}
-
-#endif // SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/cardTableRS.cpp
--- a/src/hotspot/share/gc/shared/cardTableRS.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/cardTableRS.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -571,7 +571,7 @@
// [End Case 3]
//
// (Please refer to the code in the helper class
- // ClearNonCleanCardWrapper and in CardTableModRefBS for details.)
+ // ClearNonCleanCardWrapper and in CardTable for details.)
//
// The informal arguments above can be tightened into a formal
// correctness proof and it behooves us to write up such a proof,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/collectedHeap.cpp
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/allocTracer.hpp"
-#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcLocker.inline.hpp"
@@ -585,3 +585,13 @@
void CollectedHeap::post_initialize() {
initialize_serviceability();
}
+
+oop CollectedHeap::pin_object(JavaThread* thread, oop o) {
+ Handle handle(thread, o);
+ GCLocker::lock_critical(thread);
+ return handle();
+}
+
+void CollectedHeap::unpin_object(JavaThread* thread, oop o) {
+ GCLocker::unlock_critical(thread);
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/collectedHeap.hpp
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -588,6 +588,15 @@
// perform cleanup tasks serially in the VMThread.
virtual WorkGang* get_safepoint_workers() { return NULL; }
+ // Support for object pinning. This is used by JNI's Get*Critical() and
+ // Release*Critical() family of functions. A GC may either use the GCLocker
+ // protocol to ensure no critical arrays are in-use when entering
+ // a GC pause, or it can implement pinning, which must guarantee that
+ // the object does not move while pinned.
+ virtual oop pin_object(JavaThread* thread, oop o);
+
+ virtual void unpin_object(JavaThread* thread, oop o);
+
// Non product verification and debugging.
#ifndef PRODUCT
// Support for PromotionFailureALot. Return true if it's time to cause a
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/concurrentGCThread.cpp
--- a/src/hotspot/share/gc/shared/concurrentGCThread.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/concurrentGCThread.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,6 @@
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/genCollectedHeap.cpp
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/collectorCounters.hpp"
@@ -112,7 +112,7 @@
_rem_set = new CardTableRS(reserved_region());
_rem_set->initialize();
- CardTableModRefBS *bs = new CardTableModRefBS(_rem_set);
+ CardTableBarrierSet *bs = new CardTableBarrierSet(_rem_set);
bs->initialize();
set_barrier_set(bs);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/genOopClosures.hpp
--- a/src/hotspot/share/gc/shared/genOopClosures.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/genOopClosures.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
class Generation;
class HeapWord;
class CardTableRS;
-class CardTableModRefBS;
+class CardTableBarrierSet;
class DefNewGeneration;
class KlassRemSet;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/modRefBarrierSet.hpp
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,8 +32,10 @@
class ModRefBarrierSet: public BarrierSet {
protected:
- ModRefBarrierSet(const BarrierSet::FakeRtti& fake_rtti)
- : BarrierSet(fake_rtti.add_tag(BarrierSet::ModRef)) { }
+ ModRefBarrierSet(BarrierSetAssembler* barrier_set_assembler,
+ const BarrierSet::FakeRtti& fake_rtti)
+ : BarrierSet(barrier_set_assembler,
+ fake_rtti.add_tag(BarrierSet::ModRef)) { }
~ModRefBarrierSet() { }
public:
@@ -47,6 +49,22 @@
virtual void invalidate(MemRegion mr) = 0;
virtual void write_region(MemRegion mr) = 0;
+ // Operations on arrays, or general regions (e.g., for "clone") may be
+ // optimized by some barriers.
+
+ // Below length is the # array elements being written
+ virtual void write_ref_array_pre(oop* dst, size_t length,
+ bool dest_uninitialized = false) {}
+ virtual void write_ref_array_pre(narrowOop* dst, size_t length,
+ bool dest_uninitialized = false) {}
+ // Below count is the # array elements being written, starting
+ // at the address "start", which may not necessarily be HeapWord-aligned
+ inline void write_ref_array(HeapWord* start, size_t count);
+
+ protected:
+ virtual void write_ref_array_work(MemRegion mr) = 0;
+
+ public:
// The ModRef abstraction introduces pre and post barriers
template
class AccessBarrier: public BarrierSet::AccessBarrier {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,12 +25,34 @@
#ifndef SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP
#define SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP
-#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/barrierSet.hpp"
#include "gc/shared/modRefBarrierSet.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.hpp"
+// count is number of array elements being written
+void ModRefBarrierSet::write_ref_array(HeapWord* start, size_t count) {
+ HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
+ // In the case of compressed oops, start and end may potentially be misaligned;
+ // so we need to conservatively align the first downward (this is not
+ // strictly necessary for current uses, but a case of good hygiene and,
+ // if you will, aesthetics) and the second upward (this is essential for
+ // current uses) to a HeapWord boundary, so we mark all cards overlapping
+ // this write. If this evolves in the future to calling a
+ // logging barrier of narrow oop granularity, like the pre-barrier for G1
+ // (mentioned here merely by way of example), we will need to change this
+ // interface, so it is "exactly precise" (if i may be allowed the adverbial
+ // redundancy for emphasis) and does not include narrow oop slots not
+ // included in the original write interval.
+ HeapWord* aligned_start = align_down(start, HeapWordSize);
+ HeapWord* aligned_end = align_up (end, HeapWordSize);
+ // If compressed oops were not being used, these should already be aligned
+ assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
+ "Expected heap word alignment of start and end");
+ write_ref_array_work(MemRegion(aligned_start, aligned_end));
+}
+
template
template
inline void ModRefBarrierSet::AccessBarrier::
@@ -73,7 +95,7 @@
if (!HasDecorator::value) {
// Optimized covariant case
- bs->write_ref_array_pre(dst, (int)length,
+ bs->write_ref_array_pre(dst, length,
HasDecorator::value);
Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
bs->write_ref_array((HeapWord*)dst, length);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/modRefBarrierSetAssembler.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/modRefBarrierSetAssembler.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP
+#define SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP
+
+#include "utilities/macros.hpp"
+
+#include CPU_HEADER(gc/shared/modRefBarrierSetAssembler)
+
+#endif // SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/gc/shared/vmGCOperations.cpp
--- a/src/hotspot/share/gc/shared/vmGCOperations.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,6 @@
#include "memory/oopFactory.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/macros.hpp"
#include "utilities/preserveException.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/abstractInterpreter.hpp
--- a/src/hotspot/share/interpreter/abstractInterpreter.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/abstractInterpreter.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -28,6 +28,7 @@
#include "asm/macroAssembler.hpp"
#include "code/stubs.hpp"
#include "interpreter/bytecodes.hpp"
+#include "runtime/frame.hpp"
#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/bytecodeInterpreter.cpp
--- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,7 +47,7 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threadCritical.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/bytecodeStream.cpp
--- a/src/hotspot/share/interpreter/bytecodeStream.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/bytecodeStream.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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,7 @@
#include "precompiled.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/bytecodes.hpp"
+#include "runtime/handles.inline.hpp"
Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
assert(!is_last_bytecode(), "should have been checked");
@@ -53,6 +54,11 @@
return code;
}
+BaseBytecodeStream::BaseBytecodeStream(const methodHandle& method) : _method(method) {
+ set_interval(0, _method->code_size());
+ _is_raw = false;
+}
+
#ifdef ASSERT
void BaseBytecodeStream::assert_raw_index_size(int size) const {
if (raw_code() == Bytecodes::_invokedynamic && is_raw()) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/bytecodeStream.hpp
--- a/src/hotspot/share/interpreter/bytecodeStream.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/bytecodeStream.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -28,7 +28,6 @@
#include "interpreter/bytecode.hpp"
#include "memory/allocation.hpp"
#include "oops/method.hpp"
-#include "runtime/handles.inline.hpp"
#include "utilities/bytes.hpp"
// A BytecodeStream is used for fast iteration over the bytecodes
@@ -63,10 +62,7 @@
bool _is_raw; // false in 'cooked' BytecodeStream
// Construction
- BaseBytecodeStream(const methodHandle& method) : _method(method) {
- set_interval(0, _method->code_size());
- _is_raw = false;
- }
+ BaseBytecodeStream(const methodHandle& method);
public:
// Iteration control
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/interpreterRuntime.cpp
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -53,9 +53,10 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/osThread.hpp"
@@ -84,6 +85,58 @@
}
};
+// Helper class to access current interpreter state
+class LastFrameAccessor : public StackObj {
+ frame _last_frame;
+public:
+ LastFrameAccessor(JavaThread* thread) {
+ assert(thread == Thread::current(), "sanity");
+ _last_frame = thread->last_frame();
+ }
+ bool is_interpreted_frame() const { return _last_frame.is_interpreted_frame(); }
+ Method* method() const { return _last_frame.interpreter_frame_method(); }
+ address bcp() const { return _last_frame.interpreter_frame_bcp(); }
+ int bci() const { return _last_frame.interpreter_frame_bci(); }
+ address mdp() const { return _last_frame.interpreter_frame_mdp(); }
+
+ void set_bcp(address bcp) { _last_frame.interpreter_frame_set_bcp(bcp); }
+ void set_mdp(address dp) { _last_frame.interpreter_frame_set_mdp(dp); }
+
+ // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
+ Bytecodes::Code code() const { return Bytecodes::code_at(method(), bcp()); }
+
+ Bytecode bytecode() const { return Bytecode(method(), bcp()); }
+ int get_index_u1(Bytecodes::Code bc) const { return bytecode().get_index_u1(bc); }
+ int get_index_u2(Bytecodes::Code bc) const { return bytecode().get_index_u2(bc); }
+ int get_index_u2_cpcache(Bytecodes::Code bc) const
+ { return bytecode().get_index_u2_cpcache(bc); }
+ int get_index_u4(Bytecodes::Code bc) const { return bytecode().get_index_u4(bc); }
+ int number_of_dimensions() const { return bcp()[3]; }
+ ConstantPoolCacheEntry* cache_entry_at(int i) const
+ { return method()->constants()->cache()->entry_at(i); }
+ ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
+
+ oop callee_receiver(Symbol* signature) {
+ return _last_frame.interpreter_callee_receiver(signature);
+ }
+ BasicObjectLock* monitor_begin() const {
+ return _last_frame.interpreter_frame_monitor_begin();
+ }
+ BasicObjectLock* monitor_end() const {
+ return _last_frame.interpreter_frame_monitor_end();
+ }
+ BasicObjectLock* next_monitor(BasicObjectLock* current) const {
+ return _last_frame.next_monitor_in_interpreter_frame(current);
+ }
+
+ frame& get_frame() { return _last_frame; }
+};
+
+
+bool InterpreterRuntime::is_breakpoint(JavaThread *thread) {
+ return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint;
+}
+
//------------------------------------------------------------------------------------------------------------------------
// State accessors
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/interpreterRuntime.hpp
--- a/src/hotspot/share/interpreter/interpreterRuntime.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -29,7 +29,7 @@
#include "interpreter/linkResolver.hpp"
#include "memory/universe.hpp"
#include "oops/method.hpp"
-#include "runtime/frame.inline.hpp"
+#include "runtime/frame.hpp"
#include "runtime/signature.hpp"
#include "runtime/thread.hpp"
#include "utilities/macros.hpp"
@@ -42,52 +42,6 @@
friend class PrintingClosure; // for method and bcp
private:
- // Helper class to access current interpreter state
- class LastFrameAccessor : public StackObj {
- frame _last_frame;
- public:
- LastFrameAccessor(JavaThread* thread) {
- assert(thread == Thread::current(), "sanity");
- _last_frame = thread->last_frame();
- }
- bool is_interpreted_frame() const { return _last_frame.is_interpreted_frame(); }
- Method* method() const { return _last_frame.interpreter_frame_method(); }
- address bcp() const { return _last_frame.interpreter_frame_bcp(); }
- int bci() const { return _last_frame.interpreter_frame_bci(); }
- address mdp() const { return _last_frame.interpreter_frame_mdp(); }
-
- void set_bcp(address bcp) { _last_frame.interpreter_frame_set_bcp(bcp); }
- void set_mdp(address dp) { _last_frame.interpreter_frame_set_mdp(dp); }
-
- // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
- Bytecodes::Code code() const { return Bytecodes::code_at(method(), bcp()); }
-
- Bytecode bytecode() const { return Bytecode(method(), bcp()); }
- int get_index_u1(Bytecodes::Code bc) const { return bytecode().get_index_u1(bc); }
- int get_index_u2(Bytecodes::Code bc) const { return bytecode().get_index_u2(bc); }
- int get_index_u2_cpcache(Bytecodes::Code bc) const
- { return bytecode().get_index_u2_cpcache(bc); }
- int get_index_u4(Bytecodes::Code bc) const { return bytecode().get_index_u4(bc); }
- int number_of_dimensions() const { return bcp()[3]; }
- ConstantPoolCacheEntry* cache_entry_at(int i) const
- { return method()->constants()->cache()->entry_at(i); }
- ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
-
- oop callee_receiver(Symbol* signature) {
- return _last_frame.interpreter_callee_receiver(signature);
- }
- BasicObjectLock* monitor_begin() const {
- return _last_frame.interpreter_frame_monitor_begin();
- }
- BasicObjectLock* monitor_end() const {
- return _last_frame.interpreter_frame_monitor_end();
- }
- BasicObjectLock* next_monitor(BasicObjectLock* current) const {
- return _last_frame.next_monitor_in_interpreter_frame(current);
- }
-
- frame& get_frame() { return _last_frame; }
- };
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
static void note_trap_inner(JavaThread* thread, int reason,
@@ -172,7 +126,7 @@
static void _breakpoint(JavaThread* thread, Method* method, address bcp);
static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
static void set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
- static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; }
+ static bool is_breakpoint(JavaThread *thread);
// Safepoints
static void at_safepoint(JavaThread* thread);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/linkResolver.cpp
--- a/src/hotspot/share/interpreter/linkResolver.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/linkResolver.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,6 +32,7 @@
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/linkResolver.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/rewriter.cpp
--- a/src/hotspot/share/interpreter/rewriter.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/rewriter.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,6 +31,7 @@
#include "memory/resourceArea.hpp"
#include "oops/generateOopMap.hpp"
#include "prims/methodHandles.hpp"
+#include "runtime/handles.inline.hpp"
// Computes a CPC map (new_index -> original_index) for constant pool entries
// that are referred to by the interpreter at runtime via the constant pool cache.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/rewriter.hpp
--- a/src/hotspot/share/interpreter/rewriter.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/rewriter.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
#define SHARE_VM_INTERPRETER_REWRITER_HPP
#include "memory/allocation.hpp"
-#include "runtime/handles.inline.hpp"
#include "utilities/growableArray.hpp"
// The Rewriter adds caches to the constant pool and rewrites bytecode indices
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/interpreter/templateInterpreterGenerator.cpp
--- a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -29,6 +29,7 @@
#include "interpreter/templateInterpreter.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "interpreter/templateTable.hpp"
+#include "oops/methodData.hpp"
#ifndef CC_INTERP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/compilerRuntime.cpp
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,9 +29,10 @@
#include "oops/cpCache.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/interfaceSupport.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/vframe.inline.hpp"
#include "aot/aotLoader.hpp"
// Resolve and allocate String
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,6 +39,7 @@
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciCompiler.cpp
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -34,6 +34,7 @@
#include "jvmci/jvmciRuntime.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/globals_extension.hpp"
+#include "runtime/handles.inline.hpp"
JVMCICompiler* JVMCICompiler::_instance = NULL;
elapsedTimer JVMCICompiler::_codeInstallTimer;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "code/scopeDesc.hpp"
#include "memory/oopFactory.hpp"
@@ -35,6 +36,8 @@
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/jvmciRuntime.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/vframe_hp.hpp"
@@ -98,6 +101,12 @@
return NULL;
}
+Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
+ assert(_index < _args->length(), "out of bounds");
+ oop arg=((objArrayOop) (_args))->obj_at(_index++);
+ assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+ return Handle(Thread::current(), arg);
+}
jobjectArray readConfiguration0(JNIEnv *env, TRAPS);
@@ -472,6 +481,9 @@
C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
Klass* resolved_klass = cp->klass_at(index, CHECK_NULL);
+ if (resolved_klass->is_instance_klass()) {
+ InstanceKlass::cast(resolved_klass)->link_class_or_fail(THREAD);
+ }
oop klass = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
return JNIHandles::make_local(THREAD, klass);
C2V_END
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -170,12 +170,7 @@
arrayOop _args;
int _index;
- Handle next_arg(BasicType expectedType) {
- assert(_index < _args->length(), "out of bounds");
- oop arg=((objArrayOop) (_args))->obj_at(_index++);
- assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
- return Handle(Thread::current(), arg);
- }
+ Handle next_arg(BasicType expectedType);
public:
JavaArgumentUnboxer(Symbol* signature, JavaCallArguments* jca, arrayOop args, bool is_static) : SignatureIterator(signature) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,6 +28,7 @@
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/vmStructs_jvmci.hpp"
+#include "runtime/handles.inline.hpp"
#include "utilities/resourceHash.hpp"
@@ -119,7 +120,7 @@
symbol_clinit = (address) vmSymbols::class_initializer_name();
BarrierSet* bs = Universe::heap()->barrier_set();
- if (bs->is_a(BarrierSet::CardTableModRef)) {
+ if (bs->is_a(BarrierSet::CardTableBarrierSet)) {
jbyte* base = ci_card_table_address();
assert(base != NULL, "unexpected byte_map_base");
cardtable_start_address = base;
@@ -420,4 +421,3 @@
#undef ADD_UINTX_FLAG
#undef CHECK_FLAG
}
-
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciEnv.cpp
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,6 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
-#include "runtime/sweeper.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerOracle.hpp"
@@ -45,9 +44,11 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "runtime/sweeper.hpp"
#include "utilities/dtrace.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
@@ -368,12 +369,6 @@
if (holder_is_accessible) { // Our declared holder is loaded.
constantTag tag = cpool->tag_ref_at(index);
methodHandle m = lookup_method(accessor, holder, name_sym, sig_sym, bc, tag);
- if (!m.is_null() &&
- (bc == Bytecodes::_invokestatic
- ? InstanceKlass::cast(m->method_holder())->is_not_initialized()
- : !InstanceKlass::cast(m->method_holder())->is_loaded())) {
- m = NULL;
- }
if (!m.is_null()) {
// We found the method.
return m;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciJavaClasses.hpp
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -353,30 +353,30 @@
static type name() { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
- address addr = ik->static_field_addr(_##name##_offset); \
- oop result = HeapAccess<>::oop_load((HeapWord*)addr); \
+ oop base = ik->static_field_base_raw(); \
+ oop result = HeapAccess<>::oop_load_at(base, _##name##_offset); \
return type(result); \
} \
static void set_##name(type x) { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
assert(klassName::klass() != NULL, "Class not yet loaded: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
- address addr = ik->static_field_addr(_##name##_offset); \
- HeapAccess<>::oop_store((HeapWord*)addr, x); \
+ oop base = ik->static_field_base_raw(); \
+ HeapAccess<>::oop_store_at(base, _##name##_offset, x); \
}
#define STATIC_PRIMITIVE_FIELD(klassName, name, jtypename) \
static int _##name##_offset; \
static jtypename name() { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
- address addr = ik->static_field_addr(_##name##_offset); \
- return HeapAccess<>::load((jtypename*)addr); \
+ oop base = ik->static_field_base_raw(); \
+ return HeapAccess<>::load_at(base, _##name##_offset); \
} \
static void set_##name(jtypename x) { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
- address addr = ik->static_field_addr(_##name##_offset); \
- HeapAccess<>::store((jtypename*)addr, x); \
+ oop base = ik->static_field_base_raw(); \
+ HeapAccess<>::store_at(base, _##name##_offset, x); \
}
#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jint)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/jvmci/jvmciRuntime.cpp
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,7 @@
#include "asm/codeBuffer.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "code/codeCache.hpp"
+#include "code/compiledMethod.inline.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "jvmci/jvmciRuntime.hpp"
@@ -40,7 +41,8 @@
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/libadt/vectset.cpp
--- a/src/hotspot/share/libadt/vectset.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/libadt/vectset.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "libadt/vectset.hpp"
#include "memory/allocation.inline.hpp"
+#include "memory/arena.hpp"
// Vector Sets - An Abstract Data Type
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/allocation.cpp
--- a/src/hotspot/share/memory/allocation.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/allocation.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -37,6 +37,39 @@
#include "services/memTracker.hpp"
#include "utilities/ostream.hpp"
+// allocate using malloc; will fail if no memory available
+char* AllocateHeap(size_t size,
+ MEMFLAGS flags,
+ const NativeCallStack& stack,
+ AllocFailType alloc_failmode /* = AllocFailStrategy::EXIT_OOM*/) {
+ char* p = (char*) os::malloc(size, flags, stack);
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
+ vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "AllocateHeap");
+ }
+ return p;
+}
+
+char* AllocateHeap(size_t size,
+ MEMFLAGS flags,
+ AllocFailType alloc_failmode /* = AllocFailStrategy::EXIT_OOM*/) {
+ return AllocateHeap(size, flags, CALLER_PC);
+}
+
+char* ReallocateHeap(char *old,
+ size_t size,
+ MEMFLAGS flag,
+ AllocFailType alloc_failmode) {
+ char* p = (char*) os::realloc(old, size, flag, CALLER_PC);
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
+ vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "ReallocateHeap");
+ }
+ return p;
+}
+
+void FreeHeap(void* p) {
+ os::free(p);
+}
+
void* MetaspaceObj::_shared_metaspace_base = NULL;
void* MetaspaceObj::_shared_metaspace_top = NULL;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/allocation.hpp
--- a/src/hotspot/share/memory/allocation.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/allocation.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -154,22 +154,61 @@
class NativeCallStack;
+char* AllocateHeap(size_t size,
+ MEMFLAGS flags,
+ const NativeCallStack& stack,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
+char* AllocateHeap(size_t size,
+ MEMFLAGS flags,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
+
+char* ReallocateHeap(char *old,
+ size_t size,
+ MEMFLAGS flag,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
+
+void FreeHeap(void* p);
+
template class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
public:
- NOINLINE void* operator new(size_t size, const NativeCallStack& stack) throw();
- NOINLINE void* operator new(size_t size) throw();
- NOINLINE void* operator new (size_t size, const std::nothrow_t& nothrow_constant,
- const NativeCallStack& stack) throw();
- NOINLINE void* operator new (size_t size, const std::nothrow_t& nothrow_constant)
- throw();
- NOINLINE void* operator new [](size_t size, const NativeCallStack& stack) throw();
- NOINLINE void* operator new [](size_t size) throw();
- NOINLINE void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
- const NativeCallStack& stack) throw();
- NOINLINE void* operator new [](size_t size, const std::nothrow_t& nothrow_constant)
- throw();
- void operator delete(void* p);
- void operator delete [] (void* p);
+ ALWAYSINLINE void* operator new(size_t size) throw() {
+ return (void*)AllocateHeap(size, F);
+ }
+
+ ALWAYSINLINE void* operator new(size_t size,
+ const NativeCallStack& stack) throw() {
+ return (void*)AllocateHeap(size, F, stack);
+ }
+
+ ALWAYSINLINE void* operator new(size_t size, const std::nothrow_t&,
+ const NativeCallStack& stack) throw() {
+ return (void*)AllocateHeap(size, F, stack, AllocFailStrategy::RETURN_NULL);
+ }
+
+ ALWAYSINLINE void* operator new(size_t size, const std::nothrow_t&) throw() {
+ return (void*)AllocateHeap(size, F, AllocFailStrategy::RETURN_NULL);
+ }
+
+ ALWAYSINLINE void* operator new[](size_t size) throw() {
+ return (void*)AllocateHeap(size, F);
+ }
+
+ ALWAYSINLINE void* operator new[](size_t size,
+ const NativeCallStack& stack) throw() {
+ return (void*)AllocateHeap(size, F, stack);
+ }
+
+ ALWAYSINLINE void* operator new[](size_t size, const std::nothrow_t&,
+ const NativeCallStack& stack) throw() {
+ return (void*)AllocateHeap(size, F, stack, AllocFailStrategy::RETURN_NULL);
+ }
+
+ ALWAYSINLINE void* operator new[](size_t size, const std::nothrow_t&) throw() {
+ return (void*)AllocateHeap(size, F, AllocFailStrategy::RETURN_NULL);
+ }
+
+ void operator delete(void* p) { FreeHeap(p); }
+ void operator delete [] (void* p) { FreeHeap(p); }
};
// Base class for objects allocated on the stack only.
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/allocation.inline.hpp
--- a/src/hotspot/share/memory/allocation.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/allocation.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -48,83 +48,6 @@
}
#endif
-// allocate using malloc; will fail if no memory available
-inline char* AllocateHeap(size_t size, MEMFLAGS flags,
- const NativeCallStack& stack,
- AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
- char* p = (char*) os::malloc(size, flags, stack);
- if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
- vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "AllocateHeap");
- }
- return p;
-}
-
-ALWAYSINLINE char* AllocateHeap(size_t size, MEMFLAGS flags,
- AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
- return AllocateHeap(size, flags, CURRENT_PC, alloc_failmode);
-}
-
-ALWAYSINLINE char* ReallocateHeap(char *old, size_t size, MEMFLAGS flag,
- AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
- char* p = (char*) os::realloc(old, size, flag, CURRENT_PC);
- if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
- vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "ReallocateHeap");
- }
- return p;
-}
-
-inline void FreeHeap(void* p) {
- os::free(p);
-}
-
-
-template void* CHeapObj::operator new(size_t size,
- const NativeCallStack& stack) throw() {
- return (void*)AllocateHeap(size, F, stack);
-}
-
-template void* CHeapObj::operator new(size_t size) throw() {
- return CHeapObj::operator new(size, CALLER_PC);
-}
-
-template void* CHeapObj::operator new (size_t size,
- const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
- return (void*)AllocateHeap(size, F, stack, AllocFailStrategy::RETURN_NULL);
-}
-
-template void* CHeapObj::operator new (size_t size,
- const std::nothrow_t& nothrow_constant) throw() {
- return CHeapObj::operator new(size, nothrow_constant, CALLER_PC);
-}
-
-template void* CHeapObj::operator new [](size_t size,
- const NativeCallStack& stack) throw() {
- return CHeapObj::operator new(size, stack);
-}
-
-template void* CHeapObj::operator new [](size_t size)
- throw() {
- return CHeapObj::operator new(size, CALLER_PC);
-}
-
-template void* CHeapObj::operator new [](size_t size,
- const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
- return CHeapObj::operator new(size, nothrow_constant, stack);
-}
-
-template void* CHeapObj::operator new [](size_t size,
- const std::nothrow_t& nothrow_constant) throw() {
- return CHeapObj::operator new(size, nothrow_constant, CALLER_PC);
-}
-
-template void CHeapObj::operator delete(void* p){
- FreeHeap(p);
-}
-
-template void CHeapObj::operator delete [](void* p){
- FreeHeap(p);
-}
-
template
size_t MmapArrayAllocator::size_for(size_t length) {
size_t size = length * sizeof(E);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/memRegion.hpp
--- a/src/hotspot/share/memory/memRegion.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/memRegion.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,7 @@
// Note that MemRegions are passed by value, not by reference.
// The intent is that they remain very small and contain no
// objects. These should never be allocated in heap but we do
-// create MemRegions (in CardTableModRefBS) in heap so operator
+// create MemRegions (in CardTableBarrierSet) in heap so operator
// new and operator new [] added for this special case.
class MetaWord;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/metaspace.cpp
--- a/src/hotspot/share/memory/metaspace.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/metaspace.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -113,6 +113,7 @@
} else if (size == ClassMediumChunk) {
return MediumIndex;
} else if (size > ClassMediumChunk) {
+ // A valid humongous chunk size is a multiple of the smallest chunk size.
assert(is_aligned(size, ClassSpecializedChunk), "Invalid chunk size");
return HumongousIndex;
}
@@ -124,6 +125,7 @@
} else if (size == MediumChunk) {
return MediumIndex;
} else if (size > MediumChunk) {
+ // A valid humongous chunk size is a multiple of the smallest chunk size.
assert(is_aligned(size, SpecializedChunk), "Invalid chunk size");
return HumongousIndex;
}
@@ -299,10 +301,7 @@
Metachunk* free_chunks_get(size_t chunk_word_size);
#define index_bounds_check(index) \
- assert(index == SpecializedIndex || \
- index == SmallIndex || \
- index == MediumIndex || \
- index == HumongousIndex, "Bad index: %d", (int) index)
+ assert(is_valid_chunktype(index), "Bad index: %d", (int) index)
size_t num_free_chunks(ChunkIndex index) const {
index_bounds_check(index);
@@ -2648,25 +2647,13 @@
}
ChunkIndex ChunkManager::list_index(size_t size) {
- if (size_by_index(SpecializedIndex) == size) {
- return SpecializedIndex;
- }
- if (size_by_index(SmallIndex) == size) {
- return SmallIndex;
- }
- const size_t med_size = size_by_index(MediumIndex);
- if (med_size == size) {
- return MediumIndex;
- }
-
- assert(size > med_size, "Not a humongous chunk");
- return HumongousIndex;
+ return get_chunk_type_by_size(size, is_class());
}
size_t ChunkManager::size_by_index(ChunkIndex index) const {
index_bounds_check(index);
assert(index != HumongousIndex, "Do not call for humongous chunks.");
- return _free_chunks[index].size();
+ return get_size_for_nonhumongous_chunktype(index, is_class());
}
void ChunkManager::locked_verify_free_chunks_total() {
@@ -5244,37 +5231,39 @@
// The following test is placed here instead of a gtest / unittest file
// because the ChunkManager class is only available in this file.
void ChunkManager_test_list_index() {
- ChunkManager manager(true);
-
- // Test previous bug where a query for a humongous class metachunk,
- // incorrectly matched the non-class medium metachunk size.
{
- assert(MediumChunk > ClassMediumChunk, "Precondition for test");
-
- ChunkIndex index = manager.list_index(MediumChunk);
-
- assert(index == HumongousIndex,
- "Requested size is larger than ClassMediumChunk,"
- " so should return HumongousIndex. Got index: %d", (int)index);
- }
-
- // Check the specified sizes as well.
- {
- ChunkIndex index = manager.list_index(ClassSpecializedChunk);
- assert(index == SpecializedIndex, "Wrong index returned. Got index: %d", (int)index);
- }
- {
- ChunkIndex index = manager.list_index(ClassSmallChunk);
- assert(index == SmallIndex, "Wrong index returned. Got index: %d", (int)index);
- }
- {
- ChunkIndex index = manager.list_index(ClassMediumChunk);
- assert(index == MediumIndex, "Wrong index returned. Got index: %d", (int)index);
- }
- {
- ChunkIndex index = manager.list_index(ClassMediumChunk + 1);
- assert(index == HumongousIndex, "Wrong index returned. Got index: %d", (int)index);
- }
+ // Test previous bug where a query for a humongous class metachunk,
+ // incorrectly matched the non-class medium metachunk size.
+ {
+ ChunkManager manager(true);
+
+ assert(MediumChunk > ClassMediumChunk, "Precondition for test");
+
+ ChunkIndex index = manager.list_index(MediumChunk);
+
+ assert(index == HumongousIndex,
+ "Requested size is larger than ClassMediumChunk,"
+ " so should return HumongousIndex. Got index: %d", (int)index);
+ }
+
+ // Check the specified sizes as well.
+ {
+ ChunkManager manager(true);
+ assert(manager.list_index(ClassSpecializedChunk) == SpecializedIndex, "sanity");
+ assert(manager.list_index(ClassSmallChunk) == SmallIndex, "sanity");
+ assert(manager.list_index(ClassMediumChunk) == MediumIndex, "sanity");
+ assert(manager.list_index(ClassMediumChunk + ClassSpecializedChunk) == HumongousIndex, "sanity");
+ }
+ {
+ ChunkManager manager(false);
+ assert(manager.list_index(SpecializedChunk) == SpecializedIndex, "sanity");
+ assert(manager.list_index(SmallChunk) == SmallIndex, "sanity");
+ assert(manager.list_index(MediumChunk) == MediumIndex, "sanity");
+ assert(manager.list_index(MediumChunk + SpecializedChunk) == HumongousIndex, "sanity");
+ }
+
+ }
+
}
#endif // !PRODUCT
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/metaspace.hpp
--- a/src/hotspot/share/memory/metaspace.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/metaspace.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -66,6 +66,7 @@
class PrintCLDMetaspaceInfoClosure;
class SpaceManager;
class VirtualSpaceList;
+class CollectedHeap;
// Metaspaces each have a SpaceManager and allocations
// are done by the SpaceManager. Allocations are done
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/metaspaceShared.cpp
--- a/src/hotspot/share/memory/metaspaceShared.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -46,6 +46,7 @@
#include "logging/logMessage.hpp"
#include "memory/filemap.hpp"
#include "memory/metaspace.hpp"
+#include "memory/metaspaceClosure.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceClassLoaderKlass.hpp"
@@ -56,15 +57,15 @@
#include "oops/oop.inline.hpp"
#include "oops/typeArrayKlass.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
-#include "runtime/timerTrace.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/signature.hpp"
+#include "runtime/timerTrace.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/align.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/hashtable.inline.hpp"
-#include "memory/metaspaceClosure.hpp"
ReservedSpace MetaspaceShared::_shared_rs;
VirtualSpace MetaspaceShared::_shared_vs;
@@ -233,6 +234,7 @@
// with the archived ones, so it must be done after all encodings are determined.
mapinfo->map_heap_regions();
}
+ Universe::set_narrow_klass_range(CompressedClassSpaceSize);
#endif // _LP64
} else {
assert(!mapinfo->is_open() && !UseSharedSpaces,
@@ -298,6 +300,8 @@
// Set narrow_klass_shift to be LogKlassAlignmentInBytes. This is consistent
// with AOT.
Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
+ // Set the range of klass addresses to 4GB.
+ Universe::set_narrow_klass_range(cds_total);
Metaspace::initialize_class_space(tmp_class_space);
tty->print_cr("narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d",
@@ -1820,6 +1824,13 @@
os::vm_allocation_granularity());
}
+unsigned MetaspaceShared::obj_hash(oop const& p) {
+ assert(!p->mark()->has_bias_pattern(),
+ "this object should never have been locked"); // so identity_hash won't safepoin
+ unsigned hash = (unsigned)p->identity_hash();
+ return hash;
+}
+
MetaspaceShared::ArchivedObjectCache* MetaspaceShared::_archive_object_cache = NULL;
oop MetaspaceShared::find_archived_heap_object(oop obj) {
assert(DumpSharedSpaces, "dump-time only");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/memory/metaspaceShared.hpp
--- a/src/hotspot/share/memory/metaspaceShared.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "memory/virtualspace.hpp"
-#include "oops/oop.inline.hpp"
+#include "oops/oop.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/macros.hpp"
#include "utilities/resourceHash.hpp"
@@ -96,12 +96,8 @@
static bool obj_equals(oop const& p1, oop const& p2) {
return p1 == p2;
}
- static unsigned obj_hash(oop const& p) {
- assert(!p->mark()->has_bias_pattern(),
- "this object should never have been locked"); // so identity_hash won't safepoin
- unsigned hash = (unsigned)p->identity_hash();
- return hash;
- }
+ static unsigned obj_hash(oop const& p);
+
typedef ResourceHashtable::value, T>::type
atomic_cmpxchg(T new_value, void* addr, T compare_value) {
- typedef RawAccessBarrier Raw;
if (is_hardwired_primitive()) {
const DecoratorSet expanded_decorators = decorators | AS_RAW;
return PreRuntimeDispatch::atomic_cmpxchg(new_value, addr, compare_value);
@@ -761,17 +760,33 @@
template
inline static typename EnableIf<
- HasDecorator::value, bool>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
+ HasDecorator::value && CanHardwireRaw::value, bool>::type
+ arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
typedef RawAccessBarrier Raw;
- return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
+ if (HasDecorator::value) {
+ return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
+ } else {
+ return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
+ }
+ }
+
+ template
+ inline static typename EnableIf<
+ HasDecorator::value && !CanHardwireRaw::value, bool>::type
+ arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ if (UseCompressedOops) {
+ const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
+ return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
+ } else {
+ const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
+ return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
+ }
}
template
inline static typename EnableIf<
!HasDecorator::value, bool>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
- typedef RawAccessBarrier Raw;
+ arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
if (is_hardwired_primitive()) {
const DecoratorSet expanded_decorators = decorators | AS_RAW;
return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
@@ -947,6 +962,24 @@
return PreRuntimeDispatch::load(addr);
}
+ template
+ inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
+ }
+
+ template
+ inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length) {
+ const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
+ return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
+ }
+
+ template
+ inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, narrowOop* src, narrowOop* dst, size_t length) {
+ const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
+ INTERNAL_RT_USE_COMPRESSED_OOPS;
+ return PreRuntimeDispatch::arraycopy(src_obj, dst_obj, src, dst, length);
+ }
+
// Step 1: Set default decorators. This step remembers if a type was volatile
// and then sets the MO_VOLATILE decorator by default. Otherwise, a default
// memory ordering is set for the access, and the implied decorator rules
@@ -1077,18 +1110,16 @@
}
template
- inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
+ inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
STATIC_ASSERT((HasDecorator::value ||
(IsSame::value || IsIntegral::value) ||
IsFloatingPoint::value)); // arraycopy allows type erased void elements
typedef typename Decay::type DecayedT;
- const DecoratorSet expanded_decorators = DecoratorFixup::value ?
- INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
- return PreRuntimeDispatch::arraycopy(src_obj, dst_obj,
- const_cast(src),
- const_cast(dst),
- length);
+ const DecoratorSet expanded_decorators = DecoratorFixup::value;
+ return arraycopy_reduce_types(src_obj, dst_obj,
+ const_cast(src),
+ const_cast(dst),
+ length);
}
template
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/accessBackend.hpp
--- a/src/hotspot/share/oops/accessBackend.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/accessBackend.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -384,7 +384,6 @@
template
static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
- static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length);
static void clone(oop src, oop dst, size_t size);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/accessBackend.inline.hpp
--- a/src/hotspot/share/oops/accessBackend.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/accessBackend.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -122,17 +122,6 @@
}
template
-inline bool RawAccessBarrier::oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length) {
- bool needs_oop_compress = HasDecorator::value &&
- HasDecorator::value;
- if (needs_oop_compress) {
- return arraycopy(reinterpret_cast(src), reinterpret_cast(dst), length);
- } else {
- return arraycopy(reinterpret_cast(src), reinterpret_cast(dst), length);
- }
-}
-
-template
template
inline typename EnableIf<
HasDecorator::value, T>::type
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/annotations.hpp
--- a/src/hotspot/share/oops/annotations.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/annotations.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
#include "oops/array.hpp"
#include "oops/metadata.hpp"
-#include "runtime/handles.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/constantPool.cpp
--- a/src/hotspot/share/oops/constantPool.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/constantPool.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,10 +47,11 @@
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "runtime/fieldType.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/signature.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "utilities/copy.hpp"
constantTag ConstantPool::tag_at(int which) const { return (constantTag)tags()->at_acquire(which); }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/instanceKlass.cpp
--- a/src/hotspot/share/oops/instanceKlass.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/instanceKlass.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -2255,12 +2255,6 @@
}
}
-address InstanceKlass::static_field_addr(int offset) {
- assert(offset >= InstanceMirrorKlass::offset_of_static_fields(), "has already been adjusted");
- return (address)(offset + cast_from_oop(java_mirror()));
-}
-
-
const char* InstanceKlass::signature_name() const {
int hash_len = 0;
char hash_buf[40];
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/instanceKlass.hpp
--- a/src/hotspot/share/oops/instanceKlass.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/instanceKlass.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1070,7 +1070,7 @@
int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
- address static_field_addr(int offset);
+ oop static_field_base_raw() { return java_mirror(); }
OopMapBlock* start_of_nonstatic_oop_maps() const {
return (OopMapBlock*)(start_of_itable() + itable_length());
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/method.inline.hpp
--- a/src/hotspot/share/oops/method.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/method.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_OOPS_METHOD_INLINE_HPP
#include "oops/method.hpp"
-#include "runtime/orderAccess.hpp"
+#include "runtime/orderAccess.inline.hpp"
inline address Method::from_compiled_entry() const {
return OrderAccess::load_acquire(&_from_compiled_entry);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/methodData.cpp
--- a/src/hotspot/share/oops/methodData.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/methodData.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "compiler/compilerOracle.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/linkResolver.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/methodData.hpp
--- a/src/hotspot/share/oops/methodData.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/methodData.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,6 +27,7 @@
#include "interpreter/bytecodes.hpp"
#include "memory/universe.hpp"
+#include "oops/metadata.hpp"
#include "oops/method.hpp"
#include "oops/oop.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/oop.hpp
--- a/src/hotspot/share/oops/oop.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/oop.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -284,8 +284,6 @@
// garbage collection
inline bool is_gc_marked() const;
- inline bool is_scavengable() const;
-
// Forward pointer operations for scavenge
inline bool is_forwarded() const;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/oop.inline.hpp
--- a/src/hotspot/share/oops/oop.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/oop.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -363,10 +363,6 @@
return mark()->is_marked();
}
-bool oopDesc::is_scavengable() const {
- return Universe::heap()->is_scavengable(oop(const_cast(this)));
-}
-
// Used by scavengers
bool oopDesc::is_forwarded() const {
// The extra heap check is needed since the obj might be locked, in which case the
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/oops/typeArrayOop.hpp
--- a/src/hotspot/share/oops/typeArrayOop.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/oops/typeArrayOop.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,6 @@
#include "oops/arrayOop.hpp"
#include "oops/typeArrayKlass.hpp"
-#include "runtime/orderAccess.inline.hpp"
// A typeArrayOop is an array containing basic types (non oop elements).
// It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/callnode.cpp
--- a/src/hotspot/share/opto/callnode.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/callnode.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,7 @@
#include "compiler/compileLog.hpp"
#include "ci/bcEscapeAnalyzer.hpp"
#include "compiler/oopMap.hpp"
+#include "interpreter/interpreter.hpp"
#include "opto/callGenerator.hpp"
#include "opto/callnode.hpp"
#include "opto/castnode.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/compile.cpp
--- a/src/hotspot/share/opto/compile.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/compile.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -397,13 +397,20 @@
remove_range_check_cast(cast);
}
}
- // Remove useless expensive node
+ // Remove useless expensive nodes
for (int i = C->expensive_count()-1; i >= 0; i--) {
Node* n = C->expensive_node(i);
if (!useful.member(n)) {
remove_expensive_node(n);
}
}
+ // Remove useless Opaque4 nodes
+ for (int i = opaque4_count() - 1; i >= 0; i--) {
+ Node* opaq = opaque4_node(i);
+ if (!useful.member(opaq)) {
+ remove_opaque4_node(opaq);
+ }
+ }
// clean up the late inline lists
remove_useless_late_inlines(&_string_late_inlines, useful);
remove_useless_late_inlines(&_boxing_late_inlines, useful);
@@ -1179,6 +1186,7 @@
_predicate_opaqs = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL);
_expensive_nodes = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL);
_range_check_casts = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL);
+ _opaque4_nodes = new(comp_arena()) GrowableArray(comp_arena(), 8, 0, NULL);
register_library_intrinsics();
}
@@ -1957,6 +1965,22 @@
assert(range_check_cast_count() == 0, "should be empty");
}
+void Compile::add_opaque4_node(Node* n) {
+ assert(n->Opcode() == Op_Opaque4, "Opaque4 only");
+ assert(!_opaque4_nodes->contains(n), "duplicate entry in Opaque4 list");
+ _opaque4_nodes->append(n);
+}
+
+// Remove all Opaque4 nodes.
+void Compile::remove_opaque4_nodes(PhaseIterGVN &igvn) {
+ for (int i = opaque4_count(); i > 0; i--) {
+ Node* opaq = opaque4_node(i-1);
+ assert(opaq->Opcode() == Op_Opaque4, "Opaque4 only");
+ igvn.replace_node(opaq, opaq->in(2));
+ }
+ assert(opaque4_count() == 0, "should be empty");
+}
+
// StringOpts and late inlining of string methods
void Compile::inline_string_calls(bool parse_time) {
{
@@ -2332,6 +2356,11 @@
}
}
+ if (opaque4_count() > 0) {
+ C->remove_opaque4_nodes(igvn);
+ igvn.optimize();
+ }
+
DEBUG_ONLY( _modified_nodes = NULL; )
} // (End scope of igvn; run destructor if necessary for asserts.)
@@ -3332,6 +3361,20 @@
}
break;
}
+ case Op_CmpUL: {
+ if (!Matcher::has_match_rule(Op_CmpUL)) {
+ // We don't support unsigned long comparisons. Set 'max_idx_expr'
+ // to max_julong if < 0 to make the signed comparison fail.
+ ConINode* sign_pos = new ConINode(TypeInt::make(BitsPerLong - 1));
+ Node* sign_bit_mask = new RShiftLNode(n->in(1), sign_pos);
+ Node* orl = new OrLNode(n->in(1), sign_bit_mask);
+ ConLNode* remove_sign_mask = new ConLNode(TypeLong::make(max_jlong));
+ Node* andl = new AndLNode(orl, remove_sign_mask);
+ Node* cmp = new CmpLNode(andl, n->in(2));
+ n->subsume_by(cmp, this);
+ }
+ break;
+ }
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/compile.hpp
--- a/src/hotspot/share/opto/compile.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/compile.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -34,6 +34,7 @@
#include "libadt/dict.hpp"
#include "libadt/vectset.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/methodData.hpp"
#include "opto/idealGraphPrinter.hpp"
#include "opto/phasetype.hpp"
#include "opto/phase.hpp"
@@ -415,6 +416,7 @@
GrowableArray* _predicate_opaqs; // List of Opaque1 nodes for the loop predicates.
GrowableArray* _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
GrowableArray* _range_check_casts; // List of CastII nodes with a range check dependency
+ GrowableArray* _opaque4_nodes; // List of Opaque4 nodes that have a default value
ConnectionGraph* _congraph;
#ifndef PRODUCT
IdealGraphPrinter* _printer;
@@ -809,6 +811,16 @@
// Remove all range check dependent CastIINodes.
void remove_range_check_casts(PhaseIterGVN &igvn);
+ void add_opaque4_node(Node* n);
+ void remove_opaque4_node(Node* n) {
+ if (_opaque4_nodes->contains(n)) {
+ _opaque4_nodes->remove(n);
+ }
+ }
+ Node* opaque4_node(int idx) const { return _opaque4_nodes->at(idx); }
+ int opaque4_count() const { return _opaque4_nodes->length(); }
+ void remove_opaque4_nodes(PhaseIterGVN &igvn);
+
// remove the opaque nodes that protect the predicates so that the unused checks and
// uncommon traps will be eliminated from the graph.
void cleanup_loop_predicates(PhaseIterGVN &igvn);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/graphKit.cpp
--- a/src/hotspot/share/opto/graphKit.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/graphKit.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,8 +30,9 @@
#include "gc/g1/heapRegion.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "opto/addnode.hpp"
#include "opto/castnode.hpp"
@@ -1565,7 +1566,7 @@
g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt);
break;
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
break;
default :
@@ -1580,7 +1581,7 @@
case BarrierSet::G1BarrierSet:
return true; // Can move it if no safepoint
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
return true; // There is no pre-barrier
default :
@@ -1604,7 +1605,7 @@
g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
break;
- case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableBarrierSet:
write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
break;
@@ -3811,8 +3812,8 @@
bool GraphKit::use_ReduceInitialCardMarks() {
BarrierSet *bs = Universe::heap()->barrier_set();
- return bs->is_a(BarrierSet::CardTableModRef)
- && barrier_set_cast(bs)->can_elide_tlab_store_barriers()
+ return bs->is_a(BarrierSet::CardTableBarrierSet)
+ && barrier_set_cast(bs)->can_elide_tlab_store_barriers()
&& ReduceInitialCardMarks;
}
@@ -3881,7 +3882,7 @@
Node* cast = __ CastPX(__ ctrl(), adr);
// Divide by card size
- assert(Universe::heap()->barrier_set()->is_a(BarrierSet::CardTableModRef),
+ assert(Universe::heap()->barrier_set()->is_a(BarrierSet::CardTableBarrierSet),
"Only one we handle so far.");
Node* card_offset = __ URShiftX( cast, __ ConI(CardTable::card_shift) );
@@ -4159,7 +4160,7 @@
* as part of the allocation in the case the allocated object is not located
* in the nursery, this would happen for humongous objects. This is similar to
* how CMS is required to handle this case, see the comments for the method
- * CardTableModRefBS::on_allocation_slowpath_exit and OptoRuntime::new_deferred_store_barrier.
+ * CardTableBarrierSet::on_allocation_slowpath_exit and OptoRuntime::new_deferred_store_barrier.
* A deferred card mark is required for these objects and handled in the above
* mentioned methods.
*
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/lcm.cpp
--- a/src/hotspot/share/opto/lcm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/lcm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/ad.hpp"
#include "opto/block.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/library_call.cpp
--- a/src/hotspot/share/opto/library_call.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/library_call.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
+#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/loopPredicate.cpp
--- a/src/hotspot/share/opto/loopPredicate.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/loopPredicate.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -632,7 +632,7 @@
int scale, Node* offset,
Node* init, Node* limit, jint stride,
Node* range, bool upper, bool &overflow) {
- jint con_limit = limit->is_Con() ? limit->get_int() : 0;
+ jint con_limit = (limit != NULL && limit->is_Con()) ? limit->get_int() : 0;
jint con_init = init->is_Con() ? init->get_int() : 0;
jint con_offset = offset->is_Con() ? offset->get_int() : 0;
@@ -751,26 +751,7 @@
// Integer expressions may overflow, do long comparison
range = new ConvI2LNode(range);
register_new_node(range, ctrl);
- if (!Matcher::has_match_rule(Op_CmpUL)) {
- // We don't support unsigned long comparisons. Set 'max_idx_expr'
- // to max_julong if < 0 to make the signed comparison fail.
- ConINode* sign_pos = _igvn.intcon(BitsPerLong - 1);
- set_ctrl(sign_pos, C->root());
- Node* sign_bit_mask = new RShiftLNode(max_idx_expr, sign_pos);
- register_new_node(sign_bit_mask, ctrl);
- // OR with sign bit to set all bits to 1 if negative (otherwise no change)
- max_idx_expr = new OrLNode(max_idx_expr, sign_bit_mask);
- register_new_node(max_idx_expr, ctrl);
- // AND with 0x7ff... to unset the sign bit
- ConLNode* remove_sign_mask = _igvn.longcon(max_jlong);
- set_ctrl(remove_sign_mask, C->root());
- max_idx_expr = new AndLNode(max_idx_expr, remove_sign_mask);
- register_new_node(max_idx_expr, ctrl);
-
- cmp = new CmpLNode(max_idx_expr, range);
- } else {
- cmp = new CmpULNode(max_idx_expr, range);
- }
+ cmp = new CmpULNode(max_idx_expr, range);
} else {
cmp = new CmpUNode(max_idx_expr, range);
}
@@ -785,6 +766,29 @@
return bol;
}
+// After pre/main/post loops are created, we'll put a copy of some
+// range checks between the pre and main loop to validate the initial
+// value of the induction variable for the main loop. Make a copy of
+// the predicates here with an opaque node as a place holder for the
+// initial value.
+ProjNode* PhaseIdealLoop::insert_skeleton_predicate(IfNode* iff, IdealLoopTree *loop,
+ ProjNode* proj, ProjNode *predicate_proj,
+ ProjNode* upper_bound_proj,
+ int scale, Node* offset,
+ Node* init, Node* limit, jint stride,
+ Node* rng, bool &overflow) {
+ assert(proj->_con && predicate_proj->_con, "not a range check?");
+ Node* opaque_init = new Opaque1Node(C, init);
+ register_new_node(opaque_init, upper_bound_proj);
+ BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow);
+ Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); // This will go away once loop opts are over
+ register_new_node(opaque_bol, upper_bound_proj);
+ ProjNode* new_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode());
+ _igvn.replace_input_of(new_proj->in(0), 1, opaque_bol);
+ assert(opaque_init->outcnt() > 0, "should be used");
+ return new_proj;
+}
+
//------------------------------ loop_predication_impl--------------------------
// Insert loop predicates for null checks and range checks
bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
@@ -980,6 +984,10 @@
// any dependent nodes onto the upper bound test.
new_predicate_proj = upper_bound_proj;
+ if (iff->is_RangeCheck()) {
+ new_predicate_proj = insert_skeleton_predicate(iff, loop, proj, predicate_proj, upper_bound_proj, scale, offset, init, limit, stride, rng, overflow);
+ }
+
#ifndef PRODUCT
if (TraceLoopOpts && !TraceLoopPredicate) {
tty->print("Predicate RC ");
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/loopTransform.cpp
--- a/src/hotspot/share/opto/loopTransform.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/loopTransform.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -982,7 +982,7 @@
return n;
}
-bool PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
+Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
Node* castii = new CastIINode(incr, TypeInt::INT, true);
castii->set_req(0, ctrl);
register_new_node(castii, ctrl);
@@ -990,10 +990,138 @@
Node* n = incr->fast_out(i);
if (n->is_Phi() && n->in(0) == loop) {
int nrep = n->replace_edge(incr, castii);
- return true;
+ return castii;
}
}
- return false;
+ return NULL;
+}
+
+// Make a copy of the skeleton range check predicates before the main
+// loop and set the initial value of loop as input. After unrolling,
+// the range of values for the induction variable in the main loop can
+// fall outside the allowed range of values by the array access (main
+// loop is never executed). When that happens, range check
+// CastII/ConvI2L nodes cause some data paths to die. For consistency,
+// the control paths must die too but the range checks were removed by
+// predication. The range checks that we add here guarantee that they
+// do.
+void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* min_taken, Node* castii,
+ IdealLoopTree* outer_loop, LoopNode* outer_main_head,
+ uint dd_main_head) {
+ if (UseLoopPredicate) {
+ Node* entry = pre_head->in(LoopNode::EntryControl);
+ Node* predicate = NULL;
+ predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
+ if (predicate != NULL) {
+ entry = entry->in(0)->in(0);
+ }
+ predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+ if (predicate != NULL) {
+ IfNode* iff = entry->in(0)->as_If();
+ ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con);
+ Node* rgn = uncommon_proj->unique_ctrl_out();
+ assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
+ assert(iff->in(1)->in(1)->Opcode() == Op_Opaque1, "unexpected predicate shape");
+ entry = entry->in(0)->in(0);
+ Node* prev_proj = min_taken;
+ while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
+ uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con);
+ if (uncommon_proj->unique_ctrl_out() != rgn)
+ break;
+ iff = entry->in(0)->as_If();
+ if (iff->in(1)->Opcode() == Op_Opaque4) {
+ Node_Stack to_clone(2);
+ to_clone.push(iff->in(1), 1);
+ uint current = C->unique();
+ Node* result = NULL;
+ // Look for the opaque node to replace with the init value
+ // and clone everything in between. We keep the Opaque4 node
+ // so the duplicated predicates are eliminated once loop
+ // opts are over: they are here only to keep the IR graph
+ // consistent.
+ do {
+ Node* n = to_clone.node();
+ uint i = to_clone.index();
+ Node* m = n->in(i);
+ int op = m->Opcode();
+ if (m->is_Bool() ||
+ m->is_Cmp() ||
+ op == Op_AndL ||
+ op == Op_OrL ||
+ op == Op_RShiftL ||
+ op == Op_LShiftL ||
+ op == Op_AddL ||
+ op == Op_AddI ||
+ op == Op_MulL ||
+ op == Op_MulI ||
+ op == Op_SubL ||
+ op == Op_SubI ||
+ op == Op_ConvI2L) {
+ to_clone.push(m, 1);
+ continue;
+ }
+ if (op == Op_Opaque1) {
+ if (n->_idx < current) {
+ n = n->clone();
+ }
+ n->set_req(i, castii);
+ register_new_node(n, min_taken);
+ to_clone.set_node(n);
+ }
+ for (;;) {
+ Node* cur = to_clone.node();
+ uint j = to_clone.index();
+ if (j+1 < cur->req()) {
+ to_clone.set_index(j+1);
+ break;
+ }
+ to_clone.pop();
+ if (to_clone.size() == 0) {
+ result = cur;
+ break;
+ }
+ Node* next = to_clone.node();
+ j = to_clone.index();
+ if (cur->_idx >= current) {
+ if (next->_idx < current) {
+ next = next->clone();
+ register_new_node(next, min_taken);
+ to_clone.set_node(next);
+ }
+ assert(next->in(j) != cur, "input should have been cloned");
+ next->set_req(j, cur);
+ }
+ }
+ } while (result == NULL);
+ assert(result->_idx >= current, "new node expected");
+
+ Node* proj = entry->clone();
+ Node* other_proj = uncommon_proj->clone();
+ Node* new_iff = iff->clone();
+ new_iff->set_req(1, result);
+ proj->set_req(0, new_iff);
+ other_proj->set_req(0, new_iff);
+ Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
+ register_new_node(frame, C->start());
+ // It's impossible for the predicate to fail at runtime. Use
+ // an Halt node.
+ Node* halt = new HaltNode(other_proj, frame);
+ C->root()->add_req(halt);
+ new_iff->set_req(0, prev_proj);
+
+ register_control(new_iff, outer_loop->_parent, prev_proj);
+ register_control(proj, outer_loop->_parent, new_iff);
+ register_control(other_proj, _ltree_root, new_iff);
+ register_control(halt, _ltree_root, other_proj);
+
+ prev_proj = proj;
+ }
+ entry = entry->in(0)->in(0);
+ }
+ _igvn.replace_input_of(outer_main_head, LoopNode::EntryControl, prev_proj);
+ set_idom(outer_main_head, prev_proj, dd_main_head);
+ }
+ }
}
//------------------------------insert_pre_post_loops--------------------------
@@ -1137,8 +1265,9 @@
// dependencies.
// CastII for the main loop:
- bool inserted = cast_incr_before_loop( pre_incr, min_taken, main_head );
- assert(inserted, "no castII inserted");
+ Node* castii = cast_incr_before_loop( pre_incr, min_taken, main_head );
+ assert(castii != NULL, "no castII inserted");
+ duplicate_predicates(pre_head, min_taken, castii, outer_loop, outer_main_head, dd_main_head);
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
// RCE and alignment may change this later.
@@ -1403,8 +1532,8 @@
}
// CastII for the new post loop:
- bool inserted = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
- assert(inserted, "no castII inserted");
+ Node* castii = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
+ assert(castii != NULL, "no castII inserted");
return new_main_exit;
}
@@ -1467,7 +1596,7 @@
if (!is_canonical_loop_entry(loop_head)) {
return;
}
- opaq = ctrl->in(0)->in(1)->in(1)->in(2);
+ opaq = loop_head->skip_predicates()->in(0)->in(1)->in(1)->in(2);
// Zero-trip test uses an 'opaque' node which is not shared.
assert(opaq->outcnt() == 1 && opaq->in(1) == limit, "");
}
@@ -2034,6 +2163,34 @@
return false;
}
+// Same as PhaseIdealLoop::duplicate_predicates() but for range checks
+// eliminated by iteration splitting.
+Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
+ Node* predicate_proj, int scale_con, Node* offset,
+ Node* limit, jint stride_con) {
+ bool overflow = false;
+ BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, cl->init_trip(), NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow);
+ Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
+ register_new_node(opaque_bol, predicate_proj);
+ IfNode* new_iff = NULL;
+ if (overflow) {
+ new_iff = new IfNode(predicate_proj, bol, PROB_MAX, COUNT_UNKNOWN);
+ } else {
+ new_iff = new RangeCheckNode(predicate_proj, bol, PROB_MAX, COUNT_UNKNOWN);
+ }
+ register_control(new_iff, loop->_parent, predicate_proj);
+ Node* iffalse = new IfFalseNode(new_iff);
+ register_control(iffalse, _ltree_root, new_iff);
+ ProjNode* iftrue = new IfTrueNode(new_iff);
+ register_control(iftrue, loop->_parent, new_iff);
+ Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
+ register_new_node(frame, C->start());
+ Node* halt = new HaltNode(iffalse, frame);
+ register_control(halt, _ltree_root, iffalse);
+ C->root()->add_req(halt);
+ return iftrue;
+}
+
//------------------------------do_range_check---------------------------------
// Eliminate range-checks and other trip-counter vs loop-invariant tests.
int PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
@@ -2069,7 +2226,7 @@
}
// Need to find the main-loop zero-trip guard
- Node *ctrl = cl->skip_strip_mined()->in(LoopNode::EntryControl);
+ Node *ctrl = cl->skip_predicates();
Node *iffm = ctrl->in(0);
Node *opqzm = iffm->in(1)->in(1)->in(2);
assert(opqzm->in(1) == main_limit, "do not understand situation");
@@ -2124,6 +2281,8 @@
// the loop is in canonical form to multiversion.
closed_range_checks = 0;
+ Node* predicate_proj = cl->skip_strip_mined()->in(LoopNode::EntryControl);
+ assert(predicate_proj->is_Proj() && predicate_proj->in(0)->is_If(), "if projection only");
// Check loop body for tests of trip-counter plus loop-invariant vs loop-variant.
for( uint i = 0; i < loop->_body.size(); i++ ) {
Node *iff = loop->_body[i];
@@ -2168,7 +2327,7 @@
// 'limit' maybe pinned below the zero trip test (probably from a
// previous round of rce), in which case, it can't be used in the
// zero trip test expression which must occur before the zero test's if.
- if( limit_c == ctrl ) {
+ if (is_dominator(ctrl, limit_c)) {
continue; // Don't rce this check but continue looking for other candidates.
}
@@ -2186,7 +2345,7 @@
// As above for the 'limit', the 'offset' maybe pinned below the
// zero trip test.
- if( offset_c == ctrl ) {
+ if (is_dominator(ctrl, offset_c)) {
continue; // Don't rce this check but continue looking for other candidates.
}
#ifdef ASSERT
@@ -2209,6 +2368,7 @@
add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
// (0-offset)/scale could be outside of loop iterations range.
conditional_rc = true;
+ predicate_proj = add_range_check_predicate(loop, cl, predicate_proj, scale_con, offset, limit, stride_con);
} else {
if (PrintOpto) {
tty->print_cr("missed RCE opportunity");
@@ -2278,6 +2438,10 @@
} // End of is IF
}
+ if (predicate_proj != cl->skip_strip_mined()->in(LoopNode::EntryControl)) {
+ _igvn.replace_input_of(cl->skip_strip_mined(), LoopNode::EntryControl, predicate_proj);
+ set_idom(cl->skip_strip_mined(), predicate_proj, dom_depth(cl->skip_strip_mined()));
+ }
// Update loop limits
if (conditional_rc) {
@@ -2540,7 +2704,7 @@
#ifdef ASSERT
static CountedLoopNode* locate_pre_from_main(CountedLoopNode *cl) {
- Node *ctrl = cl->skip_strip_mined()->in(LoopNode::EntryControl);
+ Node *ctrl = cl->skip_predicates();
assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "");
Node *iffm = ctrl->in(0);
assert(iffm->Opcode() == Op_If, "");
@@ -2579,7 +2743,7 @@
}
assert(locate_pre_from_main(main_head) == cl, "bad main loop");
- Node* main_iff = main_head->skip_strip_mined()->in(LoopNode::EntryControl)->in(0);
+ Node* main_iff = main_head->skip_predicates()->in(0);
// Remove the Opaque1Node of the pre loop and make it execute all iterations
phase->_igvn.replace_input_of(pre_cmp, 2, pre_cmp->in(2)->in(2));
@@ -2640,7 +2804,7 @@
}
if (needs_guard) {
// Check for an obvious zero trip guard.
- Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->skip_strip_mined()->in(LoopNode::EntryControl));
+ Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->skip_predicates());
if (inctrl->Opcode() == Op_IfTrue || inctrl->Opcode() == Op_IfFalse) {
bool maybe_swapped = (inctrl->Opcode() == Op_IfFalse);
// The test should look like just the backedge of a CountedLoop
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/loopnode.cpp
--- a/src/hotspot/share/opto/loopnode.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/loopnode.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1158,9 +1158,9 @@
return NULL;
}
-LoopNode* CountedLoopNode::skip_strip_mined(int expect_opaq) {
+LoopNode* CountedLoopNode::skip_strip_mined(int expect_skeleton) {
if (is_strip_mined()) {
- verify_strip_mined(expect_opaq);
+ verify_strip_mined(expect_skeleton);
return in(EntryControl)->as_Loop();
}
return this;
@@ -1252,6 +1252,20 @@
return l->outer_safepoint();
}
+Node* CountedLoopNode::skip_predicates() {
+ if (is_main_loop()) {
+ Node* ctrl = skip_strip_mined()->in(LoopNode::EntryControl);
+ while (ctrl != NULL && ctrl->is_Proj() && ctrl->in(0)->is_If() &&
+ ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->outcnt() == 1 &&
+ ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->unique_out()->Opcode() == Op_Halt) {
+ ctrl = ctrl->in(0)->in(0);
+ }
+
+ return ctrl;
+ }
+ return in(LoopNode::EntryControl);
+}
+
void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
// Look for the outer & inner strip mined loop, reduce number of
// iterations of the inner loop, set exit condition of outer loop,
@@ -3770,7 +3784,8 @@
if (!cl->is_main_loop() && !cl->is_post_loop()) {
return false;
}
- Node* ctrl = cl->skip_strip_mined()->in(LoopNode::EntryControl);
+ Node* ctrl = cl->skip_predicates();
+
if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) {
return false;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/loopnode.hpp
--- a/src/hotspot/share/opto/loopnode.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/loopnode.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -138,7 +138,7 @@
#endif
void verify_strip_mined(int expect_skeleton) const;
- virtual LoopNode* skip_strip_mined(int expect_opaq = 1) { return this; }
+ virtual LoopNode* skip_strip_mined(int expect_skeleton = 1) { return this; }
virtual IfTrueNode* outer_loop_tail() const { ShouldNotReachHere(); return NULL; }
virtual OuterStripMinedLoopEndNode* outer_loop_end() const { ShouldNotReachHere(); return NULL; }
virtual IfFalseNode* outer_loop_exit() const { ShouldNotReachHere(); return NULL; }
@@ -298,6 +298,11 @@
virtual IfFalseNode* outer_loop_exit() const;
virtual SafePointNode* outer_safepoint() const;
+ // If this is a main loop in a pre/main/post loop nest, walk over
+ // the predicates that were inserted by
+ // duplicate_predicates()/add_range_check_predicate()
+ Node* skip_predicates();
+
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
@@ -724,7 +729,10 @@
return ctrl;
}
- bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
+ Node* cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
+ void duplicate_predicates(CountedLoopNode* pre_head, Node *min_taken, Node* castii,
+ IdealLoopTree* outer_loop, LoopNode* outer_main_head,
+ uint dd_main_head);
public:
@@ -1067,6 +1075,15 @@
// Implementation of the loop predication to promote checks outside the loop
bool loop_predication_impl(IdealLoopTree *loop);
+ ProjNode* insert_skeleton_predicate(IfNode* iff, IdealLoopTree *loop,
+ ProjNode* proj, ProjNode *predicate_proj,
+ ProjNode* upper_bound_proj,
+ int scale, Node* offset,
+ Node* init, Node* limit, jint stride,
+ Node* rng, bool& overflow);
+ Node* add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
+ Node* predicate_proj, int scale_con, Node* offset,
+ Node* limit, jint stride_con);
// Helper function to collect predicate for eliminating the useless ones
void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/loopopts.cpp
--- a/src/hotspot/share/opto/loopopts.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/loopopts.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1029,11 +1029,18 @@
//------------------------------place_near_use---------------------------------
// Place some computation next to use but not inside inner loops.
// For inner loop uses move it to the preheader area.
-Node *PhaseIdealLoop::place_near_use( Node *useblock ) const {
+Node *PhaseIdealLoop::place_near_use(Node *useblock) const {
IdealLoopTree *u_loop = get_loop( useblock );
- return (u_loop->_irreducible || u_loop->_child)
- ? useblock
- : u_loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl);
+ if (u_loop->_irreducible) {
+ return useblock;
+ }
+ if (u_loop->_child) {
+ if (useblock == u_loop->_head && u_loop->_head->is_OuterStripMinedLoop()) {
+ return u_loop->_head->in(LoopNode::EntryControl);
+ }
+ return useblock;
+ }
+ return u_loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/macro.cpp
--- a/src/hotspot/share/opto/macro.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/macro.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
+#include "gc/shared/collectedHeap.inline.hpp"
#include "libadt/vectset.hpp"
#include "opto/addnode.hpp"
#include "opto/arraycopynode.hpp"
@@ -2667,8 +2668,7 @@
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_Opaque1 ||
n->Opcode() == Op_Opaque2 ||
- n->Opcode() == Op_Opaque3 ||
- n->Opcode() == Op_Opaque4, "unknown node type in macro list");
+ n->Opcode() == Op_Opaque3, "unknown node type in macro list");
}
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
progress = progress || success;
@@ -2733,9 +2733,6 @@
_igvn.replace_node(n, repl);
success = true;
#endif
- } else if (n->Opcode() == Op_Opaque4) {
- _igvn.replace_node(n, n->in(2));
- success = true;
} else if (n->Opcode() == Op_OuterStripMinedLoop) {
n->as_OuterStripMinedLoop()->adjust_strip_mined_loop(&_igvn);
C->remove_macro_node(n);
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/node.cpp
--- a/src/hotspot/share/opto/node.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/node.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -504,6 +504,9 @@
if (cast != NULL && cast->has_range_check()) {
C->add_range_check_cast(cast);
}
+ if (n->Opcode() == Op_Opaque4) {
+ C->add_opaque4_node(n);
+ }
n->set_idx(C->next_unique()); // Get new unique index as well
debug_only( n->verify_construction() );
@@ -612,6 +615,9 @@
if (cast != NULL && cast->has_range_check()) {
compile->remove_range_check_cast(cast);
}
+ if (Opcode() == Op_Opaque4) {
+ compile->remove_opaque4_node(this);
+ }
if (is_SafePoint()) {
as_SafePoint()->delete_replaced_nodes();
@@ -1352,6 +1358,9 @@
if (cast != NULL && cast->has_range_check()) {
igvn->C->remove_range_check_cast(cast);
}
+ if (dead->Opcode() == Op_Opaque4) {
+ igvn->C->remove_range_check_cast(dead);
+ }
igvn->C->record_dead_node(dead->_idx);
// Kill all inputs to the dead guy
for (uint i=0; i < dead->req(); i++) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/opaquenode.cpp
--- a/src/hotspot/share/opto/opaquenode.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/opaquenode.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -60,10 +60,6 @@
return (&n == this); // Always fail except on self
}
-Node* Opaque4Node::Identity(PhaseGVN* phase) {
- return phase->C->major_progress() ? this : in(2);
-}
-
const Type* Opaque4Node::Value(PhaseGVN* phase) const {
return phase->type(in(1));
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/opaquenode.hpp
--- a/src/hotspot/share/opto/opaquenode.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/opaquenode.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,14 +35,14 @@
virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const;
public:
- Opaque1Node( Compile* C, Node *n ) : Node(0,n) {
+ Opaque1Node(Compile* C, Node *n) : Node(NULL, n) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
// Special version for the pre-loop to hold the original loop limit
// which is consumed by range check elimination.
- Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {
+ Opaque1Node(Compile* C, Node *n, Node* orig_limit) : Node(NULL, n, orig_limit) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
@@ -87,25 +87,23 @@
bool rtm_opt() const { return (_opt == RTM_OPT); }
};
-// Used by GraphKit::must_be_not_null(): input 1 is a check that we
-// know implicitly is always true or false but the compiler has no way
-// to prove. If during optimizations, that check becomes true or
-// false, the Opaque4 node is replaced by that constant true or
-// false. Input 2 is the constant value we know the test takes. After
-// loop optimizations, we replace input 1 by input 2 so the control
-// that depends on that test can be removed and there's no overhead at
-// runtime.
+// Input 1 is a check that we know implicitly is always true or false
+// but the compiler has no way to prove. If during optimizations, that
+// check becomes true or false, the Opaque4 node is replaced by that
+// constant true or false. Input 2 is the constant value we know the
+// test takes. After loop optimizations, we replace input 1 by input 2
+// so the control that depends on that test can be removed and there's
+// no overhead at runtime. Used for instance by
+// GraphKit::must_be_not_null().
class Opaque4Node : public Node {
public:
- Opaque4Node(Compile* C, Node *tst, Node* final_tst) : Node(0, tst, final_tst) {
- // Put it on the Macro nodes list to removed during macro nodes expansion.
- init_flags(Flag_is_macro);
- C->add_macro_node(this);
+ Opaque4Node(Compile* C, Node *tst, Node* final_tst) : Node(NULL, tst, final_tst) {
+ // Put it on the Opaque4 nodes list to be removed after all optimizations
+ C->add_opaque4_node(this);
}
virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::BOOL; }
virtual const Type* Value(PhaseGVN* phase) const;
- virtual Node* Identity(PhaseGVN* phase);
};
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/output.cpp
--- a/src/hotspot/share/opto/output.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/output.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/assembler.inline.hpp"
+#include "asm/macroAssembler.inline.hpp"
#include "code/compiledIC.hpp"
#include "code/debugInfo.hpp"
#include "code/debugInfoRec.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/parse1.cpp
--- a/src/hotspot/share/opto/parse1.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/parse1.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,6 +39,7 @@
#include "opto/runtime.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/copy.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/phaseX.cpp
--- a/src/hotspot/share/opto/phaseX.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/phaseX.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1421,6 +1421,9 @@
if (cast != NULL && cast->has_range_check()) {
C->remove_range_check_cast(cast);
}
+ if (dead->Opcode() == Op_Opaque4) {
+ C->remove_opaque4_node(dead);
+ }
}
} // while (_stack.is_nonempty())
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/runtime.cpp
--- a/src/hotspot/share/opto/runtime.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/runtime.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
+#include "code/compiledMethod.inline.hpp"
#include "code/compiledIC.hpp"
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
@@ -60,8 +61,9 @@
#include "opto/runtime.hpp"
#include "opto/subnode.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/opto/superword.cpp
--- a/src/hotspot/share/opto/superword.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/opto/superword.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -3328,7 +3328,7 @@
return NULL;
}
- Node* p_f = cl->skip_strip_mined()->in(LoopNode::EntryControl)->in(0)->in(0);
+ Node* p_f = cl->skip_predicates()->in(0)->in(0);
if (!p_f->is_IfFalse()) return NULL;
if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/precompiled/precompiled.hpp
--- a/src/hotspot/share/precompiled/precompiled.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/precompiled/precompiled.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -54,7 +54,7 @@
# include "ci/ciSymbol.hpp"
# include "ci/ciType.hpp"
# include "ci/ciTypeArrayKlass.hpp"
-# include "ci/ciUtilities.hpp"
+# include "ci/ciUtilities.inline.hpp"
# include "ci/compilerInterface.hpp"
# include "classfile/classFileParser.hpp"
# include "classfile/classFileStream.hpp"
@@ -95,7 +95,7 @@
# include "gc/shared/ageTable.hpp"
# include "gc/shared/barrierSet.hpp"
# include "gc/shared/blockOffsetTable.hpp"
-# include "gc/shared/cardTableModRefBS.hpp"
+# include "gc/shared/cardTableBarrierSet.hpp"
# include "gc/shared/collectedHeap.hpp"
# include "gc/shared/collectorCounters.hpp"
# include "gc/shared/collectorPolicy.hpp"
@@ -176,7 +176,7 @@
# include "runtime/handles.inline.hpp"
# include "runtime/icache.hpp"
# include "runtime/init.hpp"
-# include "runtime/interfaceSupport.hpp"
+# include "runtime/interfaceSupport.inline.hpp"
# include "runtime/java.hpp"
# include "runtime/javaCalls.hpp"
# include "runtime/javaFrameAnchor.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/forte.cpp
--- a/src/hotspot/share/prims/forte.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/forte.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,9 +30,10 @@
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "prims/forte.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/thread.inline.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
// call frame copied from old .h file and renamed
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jni.cpp
--- a/src/hotspot/share/prims/jni.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jni.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -36,7 +36,6 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
-#include "gc/shared/gcLocker.inline.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
@@ -65,7 +64,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
@@ -3149,11 +3148,11 @@
JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
JNIWrapper("GetPrimitiveArrayCritical");
HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
- GCLocker::lock_critical(thread);
if (isCopy != NULL) {
*isCopy = JNI_FALSE;
}
oop a = JNIHandles::resolve_non_null(array);
+ a = Universe::heap()->pin_object(thread, a);
assert(a->is_array(), "just checking");
BasicType type;
if (a->is_objArray()) {
@@ -3170,8 +3169,8 @@
JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
JNIWrapper("ReleasePrimitiveArrayCritical");
HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
- // The array, carray and mode arguments are ignored
- GCLocker::unlock_critical(thread);
+ oop a = JNIHandles::resolve_non_null(array);
+ Universe::heap()->unpin_object(thread, a);
HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
JNI_END
@@ -3179,8 +3178,8 @@
JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
JNIWrapper("GetStringCritical");
HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
- GCLocker::lock_critical(thread);
oop s = JNIHandles::resolve_non_null(string);
+ s = Universe::heap()->pin_object(thread, s);
typeArrayOop s_value = java_lang_String::value(s);
bool is_latin1 = java_lang_String::is_latin1(s);
if (isCopy != NULL) {
@@ -3217,7 +3216,7 @@
// This assumes that ReleaseStringCritical bookends GetStringCritical.
FREE_C_HEAP_ARRAY(jchar, chars);
}
- GCLocker::unlock_critical(thread);
+ Universe::heap()->unpin_object(thread, s);
HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
JNI_END
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jniCheck.cpp
--- a/src/hotspot/share/prims/jniCheck.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jniCheck.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -36,8 +36,8 @@
#include "prims/jniCheck.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/fieldDescriptor.hpp"
-#include "runtime/handles.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/prims/jvm.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvm.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -57,7 +57,7 @@
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
@@ -68,7 +68,7 @@
#include "runtime/reflection.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vm_operations.hpp"
#include "runtime/vm_version.hpp"
#include "services/attachListener.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp
--- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "interpreter/bytecodeStream.hpp"
#include "oops/fieldStreams.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/signature.hpp"
#include "utilities/bytes.hpp"
@@ -34,6 +35,19 @@
// FIXME: fix Synthetic attribute
// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()
+JvmtiConstantPoolReconstituter::JvmtiConstantPoolReconstituter(InstanceKlass* ik) {
+ set_error(JVMTI_ERROR_NONE);
+ _ik = ik;
+ _cpool = constantPoolHandle(Thread::current(), ik->constants());
+ _symmap = new SymbolHashMap();
+ _classmap = new SymbolHashMap();
+ _cpool_size = _cpool->hash_entries_to(_symmap, _classmap);
+ if (_cpool_size == 0) {
+ set_error(JVMTI_ERROR_OUT_OF_MEMORY);
+ } else if (_cpool_size < 0) {
+ set_error(JVMTI_ERROR_INTERNAL);
+ }
+}
// Write the field information portion of ClassFile structure
// JVMSpec| u2 fields_count;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp
--- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -52,19 +52,7 @@
public:
// Calls to this constructor must be proceeded by a ResourceMark
// and a HandleMark
- JvmtiConstantPoolReconstituter(InstanceKlass* ik){
- set_error(JVMTI_ERROR_NONE);
- _ik = ik;
- _cpool = constantPoolHandle(Thread::current(), ik->constants());
- _symmap = new SymbolHashMap();
- _classmap = new SymbolHashMap();
- _cpool_size = _cpool->hash_entries_to(_symmap, _classmap);
- if (_cpool_size == 0) {
- set_error(JVMTI_ERROR_OUT_OF_MEMORY);
- } else if (_cpool_size < 0) {
- set_error(JVMTI_ERROR_INTERNAL);
- }
- }
+ JvmtiConstantPoolReconstituter(InstanceKlass* ik);
~JvmtiConstantPoolReconstituter() {
if (_symmap != NULL) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnter.hpp
--- a/src/hotspot/share/prims/jvmtiEnter.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_PRIMS_JVMTIENTER_HPP
-#define SHARE_VM_PRIMS_JVMTIENTER_HPP
-
-#include "classfile/systemDictionary.hpp"
-#include "jvmtifiles/jvmtiEnv.hpp"
-#include "memory/resourceArea.hpp"
-#include "prims/jvmtiImpl.hpp"
-#include "runtime/interfaceSupport.hpp"
-
-#endif // SHARE_VM_PRIMS_JVMTIENTER_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnter.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/prims/jvmtiEnter.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_JVMTIENTER_INLINE_HPP
+#define SHARE_VM_PRIMS_JVMTIENTER_INLINE_HPP
+
+#include "classfile/systemDictionary.hpp"
+#include "jvmtifiles/jvmtiEnv.hpp"
+#include "memory/resourceArea.hpp"
+#include "prims/jvmtiImpl.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+
+#endif // SHARE_VM_PRIMS_JVMTIENTER_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnter.xsl
--- a/src/hotspot/share/prims/jvmtiEnter.xsl Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnter.xsl Fri Mar 30 09:24:04 2018 -0700
@@ -42,7 +42,7 @@
#if INCLUDE_JVMTI
# include "logging/log.hpp"
# include "oops/oop.inline.hpp"
-# include "prims/jvmtiEnter.hpp"
+# include "prims/jvmtiEnter.inline.hpp"
# include "prims/jvmtiRawMonitor.hpp"
# include "prims/jvmtiUtil.hpp"
# include "runtime/threadSMR.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnv.cpp
--- a/src/hotspot/share/prims/jvmtiEnv.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -55,17 +55,18 @@
#include "prims/jvmtiUtil.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/jniHandles.inline.hpp"
+#include "runtime/objectMonitor.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.hpp"
#include "runtime/timerTrace.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vmThread.hpp"
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnvBase.cpp
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -38,7 +38,8 @@
#include "prims/jvmtiThreadState.inline.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/objectMonitor.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnvBase.hpp
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,11 +29,9 @@
#include "prims/jvmtiEnvThreadState.hpp"
#include "prims/jvmtiEventController.hpp"
#include "prims/jvmtiThreadState.hpp"
-#include "prims/jvmtiThreadState.inline.hpp"
#include "oops/oopHandle.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/frame.hpp"
-#include "runtime/handles.inline.hpp"
#include "runtime/thread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/growableArray.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiEnvThreadState.cpp
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -32,7 +32,7 @@
#include "prims/jvmtiImpl.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/signature.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiExport.cpp
--- a/src/hotspot/share/prims/jvmtiExport.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiExport.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -48,7 +48,7 @@
#include "prims/jvmtiThreadState.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/objectMonitor.hpp"
@@ -56,8 +56,7 @@
#include "runtime/os.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.hpp"
-#include "runtime/vframe.hpp"
-#include "services/serviceUtil.hpp"
+#include "runtime/vframe.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/parallel/psMarkSweep.hpp"
@@ -2363,10 +2362,6 @@
void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {
oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- // Ignore monitor contended enter for vm internal object.
- return;
- }
JvmtiThreadState *state = thread->jvmti_thread_state();
if (state == NULL) {
return;
@@ -2398,10 +2393,6 @@
void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {
oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- // Ignore monitor contended entered for vm internal object.
- return;
- }
JvmtiThreadState *state = thread->jvmti_thread_state();
if (state == NULL) {
return;
@@ -2465,10 +2456,6 @@
void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {
oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- // Ignore monitor waited for vm internal object.
- return;
- }
JvmtiThreadState *state = thread->jvmti_thread_state();
if (state == NULL) {
return;
@@ -2761,9 +2748,7 @@
set_enabled(false);
for (int i = 0; i < _allocated->length(); i++) {
oop obj = _allocated->at(i);
- if (ServiceUtil::visible_oop(obj)) {
- JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj);
- }
+ JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj);
}
delete _allocated;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,13 +27,10 @@
#include "gc/shared/collectedHeap.hpp"
#include "memory/universe.hpp"
#include "prims/jvmtiGetLoadedClasses.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.hpp"
#include "utilities/stack.inline.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1BarrierSet.hpp"
-#endif
-
// The closure for GetLoadedClasses
class LoadedClassesClosure : public KlassClosure {
@@ -42,20 +39,6 @@
JvmtiEnv* _env;
Thread* _cur_thread;
-// Tell the GC to keep this klass alive
-static void ensure_klass_alive(oop o) {
- // A klass that was previously considered dead can be looked up in the
- // CLD/SD, and its _java_mirror or _class_loader can be stored in a root
- // or a reachable object making it alive again. The SATB part of G1 needs
- // to get notified about this potential resurrection, otherwise the marking
- // might not find the object.
-#if INCLUDE_ALL_GCS
- if (UseG1GC && o != NULL) {
- G1BarrierSet::enqueue(o);
- }
-#endif
-}
-
public:
LoadedClassesClosure(Thread* thread, JvmtiEnv* env) : _cur_thread(thread), _env(env) {
assert(_cur_thread == Thread::current(), "must be current thread");
@@ -64,7 +47,6 @@
void do_klass(Klass* k) {
// Collect all jclasses
_classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror())));
- ensure_klass_alive(k->java_mirror());
}
int extract(jclass* result_list) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiImpl.cpp
--- a/src/hotspot/share/prims/jvmtiImpl.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,9 +39,9 @@
#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/atomic.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
#include "runtime/serviceThread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiRawMonitor.cpp
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "memory/allocation.inline.hpp"
#include "prims/jvmtiRawMonitor.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiRedefineClasses.cpp
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,6 +47,7 @@
#include "prims/resolvedMethodTable.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/deoptimization.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/relocator.hpp"
#include "utilities/bitMap.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiTagMap.cpp
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -45,6 +45,8 @@
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/mutex.hpp"
@@ -55,7 +57,6 @@
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
-#include "services/serviceUtil.hpp"
#include "utilities/macros.hpp"
// JvmtiTagHashmapEntry
@@ -1324,9 +1325,6 @@
// check if iteration has been halted
if (is_iteration_aborted()) return;
- // ignore any objects that aren't visible to profiler
- if (!ServiceUtil::visible_oop(o)) return;
-
// instanceof check when filtering by klass
if (klass() != NULL && !o->is_a(klass())) {
return;
@@ -1407,9 +1405,6 @@
// check if iteration has been halted
if (is_iteration_aborted()) return;
- // ignore any objects that aren't visible to profiler
- if (!ServiceUtil::visible_oop(obj)) return;
-
// apply class filter
if (is_filtered_by_klass_filter(obj, klass())) return;
@@ -1987,8 +1982,6 @@
// invoke basic style heap root callback
inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
- assert(ServiceUtil::visible_oop(obj), "checking");
-
// if we heap roots should be reported
jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
if (cb == NULL) {
@@ -2016,8 +2009,6 @@
jmethodID method,
int slot,
oop obj) {
- assert(ServiceUtil::visible_oop(obj), "checking");
-
// if we stack refs should be reported
jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
if (cb == NULL) {
@@ -2048,9 +2039,6 @@
oop referree,
jint index) {
- assert(ServiceUtil::visible_oop(referrer), "checking");
- assert(ServiceUtil::visible_oop(referree), "checking");
-
BasicHeapWalkContext* context = basic_context();
// callback requires the referrer's tag. If it's the same referrer
@@ -2092,8 +2080,6 @@
// invoke advanced style heap root callback
inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
oop obj) {
- assert(ServiceUtil::visible_oop(obj), "checking");
-
AdvancedHeapWalkContext* context = advanced_context();
// check that callback is provided
@@ -2148,8 +2134,6 @@
jlocation bci,
jint slot,
oop obj) {
- assert(ServiceUtil::visible_oop(obj), "checking");
-
AdvancedHeapWalkContext* context = advanced_context();
// check that callback is provider
@@ -2223,9 +2207,6 @@
// field index is only valid field in reference_info
static jvmtiHeapReferenceInfo reference_info = { 0 };
- assert(ServiceUtil::visible_oop(referrer), "checking");
- assert(ServiceUtil::visible_oop(obj), "checking");
-
AdvancedHeapWalkContext* context = advanced_context();
// check that callback is provider
@@ -2279,7 +2260,6 @@
inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
- assert(ServiceUtil::visible_oop(obj), "checking");
if (is_basic_heap_walk()) {
// map to old style root kind
@@ -2604,13 +2584,6 @@
}
}
- // some objects are ignored - in the case of simple
- // roots it's mostly Symbol*s that we are skipping
- // here.
- if (!ServiceUtil::visible_oop(o)) {
- return;
- }
-
// invoke the callback
_continue = CallbackInvoker::report_simple_root(kind, o);
@@ -2651,10 +2624,6 @@
return;
}
- if (!ServiceUtil::visible_oop(o)) {
- return;
- }
-
// invoke the callback
_continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
}
@@ -2982,7 +2951,7 @@
if (!is_primitive_field_type(type)) {
oop fld_o = o->obj_field(field->field_offset());
// ignore any objects that aren't visible to profiler
- if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
+ if (fld_o != NULL) {
assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
"have references to Klass* anymore");
int slot = field->field_index();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/jvmtiUtil.cpp
--- a/src/hotspot/share/prims/jvmtiUtil.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiUtil.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,7 @@
#include "prims/jvmtiUtil.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/exceptions.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/methodHandles.cpp
--- a/src/hotspot/share/prims/methodHandles.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/methodHandles.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -39,6 +39,7 @@
#include "oops/typeArrayOop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/timerTrace.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/methodHandles.hpp
--- a/src/hotspot/share/prims/methodHandles.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/methodHandles.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,13 +27,13 @@
#include "classfile/javaClasses.hpp"
#include "classfile/vmSymbols.hpp"
-#include "runtime/frame.inline.hpp"
+#include "runtime/frame.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
#include "utilities/macros.hpp"
#ifdef ZERO
# include "entry_zero.hpp"
+# include "interpreter/interpreter.hpp"
#endif
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/perf.cpp
--- a/src/hotspot/share/prims/perf.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/perf.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/perfData.inline.hpp"
#include "runtime/perfMemory.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/privilegedStack.cpp
--- a/src/hotspot/share/prims/privilegedStack.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/privilegedStack.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -28,7 +28,7 @@
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/privilegedStack.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
void PrivilegedElement::initialize(vframeStream* vfst, oop context, PrivilegedElement* next, TRAPS) {
Method* method = vfst->method();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/stackwalk.cpp
--- a/src/hotspot/share/prims/stackwalk.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/stackwalk.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -35,7 +35,7 @@
#include "runtime/globals.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "utilities/globalDefinitions.hpp"
// setup and cleanup actions
@@ -64,6 +64,8 @@
_need_method_info = StackWalk::need_method_info(mode);
}
+void JavaFrameStream::next() { _vfst.next();}
+
// Returns the BaseFrameStream for the current stack being traversed.
//
// Parameters:
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/stackwalk.hpp
--- a/src/hotspot/share/prims/stackwalk.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/stackwalk.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -80,7 +80,7 @@
public:
JavaFrameStream(JavaThread* thread, int mode);
- void next() { _vfst.next();}
+ void next();
bool at_end() { return _vfst.at_end(); }
Method* method() { return _vfst.method(); }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/unsafe.cpp
--- a/src/hotspot/share/prims/unsafe.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/unsafe.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -37,7 +37,7 @@
#include "prims/unsafe.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/reflection.hpp"
@@ -367,7 +367,7 @@
size_t sz = (size_t)size;
sz = align_up(sz, HeapWordSize);
- void* x = os::malloc(sz, mtInternal);
+ void* x = os::malloc(sz, mtOther);
return addr_to_java(x);
} UNSAFE_END
@@ -377,7 +377,7 @@
size_t sz = (size_t)size;
sz = align_up(sz, HeapWordSize);
- void* x = os::realloc(p, sz, mtInternal);
+ void* x = os::realloc(p, sz, mtOther);
return addr_to_java(x);
} UNSAFE_END
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/wbtestmethods/parserTests.cpp
--- a/src/hotspot/share/prims/wbtestmethods/parserTests.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/wbtestmethods/parserTests.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,9 +29,9 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/objArrayOop.inline.hpp"
-#include "prims/whitebox.hpp"
+#include "prims/whitebox.inline.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticFramework.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/whitebox.cpp
--- a/src/hotspot/share/prims/whitebox.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/whitebox.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,12 +47,13 @@
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
-#include "prims/whitebox.hpp"
+#include "prims/whitebox.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handshake.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/os.hpp"
@@ -88,6 +89,22 @@
#define SIZE_T_MAX_VALUE ((size_t) -1)
+#define CHECK_JNI_EXCEPTION_(env, value) \
+ do { \
+ JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
+ if (HAS_PENDING_EXCEPTION) { \
+ return(value); \
+ } \
+ } while (0)
+
+#define CHECK_JNI_EXCEPTION(env) \
+ do { \
+ JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
+ if (HAS_PENDING_EXCEPTION) { \
+ return; \
+ } \
+ } while (0)
+
bool WhiteBox::_used = false;
volatile bool WhiteBox::compilation_locked = false;
@@ -849,14 +866,21 @@
bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) {
// Screen for unavailable/bad comp level or null method
- if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) ||
- CompileBroker::compiler(comp_level) == NULL) {
+ AbstractCompiler* comp = CompileBroker::compiler(comp_level);
+ if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) || comp == NULL) {
return false;
}
+
+ // Check if compilation is blocking
methodHandle mh(THREAD, method);
+ DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
+ bool is_blocking = !directive->BackgroundCompilationOption;
+ DirectivesStack::release(directive);
+
+ // Compile method and check result
nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
MutexLockerEx mu(Compile_lock);
- return (mh->queued_for_compilation() || nm != NULL);
+ return ((!is_blocking && mh->queued_for_compilation()) || nm != NULL);
}
WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/whitebox.hpp
--- a/src/hotspot/share/prims/whitebox.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/prims/whitebox.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,8 @@
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "oops/symbol.hpp"
-#include "runtime/interfaceSupport.hpp"
+
+#define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL
// Unconditionally clear pedantic pending JNI checks
class ClearPendingJniExcCheck : public StackObj {
@@ -44,30 +45,6 @@
}
};
-// Entry macro to transition from JNI to VM state.
-
-#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) \
- ClearPendingJniExcCheck _clearCheck(env);
-
-#define WB_END JNI_END
-#define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL
-
-#define CHECK_JNI_EXCEPTION_(env, value) \
- do { \
- JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
- if (HAS_PENDING_EXCEPTION) { \
- return(value); \
- } \
- } while (0)
-
-#define CHECK_JNI_EXCEPTION(env) \
- do { \
- JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
- if (HAS_PENDING_EXCEPTION) { \
- return; \
- } \
- } while (0)
-
class CodeBlob;
class CodeHeap;
class JavaThread;
@@ -93,6 +70,4 @@
static bool compile_method(Method* method, int comp_level, int bci, Thread* THREAD);
};
-
-
#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/prims/whitebox.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/prims/whitebox.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_WHITEBOX_INLINE_HPP
+#define SHARE_VM_PRIMS_WHITEBOX_INLINE_HPP
+
+#include "prims/whitebox.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+
+// Entry macro to transition from JNI to VM state.
+
+#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) \
+ ClearPendingJniExcCheck _clearCheck(env);
+
+#define WB_END JNI_END
+
+#endif // SHARE_VM_PRIMS_WHITEBOX_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/advancedThresholdPolicy.cpp
--- a/src/hotspot/share/runtime/advancedThresholdPolicy.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/advancedThresholdPolicy.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, 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,7 @@
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "runtime/advancedThresholdPolicy.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/simpleThresholdPolicy.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/arguments.cpp
--- a/src/hotspot/share/runtime/arguments.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/arguments.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -517,6 +517,7 @@
{ "PrintSafepointStatistics", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) },
{ "PrintSafepointStatisticsTimeout", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) },
{ "PrintSafepointStatisticsCount",JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) },
+ { "AggressiveOpts", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) },
// --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
{ "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
@@ -2342,10 +2343,6 @@
}
LoopStripMiningIter = 0;
}
- if (FLAG_IS_DEFAULT(LoopStripMiningIterShortLoop)) {
- // blind guess
- LoopStripMiningIterShortLoop = LoopStripMiningIter / 10;
- }
#endif
if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
if ((UseNUMAInterleaving && !FLAG_IS_DEFAULT(UseNUMAInterleaving)) || (UseNUMA && !FLAG_IS_DEFAULT(UseNUMA))) {
@@ -4339,6 +4336,10 @@
// nothing to use the profiling, turn if off
FLAG_SET_DEFAULT(TypeProfileLevel, 0);
}
+ if (FLAG_IS_DEFAULT(LoopStripMiningIterShortLoop)) {
+ // blind guess
+ LoopStripMiningIterShortLoop = LoopStripMiningIter / 10;
+ }
#endif
if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/biasedLocking.cpp
--- a/src/hotspot/share/runtime/biasedLocking.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/biasedLocking.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,6 +31,7 @@
#include "runtime/atomic.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/task.hpp"
#include "runtime/threadSMR.hpp"
#include "runtime/vframe.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/deoptimization.cpp
--- a/src/hotspot/share/runtime/deoptimization.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/deoptimization.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -46,7 +46,8 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/deoptimization.hpp
--- a/src/hotspot/share/runtime/deoptimization.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/deoptimization.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
#define SHARE_VM_RUNTIME_DEOPTIMIZATION_HPP
#include "memory/allocation.hpp"
-#include "runtime/frame.inline.hpp"
+#include "runtime/frame.hpp"
class ProfileData;
class vframeArray;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/fieldDescriptor.hpp
--- a/src/hotspot/share/runtime/fieldDescriptor.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/fieldDescriptor.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,8 @@
#define SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
#include "oops/constantPool.hpp"
+#include "oops/fieldInfo.hpp"
+#include "oops/instanceKlass.hpp"
#include "oops/symbol.hpp"
#include "runtime/fieldType.hpp"
#include "utilities/accessFlags.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/frame.hpp
--- a/src/hotspot/share/runtime/frame.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/frame.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -269,7 +269,6 @@
// expression stack (may go up or down, direction == 1 or -1)
public:
intptr_t* interpreter_frame_expression_stack() const;
- static jint interpreter_frame_expression_stack_direction();
// The _at version returns a pointer because the address is used for GC.
intptr_t* interpreter_frame_expression_stack_at(jint offset) const;
@@ -462,7 +461,7 @@
StackFrameStream(JavaThread *thread, bool update = true);
// Iteration
- bool is_done() { return (_is_done) ? true : (_is_done = _fr.is_first_frame(), false); }
+ inline bool is_done();
void next() { if (!_is_done) _fr = _fr.sender(&_reg_map); }
// Query
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/frame.inline.hpp
--- a/src/hotspot/share/runtime/frame.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/frame.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -63,4 +63,8 @@
}
}
+inline bool StackFrameStream::is_done() {
+ return (_is_done) ? true : (_is_done = _fr.is_first_frame(), false);
+}
+
#endif // SHARE_VM_RUNTIME_FRAME_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/globals.cpp
--- a/src/hotspot/share/runtime/globals.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/globals.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -447,8 +447,7 @@
_name);
return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
}
- get_locked_message_ext(buf, buflen);
- return Flag::NONE;
+ return get_locked_message_ext(buf, buflen);
}
bool Flag::is_writeable() const {
@@ -462,6 +461,18 @@
return is_manageable() || is_external_ext();
}
+// Helper function for Flag::print_on().
+// Fills current line up to requested position.
+// Should the current position already be past the requested position,
+// one separator blank is enforced.
+void fill_to_pos(outputStream* st, unsigned int req_pos) {
+ if ((unsigned int)st->position() < req_pos) {
+ st->fill_to(req_pos); // need to fill with blanks to reach req_pos
+ } else {
+ st->print(" "); // enforce blank separation. Previous field too long.
+ }
+}
+
void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
// Don't print notproduct and develop flags in a product build.
if (is_constant_in_binary()) {
@@ -469,36 +480,82 @@
}
if (!printRanges) {
- // Use some named constants to make code more readable.
- const unsigned int nSpaces = 10;
- const unsigned int maxFlagLen = 40 + nSpaces;
+ // The command line options -XX:+PrintFlags* cause this function to be called
+ // for each existing flag to print information pertinent to this flag. The data
+ // is displayed in columnar form, with the following layout:
+ // col1 - data type, right-justified
+ // col2 - name, left-justified
+ // col3 - ' =' double-char, leading space to align with possible '+='
+ // col4 - value left-justified
+ // col5 - kind right-justified
+ // col6 - origin left-justified
+ // col7 - comments left-justified
+ //
+ // The column widths are fixed. They are defined such that, for most cases,
+ // an eye-pleasing tabular output is created.
+ //
+ // Sample output:
+ // bool CMSScavengeBeforeRemark = false {product} {default}
+ // uintx CMSScheduleRemarkEdenPenetration = 50 {product} {default}
+ // size_t CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} {default}
+ // uintx CMSScheduleRemarkSamplingRatio = 5 {product} {default}
+ // double CMSSmallCoalSurplusPercent = 1.050000 {product} {default}
+ // ccstr CompileCommandFile = MyFile.cmd {product} {command line}
+ // ccstrlist CompileOnly = Method1
+ // CompileOnly += Method2 {product} {command line}
+ // | | | | | | |
+ // | | | | | | +-- col7
+ // | | | | | +-- col6
+ // | | | | +-- col5
+ // | | | +-- col4
+ // | | +-- col3
+ // | +-- col2
+ // +-- col1
- // The print below assumes that the flag name is 40 characters or less.
- // This works for most flags, but there are exceptions. Our longest flag
- // name right now is UseAdaptiveGenerationSizePolicyAtMajorCollection and
- // its minor collection buddy. These are 48 characters. We use a buffer of
- // nSpaces spaces below to adjust the space between the flag value and the
- // column of flag type and origin that is printed in the end of the line.
- char spaces[nSpaces + 1] = " ";
- st->print("%9s %-*s = ", _type, maxFlagLen-nSpaces, _name);
+ const unsigned int col_spacing = 1;
+ const unsigned int col1_pos = 0;
+ const unsigned int col1_width = 9;
+ const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
+ const unsigned int col2_width = 39;
+ const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
+ const unsigned int col3_width = 2;
+ const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
+ const unsigned int col4_width = 30;
+ const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
+ const unsigned int col5_width = 20;
+ const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
+ const unsigned int col6_width = 15;
+ const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
+ const unsigned int col7_width = 1;
+ st->fill_to(col1_pos);
+ st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
+
+ fill_to_pos(st, col2_pos);
+ st->print("%s", _name);
+
+ fill_to_pos(st, col3_pos);
+ st->print(" ="); // use " =" for proper alignment with multiline ccstr output.
+
+ fill_to_pos(st, col4_pos);
if (is_bool()) {
- st->print("%-20s", get_bool() ? "true" : "false");
+ st->print("%s", get_bool() ? "true" : "false");
} else if (is_int()) {
- st->print("%-20d", get_int());
+ st->print("%d", get_int());
} else if (is_uint()) {
- st->print("%-20u", get_uint());
+ st->print("%u", get_uint());
} else if (is_intx()) {
- st->print(INTX_FORMAT_W(-20), get_intx());
+ st->print(INTX_FORMAT, get_intx());
} else if (is_uintx()) {
- st->print(UINTX_FORMAT_W(-20), get_uintx());
+ st->print(UINTX_FORMAT, get_uintx());
} else if (is_uint64_t()) {
- st->print(UINT64_FORMAT_W(-20), get_uint64_t());
+ st->print(UINT64_FORMAT, get_uint64_t());
} else if (is_size_t()) {
- st->print(SIZE_FORMAT_W(-20), get_size_t());
+ st->print(SIZE_FORMAT, get_size_t());
} else if (is_double()) {
- st->print("%-20f", get_double());
+ st->print("%f", get_double());
} else if (is_ccstr()) {
+ // Honor characters in ccstr: print multiple lines.
const char* cp = get_ccstr();
if (cp != NULL) {
const char* eol;
@@ -507,31 +564,85 @@
st->print("%.*s", (int)llen, cp);
st->cr();
cp = eol+1;
- st->print("%5s %-35s += ", "", _name);
+ fill_to_pos(st, col2_pos);
+ st->print("%s", _name);
+ fill_to_pos(st, col3_pos);
+ st->print("+=");
+ fill_to_pos(st, col4_pos);
}
- st->print("%-20s", cp);
+ st->print("%s", cp);
}
- else st->print("%-20s", "");
+ } else {
+ st->print("unhandled type %s", _type);
+ st->cr();
+ return;
}
- // Make sure we do not punch a '\0' at a negative char array index.
- unsigned int nameLen = (unsigned int)strlen(_name);
- if (nameLen <= maxFlagLen) {
- spaces[maxFlagLen - MAX2(maxFlagLen-nSpaces, nameLen)] = '\0';
- st->print("%s", spaces);
- }
- print_kind_and_origin(st);
+
+ fill_to_pos(st, col5_pos);
+ print_kind(st, col5_width);
+
+ fill_to_pos(st, col6_pos);
+ print_origin(st, col6_width);
#ifndef PRODUCT
if (withComments) {
+ fill_to_pos(st, col7_pos);
st->print("%s", _doc);
}
#endif
-
st->cr();
+ } else if (!is_bool() && !is_ccstr()) {
+ // The command line options -XX:+PrintFlags* cause this function to be called
+ // for each existing flag to print information pertinent to this flag. The data
+ // is displayed in columnar form, with the following layout:
+ // col1 - data type, right-justified
+ // col2 - name, left-justified
+ // col4 - range [ min ... max]
+ // col5 - kind right-justified
+ // col6 - origin left-justified
+ // col7 - comments left-justified
+ //
+ // The column widths are fixed. They are defined such that, for most cases,
+ // an eye-pleasing tabular output is created.
+ //
+ // Sample output:
+ // intx MinPassesBeforeFlush [ 0 ... 9223372036854775807 ] {diagnostic} {default}
+ // uintx MinRAMFraction [ 1 ... 18446744073709551615 ] {product} {default}
+ // double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default}
+ // uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default}
+ // size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default}
+ // intx MonitorBound [ 0 ... 2147483647 ] {product} {default}
+ // | | | | | |
+ // | | | | | +-- col7
+ // | | | | +-- col6
+ // | | | +-- col5
+ // | | +-- col4
+ // | +-- col2
+ // +-- col1
- } else if (!is_bool() && !is_ccstr()) {
- st->print("%9s %-50s ", _type, _name);
+ const unsigned int col_spacing = 1;
+ const unsigned int col1_pos = 0;
+ const unsigned int col1_width = 9;
+ const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
+ const unsigned int col2_width = 49;
+ const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
+ const unsigned int col3_width = 0;
+ const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
+ const unsigned int col4_width = 60;
+ const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
+ const unsigned int col5_width = 35;
+ const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
+ const unsigned int col6_width = 15;
+ const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
+ const unsigned int col7_width = 1;
+ st->fill_to(col1_pos);
+ st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
+
+ fill_to_pos(st, col2_pos);
+ st->print("%s", _name);
+
+ fill_to_pos(st, col4_pos);
RangeStrFunc func = NULL;
if (is_int()) {
func = Flag::get_int_default_range_str;
@@ -548,24 +659,29 @@
} else if (is_double()) {
func = Flag::get_double_default_range_str;
} else {
- ShouldNotReachHere();
+ st->print("unhandled type %s", _type);
+ st->cr();
+ return;
}
CommandLineFlagRangeList::print(st, _name, func);
- st->print(" %-16s", " ");
- print_kind_and_origin(st);
+ fill_to_pos(st, col5_pos);
+ print_kind(st, col5_width);
+
+ fill_to_pos(st, col6_pos);
+ print_origin(st, col6_width);
#ifndef PRODUCT
if (withComments) {
+ fill_to_pos(st, col7_pos);
st->print("%s", _doc);
}
#endif
-
st->cr();
}
}
-void Flag::print_kind_and_origin(outputStream* st) {
+void Flag::print_kind(outputStream* st, unsigned int width) {
struct Data {
int flag;
const char* name;
@@ -615,11 +731,13 @@
}
assert(buffer_used + 2 <= buffer_size, "Too small buffer");
jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
- st->print("%20s", kind);
+ st->print("%*s", width, kind);
}
+}
+void Flag::print_origin(outputStream* st, unsigned int width) {
int origin = _flags & VALUE_ORIGIN_MASK;
- st->print(" {");
+ st->print("{");
switch(origin) {
case DEFAULT:
st->print("default"); break;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/globals.hpp
--- a/src/hotspot/share/runtime/globals.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/globals.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -184,7 +184,9 @@
DIAGNOSTIC_FLAG_BUT_LOCKED,
EXPERIMENTAL_FLAG_BUT_LOCKED,
DEVELOPER_FLAG_BUT_PRODUCT_BUILD,
- NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD
+ NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD,
+ COMMERCIAL_FLAG_BUT_DISABLED,
+ COMMERCIAL_FLAG_BUT_LOCKED
};
const char* _type;
@@ -285,11 +287,12 @@
void clear_diagnostic();
Flag::MsgType get_locked_message(char*, int) const;
- void get_locked_message_ext(char*, int) const;
+ Flag::MsgType get_locked_message_ext(char*, int) const;
// printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
void print_on(outputStream* st, bool withComments = false, bool printRanges = false);
- void print_kind_and_origin(outputStream* st);
+ void print_kind(outputStream* st, unsigned int width);
+ void print_origin(outputStream* st, unsigned int width);
void print_as_flag(outputStream* st);
static const char* flag_error_str(Flag::Error error);
@@ -2650,7 +2653,7 @@
"Inline allocations larger than this in doublewords must go slow")\
\
product(bool, AggressiveOpts, false, \
- "Enable aggressive optimizations - see arguments.cpp") \
+ "(Deprecated) Enable aggressive optimizations - see arguments.cpp") \
\
product_pd(bool, CompactStrings, \
"Enable Strings to use single byte chars in backing store") \
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/globals_ext.hpp
--- a/src/hotspot/share/runtime/globals_ext.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/globals_ext.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -61,9 +61,10 @@
return false;
}
-inline void Flag::get_locked_message_ext(char* buf, int buflen) const {
+inline Flag::MsgType Flag::get_locked_message_ext(char* buf, int buflen) const {
assert(buf != NULL, "Buffer cannot be NULL");
buf[0] = '\0';
+ return Flag::NONE;
}
#endif // SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/handles.cpp
--- a/src/hotspot/share/runtime/handles.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/handles.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -214,4 +214,4 @@
area->_no_handle_mark_nesting = _no_handle_mark_nesting;
}
-#endif
+#endif // ASSERT
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/handles.hpp
--- a/src/hotspot/share/runtime/handles.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/handles.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -296,4 +296,17 @@
#endif
};
+// The HandleMarkCleaner is a faster version of HandleMark.
+// It relies on the fact that there is a HandleMark further
+// down the stack (in JavaCalls::call_helper), and just resets
+// to the saved values in that HandleMark.
+
+class HandleMarkCleaner: public StackObj {
+ private:
+ Thread* _thread;
+ public:
+ inline HandleMarkCleaner(Thread* thread);
+ inline ~HandleMarkCleaner();
+};
+
#endif // SHARE_VM_RUNTIME_HANDLES_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/handles.inline.hpp
--- a/src/hotspot/share/runtime/handles.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/handles.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -104,4 +104,13 @@
debug_only(area->_handle_mark_nesting--);
}
+inline HandleMarkCleaner::HandleMarkCleaner(Thread* thread) {
+ _thread = thread;
+ _thread->last_handle_mark()->push();
+}
+
+inline HandleMarkCleaner::~HandleMarkCleaner() {
+ _thread->last_handle_mark()->pop_and_restore();
+}
+
#endif // SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/handshake.cpp
--- a/src/hotspot/share/runtime/handshake.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/handshake.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/handshake.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/semaphore.hpp"
#include "runtime/task.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/interfaceSupport.cpp
--- a/src/hotspot/share/runtime/interfaceSupport.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/interfaceSupport.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -28,16 +28,51 @@
#include "gc/shared/genCollectedHeap.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
+#include "runtime/vmThread.hpp"
#include "utilities/preserveException.hpp"
// Implementation of InterfaceSupport
#ifdef ASSERT
+VMEntryWrapper::VMEntryWrapper() {
+ if (VerifyLastFrame) {
+ InterfaceSupport::verify_last_frame();
+ }
+}
+
+VMEntryWrapper::~VMEntryWrapper() {
+ InterfaceSupport::check_gc_alot();
+ if (WalkStackALot) {
+ InterfaceSupport::walk_stack();
+ }
+#ifdef COMPILER2
+ // This option is not used by Compiler 1
+ if (StressDerivedPointers) {
+ InterfaceSupport::stress_derived_pointers();
+ }
+#endif
+ if (DeoptimizeALot || DeoptimizeRandom) {
+ InterfaceSupport::deoptimizeAll();
+ }
+ if (ZombieALot) {
+ InterfaceSupport::zombieAll();
+ }
+ if (UnlinkSymbolsALot) {
+ InterfaceSupport::unlinkSymbols();
+ }
+ // do verification AFTER potential deoptimization
+ if (VerifyStack) {
+ InterfaceSupport::verify_stack();
+ }
+}
long InterfaceSupport::_number_of_calls = 0;
long InterfaceSupport::_scavenge_alot_counter = 1;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/interfaceSupport.hpp
--- a/src/hotspot/share/runtime/interfaceSupport.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +0,0 @@
-/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
-#define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
-
-#include "gc/shared/gcLocker.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/mutexLocker.hpp"
-#include "runtime/orderAccess.hpp"
-#include "runtime/os.hpp"
-#include "runtime/safepointMechanism.inline.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/vmThread.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/preserveException.hpp"
-
-// Wrapper for all entry points to the virtual machine.
-// The HandleMarkCleaner is a faster version of HandleMark.
-// It relies on the fact that there is a HandleMark further
-// down the stack (in JavaCalls::call_helper), and just resets
-// to the saved values in that HandleMark.
-
-class HandleMarkCleaner: public StackObj {
- private:
- Thread* _thread;
- public:
- HandleMarkCleaner(Thread* thread) {
- _thread = thread;
- _thread->last_handle_mark()->push();
- }
- ~HandleMarkCleaner() {
- _thread->last_handle_mark()->pop_and_restore();
- }
-
- private:
- inline void* operator new(size_t size, void* ptr) throw() {
- return ptr;
- }
-};
-
-// InterfaceSupport provides functionality used by the VM_LEAF_BASE and
-// VM_ENTRY_BASE macros. These macros are used to guard entry points into
-// the VM and perform checks upon leave of the VM.
-
-
-class InterfaceSupport: AllStatic {
-# ifdef ASSERT
- public:
- static long _scavenge_alot_counter;
- static long _fullgc_alot_counter;
- static long _number_of_calls;
- static long _fullgc_alot_invocation;
-
- // Helper methods used to implement +ScavengeALot and +FullGCALot
- static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
- static void gc_alot();
-
- static void walk_stack_from(vframe* start_vf);
- static void walk_stack();
-
- static void zombieAll();
- static void unlinkSymbols();
- static void deoptimizeAll();
- static void stress_derived_pointers();
- static void verify_stack();
- static void verify_last_frame();
-# endif
-
- public:
- static void serialize_thread_state_with_handler(JavaThread* thread) {
- serialize_thread_state_internal(thread, true);
- }
-
- // Should only call this if we know that we have a proper SEH set up.
- static void serialize_thread_state(JavaThread* thread) {
- serialize_thread_state_internal(thread, false);
- }
-
- private:
- static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
- // Make sure new state is seen by VM thread
- if (os::is_MP()) {
- if (UseMembar) {
- // Force a fence between the write above and read below
- OrderAccess::fence();
- } else {
- // store to serialize page so VM thread can do pseudo remote membar
- if (needs_exception_handler) {
- os::write_memory_serialize_page_with_handler(thread);
- } else {
- os::write_memory_serialize_page(thread);
- }
- }
- }
- }
-};
-
-
-// Basic class for all thread transition classes.
-
-class ThreadStateTransition : public StackObj {
- protected:
- JavaThread* _thread;
- public:
- ThreadStateTransition(JavaThread *thread) {
- _thread = thread;
- assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
- }
-
- // Change threadstate in a manner, so safepoint can detect changes.
- // Time-critical: called on exit from every runtime routine
- static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
- assert(from != _thread_in_Java, "use transition_from_java");
- assert(from != _thread_in_native, "use transition_from_native");
- assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
- assert(thread->thread_state() == from, "coming from wrong thread state");
- // Change to transition state
- thread->set_thread_state((JavaThreadState)(from + 1));
-
- InterfaceSupport::serialize_thread_state(thread);
-
- SafepointMechanism::block_if_requested(thread);
- thread->set_thread_state(to);
-
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
- }
-
- // transition_and_fence must be used on any thread state transition
- // where there might not be a Java call stub on the stack, in
- // particular on Windows where the Structured Exception Handler is
- // set up in the call stub. os::write_memory_serialize_page() can
- // fault and we can't recover from it on Windows without a SEH in
- // place.
- static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
- assert(thread->thread_state() == from, "coming from wrong thread state");
- assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
- // Change to transition state
- thread->set_thread_state((JavaThreadState)(from + 1));
-
- InterfaceSupport::serialize_thread_state_with_handler(thread);
-
- SafepointMechanism::block_if_requested(thread);
- thread->set_thread_state(to);
-
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
- }
-
- // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
- // never block on entry to the VM. This will break the code, since e.g. preserve arguments
- // have not been setup.
- static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
- assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
- thread->set_thread_state(to);
- }
-
- static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
- assert((to & 1) == 0, "odd numbers are transitions states");
- assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
- // Change to transition state
- thread->set_thread_state(_thread_in_native_trans);
-
- InterfaceSupport::serialize_thread_state_with_handler(thread);
-
- // We never install asynchronous exceptions when coming (back) in
- // to the runtime from native code because the runtime is not set
- // up to handle exceptions floating around at arbitrary points.
- if (SafepointMechanism::poll(thread) || thread->is_suspend_after_native()) {
- JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
-
- // Clear unhandled oops anywhere where we could block, even if we don't.
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
- }
-
- thread->set_thread_state(to);
- }
- protected:
- void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
- void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
- void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
- void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
-};
-
-class ThreadInVMForHandshake : public ThreadStateTransition {
- const JavaThreadState _original_state;
-
- void transition_back() {
- // This can be invoked from transition states and must return to the original state properly
- assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
- _thread->set_thread_state(_thread_in_vm_trans);
-
- InterfaceSupport::serialize_thread_state(_thread);
-
- SafepointMechanism::block_if_requested(_thread);
-
- _thread->set_thread_state(_original_state);
- }
-
- public:
-
- ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
- _original_state(thread->thread_state()) {
-
- if (thread->has_last_Java_frame()) {
- thread->frame_anchor()->make_walkable(thread);
- }
-
- thread->set_thread_state(_thread_in_vm);
- }
-
- ~ThreadInVMForHandshake() {
- transition_back();
- }
-
-};
-
-class ThreadInVMfromJava : public ThreadStateTransition {
- public:
- ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
- trans_from_java(_thread_in_vm);
- }
- ~ThreadInVMfromJava() {
- if (_thread->stack_yellow_reserved_zone_disabled()) {
- _thread->enable_stack_yellow_reserved_zone();
- }
- trans(_thread_in_vm, _thread_in_Java);
- // Check for pending. async. exceptions or suspends.
- if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
- }
-};
-
-
-class ThreadInVMfromUnknown {
- private:
- JavaThread* _thread;
- public:
- ThreadInVMfromUnknown() : _thread(NULL) {
- Thread* t = Thread::current();
- if (t->is_Java_thread()) {
- JavaThread* t2 = (JavaThread*) t;
- if (t2->thread_state() == _thread_in_native) {
- _thread = t2;
- ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
- // Used to have a HandleMarkCleaner but that is dangerous as
- // it could free a handle in our (indirect, nested) caller.
- // We expect any handles will be short lived and figure we
- // don't need an actual HandleMark.
- }
- }
- }
- ~ThreadInVMfromUnknown() {
- if (_thread) {
- ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
- }
- }
-};
-
-
-class ThreadInVMfromNative : public ThreadStateTransition {
- public:
- ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
- trans_from_native(_thread_in_vm);
- }
- ~ThreadInVMfromNative() {
- trans_and_fence(_thread_in_vm, _thread_in_native);
- }
-};
-
-
-class ThreadToNativeFromVM : public ThreadStateTransition {
- public:
- ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {
- // We are leaving the VM at this point and going directly to native code.
- // Block, if we are in the middle of a safepoint synchronization.
- assert(!thread->owns_locks(), "must release all locks when leaving VM");
- thread->frame_anchor()->make_walkable(thread);
- trans_and_fence(_thread_in_vm, _thread_in_native);
- // Check for pending. async. exceptions or suspends.
- if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
- }
-
- ~ThreadToNativeFromVM() {
- trans_from_native(_thread_in_vm);
- assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check");
- // We don't need to clear_walkable because it will happen automagically when we return to java
- }
-};
-
-
-class ThreadBlockInVM : public ThreadStateTransition {
- public:
- ThreadBlockInVM(JavaThread *thread)
- : ThreadStateTransition(thread) {
- // Once we are blocked vm expects stack to be walkable
- thread->frame_anchor()->make_walkable(thread);
- trans_and_fence(_thread_in_vm, _thread_blocked);
- }
- ~ThreadBlockInVM() {
- trans_and_fence(_thread_blocked, _thread_in_vm);
- // We don't need to clear_walkable because it will happen automagically when we return to java
- }
-};
-
-
-// This special transition class is only used to prevent asynchronous exceptions
-// from being installed on vm exit in situations where we can't tolerate them.
-// See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.
-class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {
- public:
- ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {
- trans_from_java(_thread_in_vm);
- }
- ~ThreadInVMfromJavaNoAsyncException() {
- if (_thread->stack_yellow_reserved_zone_disabled()) {
- _thread->enable_stack_yellow_reserved_zone();
- }
- trans(_thread_in_vm, _thread_in_Java);
- // NOTE: We do not check for pending. async. exceptions.
- // If we did and moved the pending async exception over into the
- // pending exception field, we would need to deopt (currently C2
- // only). However, to do so would require that we transition back
- // to the _thread_in_vm state. Instead we postpone the handling of
- // the async exception.
-
-
- // Check for pending. suspends only.
- if (_thread->has_special_runtime_exit_condition())
- _thread->handle_special_runtime_exit_condition(false);
- }
-};
-
-// Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.
-// Can be used to verify properties on enter/exit of the VM.
-
-#ifdef ASSERT
-class VMEntryWrapper {
- public:
- VMEntryWrapper() {
- if (VerifyLastFrame) {
- InterfaceSupport::verify_last_frame();
- }
- }
-
- ~VMEntryWrapper() {
- InterfaceSupport::check_gc_alot();
- if (WalkStackALot) {
- InterfaceSupport::walk_stack();
- }
-#ifdef COMPILER2
- // This option is not used by Compiler 1
- if (StressDerivedPointers) {
- InterfaceSupport::stress_derived_pointers();
- }
-#endif
- if (DeoptimizeALot || DeoptimizeRandom) {
- InterfaceSupport::deoptimizeAll();
- }
- if (ZombieALot) {
- InterfaceSupport::zombieAll();
- }
- if (UnlinkSymbolsALot) {
- InterfaceSupport::unlinkSymbols();
- }
- // do verification AFTER potential deoptimization
- if (VerifyStack) {
- InterfaceSupport::verify_stack();
- }
-
- }
-};
-
-
-class VMNativeEntryWrapper {
- public:
- VMNativeEntryWrapper() {
- if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
- }
-
- ~VMNativeEntryWrapper() {
- if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
- }
-};
-
-#endif
-
-
-// VM-internal runtime interface support
-
-#ifdef ASSERT
-
-class RuntimeHistogramElement : public HistogramElement {
- public:
- RuntimeHistogramElement(const char* name);
-};
-
-#define TRACE_CALL(result_type, header) \
- InterfaceSupport::_number_of_calls++; \
- if (CountRuntimeCalls) { \
- static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
- if (e != NULL) e->increment_count(); \
- }
-#else
-#define TRACE_CALL(result_type, header) \
- /* do nothing */
-#endif
-
-
-// LEAF routines do not lock, GC or throw exceptions
-
-#define VM_LEAF_BASE(result_type, header) \
- TRACE_CALL(result_type, header) \
- debug_only(NoHandleMark __hm;) \
- os::verify_stack_alignment(); \
- /* begin of body */
-
-#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
- TRACE_CALL(result_type, header) \
- debug_only(ResetNoHandleMark __rnhm;) \
- HandleMarkCleaner __hm(thread); \
- Thread* THREAD = thread; \
- os::verify_stack_alignment(); \
- /* begin of body */
-
-
-// ENTRY routines may lock, GC and throw exceptions
-
-#define VM_ENTRY_BASE(result_type, header, thread) \
- TRACE_CALL(result_type, header) \
- HandleMarkCleaner __hm(thread); \
- Thread* THREAD = thread; \
- os::verify_stack_alignment(); \
- /* begin of body */
-
-
-// QUICK_ENTRY routines behave like ENTRY but without a handle mark
-
-#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
- TRACE_CALL(result_type, header) \
- debug_only(NoHandleMark __hm;) \
- Thread* THREAD = thread; \
- os::verify_stack_alignment(); \
- /* begin of body */
-
-
-// Definitions for IRT (Interpreter Runtime)
-// (thread is an argument passed in to all these routines)
-
-#define IRT_ENTRY(result_type, header) \
- result_type header { \
- ThreadInVMfromJava __tiv(thread); \
- VM_ENTRY_BASE(result_type, header, thread) \
- debug_only(VMEntryWrapper __vew;)
-
-
-#define IRT_LEAF(result_type, header) \
- result_type header { \
- VM_LEAF_BASE(result_type, header) \
- debug_only(NoSafepointVerifier __nspv(true);)
-
-
-#define IRT_ENTRY_NO_ASYNC(result_type, header) \
- result_type header { \
- ThreadInVMfromJavaNoAsyncException __tiv(thread); \
- VM_ENTRY_BASE(result_type, header, thread) \
- debug_only(VMEntryWrapper __vew;)
-
-#define IRT_END }
-
-
-// Definitions for JRT (Java (Compiler/Shared) Runtime)
-
-#define JRT_ENTRY(result_type, header) \
- result_type header { \
- ThreadInVMfromJava __tiv(thread); \
- VM_ENTRY_BASE(result_type, header, thread) \
- debug_only(VMEntryWrapper __vew;)
-
-
-#define JRT_LEAF(result_type, header) \
- result_type header { \
- VM_LEAF_BASE(result_type, header) \
- debug_only(JRTLeafVerifier __jlv;)
-
-
-#define JRT_ENTRY_NO_ASYNC(result_type, header) \
- result_type header { \
- ThreadInVMfromJavaNoAsyncException __tiv(thread); \
- VM_ENTRY_BASE(result_type, header, thread) \
- debug_only(VMEntryWrapper __vew;)
-
-// Same as JRT Entry but allows for return value after the safepoint
-// to get back into Java from the VM
-#define JRT_BLOCK_ENTRY(result_type, header) \
- result_type header { \
- TRACE_CALL(result_type, header) \
- HandleMarkCleaner __hm(thread);
-
-#define JRT_BLOCK \
- { \
- ThreadInVMfromJava __tiv(thread); \
- Thread* THREAD = thread; \
- debug_only(VMEntryWrapper __vew;)
-
-#define JRT_BLOCK_NO_ASYNC \
- { \
- ThreadInVMfromJavaNoAsyncException __tiv(thread); \
- Thread* THREAD = thread; \
- debug_only(VMEntryWrapper __vew;)
-
-#define JRT_BLOCK_END }
-
-#define JRT_END }
-
-// Definitions for JNI
-
-#define JNI_ENTRY(result_type, header) \
- JNI_ENTRY_NO_PRESERVE(result_type, header) \
- WeakPreserveExceptionMark __wem(thread);
-
-#define JNI_ENTRY_NO_PRESERVE(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_ENTRY_BASE(result_type, header, thread)
-
-
-// Ensure that the VMNativeEntryWrapper constructor, which can cause
-// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).
-#define JNI_QUICK_ENTRY(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_QUICK_ENTRY_BASE(result_type, header, thread)
-
-
-#define JNI_LEAF(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
- VM_LEAF_BASE(result_type, header)
-
-
-// Close the routine and the extern "C"
-#define JNI_END } }
-
-
-
-// Definitions for JVM
-
-#define JVM_ENTRY(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_ENTRY_BASE(result_type, header, thread)
-
-
-#define JVM_ENTRY_NO_ENV(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread = JavaThread::current(); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_ENTRY_BASE(result_type, header, thread)
-
-
-#define JVM_QUICK_ENTRY(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_QUICK_ENTRY_BASE(result_type, header, thread)
-
-
-#define JVM_LEAF(result_type, header) \
-extern "C" { \
- result_type JNICALL header { \
- VM_Exit::block_if_vm_exited(); \
- VM_LEAF_BASE(result_type, header)
-
-
-#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \
- { { \
- JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
- ThreadInVMfromNative __tiv(thread); \
- debug_only(VMNativeEntryWrapper __vew;) \
- VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
-
-
-#define JVM_END } }
-
-#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/interfaceSupport.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_INLINE_HPP
+#define SHARE_VM_RUNTIME_INTERFACESUPPORT_INLINE_HPP
+
+#include "gc/shared/gcLocker.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
+#include "runtime/safepointMechanism.inline.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/vm_operations.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+#include "utilities/preserveException.hpp"
+
+// Wrapper for all entry points to the virtual machine.
+
+// InterfaceSupport provides functionality used by the VM_LEAF_BASE and
+// VM_ENTRY_BASE macros. These macros are used to guard entry points into
+// the VM and perform checks upon leave of the VM.
+
+
+class InterfaceSupport: AllStatic {
+# ifdef ASSERT
+ public:
+ static long _scavenge_alot_counter;
+ static long _fullgc_alot_counter;
+ static long _number_of_calls;
+ static long _fullgc_alot_invocation;
+
+ // Helper methods used to implement +ScavengeALot and +FullGCALot
+ static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
+ static void gc_alot();
+
+ static void walk_stack_from(vframe* start_vf);
+ static void walk_stack();
+
+ static void zombieAll();
+ static void unlinkSymbols();
+ static void deoptimizeAll();
+ static void stress_derived_pointers();
+ static void verify_stack();
+ static void verify_last_frame();
+# endif
+
+ public:
+ static void serialize_thread_state_with_handler(JavaThread* thread) {
+ serialize_thread_state_internal(thread, true);
+ }
+
+ // Should only call this if we know that we have a proper SEH set up.
+ static void serialize_thread_state(JavaThread* thread) {
+ serialize_thread_state_internal(thread, false);
+ }
+
+ private:
+ static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
+ // Make sure new state is seen by VM thread
+ if (os::is_MP()) {
+ if (UseMembar) {
+ // Force a fence between the write above and read below
+ OrderAccess::fence();
+ } else {
+ // store to serialize page so VM thread can do pseudo remote membar
+ if (needs_exception_handler) {
+ os::write_memory_serialize_page_with_handler(thread);
+ } else {
+ os::write_memory_serialize_page(thread);
+ }
+ }
+ }
+ }
+};
+
+
+// Basic class for all thread transition classes.
+
+class ThreadStateTransition : public StackObj {
+ protected:
+ JavaThread* _thread;
+ public:
+ ThreadStateTransition(JavaThread *thread) {
+ _thread = thread;
+ assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
+ }
+
+ // Change threadstate in a manner, so safepoint can detect changes.
+ // Time-critical: called on exit from every runtime routine
+ static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
+ assert(from != _thread_in_Java, "use transition_from_java");
+ assert(from != _thread_in_native, "use transition_from_native");
+ assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
+ assert(thread->thread_state() == from, "coming from wrong thread state");
+ // Change to transition state
+ thread->set_thread_state((JavaThreadState)(from + 1));
+
+ InterfaceSupport::serialize_thread_state(thread);
+
+ SafepointMechanism::block_if_requested(thread);
+ thread->set_thread_state(to);
+
+ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
+ }
+
+ // transition_and_fence must be used on any thread state transition
+ // where there might not be a Java call stub on the stack, in
+ // particular on Windows where the Structured Exception Handler is
+ // set up in the call stub. os::write_memory_serialize_page() can
+ // fault and we can't recover from it on Windows without a SEH in
+ // place.
+ static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
+ assert(thread->thread_state() == from, "coming from wrong thread state");
+ assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
+ // Change to transition state
+ thread->set_thread_state((JavaThreadState)(from + 1));
+
+ InterfaceSupport::serialize_thread_state_with_handler(thread);
+
+ SafepointMechanism::block_if_requested(thread);
+ thread->set_thread_state(to);
+
+ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
+ }
+
+ // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
+ // never block on entry to the VM. This will break the code, since e.g. preserve arguments
+ // have not been setup.
+ static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
+ assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
+ thread->set_thread_state(to);
+ }
+
+ static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
+ assert((to & 1) == 0, "odd numbers are transitions states");
+ assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
+ // Change to transition state
+ thread->set_thread_state(_thread_in_native_trans);
+
+ InterfaceSupport::serialize_thread_state_with_handler(thread);
+
+ // We never install asynchronous exceptions when coming (back) in
+ // to the runtime from native code because the runtime is not set
+ // up to handle exceptions floating around at arbitrary points.
+ if (SafepointMechanism::poll(thread) || thread->is_suspend_after_native()) {
+ JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
+
+ // Clear unhandled oops anywhere where we could block, even if we don't.
+ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
+ }
+
+ thread->set_thread_state(to);
+ }
+ protected:
+ void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
+ void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
+ void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
+ void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
+};
+
+class ThreadInVMForHandshake : public ThreadStateTransition {
+ const JavaThreadState _original_state;
+
+ void transition_back() {
+ // This can be invoked from transition states and must return to the original state properly
+ assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
+ _thread->set_thread_state(_thread_in_vm_trans);
+
+ InterfaceSupport::serialize_thread_state(_thread);
+
+ SafepointMechanism::block_if_requested(_thread);
+
+ _thread->set_thread_state(_original_state);
+ }
+
+ public:
+
+ ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
+ _original_state(thread->thread_state()) {
+
+ if (thread->has_last_Java_frame()) {
+ thread->frame_anchor()->make_walkable(thread);
+ }
+
+ thread->set_thread_state(_thread_in_vm);
+ }
+
+ ~ThreadInVMForHandshake() {
+ transition_back();
+ }
+
+};
+
+class ThreadInVMfromJava : public ThreadStateTransition {
+ public:
+ ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
+ trans_from_java(_thread_in_vm);
+ }
+ ~ThreadInVMfromJava() {
+ if (_thread->stack_yellow_reserved_zone_disabled()) {
+ _thread->enable_stack_yellow_reserved_zone();
+ }
+ trans(_thread_in_vm, _thread_in_Java);
+ // Check for pending. async. exceptions or suspends.
+ if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
+ }
+};
+
+
+class ThreadInVMfromUnknown {
+ private:
+ JavaThread* _thread;
+ public:
+ ThreadInVMfromUnknown() : _thread(NULL) {
+ Thread* t = Thread::current();
+ if (t->is_Java_thread()) {
+ JavaThread* t2 = (JavaThread*) t;
+ if (t2->thread_state() == _thread_in_native) {
+ _thread = t2;
+ ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
+ // Used to have a HandleMarkCleaner but that is dangerous as
+ // it could free a handle in our (indirect, nested) caller.
+ // We expect any handles will be short lived and figure we
+ // don't need an actual HandleMark.
+ }
+ }
+ }
+ ~ThreadInVMfromUnknown() {
+ if (_thread) {
+ ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
+ }
+ }
+};
+
+
+class ThreadInVMfromNative : public ThreadStateTransition {
+ public:
+ ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
+ trans_from_native(_thread_in_vm);
+ }
+ ~ThreadInVMfromNative() {
+ trans_and_fence(_thread_in_vm, _thread_in_native);
+ }
+};
+
+
+class ThreadToNativeFromVM : public ThreadStateTransition {
+ public:
+ ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {
+ // We are leaving the VM at this point and going directly to native code.
+ // Block, if we are in the middle of a safepoint synchronization.
+ assert(!thread->owns_locks(), "must release all locks when leaving VM");
+ thread->frame_anchor()->make_walkable(thread);
+ trans_and_fence(_thread_in_vm, _thread_in_native);
+ // Check for pending. async. exceptions or suspends.
+ if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
+ }
+
+ ~ThreadToNativeFromVM() {
+ trans_from_native(_thread_in_vm);
+ assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check");
+ // We don't need to clear_walkable because it will happen automagically when we return to java
+ }
+};
+
+
+class ThreadBlockInVM : public ThreadStateTransition {
+ public:
+ ThreadBlockInVM(JavaThread *thread)
+ : ThreadStateTransition(thread) {
+ // Once we are blocked vm expects stack to be walkable
+ thread->frame_anchor()->make_walkable(thread);
+ trans_and_fence(_thread_in_vm, _thread_blocked);
+ }
+ ~ThreadBlockInVM() {
+ trans_and_fence(_thread_blocked, _thread_in_vm);
+ // We don't need to clear_walkable because it will happen automagically when we return to java
+ }
+};
+
+
+// This special transition class is only used to prevent asynchronous exceptions
+// from being installed on vm exit in situations where we can't tolerate them.
+// See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.
+class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {
+ public:
+ ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {
+ trans_from_java(_thread_in_vm);
+ }
+ ~ThreadInVMfromJavaNoAsyncException() {
+ if (_thread->stack_yellow_reserved_zone_disabled()) {
+ _thread->enable_stack_yellow_reserved_zone();
+ }
+ trans(_thread_in_vm, _thread_in_Java);
+ // NOTE: We do not check for pending. async. exceptions.
+ // If we did and moved the pending async exception over into the
+ // pending exception field, we would need to deopt (currently C2
+ // only). However, to do so would require that we transition back
+ // to the _thread_in_vm state. Instead we postpone the handling of
+ // the async exception.
+
+
+ // Check for pending. suspends only.
+ if (_thread->has_special_runtime_exit_condition())
+ _thread->handle_special_runtime_exit_condition(false);
+ }
+};
+
+// Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.
+// Can be used to verify properties on enter/exit of the VM.
+
+#ifdef ASSERT
+class VMEntryWrapper {
+ public:
+ VMEntryWrapper();
+ ~VMEntryWrapper();
+};
+
+
+class VMNativeEntryWrapper {
+ public:
+ VMNativeEntryWrapper() {
+ if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
+ }
+
+ ~VMNativeEntryWrapper() {
+ if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
+ }
+};
+
+#endif
+
+
+// VM-internal runtime interface support
+
+#ifdef ASSERT
+
+class RuntimeHistogramElement : public HistogramElement {
+ public:
+ RuntimeHistogramElement(const char* name);
+};
+
+#define TRACE_CALL(result_type, header) \
+ InterfaceSupport::_number_of_calls++; \
+ if (CountRuntimeCalls) { \
+ static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
+ if (e != NULL) e->increment_count(); \
+ }
+#else
+#define TRACE_CALL(result_type, header) \
+ /* do nothing */
+#endif
+
+
+// LEAF routines do not lock, GC or throw exceptions
+
+#define VM_LEAF_BASE(result_type, header) \
+ TRACE_CALL(result_type, header) \
+ debug_only(NoHandleMark __hm;) \
+ os::verify_stack_alignment(); \
+ /* begin of body */
+
+#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
+ TRACE_CALL(result_type, header) \
+ debug_only(ResetNoHandleMark __rnhm;) \
+ HandleMarkCleaner __hm(thread); \
+ Thread* THREAD = thread; \
+ os::verify_stack_alignment(); \
+ /* begin of body */
+
+
+// ENTRY routines may lock, GC and throw exceptions
+
+#define VM_ENTRY_BASE(result_type, header, thread) \
+ TRACE_CALL(result_type, header) \
+ HandleMarkCleaner __hm(thread); \
+ Thread* THREAD = thread; \
+ os::verify_stack_alignment(); \
+ /* begin of body */
+
+
+// QUICK_ENTRY routines behave like ENTRY but without a handle mark
+
+#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
+ TRACE_CALL(result_type, header) \
+ debug_only(NoHandleMark __hm;) \
+ Thread* THREAD = thread; \
+ os::verify_stack_alignment(); \
+ /* begin of body */
+
+
+// Definitions for IRT (Interpreter Runtime)
+// (thread is an argument passed in to all these routines)
+
+#define IRT_ENTRY(result_type, header) \
+ result_type header { \
+ ThreadInVMfromJava __tiv(thread); \
+ VM_ENTRY_BASE(result_type, header, thread) \
+ debug_only(VMEntryWrapper __vew;)
+
+
+#define IRT_LEAF(result_type, header) \
+ result_type header { \
+ VM_LEAF_BASE(result_type, header) \
+ debug_only(NoSafepointVerifier __nspv(true);)
+
+
+#define IRT_ENTRY_NO_ASYNC(result_type, header) \
+ result_type header { \
+ ThreadInVMfromJavaNoAsyncException __tiv(thread); \
+ VM_ENTRY_BASE(result_type, header, thread) \
+ debug_only(VMEntryWrapper __vew;)
+
+#define IRT_END }
+
+
+// Definitions for JRT (Java (Compiler/Shared) Runtime)
+
+#define JRT_ENTRY(result_type, header) \
+ result_type header { \
+ ThreadInVMfromJava __tiv(thread); \
+ VM_ENTRY_BASE(result_type, header, thread) \
+ debug_only(VMEntryWrapper __vew;)
+
+
+#define JRT_LEAF(result_type, header) \
+ result_type header { \
+ VM_LEAF_BASE(result_type, header) \
+ debug_only(JRTLeafVerifier __jlv;)
+
+
+#define JRT_ENTRY_NO_ASYNC(result_type, header) \
+ result_type header { \
+ ThreadInVMfromJavaNoAsyncException __tiv(thread); \
+ VM_ENTRY_BASE(result_type, header, thread) \
+ debug_only(VMEntryWrapper __vew;)
+
+// Same as JRT Entry but allows for return value after the safepoint
+// to get back into Java from the VM
+#define JRT_BLOCK_ENTRY(result_type, header) \
+ result_type header { \
+ TRACE_CALL(result_type, header) \
+ HandleMarkCleaner __hm(thread);
+
+#define JRT_BLOCK \
+ { \
+ ThreadInVMfromJava __tiv(thread); \
+ Thread* THREAD = thread; \
+ debug_only(VMEntryWrapper __vew;)
+
+#define JRT_BLOCK_NO_ASYNC \
+ { \
+ ThreadInVMfromJavaNoAsyncException __tiv(thread); \
+ Thread* THREAD = thread; \
+ debug_only(VMEntryWrapper __vew;)
+
+#define JRT_BLOCK_END }
+
+#define JRT_END }
+
+// Definitions for JNI
+
+#define JNI_ENTRY(result_type, header) \
+ JNI_ENTRY_NO_PRESERVE(result_type, header) \
+ WeakPreserveExceptionMark __wem(thread);
+
+#define JNI_ENTRY_NO_PRESERVE(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_ENTRY_BASE(result_type, header, thread)
+
+
+// Ensure that the VMNativeEntryWrapper constructor, which can cause
+// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).
+#define JNI_QUICK_ENTRY(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_QUICK_ENTRY_BASE(result_type, header, thread)
+
+
+#define JNI_LEAF(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
+ VM_LEAF_BASE(result_type, header)
+
+
+// Close the routine and the extern "C"
+#define JNI_END } }
+
+
+
+// Definitions for JVM
+
+#define JVM_ENTRY(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_ENTRY_BASE(result_type, header, thread)
+
+
+#define JVM_ENTRY_NO_ENV(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread = JavaThread::current(); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_ENTRY_BASE(result_type, header, thread)
+
+
+#define JVM_QUICK_ENTRY(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_QUICK_ENTRY_BASE(result_type, header, thread)
+
+
+#define JVM_LEAF(result_type, header) \
+extern "C" { \
+ result_type JNICALL header { \
+ VM_Exit::block_if_vm_exited(); \
+ VM_LEAF_BASE(result_type, header)
+
+
+#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \
+ { { \
+ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+ ThreadInVMfromNative __tiv(thread); \
+ debug_only(VMNativeEntryWrapper __vew;) \
+ VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
+
+
+#define JVM_END } }
+
+#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/java.cpp
--- a/src/hotspot/share/runtime/java.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/java.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -56,7 +56,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/memprofiler.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/javaCalls.cpp
--- a/src/hotspot/share/runtime/javaCalls.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/javaCalls.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,7 +35,7 @@
#include "prims/jniCheck.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/javaFrameAnchor.hpp
--- a/src/hotspot/share/runtime/javaFrameAnchor.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/javaFrameAnchor.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,7 +25,6 @@
#ifndef SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
#define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
-#include "runtime/orderAccess.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
@@ -33,6 +32,7 @@
// An object for encapsulating the machine/os dependent part of a JavaThread frame state
//
class JavaThread;
+class MacroAssembler;
class JavaFrameAnchor {
// Too many friends...
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/mutex.cpp
--- a/src/hotspot/share/runtime/mutex.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/mutex.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutex.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/objectMonitor.cpp
--- a/src/hotspot/share/runtime/objectMonitor.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/objectMonitor.hpp
--- a/src/hotspot/share/runtime/objectMonitor.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,6 +31,8 @@
#include "runtime/park.hpp"
#include "runtime/perfData.hpp"
+class ObjectMonitor;
+
// ObjectWaiter serves as a "proxy" or surrogate thread.
// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
// ParkEvent instead. Beware, however, that the JVMTI code
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/os.cpp
--- a/src/hotspot/share/runtime/os.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/os.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -48,7 +48,7 @@
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/os.hpp
--- a/src/hotspot/share/runtime/os.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/os.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,7 +30,8 @@
#include "metaprogramming/isRegisteredEnum.hpp"
#include "metaprogramming/integralConstant.hpp"
#include "runtime/extendedPC.hpp"
-#include "runtime/handles.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/ostream.hpp"
#include "utilities/macros.hpp"
#ifndef _WINDOWS
# include
@@ -54,6 +55,7 @@
class DLL;
class FileHandle;
class NativeCallStack;
+class methodHandle;
template class GrowableArray;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/reflection.cpp
--- a/src/hotspot/share/runtime/reflection.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/reflection.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,7 +47,7 @@
#include "runtime/reflection.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
static void trace_class_resolution(const Klass* to_class) {
ResourceMark rm;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/rframe.hpp
--- a/src/hotspot/share/runtime/rframe.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/rframe.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
#define SHARE_VM_RUNTIME_RFRAME_HPP
#include "memory/allocation.hpp"
-#include "runtime/frame.inline.hpp"
+#include "runtime/frame.hpp"
// rframes ("recompiler frames") decorate stack frames with some extra information
// needed by the recompiler. The recompiler views the stack (at the time of recompilation)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/safepoint.cpp
--- a/src/hotspot/share/runtime/safepoint.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/safepoint.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -47,7 +47,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/safepointMechanism.cpp
--- a/src/hotspot/share/runtime/safepointMechanism.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/safepointMechanism.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "runtime/globals.hpp"
#include "runtime/os.hpp"
#include "runtime/safepointMechanism.inline.hpp"
+#include "services/memTracker.hpp"
#include "utilities/globalDefinitions.hpp"
SafepointMechanism::PollingType SafepointMechanism::_polling_type = SafepointMechanism::_global_page_poll;
@@ -50,6 +51,7 @@
const size_t allocation_size = 2 * page_size;
char* polling_page = os::reserve_memory(allocation_size, NULL, page_size);
os::commit_memory_or_exit(polling_page, allocation_size, false, "Unable to commit Safepoint polling page");
+ MemTracker::record_virtual_memory_type((address)polling_page, mtInternal);
char* bad_page = polling_page;
char* good_page = polling_page + page_size;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/serviceThread.cpp
--- a/src/hotspot/share/runtime/serviceThread.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/serviceThread.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/serviceThread.hpp"
#include "runtime/mutexLocker.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/sharedRuntime.cpp
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "jvm.h"
#include "aot/aotLoader.hpp"
+#include "code/compiledMethod.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
@@ -54,14 +55,15 @@
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "trace/tracing.hpp"
#include "utilities/copy.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/sharedRuntimeTrans.cpp
--- a/src/hotspot/share/runtime/sharedRuntimeTrans.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/sharedRuntimeTrans.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jni.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
// This file contains copies of the fdlibm routines used by
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/sharedRuntimeTrig.cpp
--- a/src/hotspot/share/runtime/sharedRuntimeTrig.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/sharedRuntimeTrig.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "jni.h"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sharedRuntimeMath.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/simpleThresholdPolicy.cpp
--- a/src/hotspot/share/runtime/simpleThresholdPolicy.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/simpleThresholdPolicy.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
#include "precompiled.hpp"
#include "compiler/compileBroker.hpp"
+#include "gc/shared/gcLocker.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/arguments.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/simpleThresholdPolicy.hpp"
#include "runtime/simpleThresholdPolicy.inline.hpp"
#include "code/scopeDesc.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/stubRoutines.cpp
--- a/src/hotspot/share/runtime/stubRoutines.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/stubRoutines.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/sweeper.cpp
--- a/src/hotspot/share/runtime/sweeper.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/sweeper.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -35,12 +35,14 @@
#include "oops/method.hpp"
#include "runtime/atomic.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vm_operations.hpp"
+#include "runtime/vmThread.hpp"
#include "trace/tracing.hpp"
#include "utilities/events.hpp"
#include "utilities/ticks.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/synchronizer.cpp
--- a/src/hotspot/share/runtime/synchronizer.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/synchronizer.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,7 +34,7 @@
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
@@ -43,6 +43,7 @@
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
+#include "runtime/vmThread.hpp"
#include "trace/traceMacros.hpp"
#include "trace/tracing.hpp"
#include "utilities/align.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/thread.cpp
--- a/src/hotspot/share/runtime/thread.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/thread.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -69,7 +69,7 @@
#include "runtime/globals.hpp"
#include "runtime/handshake.hpp"
#include "runtime/init.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
@@ -92,7 +92,7 @@
#include "runtime/threadSMR.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/timerTrace.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vframe_hp.hpp"
#include "runtime/vmThread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/thread.inline.hpp
--- a/src/hotspot/share/runtime/thread.inline.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/thread.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -26,6 +26,7 @@
#define SHARE_VM_RUNTIME_THREAD_INLINE_HPP
#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/thread.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/threadSMR.cpp
--- a/src/hotspot/share/runtime/threadSMR.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/threadSMR.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -29,8 +29,10 @@
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.inline.hpp"
#include "services/threadService.hpp"
+#include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/resourceHash.hpp"
+#include "utilities/vmError.hpp"
Monitor* ThreadsSMRSupport::_delete_lock =
new Monitor(Monitor::special, "Thread_SMR_delete_lock",
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframe.cpp
--- a/src/hotspot/share/runtime/vframe.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vframe.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -36,13 +36,14 @@
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
-#include "runtime/vframe.hpp"
+#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vframe_hp.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframe.hpp
--- a/src/hotspot/share/runtime/vframe.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vframe.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
#include "code/location.hpp"
#include "oops/oop.hpp"
#include "runtime/frame.hpp"
-#include "runtime/frame.inline.hpp"
#include "runtime/stackValue.hpp"
#include "runtime/stackValueCollection.hpp"
#include "utilities/growableArray.hpp"
@@ -307,14 +306,12 @@
public:
// Constructor
- vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) {
- _thread = thread;
- }
+ inline vframeStreamCommon(JavaThread* thread);
// Accessors
Method* method() const { return _method; }
int bci() const { return _bci; }
- intptr_t* frame_id() const { return _frame.id(); }
+ inline intptr_t* frame_id() const;
address frame_pc() const { return _frame.pc(); }
CodeBlob* cb() const { return _frame.cb(); }
@@ -324,19 +321,11 @@
}
// Frame type
- bool is_interpreted_frame() const { return _frame.is_interpreted_frame(); }
- bool is_entry_frame() const { return _frame.is_entry_frame(); }
+ inline bool is_interpreted_frame() const;
+ inline bool is_entry_frame() const;
// Iteration
- void next() {
- // handle frames with inlining
- if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return;
-
- // handle general case
- do {
- _frame = _frame.sender(&_reg_map);
- } while (!fill_from_frame());
- }
+ inline void next();
void security_next();
bool at_end() const { return _mode == at_end_mode; }
@@ -353,182 +342,10 @@
class vframeStream : public vframeStreamCommon {
public:
// Constructors
- vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false)
- : vframeStreamCommon(thread) {
- _stop_at_java_call_stub = stop_at_java_call_stub;
-
- if (!thread->has_last_Java_frame()) {
- _mode = at_end_mode;
- return;
- }
-
- _frame = _thread->last_frame();
- while (!fill_from_frame()) {
- _frame = _frame.sender(&_reg_map);
- }
- }
+ vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false);
// top_frame may not be at safepoint, start with sender
vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false);
};
-
-inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
- if (_sender_decode_offset == DebugInformationRecorder::serialized_null) {
- return false;
- }
- fill_from_compiled_frame(_sender_decode_offset);
- return true;
-}
-
-
-inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
- _mode = compiled_mode;
-
- // Range check to detect ridiculous offsets.
- if (decode_offset == DebugInformationRecorder::serialized_null ||
- decode_offset < 0 ||
- decode_offset >= nm()->scopes_data_size()) {
- // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
- // If we read nmethod::scopes_data at serialized_null (== 0)
- // or if read some at other invalid offset, invalid values will be decoded.
- // Based on these values, invalid heap locations could be referenced
- // that could lead to crashes in product mode.
- // Therefore, do not use the decode offset if invalid, but fill the frame
- // as it were a native compiled frame (no Java-level assumptions).
-#ifdef ASSERT
- if (WizardMode) {
- ttyLocker ttyl;
- tty->print_cr("Error in fill_from_frame: pc_desc for "
- INTPTR_FORMAT " not found or invalid at %d",
- p2i(_frame.pc()), decode_offset);
- nm()->print();
- nm()->method()->print_codes();
- nm()->print_code();
- nm()->print_pcs();
- }
- found_bad_method_frame();
-#endif
- // Provide a cheap fallback in product mode. (See comment above.)
- fill_from_compiled_native_frame();
- return;
- }
-
- // Decode first part of scopeDesc
- DebugInfoReadStream buffer(nm(), decode_offset);
- _sender_decode_offset = buffer.read_int();
- _method = buffer.read_method();
- _bci = buffer.read_bci();
-
- assert(_method->is_method(), "checking type of decoded method");
-}
-
-// The native frames are handled specially. We do not rely on ScopeDesc info
-// since the pc might not be exact due to the _last_native_pc trick.
-inline void vframeStreamCommon::fill_from_compiled_native_frame() {
- _mode = compiled_mode;
- _sender_decode_offset = DebugInformationRecorder::serialized_null;
- _method = nm()->method();
- _bci = 0;
-}
-
-inline bool vframeStreamCommon::fill_from_frame() {
- // Interpreted frame
- if (_frame.is_interpreted_frame()) {
- fill_from_interpreter_frame();
- return true;
- }
-
- // Compiled frame
-
- if (cb() != NULL && cb()->is_compiled()) {
- if (nm()->is_native_method()) {
- // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick.
- fill_from_compiled_native_frame();
- } else {
- PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc());
- int decode_offset;
- if (pc_desc == NULL) {
- // Should not happen, but let fill_from_compiled_frame handle it.
-
- // If we are trying to walk the stack of a thread that is not
- // at a safepoint (like AsyncGetCallTrace would do) then this is an
- // acceptable result. [ This is assuming that safe_for_sender
- // is so bullet proof that we can trust the frames it produced. ]
- //
- // So if we see that the thread is not safepoint safe
- // then simply produce the method and a bci of zero
- // and skip the possibility of decoding any inlining that
- // may be present. That is far better than simply stopping (or
- // asserting. If however the thread is safepoint safe this
- // is the sign of a compiler bug and we'll let
- // fill_from_compiled_frame handle it.
-
-
- JavaThreadState state = _thread->thread_state();
-
- // in_Java should be good enough to test safepoint safety
- // if state were say in_Java_trans then we'd expect that
- // the pc would have already been slightly adjusted to
- // one that would produce a pcDesc since the trans state
- // would be one that might in fact anticipate a safepoint
-
- if (state == _thread_in_Java ) {
- // This will get a method a zero bci and no inlining.
- // Might be nice to have a unique bci to signify this
- // particular case but for now zero will do.
-
- fill_from_compiled_native_frame();
-
- // There is something to be said for setting the mode to
- // at_end_mode to prevent trying to walk further up the
- // stack. There is evidence that if we walk any further
- // that we could produce a bad stack chain. However until
- // we see evidence that allowing this causes us to find
- // frames bad enough to cause segv's or assertion failures
- // we don't do it as while we may get a bad call chain the
- // probability is much higher (several magnitudes) that we
- // get good data.
-
- return true;
- }
- decode_offset = DebugInformationRecorder::serialized_null;
- } else {
- decode_offset = pc_desc->scope_decode_offset();
- }
- fill_from_compiled_frame(decode_offset);
- }
- return true;
- }
-
- // End of stack?
- if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
- _mode = at_end_mode;
- return true;
- }
-
- return false;
-}
-
-
-inline void vframeStreamCommon::fill_from_interpreter_frame() {
- Method* method = _frame.interpreter_frame_method();
- address bcp = _frame.interpreter_frame_bcp();
- int bci = method->validate_bci_from_bcp(bcp);
- // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
- // AsyncGetCallTrace interrupts the VM asynchronously. As a result
- // it is possible to access an interpreter frame for which
- // no Java-level information is yet available (e.g., becasue
- // the frame was being created when the VM interrupted it).
- // In this scenario, pretend that the interpreter is at the point
- // of entering the method.
- if (bci < 0) {
- DEBUG_ONLY(found_bad_method_frame();)
- bci = 0;
- }
- _mode = interpreted_mode;
- _method = method;
- _bci = bci;
-}
-
#endif // SHARE_VM_RUNTIME_VFRAME_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframe.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/vframe.inline.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_VFRAME_INLINE_HPP
+#define SHARE_VM_RUNTIME_VFRAME_INLINE_HPP
+
+#include "runtime/frame.inline.hpp"
+#include "runtime/vframe.hpp"
+
+inline vframeStreamCommon::vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) {
+ _thread = thread;
+}
+
+inline intptr_t* vframeStreamCommon::frame_id() const { return _frame.id(); }
+
+inline bool vframeStreamCommon::is_interpreted_frame() const { return _frame.is_interpreted_frame(); }
+
+inline bool vframeStreamCommon::is_entry_frame() const { return _frame.is_entry_frame(); }
+
+inline void vframeStreamCommon::next() {
+ // handle frames with inlining
+ if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return;
+
+ // handle general case
+ do {
+ _frame = _frame.sender(&_reg_map);
+ } while (!fill_from_frame());
+}
+
+inline vframeStream::vframeStream(JavaThread* thread, bool stop_at_java_call_stub)
+ : vframeStreamCommon(thread) {
+ _stop_at_java_call_stub = stop_at_java_call_stub;
+
+ if (!thread->has_last_Java_frame()) {
+ _mode = at_end_mode;
+ return;
+ }
+
+ _frame = _thread->last_frame();
+ while (!fill_from_frame()) {
+ _frame = _frame.sender(&_reg_map);
+ }
+}
+
+inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
+ if (_sender_decode_offset == DebugInformationRecorder::serialized_null) {
+ return false;
+ }
+ fill_from_compiled_frame(_sender_decode_offset);
+ return true;
+}
+
+
+inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
+ _mode = compiled_mode;
+
+ // Range check to detect ridiculous offsets.
+ if (decode_offset == DebugInformationRecorder::serialized_null ||
+ decode_offset < 0 ||
+ decode_offset >= nm()->scopes_data_size()) {
+ // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
+ // If we read nmethod::scopes_data at serialized_null (== 0)
+ // or if read some at other invalid offset, invalid values will be decoded.
+ // Based on these values, invalid heap locations could be referenced
+ // that could lead to crashes in product mode.
+ // Therefore, do not use the decode offset if invalid, but fill the frame
+ // as it were a native compiled frame (no Java-level assumptions).
+#ifdef ASSERT
+ if (WizardMode) {
+ ttyLocker ttyl;
+ tty->print_cr("Error in fill_from_frame: pc_desc for "
+ INTPTR_FORMAT " not found or invalid at %d",
+ p2i(_frame.pc()), decode_offset);
+ nm()->print();
+ nm()->method()->print_codes();
+ nm()->print_code();
+ nm()->print_pcs();
+ }
+ found_bad_method_frame();
+#endif
+ // Provide a cheap fallback in product mode. (See comment above.)
+ fill_from_compiled_native_frame();
+ return;
+ }
+
+ // Decode first part of scopeDesc
+ DebugInfoReadStream buffer(nm(), decode_offset);
+ _sender_decode_offset = buffer.read_int();
+ _method = buffer.read_method();
+ _bci = buffer.read_bci();
+
+ assert(_method->is_method(), "checking type of decoded method");
+}
+
+// The native frames are handled specially. We do not rely on ScopeDesc info
+// since the pc might not be exact due to the _last_native_pc trick.
+inline void vframeStreamCommon::fill_from_compiled_native_frame() {
+ _mode = compiled_mode;
+ _sender_decode_offset = DebugInformationRecorder::serialized_null;
+ _method = nm()->method();
+ _bci = 0;
+}
+
+inline bool vframeStreamCommon::fill_from_frame() {
+ // Interpreted frame
+ if (_frame.is_interpreted_frame()) {
+ fill_from_interpreter_frame();
+ return true;
+ }
+
+ // Compiled frame
+
+ if (cb() != NULL && cb()->is_compiled()) {
+ if (nm()->is_native_method()) {
+ // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick.
+ fill_from_compiled_native_frame();
+ } else {
+ PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc());
+ int decode_offset;
+ if (pc_desc == NULL) {
+ // Should not happen, but let fill_from_compiled_frame handle it.
+
+ // If we are trying to walk the stack of a thread that is not
+ // at a safepoint (like AsyncGetCallTrace would do) then this is an
+ // acceptable result. [ This is assuming that safe_for_sender
+ // is so bullet proof that we can trust the frames it produced. ]
+ //
+ // So if we see that the thread is not safepoint safe
+ // then simply produce the method and a bci of zero
+ // and skip the possibility of decoding any inlining that
+ // may be present. That is far better than simply stopping (or
+ // asserting. If however the thread is safepoint safe this
+ // is the sign of a compiler bug and we'll let
+ // fill_from_compiled_frame handle it.
+
+
+ JavaThreadState state = _thread->thread_state();
+
+ // in_Java should be good enough to test safepoint safety
+ // if state were say in_Java_trans then we'd expect that
+ // the pc would have already been slightly adjusted to
+ // one that would produce a pcDesc since the trans state
+ // would be one that might in fact anticipate a safepoint
+
+ if (state == _thread_in_Java ) {
+ // This will get a method a zero bci and no inlining.
+ // Might be nice to have a unique bci to signify this
+ // particular case but for now zero will do.
+
+ fill_from_compiled_native_frame();
+
+ // There is something to be said for setting the mode to
+ // at_end_mode to prevent trying to walk further up the
+ // stack. There is evidence that if we walk any further
+ // that we could produce a bad stack chain. However until
+ // we see evidence that allowing this causes us to find
+ // frames bad enough to cause segv's or assertion failures
+ // we don't do it as while we may get a bad call chain the
+ // probability is much higher (several magnitudes) that we
+ // get good data.
+
+ return true;
+ }
+ decode_offset = DebugInformationRecorder::serialized_null;
+ } else {
+ decode_offset = pc_desc->scope_decode_offset();
+ }
+ fill_from_compiled_frame(decode_offset);
+ }
+ return true;
+ }
+
+ // End of stack?
+ if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
+ _mode = at_end_mode;
+ return true;
+ }
+
+ return false;
+}
+
+
+inline void vframeStreamCommon::fill_from_interpreter_frame() {
+ Method* method = _frame.interpreter_frame_method();
+ address bcp = _frame.interpreter_frame_bcp();
+ int bci = method->validate_bci_from_bcp(bcp);
+ // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
+ // AsyncGetCallTrace interrupts the VM asynchronously. As a result
+ // it is possible to access an interpreter frame for which
+ // no Java-level information is yet available (e.g., becasue
+ // the frame was being created when the VM interrupted it).
+ // In this scenario, pretend that the interpreter is at the point
+ // of entering the method.
+ if (bci < 0) {
+ DEBUG_ONLY(found_bad_method_frame();)
+ bci = 0;
+ }
+ _mode = interpreted_mode;
+ _method = method;
+ _bci = bci;
+}
+
+#endif // SHARE_VM_RUNTIME_VFRAME_INLINE_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframeArray.cpp
--- a/src/hotspot/share/runtime/vframeArray.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vframeArray.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -33,6 +33,7 @@
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiThreadState.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -489,6 +490,9 @@
}
+intptr_t* vframeArray::unextended_sp() const {
+ return _original.unextended_sp();
+}
vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray* chunk,
RegisterMap *reg_map, frame sender, frame caller, frame self,
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframeArray.hpp
--- a/src/hotspot/share/runtime/vframeArray.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vframeArray.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -28,7 +28,7 @@
#include "memory/allocation.hpp"
#include "oops/arrayOop.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/frame.inline.hpp"
+#include "runtime/frame.hpp"
#include "runtime/monitorChunk.hpp"
#include "utilities/growableArray.hpp"
@@ -189,7 +189,7 @@
// Accessors for sp
intptr_t* sp() const { return _original.sp(); }
- intptr_t* unextended_sp() const { return _original.unextended_sp(); }
+ intptr_t* unextended_sp() const;
address original_pc() const { return _original.pc(); }
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vframe_hp.cpp
--- a/src/hotspot/share/runtime/vframe_hp.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vframe_hp.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -34,6 +34,7 @@
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/basicLock.hpp"
+#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/signature.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vmStructs.cpp
--- a/src/hotspot/share/runtime/vmStructs.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vmStructs.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -475,8 +475,8 @@
nonstatic_field(CardTable, _committed, MemRegion*) \
nonstatic_field(CardTable, _guard_region, MemRegion) \
nonstatic_field(CardTable, _byte_map_base, jbyte*) \
- nonstatic_field(CardTableModRefBS, _defer_initial_card_mark, bool) \
- nonstatic_field(CardTableModRefBS, _card_table, CardTable*) \
+ nonstatic_field(CardTableBarrierSet, _defer_initial_card_mark, bool) \
+ nonstatic_field(CardTableBarrierSet, _card_table, CardTable*) \
\
nonstatic_field(CollectedHeap, _reserved, MemRegion) \
nonstatic_field(CollectedHeap, _barrier_set, BarrierSet*) \
@@ -1473,7 +1473,7 @@
declare_type(TenuredSpace, OffsetTableContigSpace) \
declare_toplevel_type(BarrierSet) \
declare_type(ModRefBarrierSet, BarrierSet) \
- declare_type(CardTableModRefBS, ModRefBarrierSet) \
+ declare_type(CardTableBarrierSet, ModRefBarrierSet) \
declare_toplevel_type(CardTable) \
declare_type(CardTableRS, CardTable) \
declare_toplevel_type(BarrierSet::Name) \
@@ -1502,8 +1502,8 @@
declare_toplevel_type(CardTable*) \
declare_toplevel_type(CardTable*const) \
declare_toplevel_type(CardTableRS*) \
- declare_toplevel_type(CardTableModRefBS*) \
- declare_toplevel_type(CardTableModRefBS**) \
+ declare_toplevel_type(CardTableBarrierSet*) \
+ declare_toplevel_type(CardTableBarrierSet**) \
declare_toplevel_type(CollectedHeap*) \
declare_toplevel_type(ContiguousSpace*) \
declare_toplevel_type(DefNewGeneration*) \
@@ -2237,7 +2237,7 @@
declare_constant(AgeTable::table_size) \
\
declare_constant(BarrierSet::ModRef) \
- declare_constant(BarrierSet::CardTableModRef) \
+ declare_constant(BarrierSet::CardTableBarrierSet) \
declare_constant(BarrierSet::G1BarrierSet) \
\
declare_constant(BOTConstants::LogN) \
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vmThread.cpp
--- a/src/hotspot/share/runtime/vmThread.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vmThread.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -31,7 +31,7 @@
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/runtime/vm_operations.cpp
--- a/src/hotspot/share/runtime/vm_operations.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/runtime/vm_operations.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -35,7 +35,8 @@
#include "oops/symbol.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.inline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/diagnosticCommand.cpp
--- a/src/hotspot/share/services/diagnosticCommand.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/diagnosticCommand.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,9 +30,11 @@
#include "compiler/directivesParser.hpp"
#include "gc/shared/vmGCOperations.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "runtime/globals.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
#include "services/diagnosticArgument.hpp"
@@ -44,7 +46,6 @@
#include "utilities/debug.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"
-#include "oops/objArrayOop.inline.hpp"
static void loadAgentModule(TRAPS) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/gcNotifier.cpp
--- a/src/hotspot/share/services/gcNotifier.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/gcNotifier.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "classfile/vmSymbols.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutex.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/heapDumper.cpp
--- a/src/hotspot/share/services/heapDumper.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/heapDumper.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -37,6 +37,8 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/os.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/lowMemoryDetector.cpp
--- a/src/hotspot/share/services/lowMemoryDetector.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/lowMemoryDetector.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -27,7 +27,7 @@
#include "classfile/vmSymbols.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutex.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/management.cpp
--- a/src/hotspot/share/services/management.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/management.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -38,7 +38,7 @@
#include "runtime/arguments.hpp"
#include "runtime/globals.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/interfaceSupport.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/os.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/memTracker.cpp
--- a/src/hotspot/share/services/memTracker.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/memTracker.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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,7 @@
#include "jvm.h"
#include "runtime/mutex.hpp"
+#include "runtime/orderAccess.inline.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memBaseline.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/serviceUtil.hpp
--- a/src/hotspot/share/services/serviceUtil.hpp Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SERVICES_SERVICEUTIL_HPP
-#define SHARE_VM_SERVICES_SERVICEUTIL_HPP
-
-#include "classfile/systemDictionary.hpp"
-#include "oops/objArrayOop.hpp"
-#include "oops/oop.inline.hpp"
-
-//
-// Serviceability utility functions.
-// (Shared by MM and JVMTI).
-//
-class ServiceUtil : public AllStatic {
- public:
-
- // Return true if oop represents an object that is "visible"
- // to the java world.
- static inline bool visible_oop(oop o) {
- // instance
- if (o->is_instance()) {
- // instance objects are visible
- if (o->klass() != SystemDictionary::Class_klass()) {
- return true;
- }
- if (java_lang_Class::is_primitive(o)) {
- return true;
- }
- // java.lang.Classes are visible
- Klass* k = java_lang_Class::as_Klass(o);
- if (k->is_klass()) {
- // if it's a class for an object, an object array, or
- // primitive (type) array then it's visible.
- if (k->is_instance_klass()) {
- return true;
- }
- if (k->is_objArray_klass()) {
- return true;
- }
- if (k->is_typeArray_klass()) {
- return true;
- }
- }
- fatal("visible_oop: should never reach here #1");
- return false;
- }
- // object arrays are visible if they aren't system object arrays
- if (o->is_objArray()) {
- return true;
- }
- // type arrays are visible
- if (o->is_typeArray()) {
- return true;
- }
- // everything else (Method*s, ...) aren't visible
- fatal("visible_oop: should never reach here #2");
- return false;
- }; // end of visible_oop()
-
-};
-
-#endif // SHARE_VM_SERVICES_SERVICEUTIL_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/threadService.cpp
--- a/src/hotspot/share/services/threadService.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/threadService.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -34,6 +34,7 @@
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
+#include "runtime/objectMonitor.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.inline.hpp"
#include "runtime/vframe.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/services/threadService.hpp
--- a/src/hotspot/share/services/threadService.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/services/threadService.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,12 +30,10 @@
#include "runtime/init.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/objectMonitor.hpp"
-#include "runtime/objectMonitor.inline.hpp"
#include "runtime/perfData.hpp"
#include "runtime/thread.hpp"
#include "runtime/threadSMR.hpp"
#include "services/management.hpp"
-#include "services/serviceUtil.hpp"
class OopClosure;
class ThreadDumpResult;
@@ -548,7 +546,7 @@
static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) {
assert((java_thread != NULL), "Java thread should not be null here");
bool active = false;
- if (is_alive(java_thread) && ServiceUtil::visible_oop((oop)obj_m->object())) {
+ if (is_alive(java_thread)) {
active = contended_enter_begin(java_thread);
}
return active;
@@ -569,7 +567,7 @@
// like for vm internal objects and for external objects which are not contended
// thread status is not changed and contended enter stat is not collected.
_active = false;
- if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object()) && obj_m->contentions() > 0) {
+ if (is_alive() && obj_m->contentions() > 0) {
_stat = java_thread->get_thread_stat();
_active = contended_enter_begin(java_thread);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/trace/traceEventClasses.xsl
--- a/src/hotspot/share/trace/traceEventClasses.xsl Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/trace/traceEventClasses.xsl Fri Mar 30 09:24:04 2018 -0700
@@ -1,6 +1,6 @@
+
+ (
+
+
+ ,
+ ) : TraceEvent<>(TIMED) {
+ if (should_commit()) {
+ set_();
+ }
+ }
+
+ void commit(
+
+ ,
+ ) {
+ if (should_commit()) {
+ set_();
+ commit();
+ }
+ }
+
+ static void commit(const Ticks& startTicks,
+ const Ticks& endTicks,
+
+
+
+ ,
+ ) {
+ me(UNTIMED);
+
+ if (me.should_commit()) {
+ me.set_starttime(startTicks);
+ me.set_endtime(endTicks);
+
+ me.set_();
+ me.commit();
+ }
+ }
};
@@ -249,4 +291,13 @@
+
+
+
+
+
+
+
+
+
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/utilities/debug.cpp
--- a/src/hotspot/share/utilities/debug.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/utilities/debug.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -40,7 +40,8 @@
#include "prims/privilegedStack.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/frame.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/utilities/exceptions.cpp
--- a/src/hotspot/share/utilities/exceptions.cpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/utilities/exceptions.cpp Fri Mar 30 09:24:04 2018 -0700
@@ -30,6 +30,7 @@
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/utilities/globalDefinitions.hpp
--- a/src/hotspot/share/utilities/globalDefinitions.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -1012,12 +1012,6 @@
#undef min
#endif
-// The following defines serve the purpose of preventing use of accidentally
-// included min max macros from compiling, while continuing to allow innocent
-// min and max identifiers in the code to compile as intended.
-#define max max
-#define min min
-
// It is necessary to use templates here. Having normal overloaded
// functions does not work because it is necessary to provide both 32-
// and 64-bit overloaded functions, which does not work, and having
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/hotspot/share/utilities/globalDefinitions_xlc.hpp
--- a/src/hotspot/share/utilities/globalDefinitions_xlc.hpp Thu Mar 29 17:52:32 2018 +0530
+++ b/src/hotspot/share/utilities/globalDefinitions_xlc.hpp Fri Mar 30 09:24:04 2018 -0700
@@ -152,7 +152,18 @@
#endif
// Inlining support
-#define NOINLINE
-#define ALWAYSINLINE inline __attribute__((always_inline))
+//
+// Be aware that for function/method declarations, xlC only supports the following
+// syntax (i.e. the attribute must be placed AFTER the function/method declarator):
+//
+// void* operator new(size_t size) throw() NOINLINE;
+//
+// For function/method defintions, the more common placement BEFORE the
+// function/method declarator seems to be supported as well:
+//
+// NOINLINE void* CHeapObj::operator new(size_t size) throw() {...}
+
+#define NOINLINE __attribute__((__noinline__))
+#define ALWAYSINLINE inline __attribute__((__always_inline__))
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
--- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -27,15 +27,11 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
-import java.util.BitSet;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -67,14 +63,11 @@
// maps file descriptor to selection key, synchronize on selector
private final Map fdToKey = new HashMap<>();
- // file descriptors registered with epoll, synchronize on selector
- private final BitSet registered = new BitSet();
-
- // pending new registrations/updates, queued by implRegister and putEventOps
+ // pending new registrations/updates, queued by implRegister and putEventOpos
private final Object updateLock = new Object();
private final Deque newKeys = new ArrayDeque<>();
private final Deque updateKeys = new ArrayDeque<>();
- private final Deque updateOps = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -113,15 +106,17 @@
protected int doSelect(long timeout) throws IOException {
assert Thread.holdsLock(this);
+ // epoll_wait timeout is int
+ int to = (int) Math.min(timeout, Integer.MAX_VALUE);
+ boolean blocking = (to != 0);
+ boolean timedPoll = (to > 0);
+
int numEntries;
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
- // epoll_wait timeout is int
- int to = (int) Math.min(timeout, Integer.MAX_VALUE);
- boolean timedPoll = (to > 0);
do {
long startTime = timedPoll ? System.nanoTime() : 0;
numEntries = EPoll.wait(epfd, pollArrayAddress, NUM_EPOLLEVENTS, to);
@@ -138,7 +133,7 @@
assert IOStatus.check(numEntries);
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
return updateSelectedKeys(numEntries);
@@ -156,33 +151,34 @@
// new registrations
while ((ski = newKeys.pollFirst()) != null) {
if (ski.isValid()) {
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
+ int fd = ski.channel.getFDVal();
SelectionKeyImpl previous = fdToKey.put(fd, ski);
assert previous == null;
- assert registered.get(fd) == false;
+ assert ski.registeredEvents() == 0;
}
}
// changes to interest ops
- assert updateKeys.size() == updateOps.size();
+ assert updateKeys.size() == updateEvents.size();
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
int fd = ski.channel.getFDVal();
if (ski.isValid() && fdToKey.containsKey(fd)) {
- if (registered.get(fd)) {
- if (ops == 0) {
+ int registeredEvents = ski.registeredEvents();
+ if (newEvents != registeredEvents) {
+ if (newEvents == 0) {
// remove from epoll
EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
- registered.clear(fd);
} else {
- // modify events
- EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, ops);
+ if (registeredEvents == 0) {
+ // add to epoll
+ EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, newEvents);
+ } else {
+ // modify events
+ EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, newEvents);
+ }
}
- } else if (ops != 0) {
- // add to epoll
- EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, ops);
- registered.set(fd);
+ ski.registeredEvents(newEvents);
}
}
}
@@ -190,8 +186,9 @@
}
/**
- * Update the keys whose fd's have been selected by the epoll.
- * Add the ready keys to the ready queue.
+ * Update the keys of file descriptors that were polled and add them to
+ * the selected-key set.
+ * If the interrupt fd has been selected, drain it and clear the interrupt.
*/
private int updateSelectedKeys(int numEntries) throws IOException {
assert Thread.holdsLock(this);
@@ -233,7 +230,6 @@
@Override
protected void implClose() throws IOException {
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -245,59 +241,37 @@
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
-
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
- assert Thread.holdsLock(nioKeys());
ensureOpen();
synchronized (updateLock) {
newKeys.addLast(ski);
}
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
int fd = ski.channel.getFDVal();
- fdToKey.remove(fd);
- if (registered.get(fd)) {
- EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
- registered.clear(fd);
+ if (fdToKey.remove(fd) != null) {
+ if (ski.registeredEvents() != 0) {
+ EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
+ ski.registeredEvents(0);
+ }
+ } else {
+ assert ski.registeredEvents() == 0;
}
-
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- updateOps.addLast(ops); // ops first in case adding the key fails
+ updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -27,15 +27,11 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
-import java.util.BitSet;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -66,15 +62,11 @@
// maps file descriptor to selection key, synchronize on selector
private final Map fdToKey = new HashMap<>();
- // file descriptors registered with kqueue, synchronize on selector
- private final BitSet registeredReadFilter = new BitSet();
- private final BitSet registeredWriteFilter = new BitSet();
-
// pending new registrations/updates, queued by implRegister and putEventOps
private final Object updateLock = new Object();
private final Deque newKeys = new ArrayDeque<>();
private final Deque updateKeys = new ArrayDeque<>();
- private final Deque updateOps = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -113,14 +105,16 @@
protected int doSelect(long timeout) throws IOException {
assert Thread.holdsLock(this);
+ long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout
+ boolean blocking = (to != 0);
+ boolean timedPoll = (to > 0);
+
int numEntries;
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
- long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout
- boolean timedPoll = (to > 0);
do {
long startTime = timedPoll ? System.nanoTime() : 0;
numEntries = KQueue.poll(kqfd, pollArrayAddress, MAX_KEVENTS, to);
@@ -137,7 +131,7 @@
assert IOStatus.check(numEntries);
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
return updateSelectedKeys(numEntries);
@@ -155,41 +149,41 @@
// new registrations
while ((ski = newKeys.pollFirst()) != null) {
if (ski.isValid()) {
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
+ int fd = ski.channel.getFDVal();
SelectionKeyImpl previous = fdToKey.put(fd, ski);
assert previous == null;
- assert registeredReadFilter.get(fd) == false;
- assert registeredWriteFilter.get(fd) == false;
+ assert ski.registeredEvents() == 0;
}
}
// changes to interest ops
- assert updateKeys.size() == updateOps.size();
+ assert updateKeys.size() == updateKeys.size();
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
int fd = ski.channel.getFDVal();
if (ski.isValid() && fdToKey.containsKey(fd)) {
- // add or delete interest in read events
- if (registeredReadFilter.get(fd)) {
- if ((ops & Net.POLLIN) == 0) {
- KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
- registeredReadFilter.clear(fd);
+ int registeredEvents = ski.registeredEvents();
+ if (newEvents != registeredEvents) {
+
+ // add or delete interest in read events
+ if ((registeredEvents & Net.POLLIN) != 0) {
+ if ((newEvents & Net.POLLIN) == 0) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
+ }
+ } else if ((newEvents & Net.POLLIN) != 0) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD);
}
- } else if ((ops & Net.POLLIN) != 0) {
- KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD);
- registeredReadFilter.set(fd);
- }
- // add or delete interest in write events
- if (registeredWriteFilter.get(fd)) {
- if ((ops & Net.POLLOUT) == 0) {
- KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
- registeredWriteFilter.clear(fd);
+ // add or delete interest in write events
+ if ((registeredEvents & Net.POLLOUT) != 0) {
+ if ((newEvents & Net.POLLOUT) == 0) {
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
+ }
+ } else if ((newEvents & Net.POLLOUT) != 0) {
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD);
}
- } else if ((ops & Net.POLLOUT) != 0) {
- KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD);
- registeredWriteFilter.set(fd);
+
+ ski.registeredEvents(newEvents);
}
}
}
@@ -197,8 +191,8 @@
}
/**
- * Update the keys whose fd's have been selected by kqueue.
- * Add the ready keys to the selected key set.
+ * Update the keys of file descriptors that were polled and add them to
+ * the selected-key set.
* If the interrupt fd has been selected, drain it and clear the interrupt.
*/
private int updateSelectedKeys(int numEntries) throws IOException {
@@ -265,7 +259,6 @@
protected void implClose() throws IOException {
assert !isOpen();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -277,63 +270,41 @@
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
-
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
- assert Thread.holdsLock(nioKeys());
ensureOpen();
synchronized (updateLock) {
newKeys.addLast(ski);
}
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
int fd = ski.channel.getFDVal();
- fdToKey.remove(fd);
- if (registeredReadFilter.get(fd)) {
- KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
- registeredReadFilter.clear(fd);
- }
- if (registeredWriteFilter.get(fd)) {
- KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
- registeredWriteFilter.clear(fd);
+ int registeredEvents = ski.registeredEvents();
+ if (fdToKey.remove(fd) != null) {
+ if (registeredEvents != 0) {
+ if ((registeredEvents & Net.POLLIN) != 0)
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
+ if ((registeredEvents & Net.POLLOUT) != 0)
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
+ ski.registeredEvents(0);
+ }
+ } else {
+ assert registeredEvents == 0;
}
-
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- updateOps.addLast(ops); // ops first in case adding the key fails
+ updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/lang/StringCoding.java
--- a/src/java.base/share/classes/java/lang/StringCoding.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/lang/StringCoding.java Fri Mar 30 09:24:04 2018 -0700
@@ -52,6 +52,9 @@
import static java.lang.Character.lowSurrogate;
import static java.lang.Character.isSupplementaryCodePoint;
import static java.lang.StringUTF16.putChar;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Utility class for string encoding and decoding.
@@ -67,10 +70,6 @@
private static final ThreadLocal> encoder =
new ThreadLocal<>();
- private static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
- private static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
- private static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
-
private static T deref(ThreadLocal> tl) {
SoftReference sr = tl.get();
if (sr == null)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/lang/Thread.java
--- a/src/java.base/share/classes/java/lang/Thread.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/lang/Thread.java Fri Mar 30 09:24:04 2018 -0700
@@ -146,15 +146,14 @@
}
private volatile String name;
- private int priority;
- private Thread threadQ;
- private long eetop;
+ private int priority;
/* Whether or not the thread is a daemon thread. */
- private boolean daemon = false;
+ private boolean daemon = false;
- /* JVM state */
- private boolean stillborn = false;
+ /* Fields reserved for exclusive use by the JVM */
+ private boolean stillborn = false;
+ private long eetop;
/* What will be run. */
private Runnable target;
@@ -189,7 +188,7 @@
* not specify a stack size. It is up to the VM to do whatever it
* likes with this number; some VMs will ignore it.
*/
- private long stackSize;
+ private final long stackSize;
/*
* JVM-private state that persists after native thread termination.
@@ -199,20 +198,20 @@
/*
* Thread ID
*/
- private long tid;
+ private final long tid;
/* For generating thread ID */
private static long threadSeqNumber;
+ private static synchronized long nextThreadID() {
+ return ++threadSeqNumber;
+ }
+
/*
* Java thread status for tools, default indicates thread 'not yet started'
*/
private volatile int threadStatus;
- private static synchronized long nextThreadID() {
- return ++threadSeqNumber;
- }
-
/**
* The argument supplied to the current call to
* java.util.concurrent.locks.LockSupport.park.
@@ -378,15 +377,6 @@
public static void onSpinWait() {}
/**
- * Initializes a Thread with the current AccessControlContext.
- * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
- */
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize) {
- init(g, target, name, stackSize, null, true);
- }
-
- /**
* Initializes a Thread.
*
* @param g the Thread group
@@ -399,9 +389,9 @@
* @param inheritThreadLocals if {@code true}, inherit initial values for
* inheritable thread-locals from the constructing thread
*/
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize, AccessControlContext acc,
- boolean inheritThreadLocals) {
+ private Thread(ThreadGroup g, Runnable target, String name,
+ long stackSize, AccessControlContext acc,
+ boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
@@ -419,8 +409,8 @@
g = security.getThreadGroup();
}
- /* If the security doesn't have a strong opinion of the matter
- use the parent thread group. */
+ /* If the security manager doesn't have a strong opinion
+ on the matter, use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
@@ -459,7 +449,7 @@
this.stackSize = stackSize;
/* Set thread ID */
- tid = nextThreadID();
+ this.tid = nextThreadID();
}
/**
@@ -482,7 +472,7 @@
* {@code "Thread-"+}n, where n is an integer.
*/
public Thread() {
- init(null, null, "Thread-" + nextThreadNum(), 0);
+ this(null, null, "Thread-" + nextThreadNum(), 0);
}
/**
@@ -498,7 +488,7 @@
* nothing.
*/
public Thread(Runnable target) {
- init(null, target, "Thread-" + nextThreadNum(), 0);
+ this(null, target, "Thread-" + nextThreadNum(), 0);
}
/**
@@ -507,7 +497,7 @@
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
+ this(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
/**
@@ -534,7 +524,7 @@
* thread group
*/
public Thread(ThreadGroup group, Runnable target) {
- init(group, target, "Thread-" + nextThreadNum(), 0);
+ this(group, target, "Thread-" + nextThreadNum(), 0);
}
/**
@@ -546,7 +536,7 @@
* the name of the new thread
*/
public Thread(String name) {
- init(null, null, name, 0);
+ this(null, null, name, 0);
}
/**
@@ -570,7 +560,7 @@
* thread group
*/
public Thread(ThreadGroup group, String name) {
- init(group, null, name, 0);
+ this(group, null, name, 0);
}
/**
@@ -586,7 +576,7 @@
* the name of the new thread
*/
public Thread(Runnable target, String name) {
- init(null, target, name, 0);
+ this(null, target, name, 0);
}
/**
@@ -634,7 +624,7 @@
* thread group or cannot override the context class loader methods.
*/
public Thread(ThreadGroup group, Runnable target, String name) {
- init(group, target, name, 0);
+ this(group, target, name, 0);
}
/**
@@ -713,7 +703,7 @@
*/
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
- init(group, target, name, stackSize);
+ this(group, target, name, stackSize, null, true);
}
/**
@@ -769,7 +759,7 @@
*/
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize, boolean inheritThreadLocals) {
- init(group, target, name, stackSize, null, inheritThreadLocals);
+ this(group, target, name, stackSize, null, inheritThreadLocals);
}
/**
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/nio/charset/Charset.java
--- a/src/java.base/share/classes/java/nio/charset/Charset.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/nio/charset/Charset.java Fri Mar 30 09:24:04 2018 -0700
@@ -26,7 +26,6 @@
package java.nio.charset;
import jdk.internal.misc.VM;
-import sun.nio.cs.StandardCharsets;
import sun.nio.cs.ThreadLocalCoders;
import sun.security.action.GetPropertyAction;
@@ -311,7 +310,8 @@
}
/* The standard set of charsets */
- private static final CharsetProvider standardProvider = new StandardCharsets();
+ private static final CharsetProvider standardProvider
+ = new sun.nio.cs.StandardCharsets();
private static final String[] zeroAliases = new String[0];
@@ -609,7 +609,7 @@
if (cs != null)
defaultCharset = cs;
else
- defaultCharset = sun.nio.cs.UTF_8.INSTANCE;
+ defaultCharset = StandardCharsets.UTF_8;
}
}
return defaultCharset;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/nio/charset/StandardCharsets.java
--- a/src/java.base/share/classes/java/nio/charset/StandardCharsets.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/nio/charset/StandardCharsets.java Fri Mar 30 09:24:04 2018 -0700
@@ -41,26 +41,26 @@
* Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
* Unicode character set
*/
- public static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
+ public static final Charset US_ASCII = new sun.nio.cs.US_ASCII();
/**
* ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
*/
- public static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
+ public static final Charset ISO_8859_1 = new sun.nio.cs.ISO_8859_1();
/**
* Eight-bit UCS Transformation Format
*/
- public static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
+ public static final Charset UTF_8 = new sun.nio.cs.UTF_8();
/**
* Sixteen-bit UCS Transformation Format, big-endian byte order
*/
- public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+ public static final Charset UTF_16BE = new sun.nio.cs.UTF_16BE();
/**
* Sixteen-bit UCS Transformation Format, little-endian byte order
*/
- public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+ public static final Charset UTF_16LE = new sun.nio.cs.UTF_16LE();
/**
* Sixteen-bit UCS Transformation Format, byte order identified by an
* optional byte-order mark
*/
- public static final Charset UTF_16 = Charset.forName("UTF-16");
+ public static final Charset UTF_16 = new sun.nio.cs.UTF_16();
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java
--- a/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Fri Mar 30 09:24:04 2018 -0700
@@ -412,11 +412,11 @@
/**
* Returns the thread id for the given thread. We must access
* this directly rather than via method Thread.getId() because
- * getId() is not final, and has been known to be overridden in
- * ways that do not preserve unique mappings.
+ * getId() has been known to be overridden in ways that do not
+ * preserve unique mappings.
*/
static final long getThreadId(Thread thread) {
- return U.getLongVolatile(thread, TID);
+ return U.getLong(thread, TID);
}
// Hotspot implementation via intrinsics API
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/util/jar/Manifest.java
--- a/src/java.base/share/classes/java/util/jar/Manifest.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/util/jar/Manifest.java Fri Mar 30 09:24:04 2018 -0700
@@ -148,7 +148,7 @@
DataOutputStream dos = new DataOutputStream(out);
// Write out the main attributes for the manifest
attr.writeMain(dos);
- // Now write out the pre-entry attributes
+ // Now write out the per-entry attributes
for (Map.Entry e : entries.entrySet()) {
StringBuffer buffer = new StringBuffer("Name: ");
String value = e.getKey();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/util/zip/ZipCoder.java
--- a/src/java.base/share/classes/java/util/zip/ZipCoder.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java Fri Mar 30 09:24:04 2018 -0700
@@ -77,8 +77,7 @@
String toString(byte[] ba, int off, int length) {
try {
- return decoder().decode(ByteBuffer.wrap(ba, off, length)).toString();
-
+ return decoder().decode(ByteBuffer.wrap(ba, off, length)).toString();
} catch (CharacterCodingException x) {
throw new IllegalArgumentException(x);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/java/util/zip/ZipFile.java
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java Fri Mar 30 09:24:04 2018 -0700
@@ -64,6 +64,7 @@
import jdk.internal.misc.VM;
import jdk.internal.perf.PerfCounter;
import jdk.internal.ref.CleanerFactory;
+import jdk.internal.vm.annotation.Stable;
import static java.util.zip.ZipConstants64.*;
import static java.util.zip.ZipUtils.*;
@@ -98,14 +99,14 @@
private final String name; // zip file name
private volatile boolean closeRequested;
- private ZipCoder zc;
+ private final @Stable ZipCoder zc;
// The "resource" used by this zip file that needs to be
// cleaned after use.
// a) the input streams that need to be closed
// b) the list of cached Inflater objects
// c) the "native" source of this zip file.
- private final CleanableResource res;
+ private final @Stable CleanableResource res;
private static final int STORED = ZipEntry.STORED;
private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -369,7 +370,7 @@
public InputStream getInputStream(ZipEntry entry) throws IOException {
Objects.requireNonNull(entry, "entry");
int pos = -1;
- ZipFileInputStream in = null;
+ ZipFileInputStream in;
Source zsrc = res.zsrc;
Set istreams = res.istreams;
synchronized (this) {
@@ -604,9 +605,7 @@
private String getEntryName(int pos) {
byte[] cen = res.zsrc.cen;
int nlen = CENNAM(cen, pos);
- int clen = CENCOM(cen, pos);
- int flag = CENFLG(cen, pos);
- if (!zc.isUTF8() && (flag & EFS) != 0) {
+ if (!zc.isUTF8() && (CENFLG(cen, pos) & EFS) != 0) {
return zc.toStringUTF8(cen, pos + CENHDR, nlen);
} else {
return zc.toString(cen, pos + CENHDR, nlen);
@@ -1218,7 +1217,7 @@
static Source get(File file, boolean toDelete) throws IOException {
Key key = new Key(file,
Files.readAttributes(file.toPath(), BasicFileAttributes.class));
- Source src = null;
+ Source src;
synchronized (files) {
src = files.get(key);
if (src != null) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -1229,10 +1229,9 @@
/**
* Translates native poll revent set into a ready operation set
*/
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0) {
@@ -1244,7 +1243,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -1256,16 +1255,16 @@
((intOps & SelectionKey.OP_WRITE) != 0))
newOps |= SelectionKey.OP_WRITE;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
/**
@@ -1295,16 +1294,15 @@
/**
* Translates an interest operation set into a native poll event set
*/
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
int newOps = 0;
-
if ((ops & SelectionKey.OP_READ) != 0)
newOps |= Net.POLLIN;
if ((ops & SelectionKey.OP_WRITE) != 0)
newOps |= Net.POLLOUT;
if ((ops & SelectionKey.OP_CONNECT) != 0)
newOps |= Net.POLLIN;
- sk.selector.putEventOps(sk, newOps);
+ return newOps;
}
public FileDescriptor getFD() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/SelChImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -61,7 +61,10 @@
*/
boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk);
- void translateAndSetInterestOps(int ops, SelectionKeyImpl sk);
+ /**
+ * Translates an interest operation set into a native event set
+ */
+ int translateInterestOps(int ops);
void kill() throws IOException;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -39,21 +39,28 @@
public final class SelectionKeyImpl
extends AbstractSelectionKey
{
-
final SelChImpl channel; // package-private
- public final SelectorImpl selector;
-
- // Index for a pollfd array in Selector that this key is registered with
- private int index;
+ private final SelectorImpl selector;
private volatile int interestOps;
private volatile int readyOps;
+ // registered events in kernel, used by some Selector implementations
+ private int registeredEvents;
+
+ // index of key in pollfd array, used by some Selector implementations
+ private int index;
+
SelectionKeyImpl(SelChImpl ch, SelectorImpl sel) {
channel = ch;
selector = sel;
}
+ private void ensureValid() {
+ if (!isValid())
+ throw new CancelledKeyException();
+ }
+
@Override
public SelectableChannel channel() {
return (SelectableChannel)channel;
@@ -61,20 +68,7 @@
@Override
public Selector selector() {
- return (Selector)selector;
- }
-
- int getIndex() { // package-private
- return index;
- }
-
- void setIndex(int i) { // package-private
- index = i;
- }
-
- private void ensureValid() {
- if (!isValid())
- throw new CancelledKeyException();
+ return selector;
}
@Override
@@ -109,7 +103,7 @@
public SelectionKey nioInterestOps(int ops) {
if ((ops & ~channel().validOps()) != 0)
throw new IllegalArgumentException();
- channel.translateAndSetInterestOps(ops, this);
+ selector.putEventOps(this, channel.translateInterestOps(ops));
interestOps = ops;
return this;
}
@@ -118,6 +112,24 @@
return interestOps;
}
+ void registeredEvents(int events) {
+ // assert Thread.holdsLock(selector);
+ this.registeredEvents = events;
+ }
+
+ int registeredEvents() {
+ // assert Thread.holdsLock(selector);
+ return registeredEvents;
+ }
+
+ int getIndex() {
+ return index;
+ }
+
+ void setIndex(int i) {
+ index = i;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/SelectorImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -26,9 +26,9 @@
package sun.nio.ch;
import java.io.IOException;
-import java.net.SocketException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.AbstractSelector;
@@ -47,7 +47,7 @@
extends AbstractSelector
{
// The set of keys registered with this Selector
- protected final HashSet keys;
+ protected final Set keys;
// The set of keys with data ready for an operation
protected final Set selectedKeys;
@@ -88,6 +88,26 @@
return publicSelectedKeys;
}
+ /**
+ * Marks the beginning of a select operation that might block
+ */
+ protected final void begin(boolean blocking) {
+ if (blocking) begin();
+ }
+
+ /**
+ * Marks the end of a select operation that may have blocked
+ */
+ protected final void end(boolean blocking) {
+ if (blocking) end();
+ }
+
+ /**
+ * Selects the keys for channels that are ready for I/O operations.
+ *
+ * @param timeout timeout in milliseconds to wait, 0 to not wait, -1 to
+ * wait indefinitely
+ */
protected abstract int doSelect(long timeout) throws IOException;
private int lockAndDoSelect(long timeout) throws IOException {
@@ -125,9 +145,21 @@
public final void implCloseSelector() throws IOException {
wakeup();
synchronized (this) {
+ implClose();
synchronized (publicKeys) {
synchronized (publicSelectedKeys) {
- implClose();
+ // Deregister channels
+ Iterator i = keys.iterator();
+ while (i.hasNext()) {
+ SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
+ deregister(ski);
+ SelectableChannel selch = ski.channel();
+ if (!selch.isOpen() && !selch.isRegistered())
+ ((SelChImpl)selch).kill();
+ selectedKeys.remove(ski);
+ i.remove();
+ }
+ assert selectedKeys.isEmpty() && keys.isEmpty();
}
}
}
@@ -144,8 +176,10 @@
throw new IllegalSelectorException();
SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
k.attach(attachment);
+ // register before adding to key set
+ implRegister(k);
synchronized (publicKeys) {
- implRegister(k);
+ keys.add(k);
}
k.interestOps(ops);
return k;
@@ -156,27 +190,37 @@
protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
protected final void processDeregisterQueue() throws IOException {
- // Precondition: Synchronized on this, keys, and selectedKeys
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(publicKeys);
+ assert Thread.holdsLock(publicSelectedKeys);
+
Set cks = cancelledKeys();
synchronized (cks) {
if (!cks.isEmpty()) {
Iterator i = cks.iterator();
while (i.hasNext()) {
SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- try {
- implDereg(ski);
- } catch (SocketException se) {
- throw new IOException("Error deregistering key", se);
- } finally {
- i.remove();
- }
+ i.remove();
+
+ // remove the key from the selector
+ implDereg(ski);
+
+ selectedKeys.remove(ski);
+ keys.remove(ski);
+
+ // remove from channel's key set
+ deregister(ski);
+
+ SelectableChannel ch = ski.channel();
+ if (!ch.isOpen() && !ch.isRegistered())
+ ((SelChImpl)ch).kill();
}
}
}
}
/**
- * Invoked to change the key's interest set
+ * Change the event set in the selector
*/
- public abstract void putEventOps(SelectionKeyImpl ski, int ops);
+ protected abstract void putEventOps(SelectionKeyImpl ski, int events);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -445,10 +445,9 @@
/**
* Translates native poll revent set into a ready operation set
*/
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0) {
@@ -460,7 +459,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -468,29 +467,26 @@
((intOps & SelectionKey.OP_ACCEPT) != 0))
newOps |= SelectionKey.OP_ACCEPT;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
/**
* Translates an interest operation set into a native poll event set
*/
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
int newOps = 0;
-
- // Translate ops
if ((ops & SelectionKey.OP_ACCEPT) != 0)
newOps |= Net.POLLIN;
- // Place ops into pollfd array
- sk.selector.putEventOps(sk, newOps);
+ return newOps;
}
public FileDescriptor getFD() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -994,10 +994,9 @@
/**
* Translates native poll revent ops into a ready operation ops
*/
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0) {
@@ -1009,7 +1008,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -1026,22 +1025,22 @@
((intOps & SelectionKey.OP_WRITE) != 0) && connected)
newOps |= SelectionKey.OP_WRITE;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
/**
* Translates an interest operation set into a native poll event set
*/
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
int newOps = 0;
if ((ops & SelectionKey.OP_READ) != 0)
newOps |= Net.POLLIN;
@@ -1049,7 +1048,7 @@
newOps |= Net.POLLOUT;
if ((ops & SelectionKey.OP_CONNECT) != 0)
newOps |= Net.POLLCONN;
- sk.selector.putEventOps(sk, newOps);
+ return newOps;
}
public FileDescriptor getFD() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java
--- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Fri Mar 30 09:24:04 2018 -0700
@@ -39,9 +39,6 @@
extends Charset
implements HistoricallyNamedCharset
{
-
- public static final ISO_8859_1 INSTANCE = new ISO_8859_1();
-
public ISO_8859_1() {
super("ISO-8859-1", StandardCharsets.aliases_ISO_8859_1());
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template
--- a/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template Fri Mar 30 09:24:04 2018 -0700
@@ -83,9 +83,12 @@
Map map = cache;
if (map == null) {
map = new Cache();
- map.put("utf-8", UTF_8.INSTANCE);
- map.put("iso-8859-1", ISO_8859_1.INSTANCE);
- map.put("us-ascii", US_ASCII.INSTANCE);
+ map.put("utf-8", java.nio.charset.StandardCharsets.UTF_8);
+ map.put("iso-8859-1", java.nio.charset.StandardCharsets.ISO_8859_1);
+ map.put("us-ascii", java.nio.charset.StandardCharsets.US_ASCII);
+ map.put("utf-16", java.nio.charset.StandardCharsets.UTF_16);
+ map.put("utf-16be", java.nio.charset.StandardCharsets.UTF_16BE);
+ map.put("utf-16le", java.nio.charset.StandardCharsets.UTF_16LE);
cache = map;
}
return map;
@@ -123,11 +126,11 @@
// Classes eagerly during bootstrap
String csn;
if (charsetName.equals("UTF-8")) {
- return UTF_8.INSTANCE;
+ return java.nio.charset.StandardCharsets.UTF_8;
} else if (charsetName.equals("US-ASCII")) {
- return US_ASCII.INSTANCE;
+ return java.nio.charset.StandardCharsets.US_ASCII;
} else if (charsetName.equals("ISO-8859-1")) {
- return ISO_8859_1.INSTANCE;
+ return java.nio.charset.StandardCharsets.ISO_8859_1;
} else {
csn = canonicalize(toLower(charsetName));
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/US_ASCII.java
--- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Fri Mar 30 09:24:04 2018 -0700
@@ -36,8 +36,6 @@
extends Charset
implements HistoricallyNamedCharset
{
- public static final US_ASCII INSTANCE = new US_ASCII();
-
public US_ASCII() {
super("US-ASCII", StandardCharsets.aliases_US_ASCII());
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/UTF_16.java
--- a/src/java.base/share/classes/sun/nio/cs/UTF_16.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_16.java Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
-class UTF_16 extends Unicode
+public class UTF_16 extends Unicode
{
public UTF_16() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/UTF_16BE.java
--- a/src/java.base/share/classes/sun/nio/cs/UTF_16BE.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_16BE.java Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
-class UTF_16BE extends Unicode
+public class UTF_16BE extends Unicode
{
public UTF_16BE() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/UTF_16LE.java
--- a/src/java.base/share/classes/sun/nio/cs/UTF_16LE.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_16LE.java Fri Mar 30 09:24:04 2018 -0700
@@ -29,7 +29,7 @@
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
-class UTF_16LE extends Unicode
+public class UTF_16LE extends Unicode
{
public UTF_16LE() {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/share/classes/sun/nio/cs/UTF_8.java
--- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java Fri Mar 30 09:24:04 2018 -0700
@@ -55,9 +55,6 @@
*/
public final class UTF_8 extends Unicode {
-
- public static final UTF_8 INSTANCE = new UTF_8();
-
public UTF_8() {
super("UTF-8", StandardCharsets.aliases_UTF_8());
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -27,15 +27,11 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
-import java.util.BitSet;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -59,14 +55,11 @@
// maps file descriptor to selection key, synchronize on selector
private final Map fdToKey = new HashMap<>();
- // file descriptors registered with /dev/poll, synchronize on selector
- private final BitSet registered = new BitSet();
-
// pending new registrations/updates, queued by implRegister and putEventOps
private final Object updateLock = new Object();
private final Deque newKeys = new ArrayDeque<>();
private final Deque updateKeys = new ArrayDeque<>();
- private final Deque updateOps = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -99,15 +92,16 @@
throws IOException
{
assert Thread.holdsLock(this);
+ boolean blocking = (timeout != 0);
int numEntries;
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
numEntries = pollWrapper.poll(timeout);
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
return updateSelectedKeys(numEntries);
@@ -125,41 +119,35 @@
// new registrations
while ((ski = newKeys.pollFirst()) != null) {
if (ski.isValid()) {
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
+ int fd = ski.channel.getFDVal();
SelectionKeyImpl previous = fdToKey.put(fd, ski);
assert previous == null;
- assert registered.get(fd) == false;
+ assert ski.registeredEvents() == 0;
}
}
// Translate the queued updates to changes to the set of monitored
// file descriptors. The changes are written to the /dev/poll driver
// in bulk.
- assert updateKeys.size() == updateOps.size();
+ assert updateKeys.size() == updateEvents.size();
int index = 0;
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
int fd = ski.channel.getFDVal();
if (ski.isValid() && fdToKey.containsKey(fd)) {
- if (registered.get(fd)) {
- if (ops == 0) {
- // remove file descriptor
- pollWrapper.putPollFD(index++, fd, POLLREMOVE);
- registered.clear(fd);
- } else {
- // change events
+ int registeredEvents = ski.registeredEvents();
+ if (newEvents != registeredEvents) {
+ if (registeredEvents != 0)
pollWrapper.putPollFD(index++, fd, POLLREMOVE);
- pollWrapper.putPollFD(index++, fd, (short)ops);
+ if (newEvents != 0)
+ pollWrapper.putPollFD(index++, fd, (short)newEvents);
+ ski.registeredEvents(newEvents);
+
+ // write to /dev/poll
+ if (index > (NUM_POLLFDS-2)) {
+ pollWrapper.registerMultiple(index);
+ index = 0;
}
- } else if (ops != 0) {
- // add file descriptor
- pollWrapper.putPollFD(index++, fd, (short)ops);
- registered.set(fd);
- }
- if (index > (NUM_POLLFDS-2)) {
- pollWrapper.registerMultiple(index);
- index = 0;
}
}
}
@@ -171,8 +159,9 @@
}
/**
- * Update the keys whose fd's have been selected by the /dev/poll.
- * Add the ready keys to the ready queue.
+ * Update the keys of file descriptors that were polled and add them to
+ * the selected-key set.
+ * If the interrupt fd has been selected, drain it and clear the interrupt.
*/
private int updateSelectedKeys(int numEntries) throws IOException {
assert Thread.holdsLock(this);
@@ -214,7 +203,6 @@
protected void implClose() throws IOException {
assert !isOpen();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -224,59 +212,37 @@
pollWrapper.close();
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
-
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
- assert Thread.holdsLock(nioKeys());
ensureOpen();
synchronized (updateLock) {
newKeys.addLast(ski);
}
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
int fd = ski.channel.getFDVal();
- fdToKey.remove(fd);
- if (registered.get(fd)) {
- pollWrapper.register(fd, POLLREMOVE);
- registered.clear(fd);
+ if (fdToKey.remove(fd) != null) {
+ if (ski.registeredEvents() != 0) {
+ pollWrapper.register(fd, POLLREMOVE);
+ ski.registeredEvents(0);
+ }
+ } else {
+ assert ski.registeredEvents() == 0;
}
-
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- updateOps.addLast(ops); // ops first in case adding the key fails
+ updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java
--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -27,17 +27,14 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import jdk.internal.misc.Unsafe;
import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_FD;
import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_USER;
@@ -69,18 +66,8 @@
private final long pollArrayAddress;
private final AllocatedNativeObject pollArray;
- // a registration of a file descriptor with a selector
- private static class RegEntry {
- final SelectionKeyImpl ski;
- int registeredOps;
- int lastUpdate;
- RegEntry(SelectionKeyImpl ski) {
- this.ski = ski;
- }
- }
-
- // maps a file descriptor to registration entry, synchronize on selector
- private final Map fdToRegEntry = new HashMap<>();
+ // maps file descriptor to selection key, synchronize on selector
+ private final Map fdToKey = new HashMap<>();
// the last update operation, incremented by processUpdateQueue
private int lastUpdate;
@@ -90,7 +77,7 @@
private final Object updateLock = new Object();
private final Deque newKeys = new ArrayDeque<>();
private final Deque updateKeys = new ArrayDeque<>();
- private final Deque updateOps = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -115,14 +102,16 @@
protected int doSelect(long timeout) throws IOException {
assert Thread.holdsLock(this);
+ long to = timeout;
+ boolean blocking = (to != 0);
+ boolean timedPoll = (to > 0);
+
int numEvents;
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
- long to = timeout;
- boolean timedPoll = (to > 0);
do {
long startTime = timedPoll ? System.nanoTime() : 0;
numEvents = port_getn(pfd, pollArrayAddress, MAX_EVENTS, to);
@@ -139,7 +128,7 @@
assert IOStatus.check(numEvents);
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
return processPortEvents(numEvents);
@@ -161,30 +150,27 @@
// new registrations
while ((ski = newKeys.pollFirst()) != null) {
if (ski.isValid()) {
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
- RegEntry previous = fdToRegEntry.put(fd, new RegEntry(ski));
+ int fd = ski.channel.getFDVal();
+ SelectionKeyImpl previous = fdToKey.put(fd, ski);
assert previous == null;
+ assert ski.registeredEvents() == 0;
}
}
// changes to interest ops
- assert updateKeys.size() == updateOps.size();
+ assert updateKeys.size() == updateEvents.size();
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
int fd = ski.channel.getFDVal();
- RegEntry e = fdToRegEntry.get(fd);
- if (ski.isValid() && (e != null) && (e.lastUpdate != lastUpdate)) {
- assert e.ski == ski;
- if ((ops != e.registeredOps)) {
- if (ops == 0) {
+ if (ski.isValid() && fdToKey.containsKey(fd)) {
+ if (newEvents != ski.registeredEvents()) {
+ if (newEvents == 0) {
port_dissociate(pfd, PORT_SOURCE_FD, fd);
} else {
- port_associate(pfd, PORT_SOURCE_FD, fd, ops);
+ port_associate(pfd, PORT_SOURCE_FD, fd, newEvents);
}
- e.registeredOps = ops;
+ ski.registeredEvents(newEvents);
}
- e.lastUpdate = lastUpdate;
}
}
}
@@ -209,9 +195,8 @@
short source = getSource(i);
if (source == PORT_SOURCE_FD) {
int fd = getDescriptor(i);
- RegEntry e = fdToRegEntry.get(fd);
- if (e != null) {
- SelectionKeyImpl ski = e.ski;
+ SelectionKeyImpl ski = fdToKey.get(fd);
+ if (ski != null) {
int rOps = getEventOps(i);
if (selectedKeys.contains(ski)) {
if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
@@ -225,12 +210,11 @@
}
}
- // queue selection key so that it is re-associated at
- // next select. Push to end of deque so that changes to
- // the interest ops are processed first
- updateKeys.addLast(ski);
- updateOps.addLast(e.registeredOps);
- e.registeredOps = 0;
+ // re-queue key to head so that it is re-associated at
+ // next select (and before other changes)
+ updateEvents.addFirst(ski.registeredEvents());
+ updateKeys.addFirst(ski);
+ ski.registeredEvents(0);
}
} else if (source == PORT_SOURCE_USER) {
interrupted = true;
@@ -250,7 +234,6 @@
protected void implClose() throws IOException {
assert !isOpen();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -259,61 +242,38 @@
port_close(pfd);
pollArray.free();
-
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
- assert Thread.holdsLock(nioKeys());
ensureOpen();
synchronized (updateLock) {
newKeys.addLast(ski);
}
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
int fd = ski.channel.getFDVal();
- RegEntry e = fdToRegEntry.remove(fd);
- if (e != null && e.registeredOps != 0) {
- port_dissociate(pfd, PORT_SOURCE_FD, fd);
+ if (fdToKey.remove(fd) != null) {
+ if (ski.registeredEvents() != 0) {
+ port_dissociate(pfd, PORT_SOURCE_FD, fd);
+ ski.registeredEvents(0);
+ }
+ } else {
+ assert ski.registeredEvents() == 0;
}
-
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- // push to front of deque so that it processed before other
- // updates for the same key.
- updateOps.addFirst(ops);
- updateKeys.addFirst(ski);
+ updateEvents.addLast(events); // events first in case adding key fails
+ updateKeys.addLast(ski);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/solaris/native/libjsig/jsig.c
--- a/src/java.base/solaris/native/libjsig/jsig.c Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/solaris/native/libjsig/jsig.c Fri Mar 30 09:24:04 2018 -0700
@@ -177,13 +177,11 @@
}
}
-JNIEXPORT sa_handler_t JNICALL
-signal(int sig, sa_handler_t disp) {
+sa_handler_t signal(int sig, sa_handler_t disp) {
return set_signal(sig, disp, false);
}
-JNIEXPORT sa_handler_t JNICALL
-sigset(int sig, sa_handler_t disp) {
+sa_handler_t sigset(int sig, sa_handler_t disp) {
return set_signal(sig, disp, true);
}
@@ -199,8 +197,7 @@
return (*os_sigaction)(sig, act, oact);
}
-JNIEXPORT int JNICALL
-sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
+int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
int res;
struct sigaction oldAct;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java
--- a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -26,14 +26,11 @@
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -63,7 +60,7 @@
// pending updates, queued by putEventOps
private final Object updateLock = new Object();
private final Deque updateKeys = new ArrayDeque<>();
- private final Deque updateOps = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
// interrupt triggering and clearing
private final Object interruptLock = new Object();
@@ -99,13 +96,15 @@
protected int doSelect(long timeout) throws IOException {
assert Thread.holdsLock(this);
+ int to = (int) Math.min(timeout, Integer.MAX_VALUE); // max poll timeout
+ boolean blocking = (to != 0);
+ boolean timedPoll = (to > 0);
+
processUpdateQueue();
processDeregisterQueue();
try {
- begin();
+ begin(blocking);
- int to = (int) Math.min(timeout, Integer.MAX_VALUE); // max poll timeout
- boolean timedPoll = (to > 0);
int numPolled;
do {
long startTime = timedPoll ? System.nanoTime() : 0;
@@ -123,7 +122,7 @@
assert numPolled <= pollArraySize;
} finally {
- end();
+ end(blocking);
}
processDeregisterQueue();
@@ -137,23 +136,22 @@
assert Thread.holdsLock(this);
synchronized (updateLock) {
- assert updateKeys.size() == updateOps.size();
-
+ assert updateKeys.size() == updateEvents.size();
SelectionKeyImpl ski;
while ((ski = updateKeys.pollFirst()) != null) {
- int ops = updateOps.pollFirst();
+ int newEvents = updateEvents.pollFirst();
if (ski.isValid()) {
int index = ski.getIndex();
assert index >= 0 && index < pollArraySize;
if (index > 0) {
assert pollKeys.get(index) == ski;
- if (ops == 0) {
+ if (newEvents == 0) {
remove(ski);
} else {
- update(ski, ops);
+ update(ski, newEvents);
}
- } else if (ops != 0) {
- add(ski, ops);
+ } else if (newEvents != 0) {
+ add(ski, newEvents);
}
}
}
@@ -161,8 +159,8 @@
}
/**
- * Update the keys whose fd's have been selected by kqueue.
- * Add the ready keys to the selected key set.
+ * Update the keys of file descriptors that were polled and add them to
+ * the selected-key set.
* If the interrupt fd has been selected, drain it and clear the interrupt.
*/
private int updateSelectedKeys() throws IOException {
@@ -205,7 +203,6 @@
protected void implClose() throws IOException {
assert !isOpen();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
// prevent further wakeup
synchronized (interruptLock) {
@@ -215,59 +212,31 @@
pollArray.free();
FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1);
-
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- ski.setIndex(-1);
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
assert ski.getIndex() == 0;
- assert Thread.holdsLock(nioKeys());
-
ensureOpen();
- keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
assert !ski.isValid();
assert Thread.holdsLock(this);
- assert Thread.holdsLock(nioKeys());
- assert Thread.holdsLock(nioSelectedKeys());
// remove from poll array
int index = ski.getIndex();
if (index > 0) {
remove(ski);
}
-
- // remove from selected-key and key set
- selectedKeys.remove(ski);
- keys.remove(ski);
-
- // remove from channel's key set
- deregister(ski);
-
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl) selch).kill();
}
@Override
- public void putEventOps(SelectionKeyImpl ski, int ops) {
+ public void putEventOps(SelectionKeyImpl ski, int events) {
ensureOpen();
synchronized (updateLock) {
- updateOps.addLast(ops); // ops first in case adding the key fails
+ updateEvents.addLast(events); // events first in case adding key fails
updateKeys.addLast(ski);
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
--- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -164,10 +164,9 @@
}
}
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps();// Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0)
@@ -175,7 +174,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -183,22 +182,23 @@
((intOps & SelectionKey.OP_WRITE) != 0))
newOps |= SelectionKey.OP_WRITE;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
+ int newOps = 0;
if (ops == SelectionKey.OP_WRITE)
- ops = Net.POLLOUT;
- sk.selector.putEventOps(sk, ops);
+ newOps |= Net.POLLOUT;
+ return newOps;
}
/**
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
--- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -164,10 +164,9 @@
}
}
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0)
@@ -175,7 +174,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -183,22 +182,23 @@
((intOps & SelectionKey.OP_READ) != 0))
newOps |= SelectionKey.OP_READ;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
+ int newOps = 0;
if (ops == SelectionKey.OP_READ)
- ops = Net.POLLIN;
- sk.selector.putEventOps(sk, ops);
+ newOps |= Net.POLLIN;
+ return newOps;
}
/**
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -40,7 +40,7 @@
* @author Chris Hegarty
*/
-class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
+final class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
/* Used for IPv6 on Windows only */
private FileDescriptor fd1;
@@ -105,8 +105,16 @@
protected synchronized void bind0(int lport, InetAddress laddr)
throws SocketException
{
+ // The native bind0 may close one or both of the underlying file
+ // descriptors, and even create new sockets, so the safest course of
+ // action is to unregister the socket cleaners, and register afterwards.
+ SocketCleanable.unregister(fd);
+ SocketCleanable.unregister(fd1);
+
bind0(lport, laddr, exclusiveBind);
+ SocketCleanable.register(fd);
+ SocketCleanable.register(fd1);
}
protected synchronized void receive(DatagramPacket p)
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/classes/sun/nio/ch/PollArrayWrapper.java
--- a/src/java.base/windows/classes/sun/nio/ch/PollArrayWrapper.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/classes/sun/nio/ch/PollArrayWrapper.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -63,8 +63,9 @@
}
// Prepare another pollfd struct for use.
- void addEntry(int index, SelectionKeyImpl ski) {
+ void putEntry(int index, SelectionKeyImpl ski) {
putDescriptor(index, ski.channel.getFDVal());
+ putEventOps(index, 0);
}
// Writes the pollfd entry from the source wrapper at the source index
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java
--- a/src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -72,10 +72,9 @@
sc.configureBlocking(block);
}
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0)
@@ -83,7 +82,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -91,22 +90,23 @@
((intOps & SelectionKey.OP_WRITE) != 0))
newOps |= SelectionKey.OP_WRITE;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
+ int newOps = 0;
if ((ops & SelectionKey.OP_WRITE) != 0)
- ops = Net.POLLOUT;
- sk.selector.putEventOps(sk, ops);
+ newOps |= Net.POLLOUT;
+ return newOps;
}
public int write(ByteBuffer src) throws IOException {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java
--- a/src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -71,10 +71,9 @@
sc.configureBlocking(block);
}
- public boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
- int oldOps = sk.nioReadyOps();
+ public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
+ int intOps = ski.nioInterestOps();
+ int oldOps = ski.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0)
@@ -82,7 +81,7 @@
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@@ -90,22 +89,23 @@
((intOps & SelectionKey.OP_READ) != 0))
newOps |= SelectionKey.OP_READ;
- sk.nioReadyOps(newOps);
+ ski.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, ski.nioReadyOps(), ski);
}
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
+ return translateReadyOps(ops, 0, ski);
}
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ public int translateInterestOps(int ops) {
+ int newOps = 0;
if ((ops & SelectionKey.OP_READ) != 0)
- ops = Net.POLLIN;
- sk.selector.putEventOps(sk, ops);
+ newOps |= Net.POLLIN;
+ return newOps;
}
public int read(ByteBuffer dst) throws IOException {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
--- a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Fri Mar 30 09:24:04 2018 -0700
@@ -23,23 +23,19 @@
* questions.
*/
-/*
- */
-
-
package sun.nio.ch;
-import java.nio.channels.spi.SelectorProvider;
-import java.nio.channels.Selector;
+import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.Pipe;
-import java.nio.channels.SelectableChannel;
-import java.io.IOException;
-import java.nio.channels.CancelledKeyException;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.Map;
/**
* A multi-threaded implementation of Selector for Windows.
@@ -80,9 +76,6 @@
// File descriptors corresponding to source and sink
private final int wakeupSourceFd, wakeupSinkFd;
- // Lock for close cleanup
- private final Object closeLock = new Object();
-
// Maps file descriptors to their indices in pollArray
private static final class FdMap extends HashMap {
static final long serialVersionUID = 0L;
@@ -103,7 +96,7 @@
// class for fdMap entries
private static final class MapEntry {
- SelectionKeyImpl ski;
+ final SelectionKeyImpl ski;
long updateCount = 0;
long clearedCount = 0;
MapEntry(SelectionKeyImpl ski) {
@@ -121,6 +114,13 @@
private final Object interruptLock = new Object();
private volatile boolean interruptTriggered;
+ // pending new registrations/updates, queued by implRegister and putEventOps
+ private final Object updateLock = new Object();
+ private final Deque newKeys = new ArrayDeque<>();
+ private final Deque updateKeys = new ArrayDeque<>();
+ private final Deque updateEvents = new ArrayDeque<>();
+
+
WindowsSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
pollWrapper = new PollArrayWrapper(INIT_CAP);
@@ -135,11 +135,16 @@
pollWrapper.addWakeupSocket(wakeupSourceFd, 0);
}
+ private void ensureOpen() {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+ }
+
@Override
protected int doSelect(long timeout) throws IOException {
- if (channelArray == null)
- throw new ClosedSelectorException();
+ assert Thread.holdsLock(this);
this.timeout = timeout; // set selector timeout
+ processUpdateQueue();
processDeregisterQueue();
if (interruptTriggered) {
resetWakeupSocket();
@@ -176,6 +181,42 @@
return updated;
}
+ /**
+ * Process new registrations and changes to the interest ops.
+ */
+ private void processUpdateQueue() {
+ assert Thread.holdsLock(this);
+
+ synchronized (updateLock) {
+ SelectionKeyImpl ski;
+
+ // new registrations
+ while ((ski = newKeys.pollFirst()) != null) {
+ if (ski.isValid()) {
+ growIfNeeded();
+ channelArray[totalChannels] = ski;
+ ski.setIndex(totalChannels);
+ pollWrapper.putEntry(totalChannels, ski);
+ totalChannels++;
+ MapEntry previous = fdMap.put(ski);
+ assert previous == null;
+ }
+ }
+
+ // changes to interest ops
+ assert updateKeys.size() == updateEvents.size();
+ while ((ski = updateKeys.pollFirst()) != null) {
+ int events = updateEvents.pollFirst();
+ int fd = ski.channel.getFDVal();
+ if (ski.isValid() && fdMap.containsKey(fd)) {
+ int index = ski.getIndex();
+ assert index >= 0 && index < totalChannels;
+ pollWrapper.putEventOps(index, events);
+ }
+ }
+ }
+ }
+
// Helper threads wait on this lock for the next poll.
private final StartLock startLock = new StartLock();
@@ -503,46 +544,29 @@
@Override
protected void implClose() throws IOException {
- synchronized (closeLock) {
- if (channelArray != null) {
- if (pollWrapper != null) {
- // prevent further wakeup
- synchronized (interruptLock) {
- interruptTriggered = true;
- }
- wakeupPipe.sink().close();
- wakeupPipe.source().close();
- for(int i = 1; i < totalChannels; i++) { // Deregister channels
- if (i % MAX_SELECTABLE_FDS != 0) { // skip wakeupEvent
- deregister(channelArray[i]);
- SelectableChannel selch = channelArray[i].channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- }
- }
- pollWrapper.free();
- pollWrapper = null;
- channelArray = null;
- // Make all remaining helper threads exit
- for (SelectThread t: threads)
- t.makeZombie();
- startLock.startThreads();
- }
- }
+ assert !isOpen();
+ assert Thread.holdsLock(this);
+
+ // prevent further wakeup
+ synchronized (interruptLock) {
+ interruptTriggered = true;
}
+
+ wakeupPipe.sink().close();
+ wakeupPipe.source().close();
+ pollWrapper.free();
+
+ // Make all remaining helper threads exit
+ for (SelectThread t: threads)
+ t.makeZombie();
+ startLock.startThreads();
}
+ @Override
protected void implRegister(SelectionKeyImpl ski) {
- synchronized (closeLock) {
- if (pollWrapper == null)
- throw new ClosedSelectorException();
- growIfNeeded();
- channelArray[totalChannels] = ski;
- ski.setIndex(totalChannels);
- fdMap.put(ski);
- keys.add(ski);
- pollWrapper.addEntry(totalChannels, ski);
- totalChannels++;
+ ensureOpen();
+ synchronized (updateLock) {
+ newKeys.addLast(ski);
}
}
@@ -561,47 +585,43 @@
}
}
- protected void implDereg(SelectionKeyImpl ski) throws IOException{
- int i = ski.getIndex();
- assert (i >= 0);
- synchronized (closeLock) {
+ @Override
+ protected void implDereg(SelectionKeyImpl ski) {
+ assert !ski.isValid();
+ assert Thread.holdsLock(this);
+
+ if (fdMap.remove(ski) != null) {
+ int i = ski.getIndex();
+ assert (i >= 0);
+
if (i != totalChannels - 1) {
// Copy end one over it
SelectionKeyImpl endChannel = channelArray[totalChannels-1];
channelArray[i] = endChannel;
endChannel.setIndex(i);
- pollWrapper.replaceEntry(pollWrapper, totalChannels - 1,
- pollWrapper, i);
+ pollWrapper.replaceEntry(pollWrapper, totalChannels-1, pollWrapper, i);
}
ski.setIndex(-1);
- }
- channelArray[totalChannels - 1] = null;
- totalChannels--;
- if ( totalChannels != 1 && totalChannels % MAX_SELECTABLE_FDS == 1) {
+
+ channelArray[totalChannels - 1] = null;
totalChannels--;
- threadsCount--; // The last thread has become redundant.
- }
- fdMap.remove(ski); // Remove the key from fdMap, keys and selectedKeys
- keys.remove(ski);
- selectedKeys.remove(ski);
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- }
-
- public void putEventOps(SelectionKeyImpl sk, int ops) {
- synchronized (closeLock) {
- if (pollWrapper == null)
- throw new ClosedSelectorException();
- // make sure this sk has not been removed yet
- int index = sk.getIndex();
- if (index == -1)
- throw new CancelledKeyException();
- pollWrapper.putEventOps(index, ops);
+ if (totalChannels != 1 && totalChannels % MAX_SELECTABLE_FDS == 1) {
+ totalChannels--;
+ threadsCount--; // The last thread has become redundant.
+ }
}
}
+ @Override
+ public void putEventOps(SelectionKeyImpl ski, int events) {
+ ensureOpen();
+ synchronized (updateLock) {
+ updateEvents.addLast(events); // events first in case adding key fails
+ updateKeys.addLast(ski);
+ }
+ }
+
+ @Override
public Selector wakeup() {
synchronized (interruptLock) {
if (!interruptTriggered) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c
--- a/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Mar 29 17:52:32 2018 +0530
+++ b/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -491,7 +491,9 @@
if (WSAGetLastError() == WSAEACCES) {
WSASetLastError(WSAEADDRINUSE);
}
+ (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
NET_ThrowCurrent(env, "Cannot bind");
+ closesocket(fd);
return;
}
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Mar 30 09:24:04 2018 -0700
@@ -52,6 +52,8 @@
import sun.jvm.hotspot.memory.SymbolTable;
import sun.jvm.hotspot.memory.SystemDictionary;
import sun.jvm.hotspot.memory.Universe;
+import sun.jvm.hotspot.gc.shared.CollectedHeap;
+import sun.jvm.hotspot.gc.g1.G1CollectedHeap;
import sun.jvm.hotspot.oops.DefaultHeapVisitor;
import sun.jvm.hotspot.oops.HeapVisitor;
import sun.jvm.hotspot.oops.InstanceKlass;
@@ -1656,6 +1658,21 @@
}
}
},
+ new Command("g1regiondetails", false) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 0) {
+ usage();
+ } else {
+ CollectedHeap heap = VM.getVM().getUniverse().heap();
+ if (!(heap instanceof G1CollectedHeap)) {
+ out.println("This command is valid only for G1GC.");
+ return;
+ }
+ out.println("Region Details:");
+ ((G1CollectedHeap)heap).printRegionDetails(out);
+ }
+ }
+ },
new Command("universe", false) {
public void doit(Tokens t) {
if (t.countTokens() != 0) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -33,6 +33,7 @@
import sun.jvm.hotspot.gc.shared.CollectedHeap;
import sun.jvm.hotspot.gc.shared.CollectedHeapName;
import sun.jvm.hotspot.gc.shared.SpaceClosure;
+import sun.jvm.hotspot.gc.shared.PrintRegionClosure;
import sun.jvm.hotspot.memory.MemRegion;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObjectFactory;
@@ -40,6 +41,7 @@
import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.tools.HeapSummary;
// Mirror class for G1CollectedHeap.
@@ -133,6 +135,14 @@
tty.print("garbage-first heap");
tty.print(" [" + mr.start() + ", " + mr.end() + "]");
tty.println(" region size " + (HeapRegion.grainBytes() / 1024) + "K");
+
+ HeapSummary sum = new HeapSummary();
+ sum.printG1HeapSummary(this);
+ }
+
+ public void printRegionDetails(PrintStream tty) {
+ PrintRegionClosure prc = new PrintRegionClosure(tty);
+ heapRegionIterate(prc);
}
public G1CollectedHeap(Address addr) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
package sun.jvm.hotspot.gc.g1;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
@@ -124,4 +125,9 @@
public static long getPointerSize() {
return pointerSize;
}
+
+ public void printOn(PrintStream tty) {
+ tty.print("Region: " + bottom() + "," + top() + "," + end());
+ tty.println(":" + type.typeAnnotation());
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -40,8 +40,13 @@
private static int freeTag;
private static int youngMask;
+ private static int edenTag;
+ private static int survTag;
private static int humongousMask;
+ private static int startsHumongousTag;
+ private static int continuesHumongousTag;
private static int pinnedMask;
+ private static int archiveMask;
private static int oldMask;
private static CIntegerField tagField;
private int tag;
@@ -61,6 +66,11 @@
freeTag = db.lookupIntConstant("HeapRegionType::FreeTag");
youngMask = db.lookupIntConstant("HeapRegionType::YoungMask");
+ edenTag = db.lookupIntConstant("HeapRegionType::EdenTag");
+ survTag = db.lookupIntConstant("HeapRegionType::SurvTag");
+ startsHumongousTag = db.lookupIntConstant("HeapRegionType::StartsHumongousTag");
+ continuesHumongousTag = db.lookupIntConstant("HeapRegionType::ContinuesHumongousTag");
+ archiveMask = db.lookupIntConstant("HeapRegionType::ArchiveMask");
humongousMask = db.lookupIntConstant("HeapRegionType::HumongousMask");
pinnedMask = db.lookupIntConstant("HeapRegionType::PinnedMask");
oldMask = db.lookupIntConstant("HeapRegionType::OldMask");
@@ -70,6 +80,14 @@
return tagField.getValue(addr) == freeTag;
}
+ public boolean isEden() {
+ return tagField.getValue(addr) == edenTag;
+ }
+
+ public boolean isSurvivor() {
+ return tagField.getValue(addr) == survTag;
+ }
+
public boolean isYoung() {
return (tagField.getValue(addr) & youngMask) != 0;
}
@@ -78,6 +96,18 @@
return (tagField.getValue(addr) & humongousMask) != 0;
}
+ public boolean isStartsHumongous() {
+ return tagField.getValue(addr) == startsHumongousTag;
+ }
+
+ public boolean isContinuesHumongous() {
+ return tagField.getValue(addr) == continuesHumongousTag;
+ }
+
+ public boolean isArchive() {
+ return (tagField.getValue(addr) & archiveMask) != 0;
+ }
+
public boolean isPinned() {
return (tagField.getValue(addr) & pinnedMask) != 0;
}
@@ -89,4 +119,32 @@
public HeapRegionType(Address addr) {
super(addr);
}
+
+ public String typeAnnotation() {
+ if (isFree()) {
+ return "Free";
+ }
+ if (isEden()) {
+ return "Eden";
+ }
+ if (isSurvivor()) {
+ return "Survivor";
+ }
+ if (isStartsHumongous()) {
+ return "StartsHumongous";
+ }
+ if (isContinuesHumongous()) {
+ return "ContinuesHumongous";
+ }
+ if (isArchive()) {
+ return "Archive";
+ }
+ if (isPinned()) {
+ return "Pinned";
+ }
+ if (isOld()) {
+ return "Old";
+ }
+ return "Unknown Region Type";
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/PrintRegionClosure.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/PrintRegionClosure.java Fri Mar 30 09:24:04 2018 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.shared;
+
+import java.io.PrintStream;
+import sun.jvm.hotspot.gc.g1.HeapRegion;
+
+public class PrintRegionClosure implements SpaceClosure {
+ private PrintStream tty;
+
+ public PrintRegionClosure(PrintStream tty) {
+ this.tty = tty;
+ }
+
+ public void doSpace(Space hr) {
+ ((HeapRegion)hr).printOn(tty);
+ }
+}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -111,22 +111,7 @@
}
}
} else if (heap instanceof G1CollectedHeap) {
- G1CollectedHeap g1h = (G1CollectedHeap) heap;
- G1MonitoringSupport g1mm = g1h.g1mm();
- long edenRegionNum = g1mm.edenRegionNum();
- long survivorRegionNum = g1mm.survivorRegionNum();
- HeapRegionSetBase oldSet = g1h.oldSet();
- HeapRegionSetBase humongousSet = g1h.humongousSet();
- long oldRegionNum = oldSet.length() + humongousSet.length();
- printG1Space("G1 Heap:", g1h.n_regions(),
- g1h.used(), g1h.capacity());
- System.out.println("G1 Young Generation:");
- printG1Space("Eden Space:", edenRegionNum,
- g1mm.edenUsed(), g1mm.edenCommitted());
- printG1Space("Survivor Space:", survivorRegionNum,
- g1mm.survivorUsed(), g1mm.survivorCommitted());
- printG1Space("G1 Old Generation:", oldRegionNum,
- g1mm.oldUsed(), g1mm.oldCommitted());
+ printG1HeapSummary((G1CollectedHeap)heap);
} else if (heap instanceof ParallelScavengeHeap) {
ParallelScavengeHeap psh = (ParallelScavengeHeap) heap;
PSYoungGen youngGen = psh.youngGen();
@@ -217,6 +202,24 @@
System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used");
}
+ public void printG1HeapSummary(G1CollectedHeap g1h) {
+ G1MonitoringSupport g1mm = g1h.g1mm();
+ long edenRegionNum = g1mm.edenRegionNum();
+ long survivorRegionNum = g1mm.survivorRegionNum();
+ HeapRegionSetBase oldSet = g1h.oldSet();
+ HeapRegionSetBase humongousSet = g1h.humongousSet();
+ long oldRegionNum = oldSet.length() + humongousSet.length();
+ printG1Space("G1 Heap:", g1h.n_regions(),
+ g1h.used(), g1h.capacity());
+ System.out.println("G1 Young Generation:");
+ printG1Space("Eden Space:", edenRegionNum,
+ g1mm.edenUsed(), g1mm.edenCommitted());
+ printG1Space("Survivor Space:", survivorRegionNum,
+ g1mm.survivorUsed(), g1mm.survivorCommitted());
+ printG1Space("G1 Old Generation:", oldRegionNum,
+ g1mm.oldUsed(), g1mm.oldCommitted());
+ }
+
private void printG1Space(String spaceName, long regionNum,
long used, long capacity) {
long free = capacity - used;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Fri Mar 30 09:24:04 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -663,8 +663,12 @@
}
@Override
+ public void loadReferencedType(int cpi, int opcode) {
+ loadReferencedType(cpi, opcode, true /* initialize */);
+ }
+
@SuppressWarnings("fallthrough")
- public void loadReferencedType(int cpi, int opcode) {
+ public void loadReferencedType(int cpi, int opcode, boolean initialize) {
int index;
switch (opcode) {
case Bytecodes.CHECKCAST:
@@ -718,9 +722,11 @@
case UnresolvedClass:
case UnresolvedClassInError:
final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index);
- Class> klass = type.mirror();
- if (!klass.isPrimitive() && !klass.isArray()) {
- UNSAFE.ensureClassInitialized(klass);
+ if (initialize) {
+ Class> klass = type.mirror();
+ if (!klass.isPrimitive() && !klass.isArray()) {
+ UNSAFE.ensureClassInitialized(klass);
+ }
}
if (tag == JVM_CONSTANT.MethodRef) {
if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Fri Mar 30 09:24:04 2018 -0700
@@ -195,11 +195,6 @@
private static final int VEX_W = 0x80;
}
- private static class AvxVectorLen {
- private static final int AVX_128bit = 0x0;
- private static final int AVX_256bit = 0x1;
- }
-
private static class VexSimdPrefix {
private static final int VEX_SIMD_NONE = 0x0;
private static final int VEX_SIMD_66 = 0x1;
@@ -208,11 +203,44 @@
}
private static class VexOpcode {
+ private static final int VEX_OPCODE_NONE = 0x0;
private static final int VEX_OPCODE_0F = 0x1;
private static final int VEX_OPCODE_0F_38 = 0x2;
private static final int VEX_OPCODE_0F_3A = 0x3;
}
+ public static class AvxVectorLen {
+ public static final int AVX_128bit = 0x0;
+ public static final int AVX_256bit = 0x1;
+ public static final int AVX_512bit = 0x2;
+ public static final int AVX_NoVec = 0x4;
+ }
+
+ public static class EvexTupleType {
+ public static final int EVEX_FV = 0;
+ public static final int EVEX_HV = 4;
+ public static final int EVEX_FVM = 6;
+ public static final int EVEX_T1S = 7;
+ public static final int EVEX_T1F = 11;
+ public static final int EVEX_T2 = 13;
+ public static final int EVEX_T4 = 15;
+ public static final int EVEX_T8 = 17;
+ public static final int EVEX_HVM = 18;
+ public static final int EVEX_QVM = 19;
+ public static final int EVEX_OVM = 20;
+ public static final int EVEX_M128 = 21;
+ public static final int EVEX_DUP = 22;
+ public static final int EVEX_ETUP = 23;
+ }
+
+ public static class EvexInputSizeInBits {
+ public static final int EVEX_8bit = 0;
+ public static final int EVEX_16bit = 1;
+ public static final int EVEX_32bit = 2;
+ public static final int EVEX_64bit = 3;
+ public static final int EVEX_NObit = 4;
+ }
+
private AMD64InstructionAttr curAttributes;
AMD64InstructionAttr getCurAttributes() {
@@ -873,6 +901,7 @@
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
+ opc = VexOpcode.VEX_OPCODE_NONE;
isSimd = false;
break;
}
@@ -1770,6 +1799,13 @@
emitOperandHelper(dst, src, 0);
}
+ public final void bsfq(Register dst, Register src) {
+ int encode = prefixqAndEncode(dst.encoding(), src.encoding());
+ emitByte(0x0F);
+ emitByte(0xBC);
+ emitByte(0xC0 | encode);
+ }
+
public final void bsrl(Register dst, Register src) {
int encode = prefixAndEncode(dst.encoding(), src.encoding());
emitByte(0x0F);
@@ -1857,6 +1893,26 @@
emitByte(0xC0 | encode);
}
+ public final void evmovdquq(Register dst, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX512F);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ attributes.setIsEvexInstruction();
+ vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x6F);
+ emitOperandHelper(dst, src, 0);
+ }
+
+ public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX512BW);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setIsEvexInstruction();
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ vexPrefix(src, nds, kdst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x74);
+ emitOperandHelper(kdst, src, 0);
+ }
+
public final void hlt() {
emitByte(0xF4);
}
@@ -1982,6 +2038,32 @@
}
}
+ // This instruction produces ZF or CF flags
+ public final void kortestql(Register src1, Register src2) {
+ assert supports(CPUFeature.AVX512BW);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(src1, Register.None, src2, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x98);
+ emitByte(0xC0 | encode);
+ }
+
+ public final void kmovql(Register dst, Register src) {
+ assert supports(CPUFeature.AVX512BW);
+ if (src.getRegisterCategory().equals(AMD64.MASK)) {
+ // kmovql(KRegister dst, KRegister src)
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x90);
+ emitByte(0xC0 | encode);
+ } else {
+ // kmovql(KRegister dst, Register src)
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x92);
+ emitByte(0xC0 | encode);
+ }
+ }
+
public final void lead(Register dst, AMD64Address src) {
prefix(src, dst);
emitByte(0x8D);
@@ -2050,6 +2132,15 @@
emitOperandHelper(dst, src, 0);
}
+ /**
+ * @param wide use 4 byte encoding for displacements that would normally fit in a byte
+ */
+ public final void movl(Register dst, AMD64Address src, boolean wide) {
+ prefix(src, dst);
+ emitByte(0x8B);
+ emitOperandHelper(dst, src, wide, 0);
+ }
+
public final void movl(AMD64Address dst, int imm32) {
prefix(dst);
emitByte(0xC7);
@@ -2291,6 +2382,10 @@
NOT.emit(this, DWORD, dst);
}
+ public final void notq(Register dst) {
+ NOT.emit(this, QWORD, dst);
+ }
+
@Override
public final void ensureUniquePC() {
nop();
@@ -2540,7 +2635,7 @@
emitByte(0xC0 | encode);
}
- void pcmpestri(Register dst, AMD64Address src, int imm8) {
+ public final void pcmpestri(Register dst, AMD64Address src, int imm8) {
assert supports(CPUFeature.SSE4_2);
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2549,7 +2644,7 @@
emitByte(imm8);
}
- void pcmpestri(Register dst, Register src, int imm8) {
+ public final void pcmpestri(Register dst, Register src, int imm8) {
assert supports(CPUFeature.SSE4_2);
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2558,6 +2653,26 @@
emitByte(imm8);
}
+ public final void pmovzxbw(Register dst, AMD64Address src) {
+ assert supports(CPUFeature.SSE4_2);
+ // XXX legacy_mode should be: _legacy_mode_bw
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+ emitByte(0x30);
+ emitOperandHelper(dst, src, 0);
+ }
+
+ public final void vpmovzxbw(Register dst, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX);
+ // XXX legacy_mode should be: _legacy_mode_bw
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+ emitByte(0x30);
+ emitOperandHelper(dst, src, 0);
+ }
+
public final void push(Register src) {
int encode = prefixAndEncode(src.encoding);
emitByte(0x50 | encode);
@@ -2634,6 +2749,15 @@
emitByte(0xC0 | encode);
}
+ public final void vpxor(Register dst, Register nds, AMD64Address src) {
+ assert supports(CPUFeature.AVX);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FV, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_32bit);
+ vexPrefix(src, nds, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0xEF);
+ emitOperandHelper(dst, src, 0);
+ }
+
public final void pslld(Register dst, int imm8) {
assert isUByte(imm8) : "invalid value";
assert dst.getRegisterCategory().equals(AMD64.XMM);
@@ -3843,4 +3967,11 @@
emitByte(0x0f);
emitByte(0x0b);
}
+
+ public void lfence() {
+ emitByte(0x0f);
+ emitByte(0xae);
+ emitByte(0xe8);
+
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java Fri Mar 30 09:24:04 2018 -0700
@@ -321,4 +321,61 @@
}
// @formatter:on
}
+
+ public static JavaMethod getInvokedMethodAt(ResolvedJavaMethod method, int invokeBci) {
+ if (method.getCode() == null) {
+ return null;
+ }
+ ConstantPool cp = method.getConstantPool();
+ BytecodeStream stream = new BytecodeStream(method.getCode());
+ int opcode = stream.currentBC();
+ while (opcode != Bytecodes.END) {
+ int bci = stream.currentBCI();
+ if (bci == invokeBci) {
+ if (stream.nextBCI() > bci + 1) {
+ switch (opcode) {
+ case INVOKEVIRTUAL:
+ case INVOKESPECIAL:
+ case INVOKESTATIC: {
+ int cpi = stream.readCPI();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ case INVOKEINTERFACE: {
+ int cpi = stream.readCPI();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ case INVOKEDYNAMIC: {
+ int cpi = stream.readCPI4();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ default:
+ throw new InternalError(BytecodeDisassembler.disassembleOne(method, invokeBci));
+ }
+ }
+ }
+ stream.next();
+ opcode = stream.currentBC();
+ }
+ return null;
+ }
+
+ public static int getBytecodeAt(ResolvedJavaMethod method, int invokeBci) {
+ if (method.getCode() == null) {
+ return -1;
+ }
+ BytecodeStream stream = new BytecodeStream(method.getCode());
+ int opcode = stream.currentBC();
+ while (opcode != Bytecodes.END) {
+ int bci = stream.currentBCI();
+ if (bci == invokeBci) {
+ return opcode;
+ }
+ stream.next();
+ opcode = stream.currentBC();
+ }
+ return -1;
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java Fri Mar 30 09:24:04 2018 -0700
@@ -58,7 +58,7 @@
}
/**
- * Gets the name denoting the format of the disassmembly return by this object.
+ * Gets the name denoting the format of the disassembly returned by this object.
*/
String getName();
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java Fri Mar 30 09:24:04 2018 -0700
@@ -25,6 +25,7 @@
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Simplifiable;
import org.graalvm.compiler.graph.spi.SimplifierTool;
@@ -72,7 +73,7 @@
}
public void canonicalizeIndex(SimplifierTool tool) {
- if (index instanceof AddNode) {
+ if (index instanceof AddNode && ((IntegerStamp) index.stamp(NodeView.DEFAULT)).getBits() == 64) {
AddNode add = (AddNode) index;
ValueNode valX = add.getX();
if (valX instanceof PhiNode) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Fri Mar 30 09:24:04 2018 -0700
@@ -66,15 +66,14 @@
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.DREM;
import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FREM;
+import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp.BinaryIntrinsicOpcode.POW;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.COS;
+import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.EXP;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG10;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.SIN;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.TAN;
-import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.EXP;
-import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp.BinaryIntrinsicOpcode.POW;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
@@ -83,10 +82,11 @@
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
-import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.FloatConvert;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
@@ -107,6 +107,7 @@
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
import org.graalvm.compiler.lir.amd64.AMD64Unary;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
+import org.graalvm.compiler.lir.gen.LIRGenerator;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
@@ -114,6 +115,7 @@
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
@@ -122,7 +124,6 @@
import jdk.vm.ci.meta.VMConstant;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
-import jdk.vm.ci.code.TargetDescription;
/**
* This class implements the AMD64 specific portion of the LIR generator.
@@ -131,6 +132,40 @@
private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
+ public AMD64ArithmeticLIRGenerator(Maths maths) {
+ this.maths = maths == null ? new Maths() {
+ } : maths;
+ }
+
+ private final Maths maths;
+
+ /**
+ * Interface for emitting LIR for selected {@link Math} routines. A {@code null} return value
+ * for any method in this interface means the caller must emit the LIR itself.
+ */
+ public interface Maths {
+
+ @SuppressWarnings("unused")
+ default Variable emitLog(LIRGenerator gen, Value input, boolean base10) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitCos(LIRGenerator gen, Value input) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitSin(LIRGenerator gen, Value input) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitTan(LIRGenerator gen, Value input) {
+ return null;
+ }
+ }
+
@Override
public Variable emitNegate(Value inputVal) {
AllocatableValue input = getLIRGen().asAllocatable(inputVal);
@@ -1042,33 +1077,49 @@
@Override
public Value emitMathLog(Value input, boolean base10) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), base10 ? LOG10 : LOG, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitLog(gen, input, base10);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), base10 ? LOG10 : LOG, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathCos(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), COS, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitCos(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), COS, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathSin(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), SIN, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitSin(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), SIN, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathTan(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), TAN, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitTan(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), TAN, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Fri Mar 30 09:24:04 2018 -0700
@@ -59,6 +59,7 @@
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
+import org.graalvm.compiler.lir.amd64.AMD64ArrayCompareToOp;
import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
@@ -74,6 +75,7 @@
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import org.graalvm.compiler.lir.amd64.AMD64LFenceOp;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
@@ -490,6 +492,20 @@
}
@Override
+ public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
+ LIRKind resultKind = LIRKind.value(AMD64Kind.DWORD);
+ RegisterValue raxRes = AMD64.rax.asValue(resultKind);
+ RegisterValue cnt1 = AMD64.rcx.asValue(length1.getValueKind());
+ RegisterValue cnt2 = AMD64.rdx.asValue(length2.getValueKind());
+ emitMove(cnt1, length1);
+ emitMove(cnt2, length2);
+ append(new AMD64ArrayCompareToOp(this, kind1, kind2, raxRes, array1, array2, cnt1, cnt2));
+ Variable result = newVariable(resultKind);
+ emitMove(result, raxRes);
+ return result;
+ }
+
+ @Override
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
@@ -554,4 +570,8 @@
public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) {
return new AMD64ZapStackOp(zappedStack, zapValues);
}
+
+ public void emitLFence() {
+ append(new AMD64LFenceOp());
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java Fri Mar 30 09:24:04 2018 -0700
@@ -23,6 +23,8 @@
package org.graalvm.compiler.core.amd64;
+import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks;
+
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
@@ -37,6 +39,11 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
+import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
+import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.meta.AllocatableValue;
@@ -44,6 +51,13 @@
public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
+ public static class Options {
+ // @formatter:off
+ @Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert)
+ public static final OptionKey MitigateSpeculativeExecutionAttacks = new OptionKey<>(false);
+ // @formatter:on
+ }
+
public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
super(graph, gen, nodeMatchRules);
}
@@ -121,4 +135,21 @@
public AMD64LIRGenerator getLIRGeneratorTool() {
return (AMD64LIRGenerator) gen;
}
+
+ @Override
+ public void doBlockPrologue(Block block, OptionValues options) {
+ if (MitigateSpeculativeExecutionAttacks.getValue(options)) {
+ boolean hasControlSplitPredecessor = false;
+ for (Block b : block.getPredecessors()) {
+ if (b.getSuccessorCount() > 1) {
+ hasControlSplitPredecessor = true;
+ break;
+ }
+ }
+ boolean isStartBlock = block.getPredecessorCount() == 0;
+ if (hasControlSplitPredecessor || isStartBlock) {
+ getLIRGeneratorTool().emitLFence();
+ }
+ }
+ }
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Fri Mar 30 09:24:04 2018 -0700
@@ -259,6 +259,9 @@
@Option(help = "", type = OptionType.Debug)
public static final OptionKey OptDevirtualizeInvokesOptimistically = new OptionKey<>(true);
+ @Option(help = "Track the NodeSourcePosition.", type = OptionType.Debug)
+ public static final OptionKey TrackNodeSourcePosition = new OptionKey<>(false);
+
@Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug)
public static final OptionKey MatchExpressions = new OptionKey<>(true);
@@ -273,8 +276,7 @@
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
public static final OptionKey TraceRA = new OptionKey<>(false);
-
- @Option(help = "How to trace inlining decisions, one of: None, Linear, Tree", type = OptionType.Debug)
- public static final OptionKey TraceInlining = new OptionKey<>(TraceInliningMode.None);
+ @Option(help = "Enable tracing of inlining decision.", type = OptionType.Debug)
+ public static final OptionKey TraceInlining = new OptionKey<>(false);
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java Thu Mar 29 17:52:32 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2018, 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.
- */
-package org.graalvm.compiler.core.common;
-
-public enum TraceInliningMode {
- None(false),
- Linear(true),
- Tree(true);
-
- private final boolean tracing;
-
- TraceInliningMode(boolean tracing) {
- this.tracing = tracing;
- }
-
- public boolean isTracing() {
- return tracing;
- }
-}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java Fri Mar 30 09:24:04 2018 -0700
@@ -84,7 +84,7 @@
AbstractBlockBase> block = worklist.pollFirst();
assert block != null;
if (!processed(block)) {
- Trace trace = new Trace(startTrace(debug, block));
+ Trace trace = new Trace(findTrace(debug, block));
for (AbstractBlockBase> traceBlock : trace.getBlocks()) {
blockToTrace[traceBlock.getId()] = trace;
}
@@ -101,13 +101,13 @@
* @param debug
*/
@SuppressWarnings("try")
- private Collection> startTrace(DebugContext debug, AbstractBlockBase> block) {
+ private Collection> findTrace(DebugContext debug, AbstractBlockBase> initBlock) {
ArrayDeque> trace = new ArrayDeque<>();
- try (Indent i = debug.logAndIndent("StartTrace: %s", block)) {
+ try (Indent i = debug.logAndIndent("StartTrace: %s", initBlock)) {
try (Indent indentFront = debug.logAndIndent("Head:")) {
- for (AbstractBlockBase> currentBlock = block; currentBlock != null; currentBlock = selectPredecessor(currentBlock)) {
- addBlockToTrace(debug, currentBlock);
- trace.addFirst(currentBlock);
+ for (AbstractBlockBase> block = initBlock; block != null; block = selectPredecessor(block)) {
+ addBlockToTrace(debug, block);
+ trace.addFirst(block);
}
}
/* Number head blocks. Can not do this in the loop as we go backwards. */
@@ -117,11 +117,11 @@
}
try (Indent indentBack = debug.logAndIndent("Tail:")) {
- for (AbstractBlockBase> currentBlock = selectSuccessor(block); currentBlock != null; currentBlock = selectSuccessor(currentBlock)) {
- addBlockToTrace(debug, currentBlock);
- trace.addLast(currentBlock);
+ for (AbstractBlockBase> block = selectSuccessor(initBlock); block != null; block = selectSuccessor(block)) {
+ addBlockToTrace(debug, block);
+ trace.addLast(block);
/* This time we can number the blocks immediately as we go forwards. */
- currentBlock.setLinearScanNumber(blockNr++);
+ block.setLinearScanNumber(blockNr++);
}
}
}
@@ -129,18 +129,18 @@
return trace;
}
- private void addBlockToTrace(DebugContext debug, AbstractBlockBase> currentBlock) {
- debug.log("add %s (prob: %f)", currentBlock, currentBlock.probability());
- processed.set(currentBlock.getId());
+ private void addBlockToTrace(DebugContext debug, AbstractBlockBase> block) {
+ debug.log("add %s (prob: %f)", block, block.probability());
+ processed.set(block.getId());
}
/**
* @return The unprocessed predecessor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectPredecessor(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectPredecessor(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> pred : currentBlock.getPredecessors()) {
- if (!processed(pred) && !isBackEdge(pred, currentBlock) && (next == null || pred.probability() > next.probability())) {
+ for (AbstractBlockBase> pred : block.getPredecessors()) {
+ if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.probability() > next.probability())) {
next = pred;
}
}
@@ -155,9 +155,9 @@
/**
* @return The unprocessed successor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectSuccessor(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectSuccessor(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> succ : currentBlock.getSuccessors()) {
+ for (AbstractBlockBase> succ : block.getSuccessors()) {
if (!processed(succ) && (next == null || succ.probability() > next.probability())) {
next = succ;
}
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java Fri Mar 30 09:24:04 2018 -0700
@@ -33,7 +33,7 @@
import org.graalvm.compiler.debug.Indent;
/**
- * Computes traces by starting at a trace head and keep adding predecessors as long as possible.
+ * Computes traces by starting at a trace head and keep adding successors as long as possible.
*/
public final class UniDirectionalTraceBuilder {
@@ -87,7 +87,7 @@
AbstractBlockBase> block = worklist.poll();
assert block != null;
if (!processed(block)) {
- Trace trace = new Trace(startTrace(debug, block));
+ Trace trace = new Trace(findTrace(debug, block));
for (AbstractBlockBase> traceBlock : trace.getBlocks()) {
blockToTrace[traceBlock.getId()] = trace;
}
@@ -102,17 +102,17 @@
* Build a new trace starting at {@code block}.
*/
@SuppressWarnings("try")
- private List> startTrace(DebugContext debug, AbstractBlockBase> block) {
- assert checkPredecessorsProcessed(block);
+ private List> findTrace(DebugContext debug, AbstractBlockBase> traceStart) {
+ assert checkPredecessorsProcessed(traceStart);
ArrayList> trace = new ArrayList<>();
int blockNumber = 0;
- try (Indent i = debug.logAndIndent("StartTrace: %s", block)) {
- for (AbstractBlockBase> currentBlock = block; currentBlock != null; currentBlock = selectNext(currentBlock)) {
- debug.log("add %s (prob: %f)", currentBlock, currentBlock.probability());
- processed.set(currentBlock.getId());
- trace.add(currentBlock);
- unblock(currentBlock);
- currentBlock.setLinearScanNumber(blockNumber++);
+ try (Indent i = debug.logAndIndent("StartTrace: %s", traceStart)) {
+ for (AbstractBlockBase> block = traceStart; block != null; block = selectNext(block)) {
+ debug.log("add %s (prob: %f)", block, block.probability());
+ processed.set(block.getId());
+ trace.add(block);
+ unblock(block);
+ block.setLinearScanNumber(blockNumber++);
}
}
return trace;
@@ -120,11 +120,7 @@
private boolean checkPredecessorsProcessed(AbstractBlockBase> block) {
for (AbstractBlockBase> pred : block.getPredecessors()) {
- if (!processed(pred)) {
- assert false : "Predecessor unscheduled: " + pred;
- return false;
- }
-
+ assert processed(pred) : "Predecessor unscheduled: " + pred;
}
return true;
}
@@ -133,8 +129,8 @@
* Decrease the {@link #blocked} count for all predecessors and add them to the worklist once
* the count reaches 0.
*/
- private void unblock(AbstractBlockBase> currentBlock) {
- for (AbstractBlockBase> successor : currentBlock.getSuccessors()) {
+ private void unblock(AbstractBlockBase> block) {
+ for (AbstractBlockBase> successor : block.getSuccessors()) {
if (!processed(successor)) {
int blockCount = --blocked[successor.getId()];
assert blockCount >= 0;
@@ -148,11 +144,11 @@
/**
* @return The unprocessed predecessor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectNext(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectNext(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> succ : currentBlock.getSuccessors()) {
- if (!processed(succ) && (next == null || succ.probability() > next.probability())) {
- next = succ;
+ for (AbstractBlockBase> successor : block.getSuccessors()) {
+ if (!processed(successor) && (next == null || successor.probability() > next.probability())) {
+ next = successor;
}
}
return next;
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java Fri Mar 30 09:24:04 2018 -0700
@@ -191,8 +191,6 @@
boolean joinExactType = exactType || other.exactType;
if (Objects.equals(type, other.type)) {
joinType = type;
- } else if (type == null && other.type == null) {
- joinType = null;
} else if (type == null) {
joinType = other.type;
} else if (other.type == null) {
diff -r 5daa8ef17089 -r f9e81b6bfc20 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Thu Mar 29 17:52:32 2018 +0530
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Fri Mar 30 09:24:04 2018 -0700
@@ -176,11 +176,15 @@
StringBuilder str = new StringBuilder();
str.append('f');
str.append(getBits());
- str.append(nonNaN ? "!" : "");
- if (lowerBound == upperBound) {
- str.append(" [").append(lowerBound).append(']');
- } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) {
- str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
+ if (hasValues()) {
+ str.append(nonNaN ? "!" : "");
+ if (lowerBound == upperBound) {
+ str.append(" [").append(lowerBound).append(']');
+ } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) {
+ str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
+ }
+ } else {
+ str.append("