This commit is contained in:
Prasanta Sadhukhan 2020-05-30 10:33:28 +05:30
commit d616488567
151 changed files with 3804 additions and 2027 deletions
make
src
hotspot
java.base/share/classes
java.desktop
macosx/native/libjawt
unix/native/libjawt
windows/native/libjawt
java.net.http/share/classes
jdk.compiler/share/classes/com/sun
source/util
tools
jdk.incubator.foreign/share/classes/jdk/internal/foreign
jdk.incubator.jpackage

@ -217,7 +217,7 @@ $(eval $(call DeclareRecipesForPhase, STATIC_LIBS, \
TARGET_SUFFIX := static-libs, \
FILE_PREFIX := Lib, \
MAKE_SUBDIR := lib, \
CHECK_MODULES := $(STATIC_LIBS_MODULES), \
CHECK_MODULES := $(ALL_MODULES), \
EXTRA_ARGS := STATIC_LIBS=true, \
))
@ -798,10 +798,14 @@ else
# If not already set, set the JVM variant target so that the JVM will be built.
JVM_MAIN_LIB_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-libs
JVM_MAIN_GENSRC_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-gensrc
# Building one JVM variant is enough to start building the other libs
$(LIBS_TARGETS): $(JVM_MAIN_LIB_TARGETS)
# Static libs depend on hotspot gensrc
$(STATIC_LIBS_TARGETS): $(JVM_MAIN_GENSRC_TARGETS)
$(LAUNCHER_TARGETS): java.base-libs
ifeq ($(STATIC_BUILD), true)

@ -32,11 +32,13 @@ include $(SPEC)
include MakeBase.gmk
include Modules.gmk
ALL_MODULES = $(call FindAllModules)
################################################################################
TARGETS :=
$(foreach m, $(STATIC_LIBS_MODULES), \
$(foreach m, $(ALL_MODULES), \
$(eval $(call SetupCopyFiles, COPY_STATIC_LIBS_$m, \
FLATTEN := true, \
SRC := $(SUPPORT_OUTPUTDIR)/native/$m, \

@ -193,21 +193,6 @@ HOTSPOT_MODULES := \
jdk.internal.vm.compiler.management \
#
# The native dynamic libraries in these modules will also get built into static
# libraries for consumption by downstream projects that need to statically link
# the JDK libraries. Those static libraries are not part of the main JDK
# distribution.
STATIC_LIBS_MODULES := \
java.base \
jdk.crypto.ec \
jdk.security.auth \
java.prefs \
java.security.jgss \
java.smartcardio \
jdk.crypto.cryptoki \
jdk.net \
#
################################################################################
# Some platforms don't have the serviceability agent

@ -7,10 +7,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringJoiner;
import java.util.function.Predicate;
@ -43,10 +43,11 @@ public class GenerateJfrFiles {
metadata.verify();
metadata.wireUpTypes();
TypeCounter typeCounter = new TypeCounter();
printJfrEventIdsHpp(metadata, typeCounter, outputDirectory);
printJfrTypesHpp(metadata, typeCounter, outputDirectory);
printJfrPeriodicHpp(metadata, outputDirectory);
printJfrEventIdsHpp(metadata, outputDirectory);
printJfrEventControlHpp(metadata, outputDirectory);
printJfrTypesHpp(metadata, outputDirectory);
printJfrEventControlHpp(metadata, typeCounter, outputDirectory);
printJfrEventClassesHpp(metadata, outputDirectory);
} catch (Exception e) {
@ -55,12 +56,78 @@ public class GenerateJfrFiles {
}
}
static class TypeCounter {
final static long RESERVED_EVENT_COUNT = 2;
long typeId = -1;
long eventId = -1;
long eventCount = 0;
String firstTypeName;
String lastTypeName;
String firstEventName;
String lastEventname;
public long nextEventId(String name) {
eventCount++;
if (eventId == -1) {
eventId = firstEventId();
firstEventName = lastEventname = name;
return eventId;
}
lastEventname = name;
return ++eventId;
}
public long nextTypeId(String typeName) {
if (typeId == -1) {
lastTypeName = firstTypeName = typeName;
typeId = lastEventId();
}
lastTypeName = typeName;
return ++typeId;
}
public long firstEventId() {
return RESERVED_EVENT_COUNT;
}
public long lastEventId() {
return eventId == -1 ? firstEventId() : eventId;
}
public long eventCount() {
return eventCount;
}
public String firstTypeName() {
return firstTypeName;
}
public String lastTypeName() {
return lastTypeName;
}
public String firstEventName() {
return firstEventName;
}
public String lastEventName() {
return lastEventname;
}
}
static class XmlType {
final String name;
final String fieldType;
final String parameterType;
XmlType(String fieldType, String parameterType) {
final String javaType;
final boolean unsigned;
XmlType(String name, String fieldType, String parameterType, String javaType, boolean unsigned) {
this.name = name;
this.fieldType = fieldType;
this.parameterType = parameterType;
this.javaType = javaType;
this.unsigned = unsigned;
}
}
@ -74,7 +141,7 @@ public class GenerateJfrFiles {
static class Metadata {
final Map<String, TypeElement> types = new LinkedHashMap<>();
final Map<String, XmlType> xmlTypes = new HashMap<>();
final Map<String, XmlType> xmlTypes = new LinkedHashMap<>();
Metadata(File metadataXml, File metadataSchema) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
SAXParserFactory factory = SAXParserFactory.newInstance();
@ -110,12 +177,8 @@ public class GenerateJfrFiles {
return getList(t -> t.getClass() == EventElement.class && ((EventElement) t).periodic);
}
List<TypeElement> getNonEventsAndNonStructs() {
return getList(t -> t.getClass() != EventElement.class && !t.supportStruct);
}
List<TypeElement> getTypes() {
return getList(t -> t.getClass() == TypeElement.class && !t.supportStruct);
return getList(t -> t.getClass() == TypeElement.class);
}
List<TypeElement> getStructs() {
@ -213,8 +276,11 @@ public class GenerateJfrFiles {
String name = attributes.getValue("name");
String parameterType = attributes.getValue("parameterType");
String fieldType = attributes.getValue("fieldType");
metadata.xmlTypes.put(name, new XmlType(fieldType, parameterType));
String javaType = attributes.getValue("javaType");
boolean unsigned = getBoolean(attributes, "unsigned", false);
metadata.xmlTypes.put(name, new XmlType(name, fieldType, parameterType, javaType, unsigned));
break;
case "Relation":
case "Type":
currentType = new TypeElement();
currentType.name = attributes.getValue("name");
@ -247,6 +313,7 @@ public class GenerateJfrFiles {
@Override
public void endElement(String uri, String localName, String qName) {
switch (qName) {
case "Relation":
case "Type":
case "Event":
metadata.types.put(currentType.name, currentType);
@ -318,7 +385,7 @@ public class GenerateJfrFiles {
}
}
private static void printJfrEventControlHpp(Metadata metadata, File outputDirectory) throws Exception {
private static void printJfrEventControlHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrEventControl.hpp")) {
out.write("#ifndef JFRFILES_JFR_NATIVE_EVENTSETTING_HPP");
out.write("#define JFRFILES_JFR_NATIVE_EVENTSETTING_HPP");
@ -342,11 +409,11 @@ public class GenerateJfrFiles {
out.write("");
out.write("union JfrNativeSettings {");
out.write(" // Array version.");
out.write(" jfrNativeEventSetting bits[MaxJfrEventId];");
out.write(" jfrNativeEventSetting bits[NUMBER_OF_EVENTS];");
out.write(" // Then, to make it easy to debug,");
out.write(" // add named struct members also.");
out.write(" struct {");
out.write(" jfrNativeEventSetting pad[NUM_RESERVED_EVENTS];");
out.write(" jfrNativeEventSetting pad[NUMBER_OF_RESERVED_EVENTS];");
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" jfrNativeEventSetting " + t.name + ";");
}
@ -358,53 +425,34 @@ public class GenerateJfrFiles {
}
}
private static void printJfrEventIdsHpp(Metadata metadata, File outputDirectory) throws Exception {
private static void printJfrEventIdsHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrEventIds.hpp")) {
out.write("#ifndef JFRFILES_JFREVENTIDS_HPP");
out.write("#define JFRFILES_JFREVENTIDS_HPP");
out.write("");
out.write("#include \"utilities/macros.hpp\"");
out.write("#if INCLUDE_JFR");
out.write("#include \"jfrfiles/jfrTypes.hpp\"");
out.write("");
out.write("/**");
out.write(" * Enum of the event types in the JVM");
out.write(" */");
out.write("enum JfrEventId {");
out.write(" _jfreventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index.");
out.write(" ");
out.write(" // Events -> enum entry");
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" Jfr" + t.name + "Event,");
out.write(" JfrMetadataEvent = 0,");
out.write(" JfrCheckpointEvent = 1,");
for (TypeElement t : metadata.getEvents()) {
String name = "Jfr" + t.name +"Event";
out.write(" " + name + " = " + typeCounter.nextEventId(name) + ",");
}
out.write("");
out.write(" MaxJfrEventId");
out.write("};");
out.write("");
out.write("/**");
out.write(" * Struct types in the JVM");
out.write(" */");
out.write("enum JfrStructId {");
for (TypeElement t : metadata.getNonEventsAndNonStructs()) {
out.write(" Jfr" + t.name + "Struct,");
}
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" Jfr" + t.name + "Struct,");
}
out.write("");
out.write(" MaxJfrStructId");
out.write("};");
out.write("");
out.write("typedef enum JfrEventId JfrEventId;");
out.write("typedef enum JfrStructId JfrStructId;");
out.write("");
out.write("static const JfrEventId FIRST_EVENT_ID = " + typeCounter.firstEventName() + ";");
out.write("static const JfrEventId LAST_EVENT_ID = " + typeCounter.lastEventName() + ";");
out.write("static const int NUMBER_OF_EVENTS = " + typeCounter.eventCount() + ";");
out.write("static const int NUMBER_OF_RESERVED_EVENTS = " + TypeCounter.RESERVED_EVENT_COUNT + ";");
out.write("#endif // INCLUDE_JFR");
out.write("#endif // JFRFILES_JFREVENTIDS_HPP");
}
}
private static void printJfrTypesHpp(Metadata metadata, File outputDirectory) throws Exception {
List<String> knownTypes = List.of("Thread", "StackTrace", "Class", "StackFrame");
private static void printJfrTypesHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrTypes.hpp")) {
out.write("#ifndef JFRFILES_JFRTYPES_HPP");
out.write("#define JFRFILES_JFRTYPES_HPP");
@ -412,41 +460,54 @@ public class GenerateJfrFiles {
out.write("#include \"utilities/macros.hpp\"");
out.write("#if INCLUDE_JFR");
out.write("");
out.write("#include <string.h>");
out.write("#include \"memory/allocation.hpp\"");
out.write("");
out.write("enum JfrTypeId {");
out.write(" TYPE_NONE = 0,");
out.write(" TYPE_CLASS = 20,");
out.write(" TYPE_STRING = 21,");
out.write(" TYPE_THREAD = 22,");
out.write(" TYPE_STACKTRACE = 23,");
out.write(" TYPE_BYTES = 24,");
out.write(" TYPE_EPOCHMILLIS = 25,");
out.write(" TYPE_MILLIS = 26,");
out.write(" TYPE_NANOS = 27,");
out.write(" TYPE_TICKS = 28,");
out.write(" TYPE_ADDRESS = 29,");
out.write(" TYPE_PERCENTAGE = 30,");
out.write(" TYPE_DUMMY,");
out.write(" TYPE_DUMMY_1,");
for (TypeElement type : metadata.getTypes()) {
if (!knownTypes.contains(type.name)) {
out.write(" TYPE_" + type.name.toUpperCase() + ",");
Map<String, XmlType> javaTypes = new LinkedHashMap<>();
for (var t : metadata.xmlTypes.entrySet()) {
String name = t.getKey();
XmlType xmlType = t.getValue();
if (xmlType.javaType != null && !xmlType.unsigned) {
String typeName = "TYPE_" + name.toUpperCase();
long typeId = typeCounter.nextTypeId(typeName);
out.write(" " + typeName + " = " + typeId + ",");
javaTypes.put(name, xmlType);
}
}
for (TypeElement type : metadata.getTypes()) {
String name = type.name;
if (!javaTypes.containsKey(name)) {
String typeName = "TYPE_" + name.toUpperCase();
long typeId = typeCounter.nextTypeId(typeName);
out.write(" " + typeName + " = " + typeId + ",");
}
}
out.write("");
out.write(" NUM_JFR_TYPES,");
out.write(" TYPES_END = 255");
out.write("};");
out.write("");
out.write("enum ReservedEvent {");
out.write(" EVENT_METADATA,");
out.write(" EVENT_CHECKPOINT,");
out.write(" EVENT_BUFFERLOST,");
out.write(" NUM_RESERVED_EVENTS = TYPES_END");
out.write("static const JfrTypeId FIRST_TYPE_ID = " + typeCounter.firstTypeName() + ";");
out.write("static const JfrTypeId LAST_TYPE_ID = " + typeCounter.lastTypeName() + ";");
out.write("");
out.write("class JfrType : public AllStatic {");
out.write(" public:");
out.write(" static jlong name_to_id(const char* type_name) {");
for (Entry<String, XmlType> m : javaTypes.entrySet()) {
XmlType xmlType = m.getValue();
String javaName = xmlType.javaType;
String typeName = xmlType.name.toUpperCase();
out.write(" if (strcmp(type_name, \"" + javaName + "\") == 0) {");
out.write(" return TYPE_" + typeName + ";");
out.write(" }");
}
out.write(" return -1;");
out.write(" }");
out.write("};");
out.write("");
out.write("#endif // INCLUDE_JFR");
out.write("#endif // JFRFILES_JFRTYPES_HPP");
};
}
;
}
private static void printJfrEventClassesHpp(Metadata metadata, File outputDirectory) throws Exception {

@ -15255,7 +15255,7 @@ instruct ShouldNotReachHere() %{
ins_encode %{
if (is_reachable()) {
__ dcps1(0xdead + 1);
__ stop(_halt_reason);
}
%}

@ -60,12 +60,10 @@
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
#define STOP(error) stop(error)
#else
#define BLOCK_COMMENT(str) block_comment(str)
#define STOP(error) block_comment(error); stop(error)
#endif
#define STOP(str) stop(str);
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
// Patch any kind of instruction; there may be several instructions.
@ -2223,22 +2221,9 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
}
void MacroAssembler::stop(const char* msg) {
address ip = pc();
pusha();
mov(c_rarg0, (address)msg);
mov(c_rarg1, (address)ip);
mov(c_rarg2, sp);
mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
blr(c_rarg3);
hlt(0);
}
void MacroAssembler::warn(const char* msg) {
pusha();
mov(c_rarg0, (address)msg);
mov(lr, CAST_FROM_FN_PTR(address, warning));
blr(lr);
popa();
BLOCK_COMMENT(msg);
dcps1(0xdeae);
emit_int64((uintptr_t)msg);
}
void MacroAssembler::unimplemented(const char* what) {

@ -980,9 +980,6 @@ public:
// prints msg, dumps registers and stops execution
void stop(const char* msg);
// prints msg and continues
void warn(const char* msg);
static void debug64(char* msg, int64_t pc, int64_t regs[]);
void untested() { stop("untested"); }

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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.
*
@ -47,7 +47,7 @@ void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_
if (VerifyMethodHandles)
verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
"MH argument is a Class");
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
}
#ifdef ASSERT
@ -135,13 +135,13 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset())), temp2);
__ verify_oop(method_temp);
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), noreg, noreg);
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())), noreg, noreg);
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
@ -283,10 +283,10 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
"MemberName required for invokeVirtual etc.");
}
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {

@ -462,6 +462,10 @@ void NativeIllegalInstruction::insert(address code_pos) {
*(juint*)code_pos = 0xd4bbd5a1; // dcps1 #0xdead
}
bool NativeInstruction::is_stop() {
return uint_at(0) == 0xd4bbd5c1; // dcps1 #0xdeae
}
//-------------------------------------------------------------------
// MT-safe inserting of a jump over a jump or a nop (used by

@ -76,6 +76,7 @@ class NativeInstruction {
bool is_movz();
bool is_movk();
bool is_sigill_zombie_not_entrant();
bool is_stop();
protected:
address addr_at(int offset) const { return address(this) + offset; }

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -939,8 +939,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
address entry = __ pc();
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
Label slow_path;
const Register local_0 = c_rarg0;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2020, 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
@ -311,7 +311,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(_obj != noreg, "must be a valid register");
// Rtemp should be OK in C1
__ ldr(Rtemp, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
__ ldr(Rtemp, Address(_obj, java_lang_Class::klass_offset()));
__ ldr(Rtemp, Address(Rtemp, InstanceKlass::init_thread_offset()));
__ cmp(Rtemp, Rthread);
__ b(call_patch, ne);

@ -53,7 +53,7 @@ void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_
verify_klass(_masm, klass_reg, temp1, temp2, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
"MH argument is a Class");
}
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
}
#ifdef ASSERT
@ -95,7 +95,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
Label L;
BLOCK_COMMENT("verify_ref_kind {");
__ ldr_u32(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())));
__ ldr_u32(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset())));
__ logical_shift_right(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
__ andr(temp, temp, (unsigned)java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
__ cmp(temp, ref_kind);
@ -148,15 +148,15 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
assert_different_registers(recv, tmp, Rmethod);
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ load_heap_oop(tmp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
__ load_heap_oop(tmp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())));
__ verify_oop(tmp);
__ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
__ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())));
__ verify_oop(tmp);
__ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
__ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset())));
__ verify_oop(Rmethod);
__ access_load_at(T_ADDRESS, IN_HEAP, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), Rmethod, noreg, noreg, noreg);
__ access_load_at(T_ADDRESS, IN_HEAP, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())), Rmethod, noreg, noreg, noreg);
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
@ -305,10 +305,10 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
"MemberName required for invokeVirtual etc.");
}
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
Address vmtarget_method(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
@ -532,9 +532,7 @@ void trace_method_handle_stub(const char* adaptername,
if (has_mh && oopDesc::is_oop(mh)) {
mh->print();
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) {
java_lang_invoke_MethodHandle::form(mh)->print();
}
java_lang_invoke_MethodHandle::form(mh)->print();
}
}
}

@ -708,8 +708,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
const Register Rret_addr = Rtmp_save1;
assert_different_registers(Rthis, Rret_addr, Rsender_sp);
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
// Check if local 0 != NULL
// If the receiver is null then it is OK to jump to the slow path.

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -361,7 +361,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(_obj != noreg, "must be a valid register");
assert(_index >= 0, "must have oop index");
__ mr(R0, _obj); // spill
__ ld(_obj, java_lang_Class::klass_offset_in_bytes(), _obj);
__ ld(_obj, java_lang_Class::klass_offset(), _obj);
__ ld(_obj, in_bytes(InstanceKlass::init_thread_offset()), _obj);
__ cmpd(CCR0, _obj, R16_thread);
__ mr(_obj, R0); // restore

@ -56,7 +56,7 @@ void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_
verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
temp_reg, temp2_reg, "MH argument is a Class");
}
__ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg);
__ ld(klass_reg, java_lang_Class::klass_offset(), klass_reg);
}
#ifdef ASSERT
@ -98,7 +98,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
Label L;
BLOCK_COMMENT("verify_ref_kind {");
__ load_sized_value(temp, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes()), member_reg,
__ load_sized_value(temp, NONZERO(java_lang_invoke_MemberName::flags_offset()), member_reg,
sizeof(u4), /*is_signed*/ false);
// assert(sizeof(u4) == sizeof(java.lang.invoke.MemberName.flags), "");
__ srwi( temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
@ -174,16 +174,16 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv, FILE_AND_LINE);
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv,
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset()), recv,
temp2, noreg, false, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp,
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset()), method_temp,
temp2, noreg, false, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), method_temp,
__ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset()), method_temp,
temp2, noreg, false, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ ld(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), method_temp);
__ ld(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()), method_temp);
if (VerifyMethodHandles && !for_compiler_entry) {
// Make sure recv is already on stack.
@ -342,7 +342,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
Label L_ok;
Register temp2_defc = temp2;
__ load_heap_oop(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg,
__ load_heap_oop(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset()), member_reg,
temp3, noreg, false, IS_NOT_NULL);
load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
__ verify_klass_ptr(temp2_defc);
@ -370,18 +370,18 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2);
}
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg,
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset()), member_reg,
temp3, noreg, false, IS_NOT_NULL);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()), R19_method);
break;
case vmIntrinsics::_linkToStatic:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2);
}
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg,
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset()), member_reg,
temp3, noreg, false, IS_NOT_NULL);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()), R19_method);
break;
case vmIntrinsics::_linkToVirtual:
@ -395,7 +395,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// pick out the vtable index from the MemberName, and then we can discard it:
Register temp2_index = temp2;
__ ld(temp2_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
__ ld(temp2_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset()), member_reg);
if (VerifyMethodHandles) {
Label L_index_ok;
@ -422,13 +422,13 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
}
Register temp2_intf = temp2;
__ load_heap_oop(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg,
__ load_heap_oop(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset()), member_reg,
temp3, noreg, false, IS_NOT_NULL);
load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
__ verify_klass_ptr(temp2_intf);
Register vtable_index = R19_method;
__ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
__ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset()), member_reg);
if (VerifyMethodHandles) {
Label L_index_ok;
__ cmpdi(CCR1, vtable_index, 0);
@ -538,9 +538,7 @@ void trace_method_handle_stub(const char* adaptername,
if (has_mh && oopDesc::is_oop(mh)) {
mh->print();
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) {
java_lang_invoke_MethodHandle::form(mh)->print();
}
java_lang_invoke_MethodHandle::form(mh)->print();
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -507,8 +507,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
address entry = __ pc();
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
Label slow_path;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -353,7 +353,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
// thread.
assert(_obj != noreg, "must be a valid register");
assert(_index >= 0, "must have oop index");
__ z_lg(Z_R1_scratch, java_lang_Class::klass_offset_in_bytes(), _obj);
__ z_lg(Z_R1_scratch, java_lang_Class::klass_offset(), _obj);
__ z_cg(Z_thread, Address(Z_R1_scratch, InstanceKlass::init_thread_offset()));
__ branch_optimized(Assembler::bcondNotEqual, call_patch);

@ -56,7 +56,7 @@ void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_
verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
temp_reg, temp2_reg, "MH argument is a Class");
}
__ z_lg(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
__ z_lg(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
}
@ -111,7 +111,7 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind,
__ z_llgf(temp,
Address(member_reg,
NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())));
NONZERO(java_lang_invoke_MemberName::flags_offset())));
__ z_srl(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
__ z_nilf(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
__ compare32_and_branch(temp, constant(ref_kind), Assembler::bcondEqual, L);
@ -198,22 +198,22 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
__ verify_oop(recv, FILE_AND_LINE);
__ load_heap_oop(method_temp,
Address(recv,
NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())),
NONZERO(java_lang_invoke_MethodHandle::form_offset())),
noreg, noreg, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ load_heap_oop(method_temp,
Address(method_temp,
NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())),
NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())),
noreg, noreg, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ load_heap_oop(method_temp,
Address(method_temp,
NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())),
NONZERO(java_lang_invoke_MemberName::method_offset())),
noreg, noreg, IS_NOT_NULL);
__ verify_oop(method_temp, FILE_AND_LINE);
__ z_lg(method_temp,
Address(method_temp,
NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())));
if (VerifyMethodHandles && !for_compiler_entry) {
// Make sure recv is already on stack.
@ -379,10 +379,10 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
"MemberName required for invokeVirtual etc.");
}
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method(Z_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
Address vmtarget_method(Z_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
@ -608,9 +608,7 @@ void trace_method_handle_stub(const char* adaptername,
if (has_mh && oopDesc::is_oop(mh)) {
mh->print();
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) {
java_lang_invoke_MethodHandle::form(mh)->print();
}
java_lang_invoke_MethodHandle::form(mh)->print();
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -502,8 +502,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
Label slow_path;
address entry = __ pc();
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
BLOCK_COMMENT("Reference_get {");

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, 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
@ -361,7 +361,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
__ push(tmp2);
// Load without verification to keep code size small. We need it because
// begin_initialized_entry_offset has to fit in a byte. Also, we know it's not null.
__ movptr(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
__ movptr(tmp2, Address(_obj, java_lang_Class::klass_offset()));
__ get_thread(tmp);
__ cmpptr(tmp, Address(tmp2, InstanceKlass::init_thread_offset()));
__ pop(tmp2);

@ -53,7 +53,7 @@ void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_
if (VerifyMethodHandles)
verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
"MH argument is a Class");
__ movptr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
__ movptr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
}
#ifdef ASSERT
@ -100,7 +100,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
Label L;
BLOCK_COMMENT("verify_ref_kind {");
__ movl(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())));
__ movl(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset())));
__ shrl(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
__ andl(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
__ cmpl(temp, ref_kind);
@ -171,14 +171,14 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset())), temp2);
__ verify_oop(method_temp);
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp,
Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())),
Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())),
noreg, noreg);
if (VerifyMethodHandles && !for_compiler_entry) {
@ -338,10 +338,10 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
"MemberName required for invokeVirtual etc.");
}
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method( rbx_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
Address vmtarget_method( rbx_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
@ -581,9 +581,7 @@ void trace_method_handle_stub(const char* adaptername,
if (has_mh && oopDesc::is_oop(mh)) {
mh->print();
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) {
java_lang_invoke_MethodHandle::form(mh)->print();
}
java_lang_invoke_MethodHandle::form(mh)->print();
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
@ -718,8 +718,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
address entry = __ pc();
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
Label slow_path;
// rbx: method

@ -381,6 +381,21 @@ JVM_handle_linux_signal(int sig,
}
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
} else if (sig == SIGILL && nativeInstruction_at(pc)->is_stop()) {
// Pull a pointer to the error message out of the instruction
// stream.
const uint64_t *detail_msg_ptr
= (uint64_t*)(pc + NativeInstruction::instruction_size);
const char *detail_msg = (const char *)*detail_msg_ptr;
const char *msg = "stop";
if (TraceTraps) {
tty->print_cr("trap: %s: (SIGILL)", msg);
}
va_list detail_args;
VMError::report_and_die(INTERNAL_ERROR, msg, detail_msg, detail_args, thread,
pc, info, ucVoid, NULL, 0, 0);
va_end(detail_args);
}
else
@ -505,7 +520,7 @@ void os::print_context(outputStream *st, const void *context) {
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
print_instructions(st, pc, sizeof(char));
print_instructions(st, pc, 4/*native instruction size*/);
st->cr();
}

@ -1220,8 +1220,7 @@ void LIRGenerator::do_Return(Return* x) {
// Combination of LoadField and g1 pre-write barrier
void LIRGenerator::do_Reference_get(Intrinsic* x) {
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "referent offset not initialized");
const int referent_offset = java_lang_ref_Reference::referent_offset();
assert(x->number_of_arguments() == 1, "wrong type");
@ -1307,7 +1306,7 @@ void LIRGenerator::do_isPrimitive(Intrinsic* x) {
info = state_for(x);
}
__ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), temp, info);
__ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset(), T_ADDRESS), temp, info);
__ cmp(lir_cond_notEqual, temp, LIR_OprFact::metadataConst(0));
__ cmove(lir_cond_notEqual, LIR_OprFact::intConst(0), LIR_OprFact::intConst(1), result, T_BOOLEAN);
}
@ -2954,7 +2953,7 @@ void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
arg.load_item();
LIR_Opr klass = new_register(T_METADATA);
__ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), klass, info);
__ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset(), T_ADDRESS), klass, info);
LIR_Opr id = new_register(T_LONG);
ByteSize offset = KLASS_TRACE_ID_OFFSET;
LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);

