Merge
This commit is contained in:
commit
d616488567
make
src
hotspot
cpu
aarch64
aarch64.admacroAssembler_aarch64.cppmacroAssembler_aarch64.hppmethodHandles_aarch64.cppnativeInst_aarch64.cppnativeInst_aarch64.hpptemplateInterpreterGenerator_aarch64.cpp
arm
ppc
s390
x86
os_cpu/linux_aarch64
share
c1
ci
classfile
gc
g1/c2
shared
shenandoah
z
interpreter
jfr
jvmci
oops
opto
java.base/share/classes
java/net
sun/security/ssl
java.desktop
java.net.http/share/classes
java/net/http
jdk/internal/net/http
jdk.compiler/share/classes/com/sun
jdk.incubator.foreign/share/classes/jdk/internal/foreign
AbstractMemorySegmentImpl.javaHeapMemorySegmentImpl.javaMappedMemorySegmentImpl.javaMemoryScope.javaNativeMemorySegmentImpl.java
jdk.incubator.jpackage
macosx/classes/jdk/incubator/jpackage/internal
share/classes/jdk/incubator/jpackage/internal
windows/classes/jdk/incubator/jpackage/internal
@ -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&" fieldType="Tickspan"/>
|
||||
<XmlType name="Ticks" contentType="tickstamp" javaType="long" parameterType="const Ticks&" fieldType="Ticks"/>
|
||||
<XmlType name="Tickspan" contentType="tickspan" unsigned="true" javaType="long" parameterType="const Tickspan&" fieldType="Tickspan"/>
|
||||
<XmlType name="Ticks" contentType="tickstamp" unsigned="true" javaType="long" parameterType="const Ticks&" 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);
|
||||
}
|
||||
}
|
||||
|
56
src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/CFBundleVersion.java
Normal file
56
src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/CFBundleVersion.java
Normal file
@ -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
|
||||
|
89
src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java
89
src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java
@ -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;
|
||||
|
||||
|
17
src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/StandardBundlerParam.java
17
src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/StandardBundlerParam.java
@ -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
|
||||
|
8
src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/ExecutableRebrander.java
8
src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/ExecutableRebrander.java
@ -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 {
|
||||
|
69
src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/MsiVersion.java
Normal file
69
src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/MsiVersion.java
Normal file
@ -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
Loading…
x
Reference in New Issue
Block a user