This commit is contained in:
Jesper Wilhelmsson 2021-07-14 01:07:52 +00:00
commit 4a7ccf36e9
13 changed files with 372 additions and 68 deletions

View File

@ -857,6 +857,9 @@ else
# virtual target.
jdk.jdwp.agent-libs: jdk.jdwp.agent-gensrc
# jdk.jfr-gendata uses TOOL_JFR_GEN from buildtools-hotspot
jdk.jfr-gendata: buildtools-hotspot
# The swing beans need to have java base properly generated to avoid errors
# in javadoc. The X11 wrappers need the java.base include files to have been
# copied and processed.

View File

@ -61,36 +61,54 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
))
$(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols: \
GENERATE_SYMBOLS_FROM_JDK_VERSION := 11
JDK_JAVADOC_DIR := $(JDK_OUTPUTDIR)/modules/jdk.javadoc
ELEMENT_LISTS_PKG := jdk/javadoc/internal/doclets/toolkit/resources/releases
ELEMENT_LISTS_DIR := $(JDK_JAVADOC_DIR)/$(ELEMENT_LISTS_PKG)
$(JDK_JAVADOC_DIR)/_element_lists.marker: \
$(COMPILE_CREATE_SYMBOLS) \
$(wildcard $(TOPDIR)/make/data/symbols/*) \
$(MODULE_INFOS)
$(RM) -r $(@D)
$(MKDIR) -p $(@D)
$(ECHO) Creating javadoc element list
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \
build.tools.symbolgenerator.CreateSymbols \
build-javadoc-data \
$(CT_DATA_DESCRIPTION) \
$(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases \
11
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \
build.tools.symbolgenerator.JavadocElementList \
$(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-$(JDK_SOURCE_TARGET_VERSION).txt \
$(JAVADOC_MODULESOURCEPATH) \
$(JAVADOC_MODULES)
$(call MakeTargetDir)
$(call LogInfo, Creating javadoc element lists)
$(RM) -r $(ELEMENT_LISTS_DIR)
# Generate element-list files for JDK 11 to current-1
$(call ExecuteWithLog, $@_historic, \
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \
build.tools.symbolgenerator.CreateSymbols \
build-javadoc-data \
$(CT_DATA_DESCRIPTION) \
$(ELEMENT_LISTS_DIR) \
$(GENERATE_SYMBOLS_FROM_JDK_VERSION) \
)
# Generate element-list file for the current JDK version
$(call ExecuteWithLog, $@_current, \
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \
build.tools.symbolgenerator.JavadocElementList \
$(ELEMENT_LISTS_DIR)/element-list-$(JDK_SOURCE_TARGET_VERSION).txt \
$(JAVADOC_MODULESOURCEPATH) \
$(JAVADOC_MODULES) \
)
$(TOUCH) $@
# Copy ct.sym to the modules libs dir
$(eval $(call SetupCopyFiles, COPY_TO_LIBS, \
FILES := $(SUPPORT_OUTPUTDIR)/javadoc-symbols/*.txt, \
DEST := $(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases, \
))
################################################################################
# Copy element-lists to interim langtools
TARGETS += $(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols
INTERIM_JDK_JAVADOC_DIR := $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules/jdk.javadoc.interim
INTERIM_ELEMENT_LISTS_DIR := $(INTERIM_JDK_JAVADOC_DIR)/$(ELEMENT_LISTS_PKG)
$(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker: $(JDK_JAVADOC_DIR)/_element_lists.marker
$(call MakeDir, $(INTERIM_ELEMENT_LISTS_DIR))
$(RM) -r $(INTERIM_ELEMENT_LISTS_DIR)/*
$(CP) -R $(ELEMENT_LISTS_DIR)/* $(INTERIM_ELEMENT_LISTS_DIR)/
$(TOUCH) $@
################################################################################
TARGETS += $(JDK_JAVADOC_DIR)/_element_lists.marker \
$(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker

View File

@ -69,12 +69,11 @@ Semaphore ThreadIdExclusiveAccess::_mutex_semaphore(1);
static bool has_thread_exited(traceid tid) {
assert(tid != 0, "invariant");
return unloaded_thread_id_set != NULL && JfrPredicate<traceid, compare_traceid>::test(unloaded_thread_id_set, tid);
}
static bool add(GrowableArray<traceid>* set, traceid id) {
assert(set != NULL, "invariant");
return JfrMutablePredicate<traceid, compare_traceid>::test(set, id);
if (unloaded_thread_id_set == NULL) {
return false;
}
ThreadIdExclusiveAccess lock;
return JfrPredicate<traceid, compare_traceid>::test(unloaded_thread_id_set, tid);
}
static void add_to_unloaded_thread_set(traceid tid) {
@ -82,7 +81,7 @@ static void add_to_unloaded_thread_set(traceid tid) {
if (unloaded_thread_id_set == NULL) {
unloaded_thread_id_set = c_heap_allocate_array<traceid>();
}
add(unloaded_thread_id_set, tid);
JfrMutablePredicate<traceid, compare_traceid>::test(unloaded_thread_id_set, tid);
}
void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) {
@ -92,6 +91,15 @@ void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) {
}
}
void ObjectSampleCheckpoint::clear() {
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
if (unloaded_thread_id_set != NULL) {
delete unloaded_thread_id_set;
unloaded_thread_id_set = NULL;
}
assert(unloaded_thread_id_set == NULL, "invariant");
}
template <typename Processor>
static void do_samples(ObjectSample* sample, const ObjectSample* end, Processor& processor) {
assert(sample != NULL, "invariant");

View File

@ -41,6 +41,7 @@ class Thread;
class ObjectSampleCheckpoint : AllStatic {
friend class EventEmitter;
friend class ObjectSampler;
friend class PathToGcRootsOperation;
friend class StackTraceBlobInstaller;
private:
@ -48,6 +49,7 @@ class ObjectSampleCheckpoint : AllStatic {
static int save_mark_words(const ObjectSampler* sampler, ObjectSampleMarker& marker, bool emit_all);
static void write_stacktrace(const JfrStackTrace* trace, JfrCheckpointWriter& writer);
static void write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread);
static void clear();
public:
static void on_type_set(JfrCheckpointWriter& writer);
static void on_type_set_unload(JfrCheckpointWriter& writer);

View File

@ -27,6 +27,7 @@
#include "gc/shared/oopStorage.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
#include "jfr/leakprofiler/sampling/objectSample.hpp"
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/leakprofiler/sampling/sampleList.hpp"
@ -107,6 +108,7 @@ ObjectSampler::~ObjectSampler() {
bool ObjectSampler::create(size_t size) {
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
assert(_oop_storage != NULL, "should be already created");
ObjectSampleCheckpoint::clear();
assert(_instance == NULL, "invariant");
_instance = new ObjectSampler(size);
return _instance != NULL;

View File

@ -352,11 +352,12 @@ class JfrThreadSampler : public NonJavaThread {
};
static void clear_transition_block(JavaThread* jt) {
assert(Threads_lock->owned_by_self(), "Holding the thread table lock.");
jt->clear_trace_flag();
JfrThreadLocal* const tl = jt->jfr_thread_local();
MutexLocker ml(JfrThreadSampler::transition_block(), Mutex::_no_safepoint_check_flag);
if (tl->is_trace_block()) {
MutexLocker ml(JfrThreadSampler::transition_block(), Mutex::_no_safepoint_check_flag);
JfrThreadSampler::transition_block()->notify_all();
JfrThreadSampler::transition_block()->notify();
}
}
@ -404,16 +405,21 @@ JfrThreadSampler::~JfrThreadSampler() {
JfrCHeapObj::free(_frames, sizeof(JfrStackFrame) * _max_frames);
}
static inline bool is_released(JavaThread* jt) {
return !jt->is_trace_suspend();
}
void JfrThreadSampler::on_javathread_suspend(JavaThread* thread) {
JfrThreadLocal* const tl = thread->jfr_thread_local();
tl->set_trace_block();
{
MonitorLocker ml(transition_block(), Mutex::_no_safepoint_check_flag);
while (thread->is_trace_suspend()) {
ml.wait();
}
tl->clear_trace_block();
if (is_released(thread)) {
return;
}
JfrThreadLocal* const tl = thread->jfr_thread_local();
MonitorLocker ml(transition_block(), Mutex::_no_safepoint_check_flag);
tl->set_trace_block();
while (!is_released(thread)) {
ml.wait();
}
tl->clear_trace_block();
}
JavaThread* JfrThreadSampler::next_thread(ThreadsList* t_list, JavaThread* first_sampled, JavaThread* current) {

View File

@ -507,24 +507,29 @@ uint IdealLoopTree::estimate_peeling(PhaseIdealLoop *phase) {
// If we got the effect of peeling, either by actually peeling or by making
// a pre-loop which must execute at least once, we can remove all
// loop-invariant dominated tests in the main body.
void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree *loop, Node_List &old_new) {
void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree* loop, Node_List& old_new) {
bool progress = true;
while (progress) {
progress = false; // Reset for next iteration
Node *prev = loop->_head->in(LoopNode::LoopBackControl);//loop->tail();
Node *test = prev->in(0);
progress = false; // Reset for next iteration
Node* prev = loop->_head->in(LoopNode::LoopBackControl); // loop->tail();
Node* test = prev->in(0);
while (test != loop->_head) { // Scan till run off top of loop
int p_op = prev->Opcode();
if ((p_op == Op_IfFalse || p_op == Op_IfTrue) &&
test->is_If() && // Test?
!test->in(1)->is_Con() && // And not already obvious?
// Condition is not a member of this loop?
!loop->is_member(get_loop(get_ctrl(test->in(1))))){
assert(test != NULL, "test cannot be NULL");
Node* test_cond = NULL;
if ((p_op == Op_IfFalse || p_op == Op_IfTrue) && test->is_If()) {
test_cond = test->in(1);
}
if (test_cond != NULL && // Test?
!test_cond->is_Con() && // And not already obvious?
// And condition is not a member of this loop?
!loop->is_member(get_loop(get_ctrl(test_cond)))) {
// Walk loop body looking for instances of this test
for (uint i = 0; i < loop->_body.size(); i++) {
Node *n = loop->_body.at(i);
if (n->is_If() && n->in(1) == test->in(1) /*&& n != loop->tail()->in(0)*/) {
Node* n = loop->_body.at(i);
// Check against cached test condition because dominated_by()
// replaces the test condition with a constant.
if (n->is_If() && n->in(1) == test_cond) {
// IfNode was dominated by version in peeled loop body
progress = true;
dominated_by(old_new[prev->_idx], n);
@ -534,7 +539,6 @@ void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree *loop, Node_List &old_ne
prev = test;
test = idom(test);
} // End of scan tests in loop
} // End of while (progress)
}

View File

@ -66,7 +66,7 @@ public class DynamicCallSiteDesc {
* @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
* to the bootstrap, that would appear in the
* {@code BootstrapMethods} attribute
* @throws NullPointerException if any parameter is null
* @throws NullPointerException if any parameter or its contents are {@code null}
* @throws IllegalArgumentException if the invocation name has the incorrect
* format
* @jvms 4.2.2 Unqualified Names
@ -79,6 +79,9 @@ public class DynamicCallSiteDesc {
this.invocationType = requireNonNull(invocationType);
this.bootstrapMethod = requireNonNull(bootstrapMethod);
this.bootstrapArgs = requireNonNull(bootstrapArgs.clone());
for (int i = 0; i < this.bootstrapArgs.length; i++) {
requireNonNull(this.bootstrapArgs[i]);
}
if (invocationName.length() == 0)
throw new IllegalArgumentException("Illegal invocation name: " + invocationName);
}
@ -97,7 +100,7 @@ public class DynamicCallSiteDesc {
* to the bootstrap, that would appear in the
* {@code BootstrapMethods} attribute
* @return the nominal descriptor
* @throws NullPointerException if any parameter is null
* @throws NullPointerException if any parameter or its contents are {@code null}
* @throws IllegalArgumentException if the invocation name has the incorrect
* format
* @jvms 4.2.2 Unqualified Names

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @key stress randomness
* @requires vm.compiler2.enabled
* @bug 8269795
* @summary PhaseIdealLoop::peeled_dom_test_elim wrongly moves a non-dominated test out of a loop together with control dependent data nodes.
* This results in a crash due to an out of bounds read of an array.
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xcomp -XX:-TieredCompilation -XX:+StressGCM
* -XX:CompileCommand=compileonly,compiler.loopopts.TestPeelingRemoveDominatedTest compiler.loopopts.TestPeelingRemoveDominatedTest
*/
package compiler.loopopts;
public class TestPeelingRemoveDominatedTest {
public static int N = 400;
static boolean bFld = true;
static int iArrFld[] = new int[N];
public static void main(String[] strArr) {
TestPeelingRemoveDominatedTest _instance = new TestPeelingRemoveDominatedTest();
for (int i = 0; i < 10; i++) {
_instance.mainTest();
}
}
public void mainTest() {
vMeth();
}
static void vMeth() {
iArrFld[1] = 2;
int i6 = 2;
while (--i6 > 0) {
try {
int i3 = (iArrFld[i6 - 1] / 56);
iArrFld[1] = (-139 % i3);
} catch (ArithmeticException a_e) {
}
if (bFld) {
}
}
}
}

View File

@ -47,6 +47,8 @@ public class CallGeneratorHelper extends NativeTestHelper {
static SegmentAllocator IMPLICIT_ALLOCATOR = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
static final int SAMPLE_FACTOR = Integer.parseInt((String)System.getProperties().getOrDefault("generator.sample.factor", "-1"));
static final int MAX_FIELDS = 3;
static final int MAX_PARAMS = 3;
static final int CHUNK_SIZE = 600;
@ -199,7 +201,9 @@ public class CallGeneratorHelper extends NativeTestHelper {
int count = functions;
int fCode = functions++ / CHUNK_SIZE;
String fName = String.format("f%d_%s_%s_%s", fCode, retCode, sigCode, structCode);
downcalls.add(new Object[] { count, fName, r, ptypes, fields });
if (SAMPLE_FACTOR == -1 || (count % SAMPLE_FACTOR) == 0) {
downcalls.add(new Object[]{count, fName, r, ptypes, fields});
}
}
}
} else {
@ -207,7 +211,9 @@ public class CallGeneratorHelper extends NativeTestHelper {
int count = functions;
int fCode = functions++ / CHUNK_SIZE;
String fName = String.format("f%d_%s_%s_%s", fCode, retCode, sigCode, structCode);
downcalls.add(new Object[] { count, fName, r, ptypes, List.of() });
if (SAMPLE_FACTOR == -1 || (count % SAMPLE_FACTOR) == 0) {
downcalls.add(new Object[]{count, fName, r, ptypes, List.of()});
}
}
}
}

View File

@ -29,7 +29,7 @@
* @build NativeTestHelper CallGeneratorHelper TestDowncall
*
* @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies
* --enable-native-access=ALL-UNNAMED
* --enable-native-access=ALL-UNNAMED -Dgenerator.sample.factor=17
* TestDowncall
*/
@ -94,9 +94,6 @@ public class TestDowncall extends CallGeneratorHelper {
FunctionDescriptor descriptor = function(ret, paramTypes, fields);
Object[] args = makeArgs(paramTypes, fields, checks);
boolean needsScope = mt.returnType().equals(MemorySegment.class);
if (count % 100 == 0) {
System.gc();
}
Object res = doCall(addr, IMPLICIT_ALLOCATOR, mt, descriptor, args);
if (ret == Ret.NON_VOID) {
checks.forEach(c -> c.accept(res));

View File

@ -29,7 +29,7 @@
* @build NativeTestHelper CallGeneratorHelper TestUpcall
*
* @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies
* --enable-native-access=ALL-UNNAMED
* --enable-native-access=ALL-UNNAMED -Dgenerator.sample.factor=17
* TestUpcall
*/
@ -41,7 +41,6 @@ import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.SegmentAllocator;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -115,9 +114,6 @@ public class TestUpcall extends CallGeneratorHelper {
MethodHandle mh = abi.downcallHandle(addr, IMPLICIT_ALLOCATOR, mtype, function(ret, paramTypes, fields));
Object[] args = makeArgs(ResourceScope.newImplicitScope(), ret, paramTypes, fields, returnChecks, argChecks);
Object[] callArgs = args;
if (count % 100 == 0) {
System.gc();
}
Object res = mh.invokeWithArguments(callArgs);
argChecks.forEach(c -> c.accept(args));
if (ret == Ret.NON_VOID) {

View File

@ -0,0 +1,192 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.invoke.MethodType;
import java.lang.constant.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.testng.annotations.Test;
import static java.lang.constant.ConstantDescs.CD_int;
import static java.lang.constant.ConstantDescs.CD_void;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
/**
* @test
* @compile DynamicCallSiteDescTest.java
* @run testng DynamicCallSiteDescTest
* @summary unit tests for java.lang.constant.DynamicCallSiteDesc
*/
@Test
public class DynamicCallSiteDescTest extends SymbolicDescTest {
/* note there is no unit test for method resolveCallSiteDesc as it is being tested in another test in this
* suite, IndyDescTest
*/
public void testOf() throws ReflectiveOperationException {
DirectMethodHandleDesc dmh = ConstantDescs.ofCallsiteBootstrap(
ClassDesc.of("BootstrapAndTarget"),
"bootstrap",
ClassDesc.of("java.lang.invoke.CallSite")
);
try {
DynamicCallSiteDesc.of(
dmh,
"",
MethodTypeDesc.ofDescriptor("()I")
);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException iae) {
// good
}
try {
DynamicCallSiteDesc.of(
null,
"getTarget",
MethodTypeDesc.ofDescriptor("()I")
);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
DynamicCallSiteDesc.of(
dmh,
null,
MethodTypeDesc.ofDescriptor("()I")
);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
DynamicCallSiteDesc.of(
dmh,
"getTarget",
null
);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
DynamicCallSiteDesc.of(
dmh,
"getTarget",
MethodTypeDesc.ofDescriptor("()I"),
null
);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
DynamicCallSiteDesc.of(
dmh,
"getTarget",
MethodTypeDesc.ofDescriptor("()I"),
new ConstantDesc[]{ null }
);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
}
public void testWithArgs() throws ReflectiveOperationException {
DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap(
ClassDesc.of("BootstrapAndTarget"),
"bootstrap",
ClassDesc.of("java.lang.invoke.CallSite")
),
"getTarget",
MethodTypeDesc.ofDescriptor("()I")
);
try {
desc.withArgs(null);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
desc.withArgs(new ConstantDesc[]{ null });
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
}
public void testWithNameAndType() throws ReflectiveOperationException {
DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap(
ClassDesc.of("BootstrapAndTarget"),
"bootstrap",
ClassDesc.of("java.lang.invoke.CallSite")
),
"getTarget",
MethodTypeDesc.ofDescriptor("()I")
);
try {
desc.withNameAndType(null, MethodTypeDesc.ofDescriptor("()I"));
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
try {
desc.withNameAndType("bootstrap", null);
fail("NullPointerException expected");
} catch (NullPointerException npe) {
// good
}
}
public void testAccessorsAndFactories() throws ReflectiveOperationException {
DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap(
ClassDesc.of("BootstrapAndTarget"),
"bootstrap",
ClassDesc.of("java.lang.invoke.CallSite")
),
"_",
MethodTypeDesc.ofDescriptor("()I")
);
assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(), desc.invocationType()));
assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(),
desc.invocationName(), desc.invocationType()));
assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(),
desc.invocationName(), desc.invocationType(), desc.bootstrapArgs()));
}
}