@ -265,9 +265,9 @@ void ciField::initialize_from(fieldDescriptor* fd) {
assert(SystemDictionary::System_klass() != NULL, "Check once per vm");
if (k == SystemDictionary::System_klass()) {
// Check offsets for case 2: System.in, System.out, or System.err
if( _offset == java_lang_System::in_offset_in_bytes() ||
_offset == java_lang_System::out_offset_in_bytes() ||
_offset == java_lang_System::err_offset_in_bytes() ) {
if (_offset == java_lang_System::in_offset() ||
_offset == java_lang_System::out_offset() ||
_offset == java_lang_System::err_offset()) {
_is_constant = false;
return;
}
@ -283,7 +283,7 @@ void ciField::initialize_from(fieldDescriptor* fd) {
// For CallSite objects treat the target field as a compile time constant.
assert(SystemDictionary::CallSite_klass() != NULL, "should be already initialized");
if (k == SystemDictionary::CallSite_klass() &&
_offset == java_lang_invoke_CallSite::target_offset_in_bytes()) {
_offset == java_lang_invoke_CallSite::target_offset()) {
assert(!has_initialized_final_update(), "CallSite is not supposed to have writes to final fields outside initializers");
_is_constant = true;
} else {

@ -274,7 +274,7 @@ bool ciInstanceKlass::is_box_klass() const {
bool ciInstanceKlass::is_boxed_value_offset(int offset) const {
BasicType bt = box_klass_type();
return is_java_primitive(bt) &&
(offset == java_lang_boxing_object::value_offset_in_bytes(bt));
(offset == java_lang_boxing_object::value_offset(bt));
}
// ------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

@ -80,6 +80,8 @@ class RecordComponent;
BASIC_JAVA_CLASSES_DO_PART1(f) \
BASIC_JAVA_CLASSES_DO_PART2(f)
#define CHECK_INIT(offset) assert(offset != 0, "should be initialized"); return offset;
// Interface to java.lang.Object objects
class java_lang_Object : AllStatic {
@ -91,12 +93,12 @@ class java_lang_Object : AllStatic {
class java_lang_String : AllStatic {
private:
static int value_offset;
static int hash_offset;
static int hashIsZero_offset;
static int coder_offset;
static int _value_offset;
static int _hash_offset;
static int _hashIsZero_offset;
static int _coder_offset;
static bool initialized;
static bool _initialized;
static Handle basic_create(int length, bool byte_arr, TRAPS);
@ -124,22 +126,8 @@ class java_lang_String : AllStatic {
static void set_compact_strings(bool value);
static int value_offset_in_bytes() {
assert(initialized && (value_offset > 0), "Must be initialized");
return value_offset;
}
static int hash_offset_in_bytes() {
assert(initialized && (hash_offset > 0), "Must be initialized");
return hash_offset;
}
static int hashIsZero_offset_in_bytes() {
assert(initialized && (hashIsZero_offset > 0), "Must be initialized");
return hashIsZero_offset;
}
static int coder_offset_in_bytes() {
assert(initialized && (coder_offset > 0), "Must be initialized");
return coder_offset;
}
static int value_offset() { CHECK_INIT(_value_offset); }
static int coder_offset() { CHECK_INIT(_coder_offset); }
static inline void set_value_raw(oop string, typeArrayOop buffer);
static inline void set_value(oop string, typeArrayOop buffer);
@ -237,6 +225,7 @@ class java_lang_Class : AllStatic {
friend class JVMCIVMStructs;
private:
// The fake offsets are added by the class loader when java.lang.Class is loaded
static int _klass_offset;
@ -254,9 +243,9 @@ class java_lang_Class : AllStatic {
static int _name_offset;
static int _source_file_offset;
static int _classData_offset;
static int _classRedefinedCount_offset;
static bool offsets_computed;
static int classRedefinedCount_offset;
static bool _offsets_computed;
static GrowableArray<Klass*>* _fixup_mirror_list;
static GrowableArray<Klass*>* _fixup_module_field_list;
@ -310,8 +299,8 @@ class java_lang_Class : AllStatic {
static Klass* array_klass_acquire(oop java_class);
static void release_set_array_klass(oop java_class, Klass* klass);
// compiler support for class operations
static int klass_offset_in_bytes() { return _klass_offset; }
static int array_klass_offset_in_bytes() { return _array_klass_offset; }
static int klass_offset() { CHECK_INIT(_klass_offset); }
static int array_klass_offset() { CHECK_INIT(_array_klass_offset); }
// Support for classRedefinedCount field
static int classRedefinedCount(oop the_class_mirror);
static void set_classRedefinedCount(oop the_class_mirror, int value);
@ -319,6 +308,9 @@ class java_lang_Class : AllStatic {
// Support for embedded per-class oops
static oop protection_domain(oop java_class);
static oop init_lock(oop java_class);
static void clear_init_lock(oop java_class) {
set_init_lock(java_class, NULL);
}
static oop component_mirror(oop java_class);
static objArrayOop signers(oop java_class);
static void set_signers(oop java_class, objArrayOop signers);
@ -357,8 +349,6 @@ class java_lang_Class : AllStatic {
// Debugging
friend class JavaClasses;
friend class InstanceKlass; // verification code accesses offsets
friend class ClassFileParser; // access to number_of_fake_fields
};
// Interface to java.lang.Thread objects
@ -529,11 +519,11 @@ class java_lang_Throwable: AllStatic {
trace_chunk_size = 32
};
static int backtrace_offset;
static int detailMessage_offset;
static int stackTrace_offset;
static int depth_offset;
static int static_unassigned_stacktrace_offset;
static int _backtrace_offset;
static int _detailMessage_offset;
static int _stackTrace_offset;
static int _depth_offset;
static int _static_unassigned_stacktrace_offset;
// StackTrace (programmatic access, new since 1.4)
static void clear_stacktrace(oop throwable);
@ -547,9 +537,7 @@ class java_lang_Throwable: AllStatic {
static void set_backtrace(oop throwable, oop value);
static int depth(oop throwable);
static void set_depth(oop throwable, int value);
// Needed by JVMTI to filter out this internal field.
static int get_backtrace_offset() { return backtrace_offset;}
static int get_detailMessage_offset() { return detailMessage_offset;}
static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
// Message
static oop message(oop throwable);
static void set_message(oop throwable, oop value);
@ -586,7 +574,7 @@ class java_lang_reflect_AccessibleObject: AllStatic {
private:
// Note that to reduce dependencies on the JDK we compute these
// offsets at run-time.
static int override_offset;
static int _override_offset;
static void compute_offsets();
@ -608,17 +596,17 @@ class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject {
private:
// Note that to reduce dependencies on the JDK we compute these
// offsets at run-time.
static int clazz_offset;
static int name_offset;
static int returnType_offset;
static int parameterTypes_offset;
static int exceptionTypes_offset;
static int slot_offset;
static int modifiers_offset;
static int signature_offset;
static int annotations_offset;
static int parameter_annotations_offset;
static int annotation_default_offset;
static int _clazz_offset;
static int _name_offset;
static int _returnType_offset;
static int _parameterTypes_offset;
static int _exceptionTypes_offset;
static int _slot_offset;
static int _modifiers_offset;
static int _signature_offset;
static int _annotations_offset;
static int _parameter_annotations_offset;
static int _annotation_default_offset;
static void compute_offsets();
public:
@ -660,14 +648,14 @@ class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject
private:
// Note that to reduce dependencies on the JDK we compute these
// offsets at run-time.
static int clazz_offset;
static int parameterTypes_offset;
static int exceptionTypes_offset;
static int slot_offset;
static int modifiers_offset;
static int signature_offset;
static int annotations_offset;
static int parameter_annotations_offset;
static int _clazz_offset;
static int _parameterTypes_offset;
static int _exceptionTypes_offset;
static int _slot_offset;
static int _modifiers_offset;
static int _signature_offset;
static int _annotations_offset;
static int _parameter_annotations_offset;
static void compute_offsets();
public:
@ -703,13 +691,13 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject {
private:
// Note that to reduce dependencies on the JDK we compute these
// offsets at run-time.
static int clazz_offset;
static int name_offset;
static int type_offset;
static int slot_offset;
static int modifiers_offset;
static int signature_offset;
static int annotations_offset;
static int _clazz_offset;
static int _name_offset;
static int _type_offset;
static int _slot_offset;
static int _modifiers_offset;
static int _signature_offset;
static int _annotations_offset;
static void compute_offsets();
@ -748,10 +736,10 @@ class java_lang_reflect_Parameter {
private:
// Note that to reduce dependencies on the JDK we compute these
// offsets at run-time.
static int name_offset;
static int modifiers_offset;
static int index_offset;
static int executable_offset;
static int _name_offset;
static int _modifiers_offset;
static int _index_offset;
static int _executable_offset;
static void compute_offsets();
@ -782,9 +770,10 @@ class java_lang_reflect_Parameter {
class java_lang_Module {
private:
static int loader_offset;
static int name_offset;
static int _loader_offset;
static int _name_offset;
static int _module_entry_offset;
static void compute_offsets();
public:
@ -826,9 +815,7 @@ class reflect_ConstantPool {
// Accessors
static void set_cp(oop reflect, ConstantPool* value);
static int oop_offset() {
return _oop_offset;
}
static int oop_offset() { CHECK_INIT(_oop_offset); }
static ConstantPool* get_cp(oop reflect);
@ -845,9 +832,7 @@ class reflect_UnsafeStaticFieldAccessorImpl {
public:
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
static int base_offset() {
return _base_offset;
}
static int base_offset() { CHECK_INIT(_base_offset); }
// Debugging
friend class JavaClasses;
@ -867,9 +852,10 @@ class reflect_UnsafeStaticFieldAccessorImpl {
class java_lang_boxing_object: AllStatic {
private:
static int value_offset;
static int long_value_offset;
static int _value_offset;
static int _long_value_offset;
static void compute_offsets();
static oop initialize_and_allocate(BasicType type, TRAPS);
public:
// Allocation. Returns a boxed value, or NULL for invalid type.
@ -883,13 +869,11 @@ class java_lang_boxing_object: AllStatic {
static void print(oop box, outputStream* st) { jvalue value; print(get_value(box, &value), &value, st); }
static void print(BasicType type, jvalue* value, outputStream* st);
static int value_offset_in_bytes(BasicType type) {
return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
value_offset;
static int value_offset(BasicType type) {
return is_double_word_type(type) ? _long_value_offset : _value_offset;
}
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
static void serialize_offsets(SerializeClosure* f);
// Debugging
friend class JavaClasses;
@ -900,14 +884,14 @@ class java_lang_boxing_object: AllStatic {
// Interface to java.lang.ref.Reference objects
class java_lang_ref_Reference: AllStatic {
static int _referent_offset;
static int _queue_offset;
static int _next_offset;
static int _discovered_offset;
static bool _offsets_initialized;
public:
static int referent_offset;
static int queue_offset;
static int next_offset;
static int discovered_offset;
// Accessors
static inline oop referent(oop ref);
static inline void set_referent(oop ref, oop value);
@ -927,6 +911,11 @@ class java_lang_ref_Reference: AllStatic {
static inline bool is_final(oop ref);
static inline bool is_phantom(oop ref);
static int referent_offset() { CHECK_INIT(_referent_offset); }
static int queue_offset() { CHECK_INIT(_queue_offset); }
static int next_offset() { CHECK_INIT(_next_offset); }
static int discovered_offset() { CHECK_INIT(_discovered_offset); }
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
@ -935,10 +924,10 @@ class java_lang_ref_Reference: AllStatic {
// Interface to java.lang.ref.SoftReference objects
class java_lang_ref_SoftReference: public java_lang_ref_Reference {
public:
static int timestamp_offset;
static int static_clock_offset;
static int _timestamp_offset;
static int _static_clock_offset;
public:
// Accessors
static jlong timestamp(oop ref);
@ -980,8 +969,8 @@ class java_lang_invoke_MethodHandle: AllStatic {
static bool is_instance(oop obj);
// Accessors for code generation:
static int type_offset_in_bytes() { return _type_offset; }
static int form_offset_in_bytes() { return _form_offset; }
static int type_offset() { CHECK_INIT(_type_offset); }
static int form_offset() { CHECK_INIT(_form_offset); }
};
// Interface to java.lang.invoke.DirectMethodHandle objects
@ -1007,7 +996,7 @@ class java_lang_invoke_DirectMethodHandle: AllStatic {
static bool is_instance(oop obj);
// Accessors for code generation:
static int member_offset_in_bytes() { return _member_offset; }
static int member_offset() { CHECK_INIT(_member_offset); }
};
// Interface to java.lang.invoke.LambdaForm objects
@ -1036,7 +1025,7 @@ class java_lang_invoke_LambdaForm: AllStatic {
static bool is_instance(oop obj);
// Accessors for code generation:
static int vmentry_offset_in_bytes() { return _vmentry_offset; }
static int vmentry_offset() { CHECK_INIT(_vmentry_offset); }
};
@ -1057,7 +1046,7 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
public:
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
static int vmtarget_offset_in_bytes() { return _vmtarget_offset; }
static int vmtarget_offset() { CHECK_INIT(_vmtarget_offset); }
static Method* vmtarget(oop resolved_method);
static void set_vmtarget(oop resolved_method, Method* method);
@ -1144,12 +1133,11 @@ class java_lang_invoke_MemberName: AllStatic {
};
// Accessors for code generation:
static int clazz_offset_in_bytes() { return _clazz_offset; }
static int type_offset_in_bytes() { return _type_offset; }
static int name_offset_in_bytes() { return _name_offset; }
static int flags_offset_in_bytes() { return _flags_offset; }
static int method_offset_in_bytes() { return _method_offset; }
static int vmindex_offset_in_bytes() { return _vmindex_offset; }
static int clazz_offset() { CHECK_INIT(_clazz_offset); }
static int type_offset() { CHECK_INIT(_type_offset); }
static int flags_offset() { CHECK_INIT(_flags_offset); }
static int method_offset() { CHECK_INIT(_method_offset); }
static int vmindex_offset() { CHECK_INIT(_vmindex_offset); }
};
@ -1184,8 +1172,8 @@ class java_lang_invoke_MethodType: AllStatic {
static bool equals(oop mt1, oop mt2);
// Accessors for code generation:
static int rtype_offset_in_bytes() { return _rtype_offset; }
static int ptypes_offset_in_bytes() { return _ptypes_offset; }
static int rtype_offset() { CHECK_INIT(_rtype_offset); }
static int ptypes_offset() { CHECK_INIT(_ptypes_offset); }
};
@ -1216,7 +1204,8 @@ public:
static bool is_instance(oop obj);
// Accessors for code generation:
static int target_offset_in_bytes() { return _target_offset; }
static int target_offset() { CHECK_INIT(_target_offset); }
static int context_offset() { CHECK_INIT(_context_offset); }
};
// Interface to java.lang.invoke.ConstantCallSite objects
@ -1299,15 +1288,15 @@ class java_security_AccessControlContext: AllStatic {
class java_lang_ClassLoader : AllStatic {
private:
static int _loader_data_offset;
static bool offsets_computed;
static int parent_offset;
static int parallelCapable_offset;
static int name_offset;
static int nameAndId_offset;
static int unnamedModule_offset;
static int _parent_offset;
static int _parallelCapable_offset;
static int _name_offset;
static int _nameAndId_offset;
static int _unnamedModule_offset;
static void compute_offsets();
public:
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
static ClassLoaderData* loader_data_acquire(oop loader);
@ -1341,7 +1330,6 @@ class java_lang_ClassLoader : AllStatic {
// Debugging
friend class JavaClasses;
friend class ClassFileParser; // access to number_of_fake_fields
};
@ -1349,15 +1337,15 @@ class java_lang_ClassLoader : AllStatic {
class java_lang_System : AllStatic {
private:
static int static_in_offset;
static int static_out_offset;
static int static_err_offset;
static int static_security_offset;
static int _static_in_offset;
static int _static_out_offset;
static int _static_err_offset;
static int _static_security_offset;
public:
static int in_offset_in_bytes();
static int out_offset_in_bytes();
static int err_offset_in_bytes();
static int in_offset() { CHECK_INIT(_static_in_offset); }
static int out_offset() { CHECK_INIT(_static_out_offset); }
static int err_offset() { CHECK_INIT(_static_err_offset); }
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
@ -1371,14 +1359,14 @@ class java_lang_System : AllStatic {
class java_lang_StackTraceElement: AllStatic {
private:
static int declaringClassObject_offset;
static int classLoaderName_offset;
static int moduleName_offset;
static int moduleVersion_offset;
static int declaringClass_offset;
static int methodName_offset;
static int fileName_offset;
static int lineNumber_offset;
static int _declaringClassObject_offset;
static int _classLoaderName_offset;
static int _moduleName_offset;
static int _moduleVersion_offset;
static int _declaringClass_offset;
static int _methodName_offset;
static int _fileName_offset;
static int _lineNumber_offset;
// Setters
static void set_classLoaderName(oop element, oop value);
@ -1482,13 +1470,13 @@ class java_lang_LiveStackFrameInfo: AllStatic {
class java_lang_reflect_RecordComponent: AllStatic {
private:
static int clazz_offset;
static int name_offset;
static int type_offset;
static int accessor_offset;
static int signature_offset;
static int annotations_offset;
static int typeAnnotations_offset;
static int _clazz_offset;
static int _name_offset;
static int _type_offset;
static int _accessor_offset;
static int _signature_offset;
static int _annotations_offset;
static int _typeAnnotations_offset;
// Setters
static void set_clazz(oop element, oop value);
@ -1515,11 +1503,11 @@ class java_lang_reflect_RecordComponent: AllStatic {
class java_lang_AssertionStatusDirectives: AllStatic {
private:
static int classes_offset;
static int classEnabled_offset;
static int packages_offset;
static int packageEnabled_offset;
static int deflt_offset;
static int _classes_offset;
static int _classEnabled_offset;
static int _packages_offset;
static int _packageEnabled_offset;
static int _deflt_offset;
public:
// Setters
@ -1542,7 +1530,7 @@ class java_nio_Buffer: AllStatic {
static int _limit_offset;
public:
static int limit_offset();
static int limit_offset() { CHECK_INIT(_limit_offset); }
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
@ -1719,4 +1707,5 @@ class JavaClasses : AllStatic {
#undef DECLARE_INJECTED_FIELD_ENUM
#undef CHECK_INIT
#endif // SHARE_CLASSFILE_JAVACLASSES_HPP

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020, 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,23 +31,19 @@
#include "oops/oopsHierarchy.hpp"
void java_lang_String::set_coder(oop string, jbyte coder) {
assert(initialized && (coder_offset > 0), "Must be initialized");
string->byte_field_put(coder_offset, coder);
string->byte_field_put(_coder_offset, coder);
}
void java_lang_String::set_value_raw(oop string, typeArrayOop buffer) {
assert(initialized, "Must be initialized");
string->obj_field_put_raw(value_offset, buffer);
string->obj_field_put_raw(_value_offset, buffer);
}
void java_lang_String::set_value(oop string, typeArrayOop buffer) {
assert(initialized && (value_offset > 0), "Must be initialized");
string->obj_field_put(value_offset, (oop)buffer);
string->obj_field_put(_value_offset, (oop)buffer);
}
bool java_lang_String::hash_is_set(oop java_string) {
assert(initialized && (hash_offset > 0) && (hashIsZero_offset > 0), "Must be initialized");
return java_string->int_field(hash_offset) != 0 || java_string->bool_field(hashIsZero_offset) != 0;
return java_string->int_field(_hash_offset) != 0 || java_string->bool_field(_hashIsZero_offset) != 0;
}
// Accessors
@ -60,27 +56,24 @@ bool java_lang_String::value_equals(typeArrayOop str_value1, typeArrayOop str_va
}
typeArrayOop java_lang_String::value(oop java_string) {
assert(initialized && (value_offset > 0), "Must be initialized");
assert(is_instance(java_string), "must be java_string");
return (typeArrayOop) java_string->obj_field(value_offset);
return (typeArrayOop) java_string->obj_field(_value_offset);
}
typeArrayOop java_lang_String::value_no_keepalive(oop java_string) {
assert(initialized && (value_offset > 0), "Must be initialized");
assert(is_instance(java_string), "must be java_string");
return (typeArrayOop) java_string->obj_field_access<AS_NO_KEEPALIVE>(value_offset);
return (typeArrayOop) java_string->obj_field_access<AS_NO_KEEPALIVE>(_value_offset);
}
bool java_lang_String::is_latin1(oop java_string) {
assert(initialized && (coder_offset > 0), "Must be initialized");
assert(is_instance(java_string), "must be java_string");
jbyte coder = java_string->byte_field(coder_offset);
jbyte coder = java_string->byte_field(_coder_offset);
assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings");
return coder == CODER_LATIN1;
}
int java_lang_String::length(oop java_string, typeArrayOop value) {
assert(initialized, "Must be initialized");
assert(_initialized, "Must be initialized");
assert(is_instance(java_string), "must be java_string");
assert(value_equals(value, java_lang_String::value(java_string)),
"value must be equal to java_lang_String::value(java_string)");
@ -96,7 +89,7 @@ int java_lang_String::length(oop java_string, typeArrayOop value) {
}
int java_lang_String::length(oop java_string) {
assert(initialized, "Must be initialized");
assert(_initialized, "Must be initialized");
assert(is_instance(java_string), "must be java_string");
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
return length(java_string, value);
@ -108,51 +101,51 @@ bool java_lang_String::is_instance_inlined(oop obj) {
// Accessors
oop java_lang_ref_Reference::referent(oop ref) {
return ref->obj_field(referent_offset);
return ref->obj_field(_referent_offset);
}
void java_lang_ref_Reference::set_referent(oop ref, oop value) {
ref->obj_field_put(referent_offset, value);
ref->obj_field_put(_referent_offset, value);
}
void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {
ref->obj_field_put_raw(referent_offset, value);
ref->obj_field_put_raw(_referent_offset, value);
}
HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
return ref->obj_field_addr_raw<HeapWord>(referent_offset);
return ref->obj_field_addr_raw<HeapWord>(_referent_offset);
}
oop java_lang_ref_Reference::next(oop ref) {
return ref->obj_field(next_offset);
return ref->obj_field(_next_offset);
}
void java_lang_ref_Reference::set_next(oop ref, oop value) {
ref->obj_field_put(next_offset, value);
ref->obj_field_put(_next_offset, value);
}
void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
ref->obj_field_put_raw(next_offset, value);
ref->obj_field_put_raw(_next_offset, value);
}
HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
return ref->obj_field_addr_raw<HeapWord>(next_offset);
return ref->obj_field_addr_raw<HeapWord>(_next_offset);
}
oop java_lang_ref_Reference::discovered(oop ref) {
return ref->obj_field(discovered_offset);
return ref->obj_field(_discovered_offset);
}
void java_lang_ref_Reference::set_discovered(oop ref, oop value) {
ref->obj_field_put(discovered_offset, value);
ref->obj_field_put(_discovered_offset, value);
}
void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
ref->obj_field_put_raw(discovered_offset, value);
ref->obj_field_put_raw(_discovered_offset, value);
}
HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
return ref->obj_field_addr_raw<HeapWord>(_discovered_offset);
}
bool java_lang_ref_Reference::is_final(oop ref) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -510,7 +510,7 @@ void G1BarrierSetC2::insert_pre_barrier(GraphKit* kit, Node* base_oop, Node* off
// If offset is a constant, is it java_lang_ref_Reference::_reference_offset?
const TypeX* otype = offset->find_intptr_t_type();
if (otype != NULL && otype->is_con() &&
otype->get_con() != java_lang_ref_Reference::referent_offset) {
otype->get_con() != java_lang_ref_Reference::referent_offset()) {
// Constant offset but not the reference_offset so just return
return;
}
@ -550,7 +550,7 @@ void G1BarrierSetC2::insert_pre_barrier(GraphKit* kit, Node* base_oop, Node* off
IdealKit ideal(kit);
Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset);
Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset());
__ if_then(offset, BoolTest::eq, referent_off, unlikely); {
// Update graphKit memory and control from IdealKit.

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -222,7 +222,7 @@ void BarrierSetC1::generate_referent_check(LIRAccess& access, LabelObj* cont) {
//
// We need to generate code similar to the following...
//
// if (offset == java_lang_ref_Reference::referent_offset) {
// if (offset == java_lang_ref_Reference::referent_offset()) {
// if (src != NULL) {
// if (klass(src)->reference_type() != REF_NONE) {
// pre_barrier(..., value, ...);
@ -247,7 +247,7 @@ void BarrierSetC1::generate_referent_check(LIRAccess& access, LabelObj* cont) {
constant->as_jlong());
if (off_con != (jlong) java_lang_ref_Reference::referent_offset) {
if (off_con != (jlong) java_lang_ref_Reference::referent_offset()) {
// The constant offset is something other than referent_offset.
// We can skip generating/checking the remaining guards and
// skip generation of the code stub.
@ -314,11 +314,11 @@ void BarrierSetC1::generate_referent_check(LIRAccess& access, LabelObj* cont) {
LIR_Opr referent_off;
if (offset->type() == T_INT) {
referent_off = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset);
referent_off = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset());
} else {
assert(offset->type() == T_LONG, "what else?");
referent_off = gen->new_register(T_LONG);
__ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
__ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset()), referent_off);
}
__ cmp(lir_cond_notEqual, offset, referent_off);
__ branch(lir_cond_notEqual, offset->type(), cont->label());

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2020, 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
@ -301,7 +301,7 @@ void DiscoveredListIterator::clear_referent() {
void DiscoveredListIterator::enqueue() {
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_current_discovered,
java_lang_ref_Reference::discovered_offset,
java_lang_ref_Reference::discovered_offset(),
_next_discovered);
}
@ -311,7 +311,7 @@ void DiscoveredListIterator::complete_enqueue() {
// Swap refs_list into pending list and set obj's
// discovered to what we read from the pending list.
oop old = Universe::swap_reference_pending_list(_refs_list.head());
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_prev_discovered, java_lang_ref_Reference::discovered_offset, old);
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_prev_discovered, java_lang_ref_Reference::discovered_offset(), old);
}
}

@ -375,7 +375,7 @@ void ShenandoahBarrierSetC2::insert_pre_barrier(GraphKit* kit, Node* base_oop, N
// If offset is a constant, is it java_lang_ref_Reference::_reference_offset?
const TypeX* otype = offset->find_intptr_t_type();
if (otype != NULL && otype->is_con() &&
otype->get_con() != java_lang_ref_Reference::referent_offset) {
otype->get_con() != java_lang_ref_Reference::referent_offset()) {
// Constant offset but not the reference_offset so just return
return;
}
@ -415,7 +415,7 @@ void ShenandoahBarrierSetC2::insert_pre_barrier(GraphKit* kit, Node* base_oop, N
IdealKit ideal(kit);
Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset);
Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset());
__ if_then(offset, BoolTest::eq, referent_off, unlikely); {
// Update graphKit memory and control from IdealKit.

@ -298,7 +298,7 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
if (trace) {tty->print_cr("Mark load");}
} else if (adr_type->isa_instptr() &&
adr_type->is_instptr()->klass()->is_subtype_of(Compile::current()->env()->Reference_klass()) &&
adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset) {
adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset()) {
if (trace) {tty->print_cr("Reference.get()");}
} else if (!verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahLoad, trace, barriers_used)) {
report_verify_failure("Shenandoah verification: Load should have barriers", n);

@ -267,9 +267,10 @@ public:
}
}
if (heap->is_degenerated_gc_in_progress()) {
// Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
// let's check here.
if (heap->is_degenerated_gc_in_progress() || heap->is_full_gc_in_progress()) {
// Full GC does not execute concurrent cycle.
// Degenerated cycle may bypass concurrent cycle.
// So code roots might not be scanned, let's scan here.
_cm->concurrent_scan_code_roots(worker_id, rp);
}
@ -390,21 +391,23 @@ void ShenandoahConcurrentMark::initialize(uint workers) {
}
void ShenandoahConcurrentMark::concurrent_scan_code_roots(uint worker_id, ReferenceProcessor* rp) {
if (_heap->unload_classes()) {
return;
}
if (claim_codecache()) {
ShenandoahObjToScanQueue* q = task_queues()->queue(worker_id);
if (!_heap->unload_classes()) {
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
// TODO: We can not honor StringDeduplication here, due to lock ranking
// inversion. So, we may miss some deduplication candidates.
if (_heap->has_forwarded_objects()) {
ShenandoahMarkResolveRefsClosure cl(q, rp);
CodeBlobToOopClosure blobs(&cl, !CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobs);
} else {
ShenandoahMarkRefsClosure cl(q, rp);
CodeBlobToOopClosure blobs(&cl, !CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobs);
}
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
// TODO: We can not honor StringDeduplication here, due to lock ranking
// inversion. So, we may miss some deduplication candidates.
if (_heap->has_forwarded_objects()) {
ShenandoahMarkResolveRefsClosure cl(q, rp);
CodeBlobToOopClosure blobs(&cl, !CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobs);
} else {
ShenandoahMarkRefsClosure cl(q, rp);
CodeBlobToOopClosure blobs(&cl, !CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobs);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020, 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
@ -246,10 +246,10 @@ inline void ZBarrier::load_barrier_on_oop_array(volatile oop* p, size_t length)
inline void verify_on_weak(volatile oop* referent_addr) {
#ifdef ASSERT
if (referent_addr != NULL) {
uintptr_t base = (uintptr_t)referent_addr - java_lang_ref_Reference::referent_offset;
uintptr_t base = (uintptr_t)referent_addr - java_lang_ref_Reference::referent_offset();
oop obj = cast_to_oop(base);
assert(oopDesc::is_oop(obj), "Verification failed for: ref " PTR_FORMAT " obj: " PTR_FORMAT, (uintptr_t)referent_addr, base);
assert(java_lang_ref_Reference::is_referent_field(obj, java_lang_ref_Reference::referent_offset), "Sanity");
assert(java_lang_ref_Reference::is_referent_field(obj, java_lang_ref_Reference::referent_offset()), "Sanity");
}
#endif
}

@ -214,7 +214,7 @@ JRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::C
if (!is_fast_aldc) {
// Tell the interpreter how to unbox the primitive.
guarantee(java_lang_boxing_object::is_instance(result, type), "");
int offset = java_lang_boxing_object::value_offset_in_bytes(type);
int offset = java_lang_boxing_object::value_offset(type);
intptr_t flags = ((as_TosState(type) << ConstantPoolCacheEntry::tos_state_shift)
| (offset & ConstantPoolCacheEntry::field_index_mask));
thread->set_vm_result_2((Metadata*)flags);

@ -49,6 +49,7 @@
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/writers/jfrJavaEventWriter.hpp"
#include "jfrfiles/jfrPeriodic.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp"
@ -349,4 +350,10 @@ JVM_ENTRY_NO_ENV(jboolean, jfr_set_handler(JNIEnv * env, jobject jvm, jobject cl
return JfrJavaSupport::set_handler(clazz, handler, thread);
JVM_END
NO_TRANSITION(jlong, jfr_get_type_id_from_string(JNIEnv * env, jobject jvm, jstring type))
const char* type_name= env->GetStringUTFChars(type, NULL);
jlong id = JfrType::name_to_id(type_name);
env->ReleaseStringUTFChars(type, type_name);
return id;
NO_TRANSITION_END

@ -148,6 +148,7 @@ jobject JNICALL jfr_get_handler(JNIEnv* env, jobject jvm, jobject clazz);
jboolean JNICALL jfr_set_handler(JNIEnv* env, jobject jvm, jobject clazz, jobject handler);
jlong JNICALL jfr_get_type_id_from_string(JNIEnv* env, jobject jvm, jstring type);
#ifdef __cplusplus
}

@ -88,7 +88,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
(char*)"isExcluded", (char*)"(Ljava/lang/Thread;)Z", (void*)jfr_is_thread_excluded,
(char*)"getChunkStartNanos", (char*)"()J", (void*)jfr_chunk_start_nanos,
(char*)"getHandler", (char*)"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)jfr_get_handler,
(char*)"setHandler", (char*)"(Ljava/lang/Class;Ljdk/jfr/internal/handlers/EventHandler;)Z", (void*)jfr_set_handler
(char*)"setHandler", (char*)"(Ljava/lang/Class;Ljdk/jfr/internal/handlers/EventHandler;)Z", (void*)jfr_set_handler,
(char*)"getTypeId", (char*)"(Ljava/lang/String;)J", (void*)jfr_get_type_id_from_string
};
const size_t method_array_length = sizeof(method) / sizeof(JNINativeMethod);

@ -1304,8 +1304,8 @@
<XmlType name="ClassLoader" parameterType="const ClassLoaderData*" fieldType="const ClassLoaderData*"/>
<XmlType name="Method" parameterType="const Method*" fieldType="const Method*"/>
<XmlType name="Thread" javaType="java.lang.Thread" parameterType="u8" fieldType="u8"/>
<XmlType name="Tickspan" contentType="tickspan" javaType="long" parameterType="const Tickspan&amp;" fieldType="Tickspan"/>
<XmlType name="Ticks" contentType="tickstamp" javaType="long" parameterType="const Ticks&amp;" fieldType="Ticks"/>
<XmlType name="Tickspan" contentType="tickspan" unsigned="true" javaType="long" parameterType="const Tickspan&amp;" fieldType="Tickspan"/>
<XmlType name="Ticks" contentType="tickstamp" unsigned="true" javaType="long" parameterType="const Ticks&amp;" fieldType="Ticks"/>
<XmlType name="ulong" javaType="long" unsigned="true" parameterType="u8" fieldType="u8"/>
<XmlType name="uint" javaType="int" unsigned="true" parameterType="unsigned" fieldType="unsigned"/>
<XmlType name="ushort" javaType="short" unsigned="true" parameterType="u2" fieldType="u2"/>
@ -1319,6 +1319,7 @@
<XmlType name="boolean" javaType="boolean" parameterType="bool" fieldType="bool"/>
<XmlType name="char" javaType="char" parameterType="char" fieldType="char"/>
<XmlType name="string" javaType="java.lang.String" parameterType="const char*" fieldType="const char*"/>
<XmlType name="StackTrace" javaType="jdk.types.StackTrace" parameterType="u8" fieldType="u8"/>
<XmlContentType name="bytes" annotation="jdk.jfr.DataAmount(BYTES)" />
<XmlContentType name="tickstamp" annotation="jdk.jfr.Timestamp(TICKS)" />

@ -126,7 +126,8 @@ void JfrCheckpointWriter::release() {
}
void JfrCheckpointWriter::write_type(JfrTypeId type_id) {
assert(type_id < TYPES_END, "invariant");
assert(type_id <= LAST_TYPE_ID, "type id overflow invariant");
assert(type_id >= FIRST_TYPE_ID, "type id underflow invariant");
write<u8>(type_id);
increment();
}

@ -27,6 +27,7 @@
#include "classfile/javaClasses.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "oops/arrayKlass.inline.hpp"
#include "oops/klass.inline.hpp"
@ -52,7 +53,7 @@ static traceid atomic_inc(traceid volatile* const dest) {
}
static traceid next_class_id() {
static volatile traceid class_id_counter = MaxJfrEventId + 100;
static volatile traceid class_id_counter = LAST_TYPE_ID + 1;
return atomic_inc(&class_id_counter) << TRACE_ID_SHIFT;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2020, 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
@ -55,7 +55,10 @@ void JfrEventSetting::set_enabled(jlong id, bool enabled) {
#ifdef ASSERT
bool JfrEventSetting::bounds_check_event(jlong id) {
if ((unsigned)id < NUM_RESERVED_EVENTS || (unsigned)id >= MaxJfrEventId) {
if ((unsigned)id < FIRST_EVENT_ID) {
return false;
}
if ((unsigned)id > LAST_EVENT_ID) {
return false;
}
return true;

@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "jfr/recorder/repository/jfrChunk.hpp"
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
#include "jfr/utilities/jfrTime.hpp"

@ -192,8 +192,8 @@ class JfrEvent {
JfrEventVerifier _verifier;
void assert_precondition() {
assert(T::eventId >= (JfrEventId)NUM_RESERVED_EVENTS, "event id underflow invariant");
assert(T::eventId < MaxJfrEventId, "event id overflow invariant");
assert(T::eventId >= FIRST_EVENT_ID, "event id underflow invariant");
assert(T::eventId <= LAST_EVENT_ID, "event id overflow invariant");
DEBUG_ONLY(static_cast<T*>(this)->verify());
}

@ -26,6 +26,7 @@
#define SHARE_JFR_UTILITIES_JFRTYPES_HPP
#include "jfrfiles/jfrEventIds.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "utilities/globalDefinitions.hpp"
typedef u8 traceid;
@ -46,6 +47,11 @@ inline int sort_traceid(traceid* lhs, traceid* rhs) {
return compare_traceid(*lhs, *rhs);
}
enum ReservedEvent {
EVENT_METADATA = 0,
EVENT_CHECKPOINT = 1
};
enum EventStartTime {
UNTIMED,
TIMED

@ -157,7 +157,7 @@ class JavaArgumentUnboxer : public SignatureIterator {
return;
}
Handle arg = next_arg(type);
int box_offset = java_lang_boxing_object::value_offset_in_bytes(type);
int box_offset = java_lang_boxing_object::value_offset(type);
switch (type) {
case T_BOOLEAN: _jca->push_int(arg->bool_field(box_offset)); break;
case T_CHAR: _jca->push_int(arg->char_field(box_offset)); break;

@ -734,7 +734,7 @@ oop InstanceKlass::init_lock() const {
void InstanceKlass::fence_and_clear_init_lock() {
// make sure previous stores are all done, notably the init_state.
OrderAccess::storestore();
java_lang_Class::set_init_lock(java_mirror(), NULL);
java_lang_Class::clear_init_lock(java_mirror());
assert(!is_not_initialized(), "class must be initialized now");
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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
@ -45,10 +45,10 @@ void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
#ifdef ASSERT
// Verify fields are in the expected places.
int referent_offset = java_lang_ref_Reference::referent_offset;
int queue_offset = java_lang_ref_Reference::queue_offset;
int next_offset = java_lang_ref_Reference::next_offset;
int discovered_offset = java_lang_ref_Reference::discovered_offset;
int referent_offset = java_lang_ref_Reference::referent_offset();
int queue_offset = java_lang_ref_Reference::queue_offset();
int next_offset = java_lang_ref_Reference::next_offset();
int discovered_offset = java_lang_ref_Reference::discovered_offset();
assert(referent_offset < queue_offset, "just checking");
assert(queue_offset < next_offset, "just checking");
assert(next_offset < discovered_offset, "just checking");
@ -58,7 +58,7 @@ void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
#endif // ASSERT
// Updated map starts at "queue", covers "queue" and "next".
const int new_offset = java_lang_ref_Reference::queue_offset;
const int new_offset = java_lang_ref_Reference::queue_offset();
const unsigned int new_count = 2; // queue and next
// Verify existing map is as expected, and update if needed.

@ -1585,7 +1585,7 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr
if (flat == TypeInstPtr::KLASS) alias_type(idx)->set_rewritable(false);
if (flat == TypeAryPtr::RANGE) alias_type(idx)->set_rewritable(false);
if (flat->isa_instptr()) {
if (flat->offset() == java_lang_Class::klass_offset_in_bytes()
if (flat->offset() == java_lang_Class::klass_offset()
&& flat->is_instptr()->klass() == env()->Class_klass())
alias_type(idx)->set_rewritable(false);
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2020, 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
@ -3986,7 +3986,7 @@ Node* GraphKit::load_String_length(Node* str, bool set_ctrl) {
}
Node* GraphKit::load_String_value(Node* str, bool set_ctrl) {
int value_offset = java_lang_String::value_offset_in_bytes();
int value_offset = java_lang_String::value_offset();
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* value_field_type = string_type->add_offset(value_offset);
@ -4003,7 +4003,7 @@ Node* GraphKit::load_String_coder(Node* str, bool set_ctrl) {
if (!CompactStrings) {
return intcon(java_lang_String::CODER_UTF16);
}
int coder_offset = java_lang_String::coder_offset_in_bytes();
int coder_offset = java_lang_String::coder_offset();
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
@ -4015,7 +4015,7 @@ Node* GraphKit::load_String_coder(Node* str, bool set_ctrl) {
}
void GraphKit::store_String_value(Node* str, Node* value) {
int value_offset = java_lang_String::value_offset_in_bytes();
int value_offset = java_lang_String::value_offset();
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* value_field_type = string_type->add_offset(value_offset);
@ -4025,7 +4025,7 @@ void GraphKit::store_String_value(Node* str, Node* value) {
}
void GraphKit::store_String_coder(Node* str, Node* value) {
int coder_offset = java_lang_String::coder_offset_in_bytes();
int coder_offset = java_lang_String::coder_offset();
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* coder_field_type = string_type->add_offset(coder_offset);

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, 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
@ -170,14 +170,14 @@ class LibraryCallKit : public GraphKit {
int offset);
Node* load_klass_from_mirror(Node* mirror, bool never_see_null,
RegionNode* region, int null_path) {
int offset = java_lang_Class::klass_offset_in_bytes();
int offset = java_lang_Class::klass_offset();
return load_klass_from_mirror_common(mirror, never_see_null,
region, null_path,
offset);
}
Node* load_array_klass_from_mirror(Node* mirror, bool never_see_null,
RegionNode* region, int null_path) {
int offset = java_lang_Class::array_klass_offset_in_bytes();
int offset = java_lang_Class::array_klass_offset();
return load_klass_from_mirror_common(mirror, never_see_null,
region, null_path,
offset);
@ -3387,7 +3387,7 @@ bool LibraryCallKit::inline_native_subtype_check() {
const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads
const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
int class_klass_offset = java_lang_Class::klass_offset_in_bytes();
int class_klass_offset = java_lang_Class::klass_offset();
// First null-check both mirrors and load each mirror's klass metaobject.
int which_arg;
@ -5680,8 +5680,7 @@ bool LibraryCallKit::inline_updateByteBufferAdler32() {
//----------------------------inline_reference_get----------------------------
// public T java.lang.ref.Reference.get();
bool LibraryCallKit::inline_reference_get() {
const int referent_offset = java_lang_ref_Reference::referent_offset;
guarantee(referent_offset > 0, "should have already been set");
const int referent_offset = java_lang_ref_Reference::referent_offset();
// Get the argument:
Node* reference_obj = null_check_receiver();

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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
@ -2153,15 +2153,15 @@ const Type* LoadNode::klass_value_common(PhaseGVN* phase) const {
ciInstanceKlass* ik = tinst->klass()->as_instance_klass();
int offset = tinst->offset();
if (ik == phase->C->env()->Class_klass()
&& (offset == java_lang_Class::klass_offset_in_bytes() ||
offset == java_lang_Class::array_klass_offset_in_bytes())) {
&& (offset == java_lang_Class::klass_offset() ||
offset == java_lang_Class::array_klass_offset())) {
// We are loading a special hidden field from a Class mirror object,
// the field which points to the VM's Klass metaobject.
ciType* t = tinst->java_mirror_type();
// java_mirror_type returns non-null for compile-time Class constants.
if (t != NULL) {
// constant oop => constant klass
if (offset == java_lang_Class::array_klass_offset_in_bytes()) {
if (offset == java_lang_Class::array_klass_offset()) {
if (t->is_void()) {
// We cannot create a void array. Since void is a primitive type return null
// klass. Users of this result need to do a null check on the returned klass.
@ -2314,7 +2314,7 @@ Node* LoadNode::klass_identity_common(PhaseGVN* phase) {
// introducing a new debug info operator for Klass.java_mirror).
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
&& offset == java_lang_Class::klass_offset_in_bytes()) {
&& offset == java_lang_Class::klass_offset()) {
if (base->is_Load()) {
Node* base2 = base->in(MemNode::Address);
if (base2->is_Load()) { /* direct load of a load which is the OopHandle */

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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
@ -1666,7 +1666,7 @@ jbyte PhaseStringOpts::get_constant_coder(GraphKit& kit, Node* str) {
assert(str->is_Con(), "String must be constant");
const TypeOopPtr* str_type = kit.gvn().type(str)->isa_oopptr();
ciInstance* str_instance = str_type->const_oop()->as_instance();
jbyte coder = str_instance->field_value_by_offset(java_lang_String::coder_offset_in_bytes()).as_byte();
jbyte coder = str_instance->field_value_by_offset(java_lang_String::coder_offset()).as_byte();
assert(CompactStrings || (coder == java_lang_String::CODER_UTF16), "Strings must be UTF16 encoded");
return coder;
}
@ -1680,7 +1680,7 @@ ciTypeArray* PhaseStringOpts::get_constant_value(GraphKit& kit, Node* str) {
assert(str->is_Con(), "String must be constant");
const TypeOopPtr* str_type = kit.gvn().type(str)->isa_oopptr();
ciInstance* str_instance = str_type->const_oop()->as_instance();
ciObject* src_array = str_instance->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
ciObject* src_array = str_instance->field_value_by_offset(java_lang_String::value_offset()).as_object();
return src_array->as_type_array();
}

@ -3010,8 +3010,8 @@ TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int o
assert(this->isa_instptr(), "must be an instance ptr.");
if (klass() == ciEnv::current()->Class_klass() &&
(_offset == java_lang_Class::klass_offset_in_bytes() ||
_offset == java_lang_Class::array_klass_offset_in_bytes())) {
(_offset == java_lang_Class::klass_offset() ||
_offset == java_lang_Class::array_klass_offset())) {
// Special hidden fields from the Class.
assert(this->isa_instptr(), "must be an instance ptr.");
_is_ptr_to_narrowoop = false;

@ -188,6 +188,8 @@ public class DatagramSocket implements java.io.Closeable {
* or the socket could not bind to the specified local port.
* @throws SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the operation.
* @throws IllegalArgumentException if bindaddr is a
* SocketAddress subclass not supported by this socket.
*
* @see SecurityManager#checkListen
* @since 1.4
@ -208,11 +210,13 @@ public class DatagramSocket implements java.io.Closeable {
* as its argument to ensure the operation is allowed.
* This could result in a SecurityException.
*
* @param port port to use.
* @param port local port to use in the bind operation.
* @throws SocketException if the socket could not be opened,
* or the socket could not bind to the specified local port.
* @throws SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the operation.
* @throws IllegalArgumentException if port is <a href="#PortRange">
* out of range.</a>
*
* @see SecurityManager#checkListen
*/
@ -222,7 +226,11 @@ public class DatagramSocket implements java.io.Closeable {
/**
* Creates a datagram socket, bound to the specified local
* address. The local port must be between 0 and 65535 inclusive.
* address.
* <p><a id="PortRange"></a>The local port must be between 0 and
* 65535 inclusive. A port number of {@code zero} will let the system pick
* up an ephemeral port in a {@code bind} operation.
* <p>
* If the IP address is 0.0.0.0, the socket will be bound to the
* {@link InetAddress#isAnyLocalAddress wildcard} address,
* an IP address chosen by the kernel.
@ -233,13 +241,15 @@ public class DatagramSocket implements java.io.Closeable {
* as its argument to ensure the operation is allowed.
* This could result in a SecurityException.
*
* @param port local port to use
* @param port local port to use in the bind operation.
* @param laddr local address to bind
*
* @throws SocketException if the socket could not be opened,
* or the socket could not bind to the specified local port.
* @throws SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the operation.
* @throws IllegalArgumentException if port is <a href="#PortRange">
* out of range.</a>
*
* @see SecurityManager#checkListen
* @since 1.1
@ -311,7 +321,8 @@ public class DatagramSocket implements java.io.Closeable {
* @param port the remote port for the socket.
*
* @throws IllegalArgumentException
* if the address is null, or the port is out of range.
* if the address is null, or the port is <a href="#PortRange">
* out of range.</a>
*
* @throws SecurityException
* if a security manager has been installed and it does
@ -504,7 +515,8 @@ public class DatagramSocket implements java.io.Closeable {
* @throws IllegalArgumentException if the socket is connected,
* and connected address and packet address differ, or
* if the socket is not connected and the packet address
* is not set or if its port is out of range.
* is not set or if its port is <a href="#PortRange">out of
* range.</a>
*
* @see java.net.DatagramPacket
* @see SecurityManager#checkMulticast(InetAddress)

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2020, 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,11 +25,11 @@
package java.net;
import java.util.List;
import java.util.NavigableSet;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;
import java.security.AccessController;
import java.io.File;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
@ -954,29 +954,18 @@ public class InetAddress implements java.io.Serializable {
*/
private static final class HostsFileNameService implements NameService {
private static final InetAddress[] EMPTY_ARRAY = new InetAddress[0];
// Specify if only IPv4 addresses should be returned by HostsFileService implementation
private static final boolean preferIPv4Stack = Boolean.parseBoolean(
GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"));
private final String hostsFile;
public HostsFileNameService (String hostsFileName) {
public HostsFileNameService(String hostsFileName) {
this.hostsFile = hostsFileName;
}
private String addrToString(byte addr[]) {
String stringifiedAddress = null;
if (addr.length == Inet4Address.INADDRSZ) {
stringifiedAddress = Inet4Address.numericToTextFormat(addr);
} else { // treat as an IPV6 jobby
byte[] newAddr
= IPAddressUtil.convertFromIPv4MappedAddress(addr);
if (newAddr != null) {
stringifiedAddress = Inet4Address.numericToTextFormat(addr);
} else {
stringifiedAddress = Inet6Address.numericToTextFormat(addr);
}
}
return stringifiedAddress;
}
/**
* Lookup the host name corresponding to the IP address provided.
* Search the configured host file a host name corresponding to
@ -1037,15 +1026,15 @@ public class InetAddress implements java.io.Serializable {
public InetAddress[] lookupAllHostAddr(String host)
throws UnknownHostException {
String hostEntry;
String addrStr = null;
InetAddress[] res = null;
byte addr[] = new byte[4];
ArrayList<InetAddress> inetAddresses = null;
String addrStr;
byte addr[];
List<InetAddress> inetAddresses = new ArrayList<>();
List<InetAddress> inet4Addresses = new ArrayList<>();
List<InetAddress> inet6Addresses = new ArrayList<>();
// lookup the file and create a list InetAddress for the specified host
try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
UTF_8.INSTANCE))
{
UTF_8.INSTANCE)) {
while (hostsFileScanner.hasNextLine()) {
hostEntry = hostsFileScanner.nextLine();
if (!hostEntry.startsWith("#")) {
@ -1054,11 +1043,15 @@ public class InetAddress implements java.io.Serializable {
addrStr = extractHostAddr(hostEntry, host);
if ((addrStr != null) && (!addrStr.isEmpty())) {
addr = createAddressByteArray(addrStr);
if (inetAddresses == null) {
inetAddresses = new ArrayList<>(1);
}
if (addr != null) {
inetAddresses.add(InetAddress.getByAddress(host, addr));
InetAddress address = InetAddress.getByAddress(host, addr);
inetAddresses.add(address);
if (address instanceof Inet4Address) {
inet4Addresses.add(address);
}
if (address instanceof Inet6Address) {
inet6Addresses.add(address);
}
}
}
}
@ -1069,13 +1062,32 @@ public class InetAddress implements java.io.Serializable {
+ " as hosts file " + hostsFile + " not found ");
}
if (inetAddresses != null) {
res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]);
List<InetAddress> res;
// If "preferIPv4Stack" system property is set to "true" then return
// only IPv4 addresses
if (preferIPv4Stack) {
res = inet4Addresses;
} else {
// Otherwise, analyse "preferIPv6Addresses" value
res = switch (preferIPv6Address) {
case PREFER_IPV4_VALUE -> concatAddresses(inet4Addresses, inet6Addresses);
case PREFER_IPV6_VALUE -> concatAddresses(inet6Addresses, inet4Addresses);
default -> inetAddresses;
};
}
if (res.isEmpty()) {
throw new UnknownHostException("Unable to resolve host " + host
+ " in hosts file " + hostsFile);
}
return res;
return res.toArray(EMPTY_ARRAY);
}
private static List<InetAddress> concatAddresses(List<InetAddress> firstPart,
List<InetAddress> secondPart) {
List<InetAddress> result = new ArrayList<>(firstPart);
result.addAll(secondPart);
return result;
}
private String removeComments(String hostsEntry) {

@ -482,7 +482,8 @@ final class Finished {
shc.conContext.inputRecord.expectingFinishFlight();
} else {
// Set the session's context based on stateless/cache status
if (shc.handshakeSession.isStatelessable(shc)) {
if (shc.statelessResumption &&
shc.handshakeSession.isStatelessable()) {
shc.handshakeSession.setContext((SSLSessionContextImpl)
shc.sslContext.engineGetServerSessionContext());
} else {
@ -1140,12 +1141,7 @@ final class Finished {
//
// produce
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Sending new session ticket");
}
NewSessionTicket.kickstartProducer.produce(shc);
NewSessionTicket.t13PosthandshakeProducer.produce(shc);
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -416,6 +416,41 @@ abstract class HandshakeContext implements ConnectionContext {
handshakeType,
fragment
));
// For TLS 1.2 and previous versions, the ChangeCipherSpec
// message is always delivered before the Finished handshake
// message. ChangeCipherSpec is not a handshake message,
// and cannot be wrapped in one TLS record. The processing
// of Finished handshake message is unlikely to be delegated.
//
// However, for TLS 1.3 there is no non-handshake messages
// delivered immediately before Finished message. Then, the
// 'hasDelegated' could be true, and the Finished message is
// handled in a delegated action.
//
// The HandshakeStatus.FINISHED for the final handshake flight
// could be used to determine if the handshake has completed.
// Per the HandshakeStatus.FINISHED specification, it is only
// generated by call to SSLEngine.wrap()/unwrap(). It is
// unlikely to change the spec, so we cannot use delegated
// action and SSLEngine.getHandshakeStatus() to indicate the
// FINISHED handshake status.
//
// To workaround this special user case, the follow-on call to
// SSLEngine.wrap() method will return HandshakeStatus.FINISHED
// status if needed.
//
// As the final handshake flight is always delivered from the
// client side, so we only need to take care of the server
// dispatching processes.
//
// See also the note on
// TransportContext.needHandshakeFinishedStatus.
if (hasDelegated &&
!conContext.sslConfig.isClientMode &&
handshakeType == SSLHandshake.FINISHED.id) {
conContext.hasDelegatedFinished = true;
}
} else {
dispatch(handshakeType, plaintext.fragment);
}

@ -33,6 +33,7 @@ import java.text.MessageFormat;
import java.util.Locale;
import javax.crypto.SecretKey;
import javax.net.ssl.SSLHandshakeException;
import sun.security.ssl.PskKeyExchangeModesExtension.PskKeyExchangeMode;
import sun.security.ssl.PskKeyExchangeModesExtension.PskKeyExchangeModesSpec;
import sun.security.ssl.SessionTicketExtension.SessionTicketSpec;
import sun.security.ssl.SSLHandshake.HandshakeMessage;
@ -49,8 +50,8 @@ final class NewSessionTicket {
new T13NewSessionTicketConsumer();
static final SSLConsumer handshake12Consumer =
new T12NewSessionTicketConsumer();
static final SSLProducer kickstartProducer =
new NewSessionTicketKickstartProducer();
static final SSLProducer t13PosthandshakeProducer =
new T13NewSessionTicketProducer();
static final HandshakeProducer handshake12Producer =
new T12NewSessionTicketProducer();
@ -205,7 +206,7 @@ final class NewSessionTicket {
if (ticket.length == 0) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"No ticket in the NewSessionTicket handshake message");
"No ticket in the NewSessionTicket handshake message");
}
}
@ -307,9 +308,9 @@ final class NewSessionTicket {
}
private static final
class NewSessionTicketKickstartProducer implements SSLProducer {
class T13NewSessionTicketProducer implements SSLProducer {
// Prevent instantiation of this class.
private NewSessionTicketKickstartProducer() {
private T13NewSessionTicketProducer() {
// blank
}
@ -317,10 +318,26 @@ final class NewSessionTicket {
public byte[] produce(ConnectionContext context) throws IOException {
HandshakeContext hc = (HandshakeContext)context;
// See note on TransportContext.needHandshakeFinishedStatus.
//
// Set to need handshake finished status. Reset it later if a
// session ticket get delivered.
if (hc.conContext.hasDelegatedFinished) {
// Reset, as the delegated finished case will be handled later.
hc.conContext.hasDelegatedFinished = false;
hc.conContext.needHandshakeFinishedStatus = true;
}
// The producing happens in server side only.
if (hc instanceof ServerHandshakeContext) {
// Is this session resumable?
if (!hc.handshakeSession.isRejoinable()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"No session ticket produced: " +
"session is not resumable");
}
return null;
}
@ -332,16 +349,26 @@ final class NewSessionTicket {
PskKeyExchangeModesSpec pkemSpec =
(PskKeyExchangeModesSpec) hc.handshakeExtensions.get(
SSLExtension.PSK_KEY_EXCHANGE_MODES);
if (pkemSpec == null || !pkemSpec.contains(
PskKeyExchangeModesExtension.PskKeyExchangeMode.PSK_DHE_KE)) {
// Client doesn't support PSK with (EC)DHE key establishment.
if (pkemSpec == null ||
!pkemSpec.contains(PskKeyExchangeMode.PSK_DHE_KE)) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"No session ticket produced: " +
"client does not support psk_dhe_ke");
}
return null;
}
} else { // PostHandshakeContext
// Check if we have sent a PSK already, then we know it is using a
// allowable PSK exchange key mode
} else { // PostHandshakeContext
// Check if we have sent a PSK already, then we know it is
// using a allowable PSK exchange key mode.
if (!hc.handshakeSession.isPSKable()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"No session ticket produced: " +
"No session ticket allowed in this session");
}
return null;
}
}
@ -357,8 +384,10 @@ final class NewSessionTicket {
if (resumptionMasterSecret == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session has no resumption secret. No ticket sent.");
"No session ticket produced: " +
"no resumption secret");
}
return null;
}
@ -373,8 +402,10 @@ final class NewSessionTicket {
if (sessionTimeoutSeconds > MAX_TICKET_LIFETIME) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session timeout is too long. No ticket sent.");
"No session ticket produced: " +
"session timeout");
}
return null;
}
@ -386,7 +417,8 @@ final class NewSessionTicket {
sessionCopy.setPskIdentity(newId.getId());
// If a stateless ticket is allowed, attempt to make one
if (hc.handshakeSession.isStatelessable(hc)) {
if (hc.statelessResumption &&
hc.handshakeSession.isStatelessable()) {
nstm = new T13NewSessionTicketMessage(hc,
sessionTimeoutSeconds,
hc.sslContext.getSecureRandom(),
@ -398,19 +430,21 @@ final class NewSessionTicket {
} else {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Produced NewSessionTicket stateless " +
"handshake message", nstm);
"Produced NewSessionTicket stateless " +
"post-handshake message", nstm);
}
}
}
// If a session cache ticket is being used, make one
if (!hc.handshakeSession.isStatelessable(hc)) {
if (!hc.statelessResumption ||
!hc.handshakeSession.isStatelessable()) {
nstm = new T13NewSessionTicketMessage(hc, sessionTimeoutSeconds,
hc.sslContext.getSecureRandom(), nonceArr,
newId.getId());
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Produced NewSessionTicket handshake message",
"Produced NewSessionTicket post-handshake message",
nstm);
}
@ -427,11 +461,20 @@ final class NewSessionTicket {
// should never be null
nstm.write(hc.handshakeOutput);
hc.handshakeOutput.flush();
// See note on TransportContext.needHandshakeFinishedStatus.
//
// Reset the needHandshakeFinishedStatus flag. The delivery
// of this post-handshake message will indicate the FINISHED
// handshake status. It is not needed to have a follow-on
// SSLEngine.wrap() any longer.
if (hc.conContext.needHandshakeFinishedStatus) {
hc.conContext.needHandshakeFinishedStatus = false;
}
}
if (hc.negotiatedProtocol.useTLS13PlusSpec()) {
hc.conContext.finishPostHandshake();
}
// clean the post handshake context
hc.conContext.finishPostHandshake();
// The message has been delivered.
return null;
@ -483,7 +526,8 @@ final class NewSessionTicket {
new SessionTicketSpec().encrypt(shc, sessionCopy));
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Produced NewSessionTicket stateless handshake message", nstm);
"Produced NewSessionTicket stateless handshake message",
nstm);
}
// Output the handshake message.
@ -521,7 +565,7 @@ final class NewSessionTicket {
new T13NewSessionTicketMessage(hc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Consuming NewSessionTicket message", nstm);
"Consuming NewSessionTicket message", nstm);
}
SSLSessionContextImpl sessionCache = (SSLSessionContextImpl)
@ -532,8 +576,8 @@ final class NewSessionTicket {
nstm.ticketLifetime > MAX_TICKET_LIFETIME) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Discarding NewSessionTicket with lifetime "
+ nstm.ticketLifetime, nstm);
"Discarding NewSessionTicket with lifetime " +
nstm.ticketLifetime, nstm);
}
sessionCache.remove(hc.handshakeSession.getSessionId());
return;
@ -542,31 +586,29 @@ final class NewSessionTicket {
if (sessionCache.getSessionTimeout() > MAX_TICKET_LIFETIME) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session cache lifetime is too long. Discarding ticket.");
"Session cache lifetime is too long. " +
"Discarding ticket.");
}
return;
}
SSLSessionImpl sessionToSave = hc.conContext.conSession;
SecretKey psk = null;
if (hc.negotiatedProtocol.useTLS13PlusSpec()) {
SecretKey resumptionMasterSecret =
sessionToSave.getResumptionMasterSecret();
if (resumptionMasterSecret == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session has no resumption master secret." +
" Ignoring ticket.");
}
return;
SecretKey resumptionMasterSecret =
sessionToSave.getResumptionMasterSecret();
if (resumptionMasterSecret == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session has no resumption master secret. " +
"Ignoring ticket.");
}
// derive the PSK
psk = derivePreSharedKey(
sessionToSave.getSuite().hashAlg,
resumptionMasterSecret, nstm.getTicketNonce());
return;
}
// derive the PSK
SecretKey psk = derivePreSharedKey(
sessionToSave.getSuite().hashAlg,
resumptionMasterSecret, nstm.getTicketNonce());
// create and cache the new session
// The new session must be a child of the existing session so
// they will be invalidated together, etc.
@ -580,10 +622,8 @@ final class NewSessionTicket {
sessionCopy.setPskIdentity(nstm.ticket);
sessionCache.put(sessionCopy);
// clean handshake context
if (hc.negotiatedProtocol.useTLS13PlusSpec()) {
hc.conContext.finishPostHandshake();
}
// clean the post handshake context
hc.conContext.finishPostHandshake();
}
}
@ -615,8 +655,8 @@ final class NewSessionTicket {
nstm.ticketLifetime > MAX_TICKET_LIFETIME) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Discarding NewSessionTicket with lifetime "
+ nstm.ticketLifetime, nstm);
"Discarding NewSessionTicket with lifetime " +
nstm.ticketLifetime, nstm);
}
return;
}
@ -627,7 +667,8 @@ final class NewSessionTicket {
if (sessionCache.getSessionTimeout() > MAX_TICKET_LIFETIME) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Session cache lifetime is too long. Discarding ticket.");
"Session cache lifetime is too long. " +
"Discarding ticket.");
}
return;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
@ -164,6 +164,13 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
ByteBuffer[] srcs, int srcsOffset, int srcsLength,
ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {
// See note on TransportContext.needHandshakeFinishedStatus.
if (conContext.needHandshakeFinishedStatus) {
conContext.needHandshakeFinishedStatus = false;
return new SSLEngineResult(
Status.OK, HandshakeStatus.FINISHED, 0, 0);
}
// May need to deliver cached records.
if (isOutboundDone()) {
return new SSLEngineResult(
@ -418,7 +425,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
SSLLogger.finest("trigger NST");
}
conContext.conSession.updateNST = false;
NewSessionTicket.kickstartProducer.produce(
NewSessionTicket.t13PosthandshakeProducer.produce(
new PostHandshakeContext(conContext));
return conContext.getHandshakeStatus();
}

@ -27,13 +27,11 @@ package sun.security.ssl;
import sun.security.x509.X509CertImpl;
import java.io.IOException;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
@ -520,11 +518,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
// Some situations we cannot provide a stateless ticket, but after it
// has been negotiated
boolean isStatelessable(HandshakeContext hc) {
if (!hc.statelessResumption) {
return false;
}
boolean isStatelessable() {
// If there is no getMasterSecret with TLS1.2 or under, do not resume.
if (!protocolVersion.useTLS13PlusSpec() &&
getMasterSecret().getEncoded() == null) {
@ -534,6 +528,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
return false;
}
if (boundValues != null && boundValues.size() > 0) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.finest("There are boundValues, cannot make" +
@ -541,6 +536,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
return false;
}
return true;
}

@ -1537,7 +1537,7 @@ public final class SSLSocketImpl
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.finest("trigger new session ticket");
}
NewSessionTicket.kickstartProducer.produce(
NewSessionTicket.t13PosthandshakeProducer.produce(
new PostHandshakeContext(conContext));
}
}

@ -260,7 +260,8 @@ final class SessionTicketExtension {
public byte[] encrypt(HandshakeContext hc, SSLSessionImpl session) {
byte[] encrypted;
if (!hc.handshakeSession.isStatelessable(hc)) {
if (!hc.statelessResumption ||
!hc.handshakeSession.isStatelessable()) {
return new byte[0];
}

@ -64,6 +64,23 @@ final class TransportContext implements ConnectionContext {
Exception closeReason = null;
Exception delegatedThrown = null;
// For TLS 1.3 full handshake, the last handshake flight could be wrapped
// and encrypted in one record and delegated task would be used. There is
// no chance to return FINISHED handshake status with SSLEngine.(un)wrap().
// However, per the HandshakeStatus.FINISHED specification, this value is
// only generated by a call to SSLEngine.wrap()/unwrap() and it is never
// generated by SSLEngine.getHandshakeStatus().
//
// In order to workaround this case for TLS 1.3, the FINISHED status is
// present with SSLEngine.wrap() while delivering of the NewSessionTicket
// post-handshake message. If this post-handshake message is not needed,
// a follow-on SSLEngine.wrap() should be called to indicate the FINISHED
// handshake status. Although this special SSLEngine.wrap() should not
// consume or produce any application or network data.
boolean needHandshakeFinishedStatus = false;
boolean hasDelegatedFinished = false;
// negotiated security parameters
SSLSessionImpl conSession;
ProtocolVersion protocolVersion;
@ -589,6 +606,9 @@ final class TransportContext implements ConnectionContext {
// Special case that the inbound was closed, but outbound open.
return HandshakeStatus.NEED_WRAP;
} // Otherwise, both inbound and outbound are closed.
} else if (needHandshakeFinishedStatus) {
// Special case to get FINISHED status for TLS 1.3 full handshake.
return HandshakeStatus.NEED_WRAP;
}
return HandshakeStatus.NOT_HANDSHAKING;

@ -39,7 +39,7 @@ DEF_STATIC_JNI_OnLoad
* Get the AWT native structure.
* This function returns JNI_FALSE if an error occurs.
*/
JNIEXPORT jboolean JNICALL JAWT_GetAWT
_JNI_IMPORT_OR_EXPORT_ jboolean JNICALL JAWT_GetAWT
(JNIEnv* env, JAWT* awt)
{
if (awt == NULL) {

@ -37,7 +37,7 @@ DEF_STATIC_JNI_OnLoad
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
JNIEXPORT jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt)
_JNI_IMPORT_OR_EXPORT_ jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt)
{
#if defined(HEADLESS)
/* there are no AWT libs available at all */

@ -39,7 +39,7 @@ DEF_STATIC_JNI_OnLoad
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
extern "C" JNIEXPORT jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt)
extern "C" _JNI_IMPORT_OR_EXPORT_ jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt)
{
if (awt == NULL) {
return JNI_FALSE;

@ -506,18 +506,24 @@ public interface HttpResponse<T> {
* been completely written to the file, and {@link #body()} returns a
* reference to its {@link Path}.
*
* <p> Security manager permission checks are performed in this factory
* method, when the {@code BodyHandler} is created. Care must be taken
* that the {@code BodyHandler} is not shared with untrusted code.
* <p> In the case of the default file system provider, security manager
* permission checks are performed in this factory method, when the
* {@code BodyHandler} is created. Otherwise,
* {@linkplain FileChannel#open(Path, OpenOption...) permission checks}
* may be performed asynchronously against the caller's context
* at file access time.
* Care must be taken that the {@code BodyHandler} is not shared with
* untrusted code.
*
* @param file the file to store the body in
* @param openOptions any options to use when opening/creating the file
* @param file the file to store the body in
* @param openOptions any options to use when opening/creating the file
* @return a response body handler
* @throws IllegalArgumentException if an invalid set of open options
* are specified
* @throws SecurityException If a security manager has been installed
* and it denies {@linkplain SecurityManager#checkWrite(String)
* write access} to the file.
* are specified
* @throws SecurityException in the case of the default file system
* provider, and a security manager is installed,
* {@link SecurityManager#checkWrite(String) checkWrite}
* is invoked to check write access to the given file
*/
public static BodyHandler<Path> ofFile(Path file, OpenOption... openOptions) {
Objects.requireNonNull(file);
@ -535,15 +541,21 @@ public interface HttpResponse<T> {
*
* <p> Equivalent to: {@code ofFile(file, CREATE, WRITE)}
*
* <p> Security manager permission checks are performed in this factory
* method, when the {@code BodyHandler} is created. Care must be taken
* that the {@code BodyHandler} is not shared with untrusted code.
* <p> In the case of the default file system provider, security manager
* permission checks are performed in this factory method, when the
* {@code BodyHandler} is created. Otherwise,
* {@linkplain FileChannel#open(Path, OpenOption...) permission checks}
* may be performed asynchronously against the caller's context
* at file access time.
* Care must be taken that the {@code BodyHandler} is not shared with
* untrusted code.
*
* @param file the file to store the body in
* @param file the file to store the body in
* @return a response body handler
* @throws SecurityException If a security manager has been installed
* and it denies {@linkplain SecurityManager#checkWrite(String)
* write access} to the file.
* @throws SecurityException in the case of the default file system
* provider, and a security manager is installed,
* {@link SecurityManager#checkWrite(String) checkWrite}
* is invoked to check write access to the given file
*/
public static BodyHandler<Path> ofFile(Path file) {
return BodyHandlers.ofFile(file, CREATE, WRITE);
@ -570,20 +582,22 @@ public interface HttpResponse<T> {
* method, when the {@code BodyHandler} is created. Care must be taken
* that the {@code BodyHandler} is not shared with untrusted code.
*
* @param directory the directory to store the file in
* @param openOptions open options used when opening the file
* @param directory the directory to store the file in
* @param openOptions open options used when opening the file
* @return a response body handler
* @throws IllegalArgumentException if the given path does not exist,
* is not a directory, is not writable, or if an invalid set
* of open options are specified
* @throws SecurityException If a security manager has been installed
* and it denies
* {@linkplain SecurityManager#checkRead(String) read access}
* to the directory, or it denies
* {@linkplain SecurityManager#checkWrite(String) write access}
* to the directory, or it denies
* {@linkplain SecurityManager#checkWrite(String) write access}
* to the files within the directory.
* is not of the default file system, is not a directory,
* is not writable, or if an invalid set of open options
* are specified
* @throws SecurityException in the case of the default file system
* provider and a security manager has been installed,
* and it denies
* {@linkplain SecurityManager#checkRead(String) read access}
* to the directory, or it denies
* {@linkplain SecurityManager#checkWrite(String) write access}
* to the directory, or it denies
* {@linkplain SecurityManager#checkWrite(String) write access}
* to the files within the directory.
*/
public static BodyHandler<Path> ofFileDownload(Path directory,
OpenOption... openOptions) {
@ -1068,18 +1082,24 @@ public interface HttpResponse<T> {
* <p> The {@link HttpResponse} using this subscriber is available after
* the entire response has been read.
*
* <p> Security manager permission checks are performed in this factory
* method, when the {@code BodySubscriber} is created. Care must be taken
* that the {@code BodyHandler} is not shared with untrusted code.
* <p> In the case of the default file system provider, security manager
* permission checks are performed in this factory method, when the
* {@code BodySubscriber} is created. Otherwise,
* {@linkplain FileChannel#open(Path, OpenOption...) permission checks}
* may be performed asynchronously against the caller's context
* at file access time.
* Care must be taken that the {@code BodySubscriber} is not shared with
* untrusted code.
*
* @param file the file to store the body in
* @param openOptions the list of options to open the file with
* @param file the file to store the body in
* @param openOptions the list of options to open the file with
* @return a body subscriber
* @throws IllegalArgumentException if an invalid set of open options
* are specified
* @throws SecurityException if a security manager has been installed
* and it denies {@linkplain SecurityManager#checkWrite(String)
* write access} to the file
* are specified
* @throws SecurityException in the case of the default file system
* provider, and a security manager is installed,
* {@link SecurityManager#checkWrite(String) checkWrite}
* is invoked to check write access to the given file
*/
public static BodySubscriber<Path> ofFile(Path file, OpenOption... openOptions) {
Objects.requireNonNull(file);
@ -1097,15 +1117,21 @@ public interface HttpResponse<T> {
*
* <p> Equivalent to: {@code ofFile(file, CREATE, WRITE)}
*
* <p> Security manager permission checks are performed in this factory
* method, when the {@code BodySubscriber} is created. Care must be taken
* that the {@code BodyHandler} is not shared with untrusted code.
* <p> In the case of the default file system provider, security manager
* permission checks are performed in this factory method, when the
* {@code BodySubscriber} is created. Otherwise,
* {@linkplain FileChannel#open(Path, OpenOption...) permission checks}
* may be performed asynchronously against the caller's context
* at file access time.
* Care must be taken that the {@code BodySubscriber} is not shared with
* untrusted code.
*
* @param file the file to store the body in
* @param file the file to store the body in
* @return a body subscriber
* @throws SecurityException if a security manager has been installed
* and it denies {@linkplain SecurityManager#checkWrite(String)
* write access} to the file
* @throws SecurityException in the case of the default file system
* provider, and a security manager is installed,
* {@link SecurityManager#checkWrite(String) checkWrite}
* is invoked to check write access to the given file
*/
public static BodySubscriber<Path> ofFile(Path file) {
return ofFile(file, CREATE, WRITE);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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,11 +34,12 @@ import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandler;
@ -63,6 +64,7 @@ public final class ResponseBodyHandlers {
public static class PathBodyHandler implements BodyHandler<Path>{
private final Path file;
private final List<OpenOption> openOptions; // immutable list
private final AccessControlContext acc;
private final FilePermission filePermission;
/**
@ -77,25 +79,34 @@ public final class ResponseBodyHandlers {
FilePermission filePermission = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String fn = pathForSecurityCheck(file);
FilePermission writePermission = new FilePermission(fn, "write");
sm.checkPermission(writePermission);
filePermission = writePermission;
try {
String fn = pathForSecurityCheck(file);
FilePermission writePermission = new FilePermission(fn, "write");
sm.checkPermission(writePermission);
filePermission = writePermission;
} catch (UnsupportedOperationException ignored) {
// path not associated with the default file system provider
}
}
return new PathBodyHandler(file, openOptions, filePermission);
assert filePermission == null || filePermission.getActions().equals("write");
var acc = sm != null ? AccessController.getContext() : null;
return new PathBodyHandler(file, openOptions, acc, filePermission);
}
private PathBodyHandler(Path file,
List<OpenOption> openOptions,
AccessControlContext acc,
FilePermission filePermission) {
this.file = file;
this.openOptions = openOptions;
this.acc = acc;
this.filePermission = filePermission;
}
@Override
public BodySubscriber<Path> apply(ResponseInfo responseInfo) {
return new PathSubscriber(file, openOptions, filePermission);
return new PathSubscriber(file, openOptions, acc, filePermission);
}
}
@ -149,6 +160,7 @@ public final class ResponseBodyHandlers {
public static class FileDownloadBodyHandler implements BodyHandler<Path> {
private final Path directory;
private final List<OpenOption> openOptions;
private final AccessControlContext acc;
private final FilePermission[] filePermissions; // may be null
/**
@ -160,10 +172,17 @@ public final class ResponseBodyHandlers {
*/
public static FileDownloadBodyHandler create(Path directory,
List<OpenOption> openOptions) {
String fn;
try {
fn = pathForSecurityCheck(directory);
} catch (UnsupportedOperationException uoe) {
// directory not associated with the default file system provider
throw new IllegalArgumentException("invalid path: " + directory, uoe);
}
FilePermission filePermissions[] = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String fn = pathForSecurityCheck(directory);
FilePermission writePermission = new FilePermission(fn, "write");
String writePathPerm = fn + File.separatorChar + "*";
FilePermission writeInDirPermission = new FilePermission(writePathPerm, "write");
@ -184,15 +203,19 @@ public final class ResponseBodyHandlers {
if (!Files.isWritable(directory))
throw new IllegalArgumentException("non-writable directory: " + directory);
return new FileDownloadBodyHandler(directory, openOptions, filePermissions);
assert filePermissions == null || (filePermissions[0].getActions().equals("write")
&& filePermissions[1].getActions().equals("write"));
var acc = sm != null ? AccessController.getContext() : null;
return new FileDownloadBodyHandler(directory, openOptions, acc, filePermissions);
}
private FileDownloadBodyHandler(Path directory,
List<OpenOption> openOptions,
AccessControlContext acc,
FilePermission... filePermissions) {
this.directory = directory;
this.openOptions = openOptions;
this.acc = acc;
this.filePermissions = filePermissions;
}
@ -273,7 +296,7 @@ public final class ResponseBodyHandlers {
"Resulting file, " + file.toString() + ", outside of given directory");
}
return new PathSubscriber(file, openOptions, filePermissions);
return new PathSubscriber(file, openOptions, acc, filePermissions);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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,9 @@ import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@ -172,7 +174,9 @@ public class ResponseSubscribers {
private final Path file;
private final OpenOption[] options;
private final AccessControlContext acc;
private final FilePermission[] filePermissions;
private final boolean isDefaultFS;
private final CompletableFuture<Path> result = new MinimalFuture<>();
private final AtomicBoolean subscribed = new AtomicBoolean();
@ -192,25 +196,44 @@ public class ResponseSubscribers {
*/
public static PathSubscriber create(Path file,
List<OpenOption> options) {
FilePermission filePermission = null;
SecurityManager sm = System.getSecurityManager();
FilePermission filePermission = null;
if (sm != null) {
String fn = pathForSecurityCheck(file);
FilePermission writePermission = new FilePermission(fn, "write");
sm.checkPermission(writePermission);
filePermission = writePermission;
try {
String fn = pathForSecurityCheck(file);
FilePermission writePermission = new FilePermission(fn, "write");
sm.checkPermission(writePermission);
filePermission = writePermission;
} catch (UnsupportedOperationException ignored) {
// path not associated with the default file system provider
}
}
return new PathSubscriber(file, options, filePermission);
assert filePermission == null || filePermission.getActions().equals("write");
AccessControlContext acc = sm != null ? AccessController.getContext() : null;
return new PathSubscriber(file, options, acc, filePermission);
}
// pp so handler implementations in the same package can construct
/*package-private*/ PathSubscriber(Path file,
List<OpenOption> options,
AccessControlContext acc,
FilePermission... filePermissions) {
this.file = file;
this.options = options.stream().toArray(OpenOption[]::new);
this.filePermissions =
filePermissions == null ? EMPTY_FILE_PERMISSIONS : filePermissions;
this.acc = acc;
this.filePermissions = filePermissions == null || filePermissions[0] == null
? EMPTY_FILE_PERMISSIONS : filePermissions;
this.isDefaultFS = isDefaultFS(file);
}
private static boolean isDefaultFS(Path file) {
try {
file.toFile();
return true;
} catch (UnsupportedOperationException uoe) {
return false;
}
}
@Override
@ -222,23 +245,30 @@ public class ResponseSubscribers {
}
this.subscription = subscription;
if (System.getSecurityManager() == null) {
if (acc == null) {
try {
out = FileChannel.open(file, options);
} catch (IOException ioe) {
result.completeExceptionally(ioe);
subscription.cancel();
return;
}
} else {
try {
PrivilegedExceptionAction<FileChannel> pa =
() -> FileChannel.open(file, options);
out = AccessController.doPrivileged(pa, null, filePermissions);
out = isDefaultFS
? AccessController.doPrivileged(pa, acc, filePermissions)
: AccessController.doPrivileged(pa, acc);
} catch (PrivilegedActionException pae) {
Throwable t = pae.getCause() != null ? pae.getCause() : pae;
result.completeExceptionally(t);
subscription.cancel();
return;
} catch (Exception e) {
result.completeExceptionally(e);
subscription.cancel();
return;
}
}
subscription.request(1);
@ -249,7 +279,7 @@ public class ResponseSubscribers {
try {
out.write(items.toArray(Utils.EMPTY_BB_ARRAY));
} catch (IOException ex) {
Utils.close(out);
close();
subscription.cancel();
result.completeExceptionally(ex);
}
@ -259,12 +289,12 @@ public class ResponseSubscribers {
@Override
public void onError(Throwable e) {
result.completeExceptionally(e);
Utils.close(out);
close();
}
@Override
public void onComplete() {
Utils.close(out);
close();
result.complete(file);
}
@ -272,6 +302,22 @@ public class ResponseSubscribers {
public CompletionStage<Path> getBody() {
return result;
}
private void close() {
if (acc == null) {
Utils.close(out);
} else {
PrivilegedAction<Void> pa = () -> {
Utils.close(out);
return null;
};
if (isDefaultFS) {
AccessController.doPrivileged(pa, acc, filePermissions);
} else {
AccessController.doPrivileged(pa, acc);
}
}
}
}
public static class ByteArraySubscriber<T> implements TrustedSubscriber<T> {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020, 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 @@ import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaCompiler.CompilationTask;
@ -152,6 +153,21 @@ public abstract class DocTrees extends Trees {
*/
public abstract Element getElement(DocTreePath path);
/**
* Returns the language model type referred to by the leaf node of the given
* {@link DocTreePath}, or {@code null} if unknown. This method usually
* returns the same value as {@code getElement(path).asType()} for a
* {@code path} argument for which {@link #getElement(DocTreePath)} returns
* a non-null value, but may return a type that includes additional
* information, such as a parameterized generic type instead of a raw type.
*
* @param path the path for the tree node
* @return the referenced type, or null
*
* @since 15
*/
public abstract TypeMirror getType(DocTreePath path);
/**
* Returns the list of {@link DocTree} representing the first sentence of
* a comment.

@ -915,14 +915,9 @@ public class Checker extends DocTreePathScanner<Void, Void> {
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitReference(ReferenceTree tree, Void ignore) {
String sig = tree.getSignature();
if (sig.contains("<") || sig.contains(">")) {
env.messages.error(REFERENCE, tree, "dc.type.arg.not.allowed");
} else {
Element e = env.trees.getElement(getCurrentPath());
if (e == null)
env.messages.error(REFERENCE, tree, "dc.ref.not.found");
}
Element e = env.trees.getElement(getCurrentPath());
if (e == null)
env.messages.error(REFERENCE, tree, "dc.ref.not.found");
return super.visitReference(tree, ignore);
}

@ -80,7 +80,6 @@ dc.tag.start.unmatched = end tag missing: </{0}>
dc.tag.unknown = unknown tag: {0}
dc.tag.not.supported = tag not supported in the generated HTML version: {0}
dc.text.not.allowed = text not allowed in <{0}> element
dc.type.arg.not.allowed = type arguments not allowed here
dc.unexpected.comment=documentation comment not expected here
dc.value.not.allowed.here='{@value}' not allowed here
dc.value.not.a.constant=value does not refer to a constant

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2020, 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
@ -431,6 +431,31 @@ public class JavacTrees extends DocTrees {
return null;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public TypeMirror getType(DocTreePath path) {
DocTree tree = path.getLeaf();
if (tree instanceof DCReference) {
JCTree qexpr = ((DCReference)tree).qualifierExpression;
if (qexpr != null) {
Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
new Log.DeferredDiagnosticHandler(log);
try {
Env<AttrContext> env = getAttrContext(path.getTreePath());
Type t = attr.attribType(((DCReference) tree).qualifierExpression, env);
if (t != null && !t.isErroneous()) {
return t;
}
} catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
return null;
} finally {
log.popDiagnosticHandler(deferredDiagnosticHandler);
}
}
}
Element e = getElement(path);
return e == null ? null : e.asType();
}
@Override @DefinedBy(Api.COMPILER_TREE)
public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
return docTreeMaker.getFirstSentence(list);
@ -721,78 +746,15 @@ public class JavacTrees extends DocTrees {
if (method.params().size() != paramTypes.size())
return false;
List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes();
List<Type> methodParamTypes = method.asType().getParameterTypes();
if (!Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) {
return true;
}
return (Type.isErroneous(paramTypes))
? fuzzyMatch(paramTypes, methodParamTypes)
: types.isSameTypes(paramTypes, methodParamTypes);
methodParamTypes = types.erasureRecursive(methodParamTypes);
return types.isSameTypes(paramTypes, methodParamTypes);
}
boolean fuzzyMatch(List<Type> paramTypes, List<Type> methodParamTypes) {
List<Type> l1 = paramTypes;
List<Type> l2 = methodParamTypes;
while (l1.nonEmpty()) {
if (!fuzzyMatch(l1.head, l2.head))
return false;
l1 = l1.tail;
l2 = l2.tail;
}
return true;
}
boolean fuzzyMatch(Type paramType, Type methodParamType) {
Boolean b = fuzzyMatcher.visit(paramType, methodParamType);
return (b == Boolean.TRUE);
}
TypeRelation fuzzyMatcher = new TypeRelation() {
@Override
public Boolean visitType(Type t, Type s) {
if (t == s)
return true;
if (s.isPartial())
return visit(s, t);
switch (t.getTag()) {
case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
return t.hasTag(s.getTag());
default:
throw new AssertionError("fuzzyMatcher " + t.getTag());
}
}
@Override
public Boolean visitArrayType(ArrayType t, Type s) {
if (t == s)
return true;
if (s.isPartial())
return visit(s, t);
return s.hasTag(ARRAY)
&& visit(t.elemtype, types.elemtype(s));
}
@Override
public Boolean visitClassType(ClassType t, Type s) {
if (t == s)
return true;
if (s.isPartial())
return visit(s, t);
return t.tsym == s.tsym;
}
@Override
public Boolean visitErrorType(ErrorType t, Type s) {
return s.hasTag(CLASS)
&& t.tsym.name == ((ClassType) s).tsym.name;
}
};
@Override @DefinedBy(Api.COMPILER_TREE)
public TypeMirror getTypeMirror(TreePath path) {
Tree t = path.getLeaf();

@ -26,6 +26,8 @@
package jdk.internal.foreign;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemoryLayouts;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.SequenceLayout;
import jdk.internal.access.JavaNioAccess;
@ -68,14 +70,12 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
final long length;
final int mask;
final Thread owner;
final MemoryScope scope;
@ForceInline
AbstractMemorySegmentImpl(long length, int mask, Thread owner, MemoryScope scope) {
AbstractMemorySegmentImpl(long length, int mask, MemoryScope scope) {
this.length = length;
this.mask = mask;
this.owner = owner;
this.scope = scope;
}
@ -83,7 +83,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
abstract Object base();
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope);
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope);
abstract ByteBuffer makeByteBuffer();
@ -100,7 +100,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
}
private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) {
return dup(offset, newSize, mask, owner, scope);
return dup(offset, newSize, mask, scope);
}
@SuppressWarnings("unchecked")
@ -145,12 +145,12 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
@Override
public final boolean isAlive() {
return scope.isAliveThreadSafe();
return scope.isAlive();
}
@Override
public Thread ownerThread() {
return owner;
return scope.ownerThread();
}
@Override
@ -159,7 +159,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
if ((~accessModes() & accessModes) != 0) {
throw new IllegalArgumentException("Cannot acquire more access modes");
}
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, owner, scope);
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, scope);
}
@Override
@ -177,17 +177,16 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
@Override
public MemorySegment withOwnerThread(Thread newOwner) {
Objects.requireNonNull(newOwner);
checkValidState();
if (!isSet(HANDOFF)) {
throw unsupportedAccessMode(HANDOFF);
}
if (owner == newOwner) {
if (scope.ownerThread() == newOwner) {
throw new IllegalArgumentException("Segment already owned by thread: " + newOwner);
} else {
try {
return dup(0L, length, mask, newOwner, scope.dup());
return dup(0L, length, mask, scope.dup(newOwner));
} finally {
//flush read/writes to memory before returning the new segment
//flush read/writes to segment memory before returning the new segment
VarHandle.fullFence();
}
}
@ -198,19 +197,18 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
if (!isSet(CLOSE)) {
throw unsupportedAccessMode(CLOSE);
}
checkValidState();
closeNoCheck();
}
private final void closeNoCheck() {
scope.close(true);
scope.close();
}
final AbstractMemorySegmentImpl acquire() {
if (Thread.currentThread() != ownerThread() && !isSet(ACQUIRE)) {
throw unsupportedAccessMode(ACQUIRE);
}
return dup(0, length, mask, Thread.currentThread(), scope.acquire());
return dup(0, length, mask, scope.acquire());
}
@Override
@ -227,7 +225,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
}
void checkRange(long offset, long length, boolean writeAccess) {
checkValidState();
scope.checkValidState();
if (writeAccess && !isSet(WRITE)) {
throw unsupportedAccessMode(WRITE);
} else if (!writeAccess && !isSet(READ)) {
@ -238,10 +236,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
@Override
public final void checkValidState() {
if (owner != null && owner != Thread.currentThread()) {
throw new IllegalStateException("Attempt to access segment outside owning thread");
}
scope.checkAliveConfined();
scope.checkValidState();
}
// Helper methods
@ -415,29 +410,28 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
AbstractMemorySegmentImpl bufferSegment = (AbstractMemorySegmentImpl)nioAccess.bufferSegment(bb);
final MemoryScope bufferScope;
int modes;
final Thread owner;
if (bufferSegment != null) {
bufferScope = bufferSegment.scope;
modes = bufferSegment.mask;
owner = bufferSegment.owner;
} else {
bufferScope = new MemoryScope(bb, null);
bufferScope = MemoryScope.create(bb, null);
modes = defaultAccessModes(size);
owner = Thread.currentThread();
}
if (bb.isReadOnly()) {
modes &= ~WRITE;
}
if (base != null) {
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, owner, bufferScope);
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, bufferScope);
} else if (unmapper == null) {
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, owner, bufferScope);
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, bufferScope);
} else {
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, owner, bufferScope);
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, bufferScope);
}
}
public static AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl(0, 0, null, MemoryScope.GLOBAL) {
public static final AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl(
0, 0, MemoryScope.createUnchecked(null, null, null)
) {
@Override
ByteBuffer makeByteBuffer() {
throw new UnsupportedOperationException();
@ -454,7 +448,7 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
}
@Override
AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) {
throw new UnsupportedOperationException();
}
};

@ -52,8 +52,8 @@ public class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl {
final Supplier<H> baseProvider;
@ForceInline
HeapMemorySegmentImpl(long offset, Supplier<H> baseProvider, long length, int mask, Thread owner, MemoryScope scope) {
super(length, mask, owner, scope);
HeapMemorySegmentImpl(long offset, Supplier<H> baseProvider, long length, int mask, MemoryScope scope) {
super(length, mask, scope);
this.offset = offset;
this.baseProvider = baseProvider;
}
@ -69,8 +69,8 @@ public class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl {
}
@Override
HeapMemorySegmentImpl<H> dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
return new HeapMemorySegmentImpl<H>(this.offset + offset, baseProvider, size, mask, owner, scope);
HeapMemorySegmentImpl<H> dup(long offset, long size, int mask, MemoryScope scope) {
return new HeapMemorySegmentImpl<>(this.offset + offset, baseProvider, size, mask, scope);
}
@Override
@ -121,7 +121,7 @@ public class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl {
static <Z> HeapMemorySegmentImpl<Z> makeHeapSegment(Supplier<Z> obj, int length, int base, int scale) {
int byteSize = length * scale;
MemoryScope scope = new MemoryScope(null, null);
return new HeapMemorySegmentImpl<>(base, obj, byteSize, defaultAccessModes(byteSize), Thread.currentThread(), scope);
MemoryScope scope = MemoryScope.create(null, null);
return new HeapMemorySegmentImpl<>(base, obj, byteSize, defaultAccessModes(byteSize), scope);
}
}

@ -48,8 +48,8 @@ public class MappedMemorySegmentImpl extends NativeMemorySegmentImpl implements
private final UnmapperProxy unmapper;
MappedMemorySegmentImpl(long min, UnmapperProxy unmapper, long length, int mask, Thread owner, MemoryScope scope) {
super(min, length, mask, owner, scope);
MappedMemorySegmentImpl(long min, UnmapperProxy unmapper, long length, int mask, MemoryScope scope) {
super(min, length, mask, scope);
this.unmapper = unmapper;
}
@ -60,8 +60,8 @@ public class MappedMemorySegmentImpl extends NativeMemorySegmentImpl implements
}
@Override
MappedMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
return new MappedMemorySegmentImpl(min + offset, unmapper, size, mask, owner, scope);
MappedMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) {
return new MappedMemorySegmentImpl(min + offset, unmapper, size, mask, scope);
}
// mapped segment methods
@ -103,13 +103,13 @@ public class MappedMemorySegmentImpl extends NativeMemorySegmentImpl implements
if (bytesSize <= 0) throw new IllegalArgumentException("Requested bytes size must be > 0.");
try (FileChannelImpl channelImpl = (FileChannelImpl)FileChannel.open(path, openOptions(mapMode))) {
UnmapperProxy unmapperProxy = channelImpl.mapInternal(mapMode, 0L, bytesSize);
MemoryScope scope = new MemoryScope(null, unmapperProxy::unmap);
MemoryScope scope = MemoryScope.create(null, unmapperProxy::unmap);
int modes = defaultAccessModes(bytesSize);
if (mapMode == FileChannel.MapMode.READ_ONLY) {
modes &= ~WRITE;
}
return new MappedMemorySegmentImpl(unmapperProxy.address(), unmapperProxy, bytesSize,
modes, Thread.currentThread(), scope);
modes, scope);
}
}

@ -26,101 +26,287 @@
package jdk.internal.foreign;
import jdk.internal.vm.annotation.ForceInline;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Objects;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.StampedLock;
/**
* This class manages the temporal bounds associated with a memory segment. A scope has a liveness bit, which is updated
* when the scope is closed (this operation is triggered by {@link AbstractMemorySegmentImpl#close()}). Furthermore, a scope is
* associated with an <em>atomic</em> counter which can be incremented (upon calling the {@link #acquire()} method),
* and is decremented (when a previously acquired segment is later closed).
* This class manages the temporal bounds associated with a memory segment as well
* as thread confinement.
* A scope has a liveness bit, which is updated when the scope is closed
* (this operation is triggered by {@link AbstractMemorySegmentImpl#close()}).
* A scope may also have an associated "owner" thread that confines some operations to
* associated owner thread such as {@link #close()} or {@link #dup(Thread)}.
* Furthermore, a scope is either root scope ({@link #create(Object, Runnable) created}
* when memory segment is allocated) or child scope ({@link #acquire() acquired} from root scope).
* When a child scope is acquired from another child scope, it is actually acquired from
* the root scope. There is only a single level of children. All child scopes are peers.
* A child scope can be {@link #close() closed} at any time, but root scope can only
* be closed after all its children have been closed, at which time any associated
* cleanup action is executed (the associated memory segment is freed).
* Besides thread-confined checked scopes, {@linkplain #createUnchecked(Thread, Object, Runnable)}
* method may be used passing {@code null} as the "owner" thread to create a
* scope that doesn't check for thread-confinement while its temporal bounds are
* enforced reliably only under condition that thread that closes the scope is also
* the single thread performing the checked access or there is an external synchronization
* in place that prevents concurrent access and closing of the scope.
*/
public final class MemoryScope {
abstract class MemoryScope {
//reference to keep hold onto
final Object ref;
/**
* Creates a root MemoryScope with given ref, cleanupAction and current
* thread as the "owner" thread.
* This method may be called in any thread.
* The returned instance may be published unsafely to and used in any thread,
* but methods that explicitly state that they may only be called in "owner" thread,
* must strictly be called in the thread that created the scope
* or else IllegalStateException is thrown.
*
* @param ref an optional reference to an instance that needs to be kept reachable
* @param cleanupAction an optional cleanup action to be executed when returned scope is closed
* @return a root MemoryScope
*/
static MemoryScope create(Object ref, Runnable cleanupAction) {
return new Root(Thread.currentThread(), ref, cleanupAction);
}
int activeCount = UNACQUIRED;
/**
* Creates a root MemoryScope with given ref, cleanupAction and "owner" thread.
* This method may be called in any thread.
* The returned instance may be published unsafely to and used in any thread,
* but methods that explicitly state that they may only be called in "owner" thread,
* must strictly be called in given owner thread or else IllegalStateException is thrown.
* If given owner thread is null, the returned MemoryScope is unchecked, meaning
* that all methods may be called in any thread and that {@link #checkValidState()}
* does not check for temporal bounds.
*
* @param owner the desired owner thread. If {@code owner == null},
* the returned scope is <em>not</em> thread-confined and not checked.
* @param ref an optional reference to an instance that needs to be kept reachable
* @param cleanupAction an optional cleanup action to be executed when returned scope is closed
* @return a root MemoryScope
*/
static MemoryScope createUnchecked(Thread owner, Object ref, Runnable cleanupAction) {
return new Root(owner, ref, cleanupAction);
}
final static VarHandle COUNT_HANDLE;
private final Thread owner;
private boolean closed; // = false
private static final VarHandle CLOSED;
static {
try {
COUNT_HANDLE = MethodHandles.lookup().findVarHandle(MemoryScope.class, "activeCount", int.class);
CLOSED = MethodHandles.lookup().findVarHandle(MemoryScope.class, "closed", boolean.class);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
final static int UNACQUIRED = 0;
final static int CLOSED = -1;
final static int MAX_ACQUIRE = Integer.MAX_VALUE;
final Runnable cleanupAction;
final static MemoryScope GLOBAL = new MemoryScope(null, null);
public MemoryScope(Object ref, Runnable cleanupAction) {
this.ref = ref;
this.cleanupAction = cleanupAction;
private MemoryScope(Thread owner) {
this.owner = owner;
}
/**
* This method performs a full, thread-safe liveness check; can be used outside confinement thread.
* Acquires a child scope (or peer scope if this is a child) with current
* thread as the "owner" thread.
* This method may be called in any thread.
* The returned instance may be published unsafely to and used in any thread,
* but methods that explicitly state that they may only be called in "owner" thread,
* must strictly be called in the thread that acquired the scope
* or else IllegalStateException is thrown.
*
* @return a child (or peer) scope
* @throws IllegalStateException if root scope is already closed
*/
final boolean isAliveThreadSafe() {
return ((int)COUNT_HANDLE.getVolatile(this)) != CLOSED;
abstract MemoryScope acquire();
/**
* Closes this scope, executing any cleanup action if this is the root scope.
* This method may only be called in the "owner" thread of this scope unless the
* scope is a root scope with no owner thread - i.e. is not checked.
*
* @throws IllegalStateException if this scope is already closed or if this is
* a root scope and there is/are still active child
* scope(s) or if this method is called outside of
* owner thread in checked scope
*/
abstract void close();
/**
* Duplicates this scope with given new "owner" thread and {@link #close() closes} it.
* If this is a root scope, a new root scope is returned; this root scope is closed, but
* without executing the cleanup action, which is instead transferred to the duped scope.
* If this is a child scope, a new child scope is returned.
* This method may only be called in the "owner" thread of this scope unless the
* scope is a root scope with no owner thread - i.e. is not checked.
* The returned instance may be published unsafely to and used in any thread,
* but methods that explicitly state that they may only be called in "owner" thread,
* must strictly be called in given new "owner" thread
* or else IllegalStateException is thrown.
*
* @param newOwner new owner thread of the returned MemoryScope
* @return a duplicate of this scope
* @throws NullPointerException if given owner thread is null
* @throws IllegalStateException if this scope is already closed or if this is
* a root scope and there is/are still active child
* scope(s) or if this method is called outside of
* owner thread in checked scope
*/
abstract MemoryScope dup(Thread newOwner);
/**
* Returns "owner" thread of this scope.
*
* @return owner thread (or null for unchecked scope)
*/
final Thread ownerThread() {
return owner;
}
/**
* This method performs a quick liveness check; must be called from the confinement thread.
* This method may be called in any thread.
*
* @return {@code true} if this scope is not closed yet.
*/
final void checkAliveConfined() {
if (activeCount == CLOSED) {
throw new IllegalStateException("Segment is not alive");
final boolean isAlive() {
return !((boolean)CLOSED.getVolatile(this));
}
/**
* Checks that this scope is still alive and that this method is executed
* in the "owner" thread of this scope or this scope is unchecked (not associated
* with owner thread).
*
* @throws IllegalStateException if this scope is already closed or this
* method is executed outside owning thread
* in checked scope
*/
@ForceInline
final void checkValidState() {
if (owner != null && owner != Thread.currentThread()) {
throw new IllegalStateException("Attempted access outside owning thread");
}
checkAliveConfined(this);
}
/**
* Checks that this scope is still alive.
*
* @throws IllegalStateException if this scope is already closed
*/
@ForceInline
private static void checkAliveConfined(MemoryScope scope) {
if (scope.closed) {
throw new IllegalStateException("This segment is already closed");
}
}
MemoryScope acquire() {
int value;
do {
value = (int)COUNT_HANDLE.getVolatile(this);
if (value == CLOSED) {
//segment is not alive!
throw new IllegalStateException("Segment is not alive");
} else if (value == MAX_ACQUIRE) {
//overflow
throw new IllegalStateException("Segment acquire limit exceeded");
private static final class Root extends MemoryScope {
private final StampedLock lock = new StampedLock();
private final LongAdder acquired = new LongAdder();
private final Object ref;
private final Runnable cleanupAction;
private Root(Thread owner, Object ref, Runnable cleanupAction) {
super(owner);
this.ref = ref;
this.cleanupAction = cleanupAction;
}
@Override
MemoryScope acquire() {
// try to optimistically acquire the lock
long stamp = lock.tryOptimisticRead();
try {
for (; ; stamp = lock.readLock()) {
if (stamp == 0L)
continue;
checkAliveConfined(this); // plain read is enough here (either successful optimistic read, or full read lock)
// increment acquires
acquired.increment();
// did a call to close() occur since we acquired the lock?
if (lock.validate(stamp)) {
// no, just return the acquired scope
return new Child(Thread.currentThread());
} else {
// yes, just back off and retry (close might have failed, after all)
acquired.decrement();
}
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
lock.unlockRead(stamp);
}
} while (!COUNT_HANDLE.compareAndSet(this, value, value + 1));
return new MemoryScope(ref, this::release);
}
}
private void release() {
int value;
do {
value = (int)COUNT_HANDLE.getVolatile(this);
if (value <= UNACQUIRED) {
//cannot get here - we can't close segment twice
throw new IllegalStateException();
@Override
MemoryScope dup(Thread newOwner) {
Objects.requireNonNull(newOwner, "newOwner");
// pre-allocate duped scope so we don't get OOME later and be left with this scope closed
var duped = new Root(newOwner, ref, cleanupAction);
justClose();
return duped;
}
@Override
void close() {
justClose();
if (cleanupAction != null) {
cleanupAction.run();
}
} while (!COUNT_HANDLE.compareAndSet(this, value, value - 1));
}
void close(boolean doCleanup) {
if (!COUNT_HANDLE.compareAndSet(this, UNACQUIRED, CLOSED)) {
//first check if already closed...
checkAliveConfined();
//...if not, then we have acquired views that are still active
throw new IllegalStateException("Cannot close a segment that has active acquired views");
}
if (doCleanup && cleanupAction != null) {
cleanupAction.run();
}
}
MemoryScope dup() {
close(false);
return new MemoryScope(ref, cleanupAction);
@ForceInline
private void justClose() {
// enter critical section - no acquires are possible past this point
long stamp = lock.writeLock();
try {
checkValidState(); // plain read is enough here (full write lock)
// check for absence of active acquired children
if (acquired.sum() > 0) {
throw new IllegalStateException("Cannot close this scope as it has active acquired children");
}
// now that we made sure there's no active acquired children, we can mark scope as closed
CLOSED.set(this, true); // plain write is enough here (full write lock)
} finally {
// leave critical section
lock.unlockWrite(stamp);
}
}
private final class Child extends MemoryScope {
private Child(Thread owner) {
super(owner);
}
@Override
MemoryScope acquire() {
return Root.this.acquire();
}
@Override
MemoryScope dup(Thread newOwner) {
checkValidState(); // child scope is always checked
// pre-allocate duped scope so we don't get OOME later and be left with this scope closed
var duped = new Child(newOwner);
CLOSED.setVolatile(this, true);
return duped;
}
@Override
void close() {
checkValidState(); // child scope is always checked
CLOSED.set(this, true);
// following acts as a volatile write after plain write above so
// plain write gets flushed too (which is important for isAliveThreadSafe())
Root.this.acquired.decrement();
}
}
}
}

@ -53,14 +53,14 @@ public class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl {
final long min;
@ForceInline
NativeMemorySegmentImpl(long min, long length, int mask, Thread owner, MemoryScope scope) {
super(length, mask, owner, scope);
NativeMemorySegmentImpl(long min, long length, int mask, MemoryScope scope) {
super(length, mask, scope);
this.min = min;
}
@Override
NativeMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
return new NativeMemorySegmentImpl(min + offset, size, mask, owner, scope);
NativeMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) {
return new NativeMemorySegmentImpl(min + offset, size, mask, scope);
}
@Override
@ -93,9 +93,9 @@ public class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl {
unsafe.setMemory(buf, alignedSize, (byte)0);
}
long alignedBuf = Utils.alignUp(buf, alignmentBytes);
MemoryScope scope = new MemoryScope(null, () -> unsafe.freeMemory(buf));
MemorySegment segment = new NativeMemorySegmentImpl(buf, alignedSize, defaultAccessModes(alignedSize),
Thread.currentThread(), scope);
MemoryScope scope = MemoryScope.create(null, () -> unsafe.freeMemory(buf));
MemorySegment segment = new NativeMemorySegmentImpl(buf, alignedSize,
defaultAccessModes(alignedSize), scope);
if (alignedSize != bytesSize) {
long delta = alignedBuf - buf;
segment = segment.asSlice(delta, bytesSize);
@ -104,7 +104,7 @@ public class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl {
}
public static MemorySegment makeNativeSegmentUnchecked(MemoryAddress min, long bytesSize, Thread owner, Runnable cleanup, Object attachment) {
MemoryScope scope = new MemoryScope(attachment, cleanup);
return new NativeMemorySegmentImpl(min.toRawLongValue(), bytesSize, defaultAccessModes(bytesSize), owner, scope);
MemoryScope scope = MemoryScope.createUnchecked(owner, attachment, cleanup);
return new NativeMemorySegmentImpl(min.toRawLongValue(), bytesSize, defaultAccessModes(bytesSize), scope);
}
}

@ -0,0 +1,56 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.incubator.jpackage.internal;
import java.math.BigInteger;
final class CFBundleVersion {
/**
* Parse the given string as OSX CFBundleVersion.
* CFBundleVersion (String - iOS, OS X) specifies the build version number of
* the bundle, which identifies an iteration (released or unreleased) of the
* bundle. The build version number should be a string comprised of at most three
* non-negative, period-separated integers with the first integer being greater
* than zero.
* @throws IllegalArgumentException
*/
static DottedVersion of(String value) {
DottedVersion ver = new DottedVersion(value);
BigInteger[] components = ver.getComponents();
if (components.length > 3) {
throw new IllegalArgumentException(I18N.getString(
"message.version-string-too-many-components"));
}
if (BigInteger.ZERO.equals(components[0])) {
throw new IllegalArgumentException(I18N.getString(
"message.version-string-first-number-not-zero"));
}
return ver;
}
}

@ -1,96 +0,0 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.incubator.jpackage.internal;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* EnumeratedBundlerParams<T>
*
* Contains key-value pairs (elements) where keys are "displayable"
* keys which the IDE can display/choose and values are "identifier" values
* which can be stored in parameters' map.
*
* For instance the Mac has a predefined set of categories which can be applied
* to LSApplicationCategoryType which is required for the mac app store.
*
* The following example illustrates a simple usage of
* the MAC_CATEGORY parameter:
*
* <pre>{@code
* Set<String> keys = MAC_CATEGORY.getDisplayableKeys();
*
* String key = getLastValue(keys); // get last value for example
*
* String value = MAC_CATEGORY.getValueForDisplayableKey(key);
* params.put(MAC_CATEGORY.getID(), value);
* }</pre>
*
*/
class EnumeratedBundlerParam<T> extends BundlerParamInfo<T> {
// Not sure if this is the correct order, my idea is that from IDE
// perspective the string to display to the user is the key and then the
// value is some type of object (although probably a String in most cases)
private final Map<String, T> elements;
private final boolean strict;
EnumeratedBundlerParam(String id, Class<T> valueType,
Function<Map<String, ? super Object>, T> defaultValueFunction,
BiFunction<String, Map<String, ? super Object>, T> stringConverter,
Map<String, T> elements, boolean strict) {
this.id = id;
this.valueType = valueType;
this.defaultValueFunction = defaultValueFunction;
this.stringConverter = stringConverter;
this.elements = elements;
this.strict = strict;
}
boolean isInPossibleValues(T value) {
return elements.values().contains(value);
}
// Having the displayable values as the keys seems a bit wacky
Set<String> getDisplayableKeys() {
return Collections.unmodifiableSet(elements.keySet());
}
// mapping from a "displayable" key to an "identifier" value.
T getValueForDisplayableKey(String displayableKey) {
return elements.get(displayableKey);
}
boolean isStrict() {
return strict;
}
boolean isLoose() {
return !isStrict();
}
}

@ -51,20 +51,6 @@ public class MacAppBundler extends AbstractImageBundler {
params -> null,
(s, p) -> s);
public static final BundlerParamInfo<String> MAC_CF_BUNDLE_VERSION =
new StandardBundlerParam<>(
"mac.CFBundleVersion",
String.class,
p -> {
String s = VERSION.fetchFrom(p);
if (validCFBundleVersion(s)) {
return s;
} else {
return "100";
}
},
(s, p) -> s);
public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON =
new StandardBundlerParam<>(
".mac.default.icns",
@ -99,60 +85,18 @@ public class MacAppBundler extends AbstractImageBundler {
new StandardBundlerParam<>(
Arguments.CLIOptions.MAC_BUNDLE_SIGNING_PREFIX.getId(),
String.class,
params -> IDENTIFIER.fetchFrom(params) + ".",
params -> getIdentifier(params) + ".",
(s, p) -> s);
public static boolean validCFBundleVersion(String v) {
// CFBundleVersion (String - iOS, OS X) specifies the build version
// number of the bundle, which identifies an iteration (released or
// unreleased) of the bundle. The build version number should be a
// string comprised of three non-negative, period-separated integers
// with the first integer being greater than zero. The string should
// only contain numeric (0-9) and period (.) characters. Leading zeros
// are truncated from each integer and will be ignored (that is,
// 1.02.3 is equivalent to 1.2.3). This key is not localizable.
static String getIdentifier(Map<String, ? super Object> params) {
String s = MAIN_CLASS.fetchFrom(params);
if (s == null) return null;
if (v == null) {
return false;
int idx = s.lastIndexOf(".");
if (idx >= 1) {
return s.substring(0, idx);
}
String p[] = v.split("\\.");
if (p.length > 3 || p.length < 1) {
Log.verbose(I18N.getString(
"message.version-string-too-many-components"));
return false;
}
try {
BigInteger n = new BigInteger(p[0]);
if (BigInteger.ONE.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-first-number-not-zero"));
return false;
}
if (p.length > 1) {
n = new BigInteger(p[1]);
if (BigInteger.ZERO.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-no-negative-numbers"));
return false;
}
}
if (p.length > 2) {
n = new BigInteger(p[2]);
if (BigInteger.ZERO.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-no-negative-numbers"));
return false;
}
}
} catch (NumberFormatException ne) {
Log.verbose(I18N.getString("message.version-string-numbers-only"));
Log.verbose(ne);
return false;
}
return true;
return s;
}
@Override
@ -179,10 +123,12 @@ public class MacAppBundler extends AbstractImageBundler {
}
// validate short version
if (!validCFBundleVersion(MAC_CF_BUNDLE_VERSION.fetchFrom(params))) {
throw new ConfigException(
I18N.getString("error.invalid-cfbundle-version"),
I18N.getString("error.invalid-cfbundle-version.advice"));
try {
String version = VERSION.fetchFrom(params);
CFBundleVersion.of(version);
} catch (IllegalArgumentException ex) {
throw new ConfigException(ex.getMessage(), I18N.getString(
"error.invalid-cfbundle-version.advice"), ex);
}
// reject explicitly set sign to true and no valid signature key

@ -110,29 +110,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
return identifier;
}
identifier = IDENTIFIER.fetchFrom(params);
if (identifier != null) {
return identifier;
}
// the IDENTIFIER (above) will default to derive from
// the main-class, in case there is no main-class
// (such as runtime installer) revert to the name.
// any of these could be invalid, so check later.
return APP_NAME.fetchFrom(params);
},
(s, p) -> s);
public static final BundlerParamInfo<String> MAC_CF_BUNDLE_VERSION =
new StandardBundlerParam<>(
"mac.CFBundleVersion",
String.class,
p -> {
String s = VERSION.fetchFrom(p);
if (validCFBundleVersion(s)) {
return s;
} else {
return "100";
}
return MacAppBundler.getIdentifier(params);
},
(s, p) -> s);
@ -188,59 +166,6 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
Files.copy(in, dstFile);
}
public static boolean validCFBundleVersion(String v) {
// CFBundleVersion (String - iOS, OS X) specifies the build version
// number of the bundle, which identifies an iteration (released or
// unreleased) of the bundle. The build version number should be a
// string comprised of three non-negative, period-separated integers
// with the first integer being greater than zero. The string should
// only contain numeric (0-9) and period (.) characters. Leading zeros
// are truncated from each integer and will be ignored (that is,
// 1.02.3 is equivalent to 1.2.3). This key is not localizable.
if (v == null) {
return false;
}
String p[] = v.split("\\.");
if (p.length > 3 || p.length < 1) {
Log.verbose(I18N.getString(
"message.version-string-too-many-components"));
return false;
}
try {
BigInteger n = new BigInteger(p[0]);
if (BigInteger.ONE.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-first-number-not-zero"));
return false;
}
if (p.length > 1) {
n = new BigInteger(p[1]);
if (BigInteger.ZERO.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-no-negative-numbers"));
return false;
}
}
if (p.length > 2) {
n = new BigInteger(p[2]);
if (BigInteger.ZERO.compareTo(n) > 0) {
Log.verbose(I18N.getString(
"message.version-string-no-negative-numbers"));
return false;
}
}
} catch (NumberFormatException ne) {
Log.verbose(I18N.getString("message.version-string-numbers-only"));
Log.verbose(ne);
return false;
}
return true;
}
@Override
public Path getAppDir() {
return appDir;
@ -469,16 +394,10 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params));
data.put("DEPLOY_BUNDLE_NAME",
getBundleName(params));
data.put("DEPLOY_BUNDLE_COPYRIGHT",
COPYRIGHT.fetchFrom(params) != null ?
COPYRIGHT.fetchFrom(params) : "Unknown");
data.put("DEPLOY_BUNDLE_COPYRIGHT", COPYRIGHT.fetchFrom(params));
data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params));
data.put("DEPLOY_BUNDLE_SHORT_VERSION",
VERSION.fetchFrom(params) != null ?
VERSION.fetchFrom(params) : "1.0.0");
data.put("DEPLOY_BUNDLE_CFBUNDLE_VERSION",
MAC_CF_BUNDLE_VERSION.fetchFrom(params) != null ?
MAC_CF_BUNDLE_VERSION.fetchFrom(params) : "100");
data.put("DEPLOY_BUNDLE_SHORT_VERSION", VERSION.fetchFrom(params));
data.put("DEPLOY_BUNDLE_CFBUNDLE_VERSION", VERSION.fetchFrom(params));
boolean hasMainJar = MAIN_JAR.fetchFrom(params) != null;
boolean hasMainModule =

@ -29,7 +29,6 @@ store.bundler.name=Mac App Store Ready Bundler
dmg.bundler.name=Mac DMG Package
pkg.bundler.name=Mac PKG Package
error.invalid-cfbundle-version=Invalid CFBundleVersion: [{0}]
error.invalid-cfbundle-version.advice=Set a compatible 'appVersion' or set a 'mac.CFBundleVersion'. Valid versions are one to three integers separated by dots.
error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
@ -64,8 +63,6 @@ message.preparing-info-plist=Preparing Info.plist: {0}.
message.icon-not-icns= The specified icon "{0}" is not an ICNS file and will not be used. The default icon will be used in it's place.
message.version-string-too-many-components=Version sting may have between 1 and 3 numbers: 1, 1.2, 1.2.3.
message.version-string-first-number-not-zero=The first number in a CFBundleVersion cannot be zero or negative.
message.version-string-no-negative-numbers=Negative numbers are not allowed in version strings.
message.version-string-numbers-only=Version strings can consist of only numbers and up to two dots.
message.creating-association-with-null-extension=Creating association with null extension.
message.ignoring.symlink=Warning: codesign is skipping the symlink {0}.
message.already.signed=File already signed: {0}.

@ -29,7 +29,6 @@ store.bundler.name=Mac App Store\u306E\u6E96\u5099\u5B8C\u4E86\u30D0\u30F3\u30C9
dmg.bundler.name=Mac DMG\u30D1\u30C3\u30B1\u30FC\u30B8
pkg.bundler.name=Mac PKG\u30D1\u30C3\u30B1\u30FC\u30B8
error.invalid-cfbundle-version=\u7121\u52B9\u306ACFBundleVersion: [{0}]
error.invalid-cfbundle-version.advice=\u4E92\u63DB\u6027\u306E\u3042\u308B'appVersion'\u3092\u8A2D\u5B9A\u3059\u308B\u304B\u3001'mac.CFBundleVersion'\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u305F1\u304B\u30893\u3064\u306E\u6574\u6570\u3067\u3059\u3002
error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
@ -65,8 +64,6 @@ message.preparing-info-plist=Info.plist\u3092\u6E96\u5099\u3057\u3066\u3044\u307
message.icon-not-icns= \u6307\u5B9A\u3057\u305F\u30A2\u30A4\u30B3\u30F3"{0}"\u306FICNS\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u304F\u3001\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u304C\u305D\u306E\u4F4D\u7F6E\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002
message.version-string-too-many-components=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u306F\u30011\u30011.2\u30011.2.3\u306A\u30691\u304B\u30893\u306E\u6570\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
message.version-string-first-number-not-zero=CFBundleVersion\u306E\u6700\u521D\u306E\u6570\u5B57\u306F\u3001\u30BC\u30ED\u307E\u305F\u306F\u8CA0\u306E\u5024\u306B\u3067\u304D\u307E\u305B\u3093\u3002
message.version-string-no-negative-numbers=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u8CA0\u306E\u6570\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3002
message.version-string-numbers-only=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306F\u3001\u6570\u5B57\u30682\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u3067\u306E\u307F\u69CB\u6210\u3067\u304D\u307E\u3059\u3002
message.creating-association-with-null-extension=null\u62E1\u5F35\u5B50\u3068\u306E\u95A2\u9023\u4ED8\u3051\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059\u3002
message.ignoring.symlink=\u8B66\u544A: codesign\u304Csymlink {0}\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059
message.already.signed=File already signed: {0}.

@ -29,7 +29,6 @@ store.bundler.name=\u652F\u6301 Mac App Store \u7684\u6253\u5305\u7A0B\u5E8F
dmg.bundler.name=Mac DMG \u7A0B\u5E8F\u5305
pkg.bundler.name=Mac PKG \u7A0B\u5E8F\u5305
error.invalid-cfbundle-version=\u65E0\u6548\u7684 CFBundleVersion\uFF1A[{0}]
error.invalid-cfbundle-version.advice=\u8BBE\u7F6E\u517C\u5BB9\u7684 'appVersion' \u6216\u8005\u8BBE\u7F6E 'mac.CFBundleVersion'\u3002\u6709\u6548\u7248\u672C\u5305\u542B\u4E00\u5230\u4E09\u4E2A\u7528\u70B9\u5206\u9694\u7684\u6574\u6570\u3002
error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
@ -65,8 +64,6 @@ message.preparing-info-plist=\u6B63\u5728\u51C6\u5907 Info.plist: {0}\u3002
message.icon-not-icns= \u6307\u5B9A\u7684\u56FE\u6807 "{0}" \u4E0D\u662F ICNS \u6587\u4EF6, \u4E0D\u4F1A\u4F7F\u7528\u3002\u5C06\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\u4EE3\u66FF\u3002
message.version-string-too-many-components=\u7248\u672C\u5B57\u7B26\u4E32\u53EF\u4EE5\u5305\u542B 1 \u5230 3 \u4E2A\u6570\u5B57: 1, 1.2, 1.2.3\u3002
message.version-string-first-number-not-zero=CFBundleVersion \u4E2D\u7684\u7B2C\u4E00\u4E2A\u6570\u5B57\u4E0D\u80FD\u4E3A\u96F6\u6216\u8D1F\u6570\u3002
message.version-string-no-negative-numbers=\u7248\u672C\u5B57\u7B26\u4E32\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u8D1F\u6570\u3002
message.version-string-numbers-only=\u7248\u672C\u5B57\u7B26\u4E32\u53EA\u80FD\u5305\u542B\u6570\u5B57\u548C\u6700\u591A\u4E24\u4E2A\u70B9\u3002
message.creating-association-with-null-extension=\u6B63\u5728\u4F7F\u7528\u7A7A\u6269\u5C55\u540D\u521B\u5EFA\u5173\u8054\u3002
message.ignoring.symlink=\u8B66\u544A: codesign \u6B63\u5728\u8DF3\u8FC7\u7B26\u53F7\u94FE\u63A5 {0}\u3002
message.already.signed=File already signed: {0}.

@ -104,7 +104,6 @@ public abstract class AbstractAppImageBuilder {
out.println("app.name=" + APP_NAME.fetchFrom(params));
out.println("app.version=" + VERSION.fetchFrom(params));
out.println("app.runtime=" + getCfgRuntimeDir());
out.println("app.identifier=" + IDENTIFIER.fetchFrom(params));
out.println("app.classpath="
+ getCfgClassPath(CLASSPATH.fetchFrom(params)));

@ -25,18 +25,21 @@
package jdk.incubator.jpackage.internal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Dotted numeric version string.
* E.g.: 1.0.37, 10, 0.5
*/
class DottedVersion implements Comparable<String> {
final class DottedVersion implements Comparable<String> {
public DottedVersion(String version) {
DottedVersion(String version) {
greedy = true;
components = parseVersionString(version, greedy);
value = version;
@ -48,49 +51,61 @@ class DottedVersion implements Comparable<String> {
value = version;
}
public static DottedVersion greedy(String version) {
static DottedVersion greedy(String version) {
return new DottedVersion(version);
}
public static DottedVersion lazy(String version) {
static DottedVersion lazy(String version) {
return new DottedVersion(version, false);
}
@Override
public int compareTo(String o) {
int result = 0;
int[] otherComponents = parseVersionString(o, greedy);
for (int i = 0; i < Math.min(components.length, otherComponents.length)
BigInteger[] otherComponents = parseVersionString(o, greedy);
for (int i = 0; i < Math.max(components.length, otherComponents.length)
&& result == 0; ++i) {
result = components[i] - otherComponents[i];
}
final BigInteger x;
if (i < components.length) {
x = components[i];
} else {
x = BigInteger.ZERO;
}
if (result == 0) {
result = components.length - otherComponents.length;
final BigInteger y;
if (i < otherComponents.length) {
y = otherComponents[i];
} else {
y = BigInteger.ZERO;
}
result = x.compareTo(y);
}
return result;
}
private static int[] parseVersionString(String version, boolean greedy) {
private static BigInteger[] parseVersionString(String version, boolean greedy) {
Objects.requireNonNull(version);
if (version.isEmpty()) {
if (!greedy) {
return new int[] {0};
return new BigInteger[] {BigInteger.ZERO};
}
throw new IllegalArgumentException("Version may not be empty string");
throw new IllegalArgumentException(I18N.getString(
"error.version-string-empty"));
}
int lastNotZeroIdx = -1;
List<Integer> components = new ArrayList<>();
List<BigInteger> components = new ArrayList<>();
for (var component : version.split("\\.", -1)) {
if (component.isEmpty()) {
if (!greedy) {
break;
}
throw new IllegalArgumentException(String.format(
"Version [%s] contains a zero lenght component", version));
throw new IllegalArgumentException(MessageFormat.format(
I18N.getString(
"error.version-string-zero-length-component"),
version));
}
if (!DIGITS.matcher(component).matches()) {
@ -99,23 +114,27 @@ class DottedVersion implements Comparable<String> {
break;
}
throw new IllegalArgumentException(String.format(
"Version [%s] contains invalid component [%s]", version,
component));
throw new IllegalArgumentException(MessageFormat.format(
I18N.getString(
"error.version-string-invalid-component"),
version, component));
}
final int num;
final BigInteger num;
try {
num = Integer.parseInt(component);
num = new BigInteger(component);
} catch (NumberFormatException ex) {
if (!greedy) {
break;
}
throw ex;
throw new IllegalArgumentException(MessageFormat.format(
I18N.getString(
"error.version-string-invalid-component"),
version, component));
}
if (num != 0) {
if (num != BigInteger.ZERO) {
lastNotZeroIdx = components.size();
}
components.add(num);
@ -127,9 +146,10 @@ class DottedVersion implements Comparable<String> {
}
if (components.isEmpty()) {
components.add(0);
components.add(BigInteger.ZERO);
}
return components.stream().mapToInt(Integer::intValue).toArray();
return components.stream()
.collect(Collectors.toList()).toArray(BigInteger[]::new);
}
@Override
@ -137,11 +157,11 @@ class DottedVersion implements Comparable<String> {
return value;
}
int[] getComponents() {
BigInteger[] getComponents() {
return components;
}
final private int[] components;
final private BigInteger[] components;
final private String value;
final private boolean greedy;

@ -308,23 +308,6 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
(s, p) -> null
);
static final StandardBundlerParam<String> IDENTIFIER =
new StandardBundlerParam<>(
"identifier.default",
String.class,
params -> {
String s = MAIN_CLASS.fetchFrom(params);
if (s == null) return null;
int idx = s.lastIndexOf(".");
if (idx >= 1) {
return s.substring(0, idx);
}
return s;
},
(s, p) -> s
);
static final StandardBundlerParam<Boolean> BIND_SERVICES =
new StandardBundlerParam<>(
Arguments.CLIOptions.BIND_SERVICES.getId(),

@ -43,6 +43,10 @@ message.bundle-created=Succeeded in building {0} package
message.module-version=Using version "{0}" from module "{1}" as application version
message.module-class=Using class "{0}" from module "{1}" as application main class
error.version-string-empty="Version may not be empty string"
error.version-string-zero-length-component="Version [{0}] contains a zero length component"
error.version-string-invalid-component="Version [{0}] contains invalid component [{1}]"
error.cannot-create-output-dir=Destination directory {0} cannot be created
error.cannot-write-to-output-dir=Destination directory {0} is not writable
error.root-exists=Error: Application destination directory {0} already exists

@ -43,6 +43,10 @@ message.bundle-created={0}\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F5C\u6210\u306B
message.module-version=\u30E2\u30B8\u30E5\u30FC\u30EB"{1}"\u306E\u30D0\u30FC\u30B8\u30E7\u30F3"{0}"\u3092\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u3068\u3057\u3066\u4F7F\u7528
message.module-class=\u30E2\u30B8\u30E5\u30FC\u30EB"{1}"\u306E\u30AF\u30E9\u30B9"{0}"\u3092\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u3068\u3057\u3066\u4F7F\u7528
error.version-string-empty="Version may not be empty string"
error.version-string-zero-length-component="Version [{0}] contains a zero length component"
error.version-string-invalid-component="Version [{0}] contains invalid component [{1}]"
error.cannot-create-output-dir=\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002
error.cannot-write-to-output-dir=\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u4E0D\u53EF\u3067\u3059
error.root-exists=\u30A8\u30E9\u30FC: \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059

@ -43,6 +43,10 @@ message.bundle-created=\u5DF2\u6210\u529F\u5730\u6784\u5EFA {0} \u7A0B\u5E8F\u53
message.module-version=\u6B63\u5728\u5C06\u6A21\u5757 "{1}" \u4E2D\u7684\u7248\u672C "{0}" \u7528\u4F5C\u5E94\u7528\u7A0B\u5E8F\u7248\u672C
message.module-class=\u6B63\u5728\u5C06\u6A21\u5757 "{1}" \u4E2D\u7684\u7C7B "{0}" \u7528\u4F5C\u5E94\u7528\u7A0B\u5E8F\u4E3B\u7C7B
error.version-string-empty="Version may not be empty string"
error.version-string-zero-length-component="Version [{0}] contains a zero length component"
error.version-string-invalid-component="Version [{0}] contains invalid component [{1}]"
error.cannot-create-output-dir=\u65E0\u6CD5\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 {0}
error.cannot-write-to-output-dir=\u76EE\u6807\u76EE\u5F55 {0} \u4E0D\u53EF\u5199
error.root-exists=\u9519\u8BEF\uFF1A\u5E94\u7528\u7A0B\u5E8F\u76EE\u6807\u76EE\u5F55 {0} \u5DF2\u5B58\u5728

@ -26,10 +26,10 @@ package jdk.incubator.jpackage.internal;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.text.MessageFormat;
@ -37,14 +37,12 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.ResourceBundle;
import static jdk.incubator.jpackage.internal.OverridableResource.createResource;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.COPYRIGHT;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.DESCRIPTION;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION;
@ -150,8 +148,8 @@ final class ExecutableRebrander {
}
private static String getFixedFileVersion(String value) {
int[] versionComponents = DottedVersion.greedy(value).getComponents();
int addComponentsCount = 4 - versionComponents.length;
int addComponentsCount = 4
- DottedVersion.greedy(value).getComponents().length;
if (addComponentsCount > 0) {
StringBuilder sb = new StringBuilder(value);
do {

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.incubator.jpackage.internal;
import java.math.BigInteger;
final class MsiVersion {
/**
* Parse the given string as Windows MSI Product version.
* https://msdn.microsoft.com/en-us/library/aa370859%28v=VS.85%29.aspx The
* format of the string is as follows: major.minor.build. The first field is
* the major version and has a maximum value of 255. The second field is the
* minor version and has a maximum value of 255. The third field is called
* the build version or the update version and has a maximum value of
* 65,535.
* @throws IllegalArgumentException
*/
static DottedVersion of(String value) {
DottedVersion ver = new DottedVersion(value);
BigInteger[] components = ver.getComponents();
if (components.length > 3) {
throw new IllegalArgumentException(I18N.getString(
"error.msi-product-version-too-many-components"));
}
if (BigInteger.valueOf(255).compareTo(components[0]) < 0) {
throw new IllegalArgumentException(I18N.getString(
"error.msi-product-version-major-out-of-range"));
}
if (components.length > 1 && BigInteger.valueOf(255).compareTo(
components[1]) < 0) {
throw new IllegalArgumentException(I18N.getString(
"error.msi-product-version-minor-out-of-range"));
}
if (components.length > 2 && BigInteger.valueOf(65535).compareTo(
components[2]) < 0) {
throw new IllegalArgumentException(I18N.getString(
"error.msi-product-version-build-out-of-range"));
}
return ver;
}
}

@ -248,14 +248,12 @@ public class WinMsiBundler extends AbstractBundler {
/********* validate bundle parameters *************/
String version = PRODUCT_VERSION.fetchFrom(params);
if (!isVersionStringValid(version)) {
throw new ConfigException(
MessageFormat.format(I18N.getString(
"error.version-string-wrong-format"), version),
MessageFormat.format(I18N.getString(
"error.version-string-wrong-format.advice"),
PRODUCT_VERSION.getID()));
try {
String version = PRODUCT_VERSION.fetchFrom(params);
MsiVersion.of(version);
} catch (IllegalArgumentException ex) {
throw new ConfigException(ex.getMessage(), I18N.getString(
"error.version-string-wrong-format.advice"), ex);
}
FileAssociation.verify(FileAssociation.fetchFrom(params));
@ -270,57 +268,6 @@ public class WinMsiBundler extends AbstractBundler {
}
}
// https://msdn.microsoft.com/en-us/library/aa370859%28v=VS.85%29.aspx
// The format of the string is as follows:
// major.minor.build
// The first field is the major version and has a maximum value of 255.
// The second field is the minor version and has a maximum value of 255.
// The third field is called the build version or the update version and
// has a maximum value of 65,535.
static boolean isVersionStringValid(String v) {
if (v == null) {
return true;
}
String p[] = v.split("\\.");
if (p.length > 3) {
Log.verbose(I18N.getString(
"message.version-string-too-many-components"));
return false;
}
try {
int val = Integer.parseInt(p[0]);
if (val < 0 || val > 255) {
Log.verbose(I18N.getString(
"error.version-string-major-out-of-range"));
return false;
}
if (p.length > 1) {
val = Integer.parseInt(p[1]);
if (val < 0 || val > 255) {
Log.verbose(I18N.getString(
"error.version-string-minor-out-of-range"));
return false;
}
}
if (p.length > 2) {
val = Integer.parseInt(p[2]);
if (val < 0 || val > 65535) {
Log.verbose(I18N.getString(
"error.version-string-build-out-of-range"));
return false;
}
}
} catch (NumberFormatException ne) {
Log.verbose(I18N.getString("error.version-string-part-not-number"));
Log.verbose(ne);
return false;
}
return true;
}
private void prepareProto(Map<String, ? super Object> params)
throws PackagerException, IOException {
File appImage = StandardBundlerParam.getPredefinedAppImage(params);

@ -40,12 +40,11 @@ resource.overrides-wix-file=Overrides WiX project file
error.no-wix-tools=Can not find WiX tools (light.exe, candle.exe)
error.no-wix-tools.advice=Download WiX 3.0 or later from https://wixtoolset.org and add it to the PATH.
error.version-string-wrong-format=Version string is not compatible with MSI rules [{0}]
error.version-string-wrong-format.advice=Set the bundler argument "{0}" according to these rules: https://msdn.microsoft.com/en-us/library/aa370859%28v\=VS.85%29.aspx .
error.version-string-major-out-of-range=Major version must be in the range [0, 255]
error.version-string-build-out-of-range=Build part of version must be in the range [0, 65535]
error.version-string-minor-out-of-range=Minor version must be in the range [0, 255]
error.version-string-part-not-number=Failed to convert version component to int
error.version-string-wrong-format.advice=Set value of --app-version parameter according to these rules: https://msdn.microsoft.com/en-us/library/aa370859%28v\=VS.85%29.aspx
error.msi-product-version-too-many-components=Version sting may have between 1 and 3 components: 1, 1.2, 1.2.3.
error.msi-product-version-major-out-of-range=Major version must be in the range [0, 255]
error.msi-product-version-build-out-of-range=Build part of version must be in the range [0, 65535]
error.msi-product-version-minor-out-of-range=Minor version must be in the range [0, 255]
error.version-swap=Failed to update version information for {0}
error.invalid-envvar=Invalid value of {0} environment variable

@ -40,12 +40,11 @@ resource.overrides-wix-file=WiX\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30FB\u30D5\
error.no-wix-tools=WiX\u30C4\u30FC\u30EB(light.exe\u3001candle.exe)\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
error.no-wix-tools.advice=WiX 3.0\u4EE5\u964D\u3092https://wixtoolset.org\u304B\u3089\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3001PATH\u306B\u8FFD\u52A0\u3057\u307E\u3059\u3002
error.version-string-wrong-format=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306FMSI\u898F\u5247[{0}]\u3068\u4E92\u63DB\u6027\u304C\u3042\u308A\u307E\u305B\u3093
error.version-string-wrong-format.advice=\u30D0\u30F3\u30C9\u30E9\u5F15\u6570"{0}"\u3092\u6B21\u306E\u898F\u5247\u306B\u5F93\u3063\u3066\u8A2D\u5B9A\u3057\u307E\u3059: https://msdn.microsoft.com/en-us/library/aa370859%28v=VS.85%29.aspx\u3002
error.version-string-major-out-of-range=\u30E1\u30B8\u30E3\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u7BC4\u56F2[0, 255]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.version-string-build-out-of-range=\u30D0\u30FC\u30B8\u30E7\u30F3\u306E\u30D3\u30EB\u30C9\u90E8\u5206\u306F\u7BC4\u56F2[0, 65535]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.version-string-minor-out-of-range=\u30DE\u30A4\u30CA\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u7BC4\u56F2[0, 255]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.version-string-part-not-number=\u30D0\u30FC\u30B8\u30E7\u30F3\u30FB\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306Eint\u3078\u306E\u5909\u63DB\u306B\u5931\u6557\u3057\u307E\u3057\u305F
error.version-string-wrong-format.advice=Set value of --app-version parameter according to these rules: https://msdn.microsoft.com/en-us/library/aa370859%28v\=VS.85%29.aspx
error.msi-product-version-too-many-components=Version sting may have between 1 and 3 components: 1, 1.2, 1.2.3.
error.msi-product-version-major-out-of-range=\u30E1\u30B8\u30E3\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u7BC4\u56F2[0, 255]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.msi-product-version-build-out-of-range=\u30D0\u30FC\u30B8\u30E7\u30F3\u306E\u30D3\u30EB\u30C9\u90E8\u5206\u306F\u7BC4\u56F2[0, 65535]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.msi-product-version-minor-out-of-range=\u30DE\u30A4\u30CA\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u7BC4\u56F2[0, 255]\u5185\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
error.version-swap={0}\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F
error.invalid-envvar={0}\u74B0\u5883\u5909\u6570\u306E\u5024\u304C\u7121\u52B9\u3067\u3059

Some files were not shown because too many files have changed in this diff Show More