Skip to content

Commit

Permalink
Merge branch 'upstream-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Datadog Syncup Service committed May 13, 2024
2 parents 5938e9a + ff4bf1c commit ee173e5
Show file tree
Hide file tree
Showing 26 changed files with 654 additions and 144 deletions.
64 changes: 41 additions & 23 deletions src/hotspot/share/opto/superword.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ SuperWord::SuperWord(const VLoopAnalyzer &vloop_analyzer) :
_arena(mtCompiler),
_node_info(arena(), _vloop.estimated_body_length(), 0, SWNodeInfo::initial), // info needed per node
_clone_map(phase()->C->clone_map()), // map of nodes created in cloning
_align_to_ref(nullptr), // memory reference to align vectors to
_pairset(&_arena, _vloop_analyzer),
_packset(&_arena, _vloop_analyzer
NOT_PRODUCT(COMMA is_trace_superword_packset())
NOT_PRODUCT(COMMA is_trace_superword_rejections())
),
_mem_ref_for_main_loop_alignment(nullptr),
_aw_for_main_loop_alignment(0),
_do_vector_loop(phase()->C->do_vector_loop()), // whether to do vectorization/simd style
_num_work_vecs(0), // amount of vector work we have
_num_reductions(0) // amount of reduction work we have
Expand Down Expand Up @@ -516,22 +517,12 @@ void SuperWord::find_adjacent_refs() {

int max_idx;

// Take the first mem_ref as the reference to align to. The pre-loop trip count is
// modified to align this reference to a vector-aligned address. If strict alignment
// is required, we may change the reference later (see filter_packs_for_alignment()).
MemNode* align_to_mem_ref = nullptr;

while (memops.size() != 0) {
// Find a memory reference to align to.
MemNode* mem_ref = find_align_to_ref(memops, max_idx);
if (mem_ref == nullptr) break;
int iv_adjustment = get_iv_adjustment(mem_ref);

if (align_to_mem_ref == nullptr) {
align_to_mem_ref = mem_ref;
set_align_to_ref(align_to_mem_ref);
}

const VPointer& align_to_ref_p = vpointer(mem_ref);
// Set alignment relative to "align_to_ref" for all related memory operations.
for (int i = memops.size() - 1; i >= 0; i--) {
Expand Down Expand Up @@ -573,9 +564,6 @@ void SuperWord::find_adjacent_refs() {
}
} // while (memops.size() != 0)

assert(_pairset.is_empty() || align_to_mem_ref != nullptr,
"pairset empty or we find the alignment reference");

#ifndef PRODUCT
if (is_trace_superword_packset()) {
tty->print_cr("\nAfter Superword::find_adjacent_refs");
Expand Down Expand Up @@ -1723,7 +1711,11 @@ void SuperWord::filter_packs_for_alignment() {
if (current->is_constrained()) {
// Solution is constrained (not trivial)
// -> must change pre-limit to achieve alignment
set_align_to_ref(current->as_constrained()->mem_ref());
MemNode const* mem = current->as_constrained()->mem_ref();
Node_List* pack = get_pack(mem);
assert(pack != nullptr, "memop of final solution must still be packed");
_mem_ref_for_main_loop_alignment = mem;
_aw_for_main_loop_alignment = pack->size() * mem->memory_size();
}
}

Expand Down Expand Up @@ -3397,6 +3389,32 @@ LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) {
return dep;
}

// Find the memop pack with the maximum vector width, unless they were already
// determined by SuperWord::filter_packs_for_alignment().
void SuperWord::determine_mem_ref_and_aw_for_main_loop_alignment() {
if (_mem_ref_for_main_loop_alignment != nullptr) {
assert(vectors_should_be_aligned(), "mem_ref only set if filtered for alignment");
return;
}

MemNode const* mem_ref = nullptr;
int max_aw = 0;
for (int i = 0; i < _packset.length(); i++) {
Node_List* pack = _packset.at(i);
MemNode* first = pack->at(0)->isa_Mem();
if (first == nullptr) { continue; }

int vw = first->memory_size() * pack->size();
if (vw > max_aw) {
max_aw = vw;
mem_ref = first;
}
}
assert(mem_ref != nullptr && max_aw > 0, "found mem_ref and aw");
_mem_ref_for_main_loop_alignment = mem_ref;
_aw_for_main_loop_alignment = max_aw;
}

#define TRACE_ALIGN_VECTOR_NODE(node) { \
DEBUG_ONLY( \
if (is_trace_align_vector()) { \
Expand All @@ -3407,11 +3425,14 @@ LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) {
} \

// Ensure that the main loop vectors are aligned by adjusting the pre loop limit. We memory-align
// the address of "align_to_ref" to the maximal possible vector width. We adjust the pre-loop
// iteration count by adjusting the pre-loop limit.
// the address of "_mem_ref_for_main_loop_alignment" to "_aw_for_main_loop_alignment", which is a
// sufficiently large alignment width. We adjust the pre-loop iteration count by adjusting the
// pre-loop limit.
void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() {
const MemNode* align_to_ref = _align_to_ref;
assert(align_to_ref != nullptr, "align_to_ref must be set");
determine_mem_ref_and_aw_for_main_loop_alignment();
const MemNode* align_to_ref = _mem_ref_for_main_loop_alignment;
const int aw = _aw_for_main_loop_alignment;
assert(align_to_ref != nullptr && aw > 0, "must have alignment reference and aw");
assert(cl()->is_main_loop(), "can only do alignment for main loop");

// The opaque node for the limit, where we adjust the input
Expand Down Expand Up @@ -3556,10 +3577,7 @@ void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() {
// = MIN(new_limit, orig_limit) (15a, stride > 0)
// constrained_limit = MAX(old_limit - adjust_pre_iter, orig_limit)
// = MAX(new_limit, orig_limit) (15a, stride < 0)

// We chose an aw that is the maximal possible vector width for the type of
// align_to_ref.
const int aw = vector_width_in_bytes(align_to_ref);
//
const int stride = iv_stride();
const int scale = align_to_ref_p.scale_in_bytes();
const int offset = align_to_ref_p.offset_in_bytes();
Expand Down
9 changes: 6 additions & 3 deletions src/hotspot/share/opto/superword.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,15 @@ class SuperWord : public ResourceObj {

GrowableArray<SWNodeInfo> _node_info; // Info needed per node
CloneMap& _clone_map; // map of nodes created in cloning
MemNode const* _align_to_ref; // Memory reference that pre-loop will align to

PairSet _pairset;
PackSet _packset;

// Memory reference, and the alignment width (aw) for which we align the main-loop,
// by adjusting the pre-loop limit.
MemNode const* _mem_ref_for_main_loop_alignment;
int _aw_for_main_loop_alignment;

public:
SuperWord(const VLoopAnalyzer &vloop_analyzer);

Expand Down Expand Up @@ -563,8 +567,6 @@ class SuperWord : public ResourceObj {
Arena* arena() { return &_arena; }

int get_vw_bytes_special(MemNode* s);
const MemNode* align_to_ref() const { return _align_to_ref; }
void set_align_to_ref(const MemNode* m) { _align_to_ref = m; }

// Ensure node_info contains element "i"
void grow_node_info(int i) { if (i >= _node_info.length()) _node_info.at_put_grow(i, SWNodeInfo::initial); }
Expand Down Expand Up @@ -670,6 +672,7 @@ class SuperWord : public ResourceObj {
// Alignment within a vector memory reference
int memory_alignment(MemNode* s, int iv_adjust);
// Ensure that the main loop vectors are aligned by adjusting the pre loop limit.
void determine_mem_ref_and_aw_for_main_loop_alignment();
void adjust_pre_loop_limit_to_align_main_loop_vectors();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import sun.invoke.util.Wrapper;
import sun.util.logging.PlatformLogger;

import java.util.ArrayList;
import java.util.HashSet;
Expand Down Expand Up @@ -73,6 +72,7 @@ static class HolderClassBuilder {

private final TreeSet<String> speciesTypes = new TreeSet<>();
private final TreeSet<String> invokerTypes = new TreeSet<>();
private final TreeSet<String> linkerTypes = new TreeSet<>();
private final TreeSet<String> callSiteTypes = new TreeSet<>();
private final Map<String, Set<String>> dmhMethods = new TreeMap<>();

Expand All @@ -87,6 +87,12 @@ HolderClassBuilder addInvokerType(String methodType) {
return this;
}

HolderClassBuilder addLinkerType(String methodType) {
validateMethodType(methodType);
linkerTypes.add(methodType);
return this;
}

HolderClassBuilder addCallSiteType(String csType) {
validateMethodType(csType);
callSiteTypes.add(csType);
Expand Down Expand Up @@ -130,19 +136,33 @@ Map<String, byte[]> build() {
}
}

// The invoker type to ask for is retrieved by removing the first
// The linker type to ask for is retrieved by removing the first
// and the last argument, which needs to be of Object.class
MethodType[] linkerMethodTypes = new MethodType[linkerTypes.size()];
index = 0;
for (String linkerType : linkerTypes) {
MethodType mt = asMethodType(linkerType);
final int lastParam = mt.parameterCount() - 1;
if (!checkLinkerTypeParams(mt)) {
throw new RuntimeException(
"Linker type parameter must start and end with Object: " + linkerType);
}
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
linkerMethodTypes[index] = mt.dropParameterTypes(0, 1);
index++;
}

// The invoker type to ask for is retrieved by removing the first
// argument, which needs to be of Object.class
MethodType[] invokerMethodTypes = new MethodType[invokerTypes.size()];
index = 0;
for (String invokerType : invokerTypes) {
MethodType mt = asMethodType(invokerType);
final int lastParam = mt.parameterCount() - 1;
if (!checkInvokerTypeParams(mt)) {
throw new RuntimeException(
"Invoker type parameter must start and end with Object: " + invokerType);
"Invoker type parameter must start with 2 Objects: " + invokerType);
}
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
invokerMethodTypes[index] = mt.dropParameterTypes(0, 1);
invokerMethodTypes[index] = mt.dropParameterTypes(0, 2);
index++;
}

Expand Down Expand Up @@ -171,7 +191,7 @@ Map<String, byte[]> build() {
DELEGATING_HOLDER, directMethodTypes));
result.put(INVOKERS_HOLDER,
generateInvokersHolderClassBytes(INVOKERS_HOLDER,
invokerMethodTypes, callSiteMethodTypes));
linkerMethodTypes, invokerMethodTypes, callSiteMethodTypes));
result.put(BASIC_FORMS_HOLDER,
generateBasicFormsClassBytes(BASIC_FORMS_HOLDER));

Expand Down Expand Up @@ -207,6 +227,12 @@ public static MethodType asMethodType(String basicSignatureString) {
}

public static boolean checkInvokerTypeParams(MethodType mt) {
return (mt.parameterCount() >= 2 &&
mt.parameterType(0) == Object.class &&
mt.parameterType(1) == Object.class);
}

public static boolean checkLinkerTypeParams(MethodType mt) {
final int lastParam = mt.parameterCount() - 1;
return (mt.parameterCount() >= 2 &&
mt.parameterType(0) == Object.class &&
Expand Down Expand Up @@ -320,15 +346,11 @@ static Map<String, byte[]> generateHolderClasses(Stream<String> traces) {
if ("linkToTargetMethod".equals(parts[2]) ||
"linkToCallSite".equals(parts[2])) {
builder.addCallSiteType(methodType);
} else if (parts[2].endsWith("nvoker")) {
// MH.exactInvoker exactInvoker MH.invoker invoker
builder.addInvokerType(methodType);
} else {
MethodType mt = HolderClassBuilder.asMethodType(methodType);
// Work around JDK-8327499
if (HolderClassBuilder.checkInvokerTypeParams(mt)) {
builder.addInvokerType(methodType);
} else {
PlatformLogger.getLogger("java.lang.invoke")
.warning("Invalid LF_RESOLVE " + parts[1] + " " + parts[2] + " " + parts[3]);
}
builder.addLinkerType(methodType);
}
} else if (parts[1].contains("DirectMethodHandle")) {
String dmh = parts[2];
Expand Down Expand Up @@ -465,34 +487,52 @@ static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,

/**
* Returns a {@code byte[]} representation of a class implementing
* the invoker forms for the set of supplied {@code invokerMethodTypes}
* and {@code callSiteMethodTypes}.
* the invoker forms for the set of supplied {@code linkerMethodTypes}
* {@code invokerMethodTypes}, and {@code callSiteMethodTypes}.
*/
static byte[] generateInvokersHolderClassBytes(String className,
MethodType[] invokerMethodTypes, MethodType[] callSiteMethodTypes) {
MethodType[] linkerMethodTypes, MethodType[] invokerMethodTypes,
MethodType[] callSiteMethodTypes) {

HashSet<MethodType> dedupSet = new HashSet<>();
ArrayList<LambdaForm> forms = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
int[] types = {
MethodTypeForm.LF_EX_LINKER,

int[] invokerTypes = {
MethodTypeForm.LF_EX_INVOKER,
MethodTypeForm.LF_GEN_LINKER,
MethodTypeForm.LF_GEN_INVOKER
MethodTypeForm.LF_GEN_INVOKER,
};

for (int i = 0; i < invokerMethodTypes.length; i++) {
for (MethodType methodType : invokerMethodTypes) {
// generate methods representing invokers of the specified type
if (dedupSet.add(invokerMethodTypes[i])) {
for (int type : types) {
LambdaForm invokerForm = Invokers.invokeHandleForm(invokerMethodTypes[i],
if (dedupSet.add(methodType)) {
for (int type : invokerTypes) {
LambdaForm invokerForm = Invokers.invokeHandleForm(methodType,
/*customized*/false, type);
forms.add(invokerForm);
names.add(invokerForm.kind.defaultLambdaName);
}
}
}

int[] linkerTypes = {
MethodTypeForm.LF_EX_LINKER,
MethodTypeForm.LF_GEN_LINKER,
};

dedupSet = new HashSet<>();
for (MethodType methodType : linkerMethodTypes) {
// generate methods representing linkers of the specified type
if (dedupSet.add(methodType)) {
for (int type : linkerTypes) {
LambdaForm linkerForm = Invokers.invokeHandleForm(methodType,
/*customized*/false, type);
forms.add(linkerForm);
names.add(linkerForm.kind.defaultLambdaName);
}
}
}

dedupSet = new HashSet<>();
for (int i = 0; i < callSiteMethodTypes.length; i++) {
// generate methods representing invokers of the specified type
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -152,6 +152,8 @@ public interface KeyValue extends XMLStructure {
* the value of the <code>type</code> parameter of the
* {@link RetrievalMethod} class to describe a remote
* <code>ECKeyValue</code> structure.
*
* @since 13
*/
static final String EC_TYPE =
"http://www.w3.org/2009/xmldsig11#ECKeyValue";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2974,10 +2974,10 @@ public void visitTypeTest(JCInstanceOf tree) {
// preserving the side effects of the value
VarSymbol dollar_s = new VarSymbol(FINAL | SYNTHETIC,
names.fromString("tmp" + tree.pos + this.target.syntheticNameChar()),
tree.expr.type,
types.erasure(tree.expr.type),
currentMethodSym);
JCStatement var = make.at(tree.pos())
.VarDef(dollar_s, instanceOfExpr).setType(dollar_s.type);
.VarDef(dollar_s, instanceOfExpr);

if (types.isUnconditionallyExact(tree.expr.type, tree.pattern.type)) {
exactnessCheck = make.Literal(BOOLEAN, 1).setType(syms.booleanType.constType(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public JdkConsole printf(String format, Object ... args) {
public String readLine(String fmt, Object ... args) {
try {
initJLineIfNeeded();
return jline.readLine(fmt.formatted(args));
return jline.readLine(fmt.formatted(args).replace("%", "%%"));
} catch (EndOfFileException eofe) {
return null;
}
Expand All @@ -113,7 +113,8 @@ public String readLine() {
public char[] readPassword(String fmt, Object ... args) {
try {
initJLineIfNeeded();
return jline.readLine(fmt.formatted(args), '\0').toCharArray();
return jline.readLine(fmt.formatted(args).replace("%", "%%"), '\0')
.toCharArray();
} catch (EndOfFileException eofe) {
return null;
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,5 +25,6 @@

/**
* This package defines APIs for signing jar files.
* @since 9
*/
package jdk.security.jarsigner;
Loading

0 comments on commit ee173e5

Please sign in to comment.