Skip to content

Commit

Permalink
8290981: Enable CDS for zero builds
Browse files Browse the repository at this point in the history
Co-authored-by: Aleksey Shipilev <shade@openjdk.org>
Reviewed-by: erikj, shade, ihse
  • Loading branch information
iklam and shipilev committed Aug 19, 2022
1 parent 6a8a531 commit 57aac2a
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 71 deletions.
88 changes: 38 additions & 50 deletions make/Images.gmk
@@ -1,5 +1,5 @@
#
# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2022, 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
Expand Down Expand Up @@ -114,67 +114,55 @@ $(eval $(call SetupExecute, jlink_jre, \

JLINK_JRE_TARGETS := $(jlink_jre)

ifeq ($(BUILD_CDS_ARCHIVE), true)
# Helper function for creating the CDS archives for the JDK and JRE
#
# Param1 - VM variant (e.g., server, client, zero, ...)
# Param2 - _nocoops, or empty
define CreateCDSArchive
$1_$2_DUMP_EXTRA_ARG := $(if $(filter _nocoops, $2),-XX:-UseCompressedOops,)
$1_$2_DUMP_TYPE := $(if $(filter _nocoops, $2),-NOCOOPS,)

ifeq ($(OPENJDK_TARGET_OS), windows)
CDS_ARCHIVE := bin/server/classes.jsa
CDS_NOCOOPS_ARCHIVE := bin/server/classes_nocoops.jsa
$1_$2_CDS_ARCHIVE := bin/$1/classes$2.jsa
else
CDS_ARCHIVE := lib/server/classes.jsa
CDS_NOCOOPS_ARCHIVE := lib/server/classes_nocoops.jsa
$1_$2_CDS_ARCHIVE := lib/$1/classes$2.jsa
endif

$(eval $(call SetupExecute, gen_cds_archive_jdk, \
WARN := Creating CDS archive for jdk image, \
DEPS := $(jlink_jdk), \
OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_ARCHIVE), \
SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \
COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_ARCHIVE) \
-Xmx128M -Xms128M $(LOG_INFO), \
$$(eval $$(call SetupExecute, $1_$2_gen_cds_archive_jdk, \
WARN := Creating CDS$$($1_$2_DUMP_TYPE) archive for jdk image for $1, \
DEPS := $$(jlink_jdk), \
OUTPUT_FILE := $$(JDK_IMAGE_DIR)/$$($1_$2_CDS_ARCHIVE), \
SUPPORT_DIR := $$(SUPPORT_OUTPUTDIR)/images/jdk, \
COMMAND := $$(FIXPATH) $$(JDK_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$$(JDK_IMAGE_DIR)/$$($1_$2_CDS_ARCHIVE) \
-$1 $$($1_$2_DUMP_EXTRA_ARG) -Xmx128M -Xms128M $$(LOG_INFO), \
))

JDK_TARGETS += $(gen_cds_archive_jdk)
JDK_TARGETS += $$($1_$2_gen_cds_archive_jdk)

$(eval $(call SetupExecute, gen_cds_archive_jre, \
WARN := Creating CDS archive for jre image, \
DEPS := $(jlink_jre), \
OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_ARCHIVE), \
SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \
COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_ARCHIVE) \
-Xmx128M -Xms128M $(LOG_INFO), \
$$(eval $$(call SetupExecute, $1_$2_gen_cds_archive_jre, \
WARN := Creating CDS$$($1_$2_DUMP_TYPE) archive for jre image for $1, \
DEPS := $$(jlink_jre), \
OUTPUT_FILE := $$(JRE_IMAGE_DIR)/$$($1_$2_CDS_ARCHIVE), \
SUPPORT_DIR := $$(SUPPORT_OUTPUTDIR)/images/jre, \
COMMAND := $$(FIXPATH) $$(JRE_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$$(JRE_IMAGE_DIR)/$$($1_$2_CDS_ARCHIVE) \
-$1 $$($1_$2_DUMP_EXTRA_ARG) -Xmx128M -Xms128M $$(LOG_INFO), \
))

JRE_TARGETS += $(gen_cds_archive_jre)
JRE_TARGETS += $$($1_$2_gen_cds_archive_jre)
endef

ifeq ($(BUILD_CDS_ARCHIVE), true)
$(foreach v, $(JVM_VARIANTS), \
$(eval $(call CreateCDSArchive,$v,)) \
)

ifeq ($(call isTargetCpuBits, 64), true)
$(eval $(call SetupExecute, gen_cds_nocoops_archive_jdk, \
WARN := Creating CDS-NOCOOPS archive for jdk image, \
DEPS := $(jlink_jdk), \
OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \
SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \
COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \
-XX:-UseCompressedOops \
-Xmx128M -Xms128M $(LOG_INFO), \
))

JDK_TARGETS += $(gen_cds_nocoops_archive_jdk)

$(eval $(call SetupExecute, gen_cds_nocoops_archive_jre, \
WARN := Creating CDS-NOCOOPS archive for jre image, \
DEPS := $(jlink_jre), \
OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \
SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \
COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \
-XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \
-XX:-UseCompressedOops \
-Xmx128M -Xms128M $(LOG_INFO), \
))

JRE_TARGETS += $(gen_cds_nocoops_archive_jre)
$(foreach v, $(JVM_VARIANTS), \
$(eval $(call CreateCDSArchive,$v,_nocoops)) \
)
endif

endif

################################################################################
Expand Down
2 changes: 1 addition & 1 deletion make/autoconf/jvm-features.m4
Expand Up @@ -410,7 +410,7 @@ AC_DEFUN([JVM_FEATURES_PREPARE_VARIANT],
elif test "x$variant" = "xcore"; then
JVM_FEATURES_VARIANT_UNAVAILABLE="cds minimal zero"
elif test "x$variant" = "xzero"; then
JVM_FEATURES_VARIANT_UNAVAILABLE="cds compiler1 compiler2 \
JVM_FEATURES_VARIANT_UNAVAILABLE="compiler1 compiler2 \
jvmci minimal zgc"
else
JVM_FEATURES_VARIANT_UNAVAILABLE="minimal zero"
Expand Down
59 changes: 48 additions & 11 deletions src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp
Expand Up @@ -48,6 +48,7 @@
#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
Expand Down Expand Up @@ -588,8 +589,8 @@ void BytecodeInterpreter::run(interpreterState istate) {
/* 0xE0 */ &&opc_fast_iload, &&opc_fast_iload2, &&opc_fast_icaload, &&opc_fast_invokevfinal,
/* 0xE4 */ &&opc_default, &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w,
/* 0xE8 */ &&opc_return_register_finalizer,
&&opc_invokehandle, &&opc_default, &&opc_default,
/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
&&opc_invokehandle, &&opc_nofast_getfield,&&opc_nofast_putfield,
/* 0xEC */ &&opc_nofast_aload_0,&&opc_nofast_iload, &&opc_default, &&opc_default,

/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
Expand Down Expand Up @@ -862,6 +863,13 @@ void BytecodeInterpreter::run(interpreterState istate) {
UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
}

CASE(_nofast_iload):
{
// Normal, non-rewritable iload handling.
SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0);
UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
}

CASE(_fast_iload):
CASE(_fload):
SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0);
Expand Down Expand Up @@ -922,8 +930,9 @@ void BytecodeInterpreter::run(interpreterState istate) {
case Bytecodes::_fast_igetfield:
REWRITE_AT_PC(Bytecodes::_fast_iaccess_0);
break;
case Bytecodes::_getfield: {
/* Otherwise, do nothing here, wait until it gets rewritten to _fast_Xgetfield.
case Bytecodes::_getfield:
case Bytecodes::_nofast_getfield: {
/* Otherwise, do nothing here, wait until/if it gets rewritten to _fast_Xgetfield.
* Unfortunately, this punishes volatile field access, because it never gets
* rewritten. */
break;
Expand All @@ -933,6 +942,15 @@ void BytecodeInterpreter::run(interpreterState istate) {
break;
}
}
// Normal aload_0 handling.
VERIFY_OOP(LOCALS_OBJECT(0));
SET_STACK_OBJECT(LOCALS_OBJECT(0), 0);
UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
}

CASE(_nofast_aload_0):
{
// Normal, non-rewritable aload_0 handling.
VERIFY_OOP(LOCALS_OBJECT(0));
SET_STACK_OBJECT(LOCALS_OBJECT(0), 0);
UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
Expand Down Expand Up @@ -1701,6 +1719,7 @@ void BytecodeInterpreter::run(interpreterState istate) {
* constant pool index in the instruction.
*/
CASE(_getfield):
CASE(_nofast_getfield):
CASE(_getstatic):
{
u2 index;
Expand All @@ -1711,9 +1730,16 @@ void BytecodeInterpreter::run(interpreterState istate) {
// split all the bytecode cases out so c++ compiler has a chance
// for constant prop to fold everything possible away.

// Interpreter runtime does not expect "nofast" opcodes,
// prepare the vanilla opcode for it.
Bytecodes::Code code = (Bytecodes::Code)opcode;
if (code == Bytecodes::_nofast_getfield) {
code = Bytecodes::_getfield;
}

cache = cp->entry_at(index);
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
if (!cache->is_resolved(code)) {
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, code),
handle_exception);
cache = cp->entry_at(index);
}
Expand All @@ -1727,7 +1753,8 @@ void BytecodeInterpreter::run(interpreterState istate) {
obj = STACK_OBJECT(-1);
CHECK_NULL(obj);
// Check if we can rewrite non-volatile _getfield to one of the _fast_Xgetfield.
if (REWRITE_BYTECODES && !cache->is_volatile()) {
if (REWRITE_BYTECODES && !cache->is_volatile() &&
((Bytecodes::Code)opcode != Bytecodes::_nofast_getfield)) {
// Rewrite current BC to _fast_Xgetfield.
REWRITE_AT_PC(fast_get_type(cache->flag_state()));
}
Expand Down Expand Up @@ -1819,12 +1846,21 @@ void BytecodeInterpreter::run(interpreterState istate) {
}

CASE(_putfield):
CASE(_nofast_putfield):
CASE(_putstatic):
{
u2 index = Bytes::get_native_u2(pc+1);
ConstantPoolCacheEntry* cache = cp->entry_at(index);
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),

// Interpreter runtime does not expect "nofast" opcodes,
// prepare the vanilla opcode for it.
Bytecodes::Code code = (Bytecodes::Code)opcode;
if (code == Bytecodes::_nofast_putfield) {
code = Bytecodes::_putfield;
}

if (!cache->is_resolved(code)) {
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, code),
handle_exception);
cache = cp->entry_at(index);
}
Expand All @@ -1849,7 +1885,8 @@ void BytecodeInterpreter::run(interpreterState istate) {
CHECK_NULL(obj);

// Check if we can rewrite non-volatile _putfield to one of the _fast_Xputfield.
if (REWRITE_BYTECODES && !cache->is_volatile()) {
if (REWRITE_BYTECODES && !cache->is_volatile() &&
((Bytecodes::Code)opcode != Bytecodes::_nofast_putfield)) {
// Rewrite current BC to _fast_Xputfield.
REWRITE_AT_PC(fast_put_type(cache->flag_state()));
}
Expand Down Expand Up @@ -2415,7 +2452,7 @@ void BytecodeInterpreter::run(interpreterState istate) {
CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
if (cache->is_vfinal()) {
callee = cache->f2_as_vfinal_method();
if (REWRITE_BYTECODES) {
if (REWRITE_BYTECODES && !UseSharedSpaces && !Arguments::is_dumping_archive()) {
// Rewrite to _fast_invokevfinal.
REWRITE_AT_PC(Bytecodes::_fast_invokevfinal);
}
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, 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
Expand Down Expand Up @@ -28,7 +28,7 @@
* @summary Test dynamic CDS with JFR recording.
* Dynamic dump should skip the class such as jdk/jfr/events/FileReadEvent
* if one of its super classes has been redefined during JFR startup.
* @requires vm.cds
* @requires vm.cds & vm.hasJFR
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
* /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes
* @build JFRDynamicCDSApp jdk.test.whitebox.WhiteBox
Expand Down
Expand Up @@ -102,12 +102,10 @@ public static void main(String[] args) throws Exception {
}
}

// Now rename classes.jsa to old-classes.jsa
String dstDir = java_home_dst + File.separator + "lib" + File.separator + "server";
CDSTestUtils.rename(new File(dstDir + File.separator + "classes.jsa"),
new File(dstDir + File.separator + "old-classes.jsa"));
System.out.println("======= renamed classes.jsa to old-classes.jsa");

// Remove all possible default archives
removeDefaultArchives(java_home_dst, "zero");
removeDefaultArchives(java_home_dst, "server");
removeDefaultArchives(java_home_dst, "client");
{
ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava,
"-Xlog:cds",
Expand All @@ -116,7 +114,6 @@ public static void main(String[] args) throws Exception {
.shouldHaveExitValue(0)
.shouldContain("UseSharedSpaces: Initialize static archive failed")
.shouldContain("UseSharedSpaces: Unable to map shared spaces")
.shouldContain("mixed mode")
.shouldNotContain("sharing");
}
// delete existing jsa file
Expand All @@ -142,6 +139,19 @@ public static void main(String[] args) throws Exception {
throw new RuntimeException("Archive file " + jsaFileName + " should not be created at exit");
}
}
}

private static void removeDefaultArchives(String java_home_dst, String variant) {
removeDefaultArchive(java_home_dst, variant, "");
removeDefaultArchive(java_home_dst, variant, "_nocoops");
}

private static void removeDefaultArchive(String java_home_dst, String variant, String suffix) {
String fileName = java_home_dst + File.separator + "lib" + File.separator + variant +
File.separator + "classes" + suffix + ".jsa";
File f = new File(fileName);
if (f.delete()) {
System.out.println("======= removed " + fileName);
}
}
}

1 comment on commit 57aac2a

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.