mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
Merge
This commit is contained in:
commit
e6b28e05c6
27 changed files with 329 additions and 72 deletions
|
@ -191,7 +191,8 @@ CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, boo
|
||||||
, _oop_map(NULL)
|
, _oop_map(NULL)
|
||||||
, _stack(stack)
|
, _stack(stack)
|
||||||
, _is_method_handle_invoke(false)
|
, _is_method_handle_invoke(false)
|
||||||
, _deoptimize_on_exception(deoptimize_on_exception) {
|
, _deoptimize_on_exception(deoptimize_on_exception)
|
||||||
|
, _force_reexecute(false) {
|
||||||
assert(_stack != NULL, "must be non null");
|
assert(_stack != NULL, "must be non null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +204,8 @@ CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack)
|
||||||
, _oop_map(NULL)
|
, _oop_map(NULL)
|
||||||
, _stack(stack == NULL ? info->_stack : stack)
|
, _stack(stack == NULL ? info->_stack : stack)
|
||||||
, _is_method_handle_invoke(info->_is_method_handle_invoke)
|
, _is_method_handle_invoke(info->_is_method_handle_invoke)
|
||||||
, _deoptimize_on_exception(info->_deoptimize_on_exception) {
|
, _deoptimize_on_exception(info->_deoptimize_on_exception)
|
||||||
|
, _force_reexecute(info->_force_reexecute) {
|
||||||
|
|
||||||
// deep copy of exception handlers
|
// deep copy of exception handlers
|
||||||
if (info->_exception_handlers != NULL) {
|
if (info->_exception_handlers != NULL) {
|
||||||
|
@ -215,7 +217,8 @@ CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack)
|
||||||
void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
|
void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
|
||||||
// record the safepoint before recording the debug info for enclosing scopes
|
// record the safepoint before recording the debug info for enclosing scopes
|
||||||
recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
|
recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
|
||||||
_scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, _is_method_handle_invoke);
|
bool reexecute = _force_reexecute || _scope_debug_info->should_reexecute();
|
||||||
|
_scope_debug_info->record_debug_info(recorder, pc_offset, reexecute, _is_method_handle_invoke);
|
||||||
recorder->end_safepoint(pc_offset);
|
recorder->end_safepoint(pc_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,16 +232,15 @@ class IRScopeDebugInfo: public CompilationResourceObj {
|
||||||
//Whether we should reexecute this bytecode for deopt
|
//Whether we should reexecute this bytecode for deopt
|
||||||
bool should_reexecute();
|
bool should_reexecute();
|
||||||
|
|
||||||
void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) {
|
void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool reexecute, bool is_method_handle_invoke = false) {
|
||||||
if (caller() != NULL) {
|
if (caller() != NULL) {
|
||||||
// Order is significant: Must record caller first.
|
// Order is significant: Must record caller first.
|
||||||
caller()->record_debug_info(recorder, pc_offset, false/*topmost*/);
|
caller()->record_debug_info(recorder, pc_offset, false/*reexecute*/);
|
||||||
}
|
}
|
||||||
DebugToken* locvals = recorder->create_scope_values(locals());
|
DebugToken* locvals = recorder->create_scope_values(locals());
|
||||||
DebugToken* expvals = recorder->create_scope_values(expressions());
|
DebugToken* expvals = recorder->create_scope_values(expressions());
|
||||||
DebugToken* monvals = recorder->create_monitor_values(monitors());
|
DebugToken* monvals = recorder->create_monitor_values(monitors());
|
||||||
// reexecute allowed only for the topmost frame
|
// reexecute allowed only for the topmost frame
|
||||||
bool reexecute = topmost ? should_reexecute() : false;
|
|
||||||
bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
|
bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
|
||||||
bool rethrow_exception = false;
|
bool rethrow_exception = false;
|
||||||
bool is_opt_native = false;
|
bool is_opt_native = false;
|
||||||
|
@ -264,6 +263,7 @@ class CodeEmitInfo: public CompilationResourceObj {
|
||||||
ValueStack* _stack; // used by deoptimization (contains also monitors
|
ValueStack* _stack; // used by deoptimization (contains also monitors
|
||||||
bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site.
|
bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site.
|
||||||
bool _deoptimize_on_exception;
|
bool _deoptimize_on_exception;
|
||||||
|
bool _force_reexecute; // force the reexecute flag on, used for patching stub
|
||||||
|
|
||||||
FrameMap* frame_map() const { return scope()->compilation()->frame_map(); }
|
FrameMap* frame_map() const { return scope()->compilation()->frame_map(); }
|
||||||
Compilation* compilation() const { return scope()->compilation(); }
|
Compilation* compilation() const { return scope()->compilation(); }
|
||||||
|
@ -290,7 +290,11 @@ class CodeEmitInfo: public CompilationResourceObj {
|
||||||
bool is_method_handle_invoke() const { return _is_method_handle_invoke; }
|
bool is_method_handle_invoke() const { return _is_method_handle_invoke; }
|
||||||
void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; }
|
void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; }
|
||||||
|
|
||||||
|
bool force_reexecute() const { return _force_reexecute; }
|
||||||
|
void set_force_reexecute() { _force_reexecute = true; }
|
||||||
|
|
||||||
int interpreter_frame_size() const;
|
int interpreter_frame_size() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod
|
||||||
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) {
|
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) {
|
||||||
_masm->nop();
|
_masm->nop();
|
||||||
}
|
}
|
||||||
|
info->set_force_reexecute();
|
||||||
patch->install(_masm, patch_code, obj, info);
|
patch->install(_masm, patch_code, obj, info);
|
||||||
append_code_stub(patch);
|
append_code_stub(patch);
|
||||||
|
|
||||||
|
|
|
@ -117,9 +117,11 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
|
||||||
|
|
||||||
if (h_m->method_holder()->is_linked()) {
|
if (h_m->method_holder()->is_linked()) {
|
||||||
_can_be_statically_bound = h_m->can_be_statically_bound();
|
_can_be_statically_bound = h_m->can_be_statically_bound();
|
||||||
|
_can_omit_stack_trace = h_m->can_omit_stack_trace();
|
||||||
} else {
|
} else {
|
||||||
// Have to use a conservative value in this case.
|
// Have to use a conservative value in this case.
|
||||||
_can_be_statically_bound = false;
|
_can_be_statically_bound = false;
|
||||||
|
_can_omit_stack_trace = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the definition of this condition to be more useful:
|
// Adjust the definition of this condition to be more useful:
|
||||||
|
@ -176,6 +178,7 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
|
||||||
_intrinsic_id( vmIntrinsics::_none),
|
_intrinsic_id( vmIntrinsics::_none),
|
||||||
_instructions_size(-1),
|
_instructions_size(-1),
|
||||||
_can_be_statically_bound(false),
|
_can_be_statically_bound(false),
|
||||||
|
_can_omit_stack_trace(true),
|
||||||
_liveness( NULL)
|
_liveness( NULL)
|
||||||
#if defined(COMPILER2)
|
#if defined(COMPILER2)
|
||||||
,
|
,
|
||||||
|
@ -766,6 +769,20 @@ bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const {
|
||||||
return (holder() == context) && can_be_statically_bound();
|
return (holder() == context) && can_be_statically_bound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// ciMethod::can_omit_stack_trace
|
||||||
|
//
|
||||||
|
// Tries to determine whether a method can omit stack trace in throw in compiled code.
|
||||||
|
bool ciMethod::can_omit_stack_trace() const {
|
||||||
|
if (!StackTraceInThrowable) {
|
||||||
|
return true; // stack trace is switched off.
|
||||||
|
}
|
||||||
|
if (!OmitStackTraceInFastThrow) {
|
||||||
|
return false; // Have to provide stack trace.
|
||||||
|
}
|
||||||
|
return _can_omit_stack_trace;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMethod::resolve_invoke
|
// ciMethod::resolve_invoke
|
||||||
//
|
//
|
||||||
|
|
|
@ -92,6 +92,7 @@ class ciMethod : public ciMetadata {
|
||||||
bool _is_c2_compilable;
|
bool _is_c2_compilable;
|
||||||
bool _can_be_parsed;
|
bool _can_be_parsed;
|
||||||
bool _can_be_statically_bound;
|
bool _can_be_statically_bound;
|
||||||
|
bool _can_omit_stack_trace;
|
||||||
bool _has_reserved_stack_access;
|
bool _has_reserved_stack_access;
|
||||||
bool _is_overpass;
|
bool _is_overpass;
|
||||||
|
|
||||||
|
@ -364,6 +365,8 @@ class ciMethod : public ciMetadata {
|
||||||
|
|
||||||
bool can_be_statically_bound(ciInstanceKlass* context) const;
|
bool can_be_statically_bound(ciInstanceKlass* context) const;
|
||||||
|
|
||||||
|
bool can_omit_stack_trace() const;
|
||||||
|
|
||||||
// Replay data methods
|
// Replay data methods
|
||||||
static void dump_name_as_ascii(outputStream* st, Method* method);
|
static void dump_name_as_ascii(outputStream* st, Method* method);
|
||||||
void dump_name_as_ascii(outputStream* st);
|
void dump_name_as_ascii(outputStream* st);
|
||||||
|
|
|
@ -142,6 +142,7 @@
|
||||||
template(java_util_Iterator, "java/util/Iterator") \
|
template(java_util_Iterator, "java/util/Iterator") \
|
||||||
template(java_lang_Record, "java/lang/Record") \
|
template(java_lang_Record, "java/lang/Record") \
|
||||||
template(sun_instrument_InstrumentationImpl, "sun/instrument/InstrumentationImpl") \
|
template(sun_instrument_InstrumentationImpl, "sun/instrument/InstrumentationImpl") \
|
||||||
|
template(sun_invoke_util_ValueConversions, "sun/invoke/util/ValueConversions") \
|
||||||
\
|
\
|
||||||
template(jdk_internal_loader_NativeLibraries, "jdk/internal/loader/NativeLibraries") \
|
template(jdk_internal_loader_NativeLibraries, "jdk/internal/loader/NativeLibraries") \
|
||||||
template(jdk_internal_loader_BuiltinClassLoader, "jdk/internal/loader/BuiltinClassLoader") \
|
template(jdk_internal_loader_BuiltinClassLoader, "jdk/internal/loader/BuiltinClassLoader") \
|
||||||
|
|
|
@ -202,7 +202,7 @@ static void prepare_for_resolution() {
|
||||||
|
|
||||||
static bool stack_trace_precondition(const ObjectSample* sample) {
|
static bool stack_trace_precondition(const ObjectSample* sample) {
|
||||||
assert(sample != NULL, "invariant");
|
assert(sample != NULL, "invariant");
|
||||||
return sample->has_stack_trace_id() && !sample->is_dead();
|
return sample->has_stack_trace_id() && !sample->is_dead() && !sample->stacktrace().valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
class StackTraceBlobInstaller {
|
class StackTraceBlobInstaller {
|
||||||
|
@ -249,7 +249,7 @@ void StackTraceBlobInstaller::install(ObjectSample* sample) {
|
||||||
writer.write_type(TYPE_STACKTRACE);
|
writer.write_type(TYPE_STACKTRACE);
|
||||||
writer.write_count(1);
|
writer.write_count(1);
|
||||||
ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer);
|
ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer);
|
||||||
blob = writer.copy();
|
blob = writer.move();
|
||||||
_cache.put(sample, blob);
|
_cache.put(sample, blob);
|
||||||
sample->set_stacktrace(blob);
|
sample->set_stacktrace(blob);
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_klass_unloaded(traceid klass_id) {
|
static bool is_klass_unloaded(traceid klass_id) {
|
||||||
assert(ClassLoaderDataGraph_lock->owned_by_self(), "invariant");
|
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
|
||||||
return JfrKlassUnloading::is_unloaded(klass_id);
|
return JfrKlassUnloading::is_unloaded(klass_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +381,12 @@ void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge
|
||||||
assert(sampler != NULL, "invariant");
|
assert(sampler != NULL, "invariant");
|
||||||
assert(edge_store != NULL, "invariant");
|
assert(edge_store != NULL, "invariant");
|
||||||
assert(thread != NULL, "invariant");
|
assert(thread != NULL, "invariant");
|
||||||
|
{
|
||||||
|
// First install stacktrace blobs for the most recently added candidates.
|
||||||
|
MutexLocker lock(SafepointSynchronize::is_at_safepoint() ? nullptr : ClassLoaderDataGraph_lock);
|
||||||
|
// the lock is needed to ensure the unload lists do not grow in the middle of inspection.
|
||||||
|
install_stack_traces(sampler);
|
||||||
|
}
|
||||||
write_sample_blobs(sampler, emit_all, thread);
|
write_sample_blobs(sampler, emit_all, thread);
|
||||||
// write reference chains
|
// write reference chains
|
||||||
if (!edge_store->is_empty()) {
|
if (!edge_store->is_empty()) {
|
||||||
|
|
|
@ -232,6 +232,7 @@ int write__klass(JfrCheckpointWriter* writer, const void* k) {
|
||||||
int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
|
int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
|
||||||
assert(k != NULL, "invariant");
|
assert(k != NULL, "invariant");
|
||||||
KlassPtr klass = (KlassPtr)k;
|
KlassPtr klass = (KlassPtr)k;
|
||||||
|
CLEAR_LEAKP(klass);
|
||||||
return write_klass(writer, klass, true);
|
return write_klass(writer, klass, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +836,7 @@ class MethodIteratorHost {
|
||||||
private:
|
private:
|
||||||
MethodCallback _method_cb;
|
MethodCallback _method_cb;
|
||||||
KlassCallback _klass_cb;
|
KlassCallback _klass_cb;
|
||||||
MethodUsedPredicate<leakp> _method_used_predicate;
|
MethodUsedPredicate _method_used_predicate;
|
||||||
MethodFlagPredicate<leakp> _method_flag_predicate;
|
MethodFlagPredicate<leakp> _method_flag_predicate;
|
||||||
public:
|
public:
|
||||||
MethodIteratorHost(JfrCheckpointWriter* writer,
|
MethodIteratorHost(JfrCheckpointWriter* writer,
|
||||||
|
|
|
@ -146,16 +146,12 @@ class SymbolPredicate {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool leakp>
|
|
||||||
class MethodUsedPredicate {
|
class MethodUsedPredicate {
|
||||||
bool _current_epoch;
|
bool _current_epoch;
|
||||||
public:
|
public:
|
||||||
MethodUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {}
|
MethodUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {}
|
||||||
bool operator()(const Klass* klass) {
|
bool operator()(const Klass* klass) {
|
||||||
if (_current_epoch) {
|
return _current_epoch ? METHOD_USED_THIS_EPOCH(klass) : METHOD_USED_PREVIOUS_EPOCH(klass);
|
||||||
return leakp ? IS_LEAKP(klass) : METHOD_USED_THIS_EPOCH(klass);
|
|
||||||
}
|
|
||||||
return leakp ? IS_LEAKP(klass) : METHOD_USED_PREVIOUS_EPOCH(klass);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -818,6 +818,18 @@ bool Method::can_be_statically_bound(InstanceKlass* context) const {
|
||||||
return (method_holder() == context) && can_be_statically_bound();
|
return (method_holder() == context) && can_be_statically_bound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns false if this is one of specially treated methods for
|
||||||
|
* which we have to provide stack trace in throw in compiled code.
|
||||||
|
* Returns true otherwise.
|
||||||
|
*/
|
||||||
|
bool Method::can_omit_stack_trace() {
|
||||||
|
if (klass_name() == vmSymbols::sun_invoke_util_ValueConversions()) {
|
||||||
|
return false; // All methods in sun.invoke.util.ValueConversions
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Method::is_accessor() const {
|
bool Method::is_accessor() const {
|
||||||
return is_getter() || is_setter();
|
return is_getter() || is_setter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -600,6 +600,9 @@ public:
|
||||||
bool can_be_statically_bound(InstanceKlass* context) const;
|
bool can_be_statically_bound(InstanceKlass* context) const;
|
||||||
bool can_be_statically_bound(AccessFlags class_access_flags) const;
|
bool can_be_statically_bound(AccessFlags class_access_flags) const;
|
||||||
|
|
||||||
|
// true if method can omit stack trace in throw in compiled code.
|
||||||
|
bool can_omit_stack_trace();
|
||||||
|
|
||||||
// returns true if the method has any backward branches.
|
// returns true if the method has any backward branches.
|
||||||
bool has_loops() {
|
bool has_loops() {
|
||||||
return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag();
|
return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag();
|
||||||
|
|
|
@ -560,8 +560,7 @@ void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) {
|
||||||
// let us handle the throw inline, with a preconstructed instance.
|
// let us handle the throw inline, with a preconstructed instance.
|
||||||
// Note: If the deopt count has blown up, the uncommon trap
|
// Note: If the deopt count has blown up, the uncommon trap
|
||||||
// runtime is going to flush this nmethod, not matter what.
|
// runtime is going to flush this nmethod, not matter what.
|
||||||
if (treat_throw_as_hot
|
if (treat_throw_as_hot && method()->can_omit_stack_trace()) {
|
||||||
&& (!StackTraceInThrowable || OmitStackTraceInFastThrow)) {
|
|
||||||
// If the throw is local, we use a pre-existing instance and
|
// If the throw is local, we use a pre-existing instance and
|
||||||
// punt on the backtrace. This would lead to a missing backtrace
|
// punt on the backtrace. This would lead to a missing backtrace
|
||||||
// (a repeat of 4292742) if the backtrace object is ever asked
|
// (a repeat of 4292742) if the backtrace object is ever asked
|
||||||
|
|
|
@ -798,6 +798,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||||
// at an uncommon trap for an invoke (where the compiler
|
// at an uncommon trap for an invoke (where the compiler
|
||||||
// generates debug info before the invoke has executed)
|
// generates debug info before the invoke has executed)
|
||||||
Bytecodes::Code cur_code = str.next();
|
Bytecodes::Code cur_code = str.next();
|
||||||
|
Bytecodes::Code next_code = Bytecodes::_shouldnotreachhere;
|
||||||
if (Bytecodes::is_invoke(cur_code)) {
|
if (Bytecodes::is_invoke(cur_code)) {
|
||||||
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
|
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
|
||||||
cur_invoke_parameter_size = invoke.size_of_parameters();
|
cur_invoke_parameter_size = invoke.size_of_parameters();
|
||||||
|
@ -806,7 +807,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (str.bci() < max_bci) {
|
if (str.bci() < max_bci) {
|
||||||
Bytecodes::Code next_code = str.next();
|
next_code = str.next();
|
||||||
if (next_code >= 0) {
|
if (next_code >= 0) {
|
||||||
// The interpreter oop map generator reports results before
|
// The interpreter oop map generator reports results before
|
||||||
// the current bytecode has executed except in the case of
|
// the current bytecode has executed except in the case of
|
||||||
|
@ -854,6 +855,10 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||||
// Print out some information that will help us debug the problem
|
// Print out some information that will help us debug the problem
|
||||||
tty->print_cr("Wrong number of expression stack elements during deoptimization");
|
tty->print_cr("Wrong number of expression stack elements during deoptimization");
|
||||||
tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1);
|
tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1);
|
||||||
|
tty->print_cr(" Current code %s", Bytecodes::name(cur_code));
|
||||||
|
if (try_next_mask) {
|
||||||
|
tty->print_cr(" Next code %s", Bytecodes::name(next_code));
|
||||||
|
}
|
||||||
tty->print_cr(" Fabricated interpreter frame had %d expression stack elements",
|
tty->print_cr(" Fabricated interpreter frame had %d expression stack elements",
|
||||||
iframe->interpreter_frame_expression_stack_size());
|
iframe->interpreter_frame_expression_stack_size());
|
||||||
tty->print_cr(" Interpreter oop map had %d expression stack elements", mask.expression_stack_size());
|
tty->print_cr(" Interpreter oop map had %d expression stack elements", mask.expression_stack_size());
|
||||||
|
|
|
@ -1313,7 +1313,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||||
return super.engineGetAttributes(alias);
|
return super.engineGetAttributes(alias);
|
||||||
}
|
}
|
||||||
Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
|
Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
|
||||||
return getAttributes(entry);
|
return Collections.unmodifiableSet(new HashSet<>(getAttributes(entry)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -55,7 +55,7 @@ import java.util.Optional;
|
||||||
* {@linkplain #downcallHandle(FunctionDescriptor) Linking a foreign function} is a process which requires a function descriptor,
|
* {@linkplain #downcallHandle(FunctionDescriptor) Linking a foreign function} is a process which requires a function descriptor,
|
||||||
* a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns,
|
* a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns,
|
||||||
* when complete, a downcall method handle, that is, a method handle that can be used to invoke the target native function.
|
* when complete, a downcall method handle, that is, a method handle that can be used to invoke the target native function.
|
||||||
* The Java {@link java.lang.invoke.MethodType method type} associated with the returned method handle is
|
* The Java {@linkplain java.lang.invoke.MethodType method type} associated with the returned method handle is
|
||||||
* {@linkplain #downcallType(FunctionDescriptor) derived} from the argument and return layouts in the function descriptor.
|
* {@linkplain #downcallType(FunctionDescriptor) derived} from the argument and return layouts in the function descriptor.
|
||||||
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred,
|
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred,
|
||||||
* as described below:
|
* as described below:
|
||||||
|
@ -69,7 +69,8 @@ import java.util.Optional;
|
||||||
* <li>or, if {@code L} is a {@link GroupLayout}, then {@code C} is set to {@code MemorySegment.class}</li>
|
* <li>or, if {@code L} is a {@link GroupLayout}, then {@code C} is set to {@code MemorySegment.class}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* The downcall method handle type, derived as above, might be decorated by additional leading parameters:
|
* The downcall method handle type, derived as above, might be decorated by additional leading parameters,
|
||||||
|
* in the given order if both are present:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>If the downcall method handle is created {@linkplain #downcallHandle(FunctionDescriptor) without specifying a native symbol},
|
* <li>If the downcall method handle is created {@linkplain #downcallHandle(FunctionDescriptor) without specifying a native symbol},
|
||||||
* the downcall method handle type features a leading parameter of type {@link NativeSymbol}, from which the
|
* the downcall method handle type features a leading parameter of type {@link NativeSymbol}, from which the
|
||||||
|
@ -91,7 +92,7 @@ import java.util.Optional;
|
||||||
* handle and a function descriptor; in this case, the set of memory layouts in the function descriptor
|
* handle and a function descriptor; in this case, the set of memory layouts in the function descriptor
|
||||||
* specify the signature of the function pointer associated with the upcall stub.
|
* specify the signature of the function pointer associated with the upcall stub.
|
||||||
* <p>
|
* <p>
|
||||||
* The type of the provided method handle has to match the Java {@link java.lang.invoke.MethodType method type}
|
* The type of the provided method handle has to match the Java {@linkplain java.lang.invoke.MethodType method type}
|
||||||
* associated with the upcall stub, which is derived from the argument and return layouts in the function descriptor.
|
* associated with the upcall stub, which is derived from the argument and return layouts in the function descriptor.
|
||||||
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred, as described below:
|
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred, as described below:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
@ -109,7 +110,7 @@ import java.util.Optional;
|
||||||
*
|
*
|
||||||
* <h2>System lookup</h2>
|
* <h2>System lookup</h2>
|
||||||
*
|
*
|
||||||
* This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) lookup} symbols
|
* This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) look up} symbols
|
||||||
* in the standard libraries associated with this linker. The set of symbols available for lookup is unspecified,
|
* in the standard libraries associated with this linker. The set of symbols available for lookup is unspecified,
|
||||||
* as it depends on the platform and on the operating system.
|
* as it depends on the platform and on the operating system.
|
||||||
*
|
*
|
||||||
|
@ -163,7 +164,7 @@ public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a symbol in the standard libraries associated with this linker.
|
* Look up a symbol in the standard libraries associated with this linker.
|
||||||
* The set of symbols available for lookup is unspecified, as it depends on the platform and on the operating system.
|
* The set of symbols available for lookup is unspecified, as it depends on the platform and on the operating system.
|
||||||
* @return a symbol in the standard libraries associated with this linker.
|
* @return a symbol in the standard libraries associated with this linker.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,14 +29,16 @@ package jdk.incubator.foreign;
|
||||||
import jdk.internal.foreign.MemoryAddressImpl;
|
import jdk.internal.foreign.MemoryAddressImpl;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A memory address models a reference into a memory location. Memory addresses are typically obtained in three ways:
|
* A memory address models a reference into a memory location. Memory addresses are typically obtained in one of the following ways:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>By calling {@link Addressable#address()} on an instance of type {@link Addressable} (e.g. a memory segment);</li>
|
* <li>By calling {@link Addressable#address()} on an instance of type {@link Addressable} (e.g. a memory segment);</li>
|
||||||
* <li>By invoking a {@linkplain CLinker#downcallHandle(FunctionDescriptor) downcall method handle} which returns a pointer;</li>
|
* <li>By invoking a {@linkplain CLinker#downcallHandle(FunctionDescriptor) downcall method handle} which returns a pointer;</li>
|
||||||
* <li>By reading an address from memory, e.g. via {@link MemorySegment#get(ValueLayout.OfAddress, long)}.</li>
|
* <li>By reading an address from memory, e.g. via {@link MemorySegment#get(ValueLayout.OfAddress, long)}.</li>
|
||||||
|
* <li>By the invocation of an {@linkplain CLinker#upcallStub(MethodHandle, FunctionDescriptor, ResourceScope) upcall stub} which accepts a pointer.
|
||||||
* </ul>
|
* </ul>
|
||||||
* A memory address is backed by a raw machine pointer, expressed as a {@linkplain #toRawLongValue() long value}.
|
* A memory address is backed by a raw machine pointer, expressed as a {@linkplain #toRawLongValue() long value}.
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,7 +56,7 @@ import java.util.stream.Stream;
|
||||||
* A memory segment models a contiguous region of memory. A memory segment is associated with both spatial
|
* A memory segment models a contiguous region of memory. A memory segment is associated with both spatial
|
||||||
* and temporal bounds (e.g. a {@link ResourceScope}). Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location
|
* and temporal bounds (e.g. a {@link ResourceScope}). Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location
|
||||||
* which falls <em>outside</em> the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access
|
* which falls <em>outside</em> the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access
|
||||||
* operations on a segment cannot occur after the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}).
|
* operations on a segment cannot occur <em>after</em> the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}).
|
||||||
* <p>
|
* <p>
|
||||||
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
|
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
|
||||||
* programmers should treat instances that are {@linkplain Object#equals(Object) equal} as interchangeable and should not
|
* programmers should treat instances that are {@linkplain Object#equals(Object) equal} as interchangeable and should not
|
||||||
|
@ -157,7 +157,7 @@ import java.util.stream.Stream;
|
||||||
* scope, it can only be accessed by the thread which owns the scope.
|
* scope, it can only be accessed by the thread which owns the scope.
|
||||||
* <p>
|
* <p>
|
||||||
* Heap and buffer segments are always associated with a <em>global</em>, shared scope. This scope cannot be closed,
|
* Heap and buffer segments are always associated with a <em>global</em>, shared scope. This scope cannot be closed,
|
||||||
* and can be considered as <em>always alive</em>.
|
* and segments associated with it can be considered as <em>always alive</em>.
|
||||||
*
|
*
|
||||||
* <h2>Memory segment views</h2>
|
* <h2>Memory segment views</h2>
|
||||||
*
|
*
|
||||||
|
@ -217,11 +217,11 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
* The returned spliterator splits this segment according to the specified element layout; that is,
|
* The returned spliterator splits this segment according to the specified element layout; that is,
|
||||||
* if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving
|
* if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving
|
||||||
* approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of
|
* approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of
|
||||||
* this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that feature the same
|
* this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that
|
||||||
* scope as this given segment.
|
* are associated with the same scope as this segment.
|
||||||
* <p>
|
* <p>
|
||||||
* The returned spliterator effectively allows to slice this segment into disjoint sub-segments, which can then
|
* The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices},
|
||||||
* be processed in parallel by multiple threads.
|
* which can then be processed in parallel by multiple threads.
|
||||||
*
|
*
|
||||||
* @param elementLayout the layout to be used for splitting.
|
* @param elementLayout the layout to be used for splitting.
|
||||||
* @return the element spliterator for this segment
|
* @return the element spliterator for this segment
|
||||||
|
@ -679,7 +679,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -690,7 +690,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -701,7 +701,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -712,7 +712,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -723,7 +723,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -734,7 +734,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
@ -745,7 +745,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
|
* Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
|
||||||
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
|
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
|
||||||
*
|
*
|
||||||
* @param arr the primitive array backing the array memory segment.
|
* @param arr the primitive array backing the array memory segment.
|
||||||
* @return a new array memory segment.
|
* @return a new array memory segment.
|
||||||
|
|
|
@ -456,7 +456,6 @@ public interface SegmentAllocator {
|
||||||
* Returns a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}.
|
* Returns a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}.
|
||||||
* Equivalent to (but likely more efficient than) the following code:
|
* Equivalent to (but likely more efficient than) the following code:
|
||||||
* {@snippet lang=java :
|
* {@snippet lang=java :
|
||||||
* ResourceScope scope = ...
|
|
||||||
* SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
|
* SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
|
|
@ -59,7 +59,8 @@ import java.util.function.Consumer;
|
||||||
sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SharedUtils.EmptyVaList {
|
sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SharedUtils.EmptyVaList {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next value as an {@code int} and advances this variable argument list's position.
|
* Reads the next value as an {@code int} and advances this variable argument list's position. The behavior of this
|
||||||
|
* method is equivalent to the C {@code va_arg} function.
|
||||||
*
|
*
|
||||||
* @param layout the layout of the value to be read.
|
* @param layout the layout of the value to be read.
|
||||||
* @return the {@code int} value read from this variable argument list.
|
* @return the {@code int} value read from this variable argument list.
|
||||||
|
@ -69,7 +70,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
int nextVarg(ValueLayout.OfInt layout);
|
int nextVarg(ValueLayout.OfInt layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next value as a {@code long} and advances this variable argument list's position.
|
* Reads the next value as a {@code long} and advances this variable argument list's position. The behavior of this
|
||||||
|
* method is equivalent to the C {@code va_arg} function.
|
||||||
*
|
*
|
||||||
* @param layout the layout of the value to be read.
|
* @param layout the layout of the value to be read.
|
||||||
* @return the {@code long} value read from this variable argument list.
|
* @return the {@code long} value read from this variable argument list.
|
||||||
|
@ -79,7 +81,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
long nextVarg(ValueLayout.OfLong layout);
|
long nextVarg(ValueLayout.OfLong layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next value as a {@code double} and advances this variable argument list's position.
|
* Reads the next value as a {@code double} and advances this variable argument list's position. The behavior of this
|
||||||
|
* method is equivalent to the C {@code va_arg} function.
|
||||||
*
|
*
|
||||||
* @param layout the layout of the value
|
* @param layout the layout of the value
|
||||||
* @return the {@code double} value read from this variable argument list.
|
* @return the {@code double} value read from this variable argument list.
|
||||||
|
@ -89,7 +92,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
double nextVarg(ValueLayout.OfDouble layout);
|
double nextVarg(ValueLayout.OfDouble layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position.
|
* Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position. The behavior of this
|
||||||
|
* method is equivalent to the C {@code va_arg} function.
|
||||||
*
|
*
|
||||||
* @param layout the layout of the value to be read.
|
* @param layout the layout of the value to be read.
|
||||||
* @return the {@code MemoryAddress} value read from this variable argument list.
|
* @return the {@code MemoryAddress} value read from this variable argument list.
|
||||||
|
@ -99,7 +103,13 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
MemoryAddress nextVarg(ValueLayout.OfAddress layout);
|
MemoryAddress nextVarg(ValueLayout.OfAddress layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position.
|
* Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position. The behavior of this
|
||||||
|
* method is equivalent to the C {@code va_arg} function. The provided group layout must correspond to a C struct or union
|
||||||
|
* type.
|
||||||
|
* <p>
|
||||||
|
* How the value is read in the returned segment is ABI-dependent: calling this method on a group layout
|
||||||
|
* with member layouts {@code L_1, L_2, ... L_n} is not guaranteed to be semantically equivalent to perform distinct
|
||||||
|
* calls to {@code nextVarg} for each of the layouts in {@code L_1, L_2, ... L_n}.
|
||||||
* <p>
|
* <p>
|
||||||
* The memory segment returned by this method will be allocated using the given {@link SegmentAllocator}.
|
* The memory segment returned by this method will be allocated using the given {@link SegmentAllocator}.
|
||||||
*
|
*
|
||||||
|
@ -129,9 +139,12 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies this variable argument list at its current position into a new variable argument list associated
|
* Copies this variable argument list at its current position into a new variable argument list associated
|
||||||
* with the same scope as this variable argument list. Copying is useful to
|
* with the same scope as this variable argument list. The behavior of this method is equivalent to the C
|
||||||
* traverse the variable argument list elements, starting from the current position, without affecting the state
|
* {@code va_copy} function.
|
||||||
* of the original variable argument list, essentially allowing the elements to be traversed multiple times.
|
* <p>
|
||||||
|
* Copying is useful to traverse the variable argument list elements, starting from the current position,
|
||||||
|
* without affecting the state of the original variable argument list, essentially allowing the elements to be
|
||||||
|
* traversed multiple times.
|
||||||
*
|
*
|
||||||
* @return a copy of this variable argument list.
|
* @return a copy of this variable argument list.
|
||||||
* @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from
|
* @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from
|
||||||
|
@ -187,8 +200,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||||
* of the underlying variable argument list.
|
* of the underlying variable argument list.
|
||||||
* @param scope scope the scope to be associated with the new variable arity list.
|
* @param scope scope the scope to be associated with the new variable arity list.
|
||||||
* @return a new variable argument list.
|
* @return a new variable argument list.
|
||||||
* @throws IllegalStateException if the scope associated with {@code allocator} has been already closed,
|
* @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
|
||||||
* or if access occurs from a thread other than the thread owning that scope.
|
* than the thread owning {@code scope}.
|
||||||
*/
|
*/
|
||||||
static VaList make(Consumer<Builder> actions, ResourceScope scope) {
|
static VaList make(Consumer<Builder> actions, ResourceScope scope) {
|
||||||
Objects.requireNonNull(actions);
|
Objects.requireNonNull(actions);
|
||||||
|
|
|
@ -41,7 +41,7 @@ import java.util.OptionalLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as <em>integral</em> types
|
* A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as <em>integral</em> types
|
||||||
* (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size, a {@linkplain ByteOrder byte order})
|
* (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size, an alignment, a {@linkplain ByteOrder byte order})
|
||||||
* and a <em>carrier</em>, that is, the Java type that should be used when {@linkplain MemorySegment#get(OfInt, long) accessing}
|
* and a <em>carrier</em>, that is, the Java type that should be used when {@linkplain MemorySegment#get(OfInt, long) accessing}
|
||||||
* a memory region using the value layout.
|
* a memory region using the value layout.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
* <h3><a id="safety"></a>Safety</h3>
|
* <h3><a id="safety"></a>Safety</h3>
|
||||||
*
|
*
|
||||||
* This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment,
|
* This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment,
|
||||||
* the access coordinates are validated (upon access), to make sure that access does not occur at an address which resides
|
* the access coordinates are validated (upon access), to make sure that access does not occur at any address which resides
|
||||||
* <em>outside</em> the boundaries of the memory segment used by the dereference operation. We call this guarantee <em>spatial safety</em>;
|
* <em>outside</em> the boundaries of the memory segment used by the dereference operation. We call this guarantee <em>spatial safety</em>;
|
||||||
* in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in
|
* in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in
|
||||||
* Section {@jls 15.10.4} of <cite>The Java Language Specification</cite>.
|
* Section {@jls 15.10.4} of <cite>The Java Language Specification</cite>.
|
||||||
|
@ -99,10 +99,10 @@
|
||||||
* <h2>Foreign function access</h2>
|
* <h2>Foreign function access</h2>
|
||||||
* The key abstractions introduced to support foreign function access are {@link jdk.incubator.foreign.SymbolLookup},
|
* The key abstractions introduced to support foreign function access are {@link jdk.incubator.foreign.SymbolLookup},
|
||||||
* {@link jdk.incubator.foreign.MemoryAddress} and {@link jdk.incubator.foreign.CLinker}.
|
* {@link jdk.incubator.foreign.MemoryAddress} and {@link jdk.incubator.foreign.CLinker}.
|
||||||
* The first is used to lookup symbols inside native libraries; the second is used to model native addresses (more on that later),
|
* The first is used to look up symbols inside native libraries; the second is used to model native addresses (more on that later),
|
||||||
* while the third provides linking capabilities which allows modelling foreign functions as {@link java.lang.invoke.MethodHandle} instances,
|
* while the third provides linking capabilities which allows modelling foreign functions as {@link java.lang.invoke.MethodHandle} instances,
|
||||||
* so that clients can perform foreign function calls directly in Java, without the need for intermediate layers of native
|
* so that clients can perform foreign function calls directly in Java, without the need for intermediate layers of native
|
||||||
* code (as it's the case with the <a href="{@docRoot}/../specs/jni/index.html">Java Native Interface (JNI)</a>).
|
* code (as is the case with the <a href="{@docRoot}/../specs/jni/index.html">Java Native Interface (JNI)</a>).
|
||||||
* <p>
|
* <p>
|
||||||
* For example, to compute the length of a string using the C standard library function {@code strlen} on a Linux x64 platform,
|
* For example, to compute the length of a string using the C standard library function {@code strlen} on a Linux x64 platform,
|
||||||
* we can use the following code:
|
* we can use the following code:
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* Here, we obtain a {@linkplain jdk.incubator.foreign.CLinker#systemCLinker() linker instance} and we use it
|
* Here, we obtain a {@linkplain jdk.incubator.foreign.CLinker#systemCLinker() linker instance} and we use it
|
||||||
* to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) lookup} the {@code strlen} symbol in the
|
* to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) look up} the {@code strlen} symbol in the
|
||||||
* standard C library; a <em>downcall method handle</em> targeting said symbol is subsequently
|
* standard C library; a <em>downcall method handle</em> targeting said symbol is subsequently
|
||||||
* {@linkplain jdk.incubator.foreign.CLinker#downcallHandle(jdk.incubator.foreign.FunctionDescriptor) obtained}.
|
* {@linkplain jdk.incubator.foreign.CLinker#downcallHandle(jdk.incubator.foreign.FunctionDescriptor) obtained}.
|
||||||
* To complete the linking successfully, we must provide a {@link jdk.incubator.foreign.FunctionDescriptor} instance,
|
* To complete the linking successfully, we must provide a {@link jdk.incubator.foreign.FunctionDescriptor} instance,
|
||||||
|
@ -138,9 +138,9 @@
|
||||||
* <h3>Foreign addresses</h3>
|
* <h3>Foreign addresses</h3>
|
||||||
*
|
*
|
||||||
* When a memory segment is created from Java code, the segment properties (spatial bounds, temporal bounds and confinement)
|
* When a memory segment is created from Java code, the segment properties (spatial bounds, temporal bounds and confinement)
|
||||||
* are fully known at segment creation. But when interacting with native libraries, clients will often receive <em>raw</em> pointers;
|
* are fully known at segment creation. But when interacting with native libraries, clients will often receive <em>raw</em> pointers.
|
||||||
* such pointers have no spatial bounds (example: does the C type {@code char*} refer to a single {@code char} value,
|
* Such pointers have no spatial bounds. For example, the C type {@code char*} can refer to a single {@code char} value,
|
||||||
* or an array of {@code char} values, of given size?), no notion of temporal bounds, nor thread-confinement.
|
* or an array of {@code char} values, of given size. Nor do said pointers have any notion of temporal bounds or thread-confinement.
|
||||||
* <p>
|
* <p>
|
||||||
* Raw pointers are modelled using the {@link jdk.incubator.foreign.MemoryAddress} class. When clients receive a
|
* Raw pointers are modelled using the {@link jdk.incubator.foreign.MemoryAddress} class. When clients receive a
|
||||||
* memory address instance from a foreign function call, they can perform memory dereference on it directly,
|
* memory address instance from a foreign function call, they can perform memory dereference on it directly,
|
||||||
|
@ -167,7 +167,7 @@
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* <h3>Upcalls</h3>
|
* <h3>Upcalls</h3>
|
||||||
* The {@link jdk.incubator.foreign.CLinker} interface also allows to turn an existing method handle (which might point
|
* The {@link jdk.incubator.foreign.CLinker} interface also allows clients to turn an existing method handle (which might point
|
||||||
* to a Java method) into a memory address, so that Java code can effectively be passed to other foreign functions.
|
* to a Java method) into a memory address, so that Java code can effectively be passed to other foreign functions.
|
||||||
* For instance, we can write a method that compares two integer values, as follows:
|
* For instance, we can write a method that compares two integer values, as follows:
|
||||||
*
|
*
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
* As before, we need to create a {@link jdk.incubator.foreign.FunctionDescriptor} instance, this time describing the signature
|
* As before, we need to create a {@link jdk.incubator.foreign.FunctionDescriptor} instance, this time describing the signature
|
||||||
* of the function pointer we want to create. The descriptor can be used to
|
* of the function pointer we want to create. The descriptor can be used to
|
||||||
* {@linkplain jdk.incubator.foreign.CLinker#upcallType(jdk.incubator.foreign.FunctionDescriptor) derive} a method type
|
* {@linkplain jdk.incubator.foreign.CLinker#upcallType(jdk.incubator.foreign.FunctionDescriptor) derive} a method type
|
||||||
* that can be used to lookup the method handle for {@code IntComparator.intCompare}.
|
* that can be used to look up the method handle for {@code IntComparator.intCompare}.
|
||||||
* <p>
|
* <p>
|
||||||
* Now that we have a method handle instance, we can turn it into a fresh function pointer,
|
* Now that we have a method handle instance, we can turn it into a fresh function pointer,
|
||||||
* using the {@link jdk.incubator.foreign.CLinker} interface, as follows:
|
* using the {@link jdk.incubator.foreign.CLinker} interface, as follows:
|
||||||
|
|
|
@ -191,7 +191,7 @@ public class IOUtils {
|
||||||
PrintStream consumer, boolean writeOutputToFile, long timeout)
|
PrintStream consumer, boolean writeOutputToFile, long timeout)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
exec(pb, testForPresenceOnly, consumer, writeOutputToFile,
|
exec(pb, testForPresenceOnly, consumer, writeOutputToFile,
|
||||||
Executor.INFINITE_TIMEOUT, false);
|
timeout, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
|
static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -30,6 +30,16 @@
|
||||||
* @run main BSMCalledTwice
|
* @run main BSMCalledTwice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8262134
|
||||||
|
* @library /test/lib
|
||||||
|
* @requires vm.debug
|
||||||
|
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||||
|
* @compile -XDignore.symbol.file BSMCalledTwice.java
|
||||||
|
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestC::* -XX:+DeoptimizeALot -XX:+VerifyStack BSMCalledTwice
|
||||||
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
|
@ -834,9 +834,6 @@ jdk/jfr/api/consumer/streaming/TestLatestEvent.java 8268297 windows-
|
||||||
|
|
||||||
# jdk_jpackage
|
# jdk_jpackage
|
||||||
|
|
||||||
tools/jpackage/share/IconTest.java 8278233 macosx-x64
|
|
||||||
tools/jpackage/share/MultiNameTwoPhaseTest.java 8278233 macosx-x64
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
# Client manual tests
|
# Client manual tests
|
||||||
|
|
111
test/jdk/java/lang/reflect/IllegalArgumentsTest.java
Normal file
111
test/jdk/java/lang/reflect/IllegalArgumentsTest.java
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* @bug 8277964
|
||||||
|
* @summary Test IllegalArgumentException be thrown when an argument is invalid
|
||||||
|
* @run testng/othervm IllegalArgumentsTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class IllegalArgumentsTest {
|
||||||
|
static class T {
|
||||||
|
public T(int i) {}
|
||||||
|
|
||||||
|
public static void m(int i) {}
|
||||||
|
|
||||||
|
public void m1(String s) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wrongArgumentType() throws ReflectiveOperationException {
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Constructor<T> ctor = T.class.getConstructor(int.class);
|
||||||
|
ctor.newInstance(int.class); // wrong argument type
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Method method = T.class.getMethod("m", int.class);
|
||||||
|
method.invoke(null, int.class); // wrong argument type
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullArguments() throws ReflectiveOperationException {
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Constructor<T> ctor = T.class.getConstructor(int.class);
|
||||||
|
ctor.newInstance(new Object[] {null});
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Method method = T.class.getMethod("m", int.class);
|
||||||
|
method.invoke(null, new Object[] {null});
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void illegalArguments() throws ReflectiveOperationException {
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Constructor<T> ctor = T.class.getConstructor(int.class);
|
||||||
|
ctor.newInstance(new Object[] { 10, 20});
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Method method = T.class.getMethod("m", int.class);
|
||||||
|
method.invoke(null, new Object[] { 10, 20});
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wrongReceiver() throws ReflectiveOperationException {
|
||||||
|
for (int i = 0; i < 100_000; ++i) {
|
||||||
|
try {
|
||||||
|
Method method = T.class.getMethod("m1", String.class);
|
||||||
|
method.invoke(this, "bad receiver");
|
||||||
|
throw new RuntimeException("Expected IAE not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* @bug 8278744
|
||||||
|
* @summary KeyStore:getAttributes() not returning unmodifiable Set
|
||||||
|
* @library /test/lib
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.SecurityTools;
|
||||||
|
import jdk.test.lib.Utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
public class UnmodifiableAttributes {
|
||||||
|
public static final void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
var oneAttr = new KeyStore.Entry.Attribute() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "1.2.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return "testVal";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
char[] pass = "changeit".toCharArray();
|
||||||
|
|
||||||
|
SecurityTools.keytool("-keystore ks -storepass changeit -genkeypair -alias a -dname CN=A -keyalg EC")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
KeyStore ks = KeyStore.getInstance(new File("ks"), pass);
|
||||||
|
|
||||||
|
var attrs = ks.getAttributes("a");
|
||||||
|
Utils.runAndCheckException(() -> attrs.add(oneAttr), UnsupportedOperationException.class);
|
||||||
|
|
||||||
|
var attrs2 = ks.getEntry("a", new KeyStore.PasswordProtection(pass)).getAttributes();
|
||||||
|
Utils.runAndCheckException(() -> attrs2.add(oneAttr), UnsupportedOperationException.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -51,10 +51,10 @@ import jdk.test.lib.jfr.Events;
|
||||||
*/
|
*/
|
||||||
public final class TestHiddenMethod {
|
public final class TestHiddenMethod {
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
// Must call in separate thread because JTREG uses reflection
|
||||||
try (Recording recording = new Recording()) {
|
// to invoke main method, which uses hidden methods.
|
||||||
recording.enable(MyEvent.class).withThreshold(Duration.ofMillis(0));
|
public static class TestThread extends Thread {
|
||||||
recording.start();
|
public void run() {
|
||||||
// doPrivileged calls a method that has the @Hidden
|
// doPrivileged calls a method that has the @Hidden
|
||||||
// annotation
|
// annotation
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||||
|
@ -65,8 +65,19 @@ public final class TestHiddenMethod {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
MyEvent event = new MyEvent();
|
MyEvent event = new MyEvent();
|
||||||
event.commit();
|
event.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
try (Recording recording = new Recording()) {
|
||||||
|
recording.enable(MyEvent.class).withThreshold(Duration.ofMillis(0));
|
||||||
|
recording.start();
|
||||||
|
Thread t = new TestThread();
|
||||||
|
t.start();
|
||||||
|
t.join();
|
||||||
recording.stop();
|
recording.stop();
|
||||||
|
|
||||||
List<RecordedEvent> events = Events.fromRecording(recording);
|
List<RecordedEvent> events = Events.fromRecording(recording);
|
||||||
|
@ -78,9 +89,7 @@ public final class TestHiddenMethod {
|
||||||
System.out.println("visibleEvent:" + visibleEvent);
|
System.out.println("visibleEvent:" + visibleEvent);
|
||||||
|
|
||||||
assertTrue(hasHiddenStackFrame(hiddenEvent), "No hidden frame in hidden event: " + hiddenEvent);
|
assertTrue(hasHiddenStackFrame(hiddenEvent), "No hidden frame in hidden event: " + hiddenEvent);
|
||||||
|
assertFalse(hasHiddenStackFrame(visibleEvent), "Hidden frame in visible event: " + visibleEvent);
|
||||||
// Temporary disable this test until JDK-8272064 is resolved.
|
|
||||||
// assertFalse(hasHiddenStackFrame(visibleEvent), "Hidden frame in visible event: " + visibleEvent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue