mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
Merge
This commit is contained in:
commit
fcd7686431
50 changed files with 1008 additions and 767 deletions
|
@ -31,8 +31,8 @@ ifndef OPENJDK
|
|||
REASON = "This JDK does not support SDT probes"
|
||||
else
|
||||
|
||||
# We need a recent GCC for the default
|
||||
ifeq "$(shell expr \( $(CC_VER_MAJOR) \>= 4 \) \& \( $(CC_VER_MINOR) \>= 4 \) )" "0"
|
||||
# We need a recent GCC for the default (4.4 or later)
|
||||
ifeq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 4 \) \) \| \( $(CC_VER_MAJOR) \>= 5 \) )" "0"
|
||||
REASON = "gcc version is too old"
|
||||
else
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
|
|||
$(HOTSPOT_TOPDIR)/test/native_sanity \
|
||||
$(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
|
||||
$(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
|
||||
$(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
|
||||
#
|
||||
|
||||
BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
|
||||
|
|
|
@ -1267,10 +1267,6 @@ void os::shutdown() {
|
|||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core, NULL, NULL);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core, void* siginfo, void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
|
|
|
@ -1131,10 +1131,6 @@ void os::shutdown() {
|
|||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core, NULL, NULL);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core, void* siginfo, void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
|
|
|
@ -1478,10 +1478,6 @@ void os::shutdown() {
|
|||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core, NULL, NULL);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core, void* siginfo, void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
|
|
|
@ -1520,10 +1520,6 @@ void os::shutdown() {
|
|||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core, NULL, NULL);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core, void* siginfo, void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
|
|
|
@ -997,7 +997,16 @@ void os::check_dump_limit(char* buffer, size_t buffsz) {
|
|||
if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
|
||||
jio_snprintf(buffer, buffsz, "CreateCoredumpOnCrash is disabled from command line");
|
||||
status = false;
|
||||
} else {
|
||||
}
|
||||
|
||||
#ifndef ASSERT
|
||||
if (!os::win32::is_windows_server() && FLAG_IS_DEFAULT(CreateCoredumpOnCrash)) {
|
||||
jio_snprintf(buffer, buffsz, "Minidumps are not enabled by default on client versions of Windows");
|
||||
status = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status) {
|
||||
const char* cwd = get_current_directory(NULL, 0);
|
||||
int pid = current_process_id();
|
||||
if (cwd != NULL) {
|
||||
|
@ -1086,10 +1095,6 @@ void os::abort(bool dump_core, void* siginfo, void* context) {
|
|||
win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core, NULL, NULL);
|
||||
}
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
void os::die() {
|
||||
win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1);
|
||||
|
|
|
@ -709,24 +709,23 @@ Method* ciEnv::lookup_method(InstanceKlass* accessor,
|
|||
KlassHandle h_holder(THREAD, holder);
|
||||
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
|
||||
methodHandle dest_method;
|
||||
LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true);
|
||||
switch (bc) {
|
||||
case Bytecodes::_invokestatic:
|
||||
dest_method =
|
||||
LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);
|
||||
LinkResolver::resolve_static_call_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokespecial:
|
||||
dest_method =
|
||||
LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);
|
||||
LinkResolver::resolve_special_call_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokeinterface:
|
||||
dest_method =
|
||||
LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,
|
||||
h_accessor, true);
|
||||
LinkResolver::linktime_resolve_interface_method_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokevirtual:
|
||||
dest_method =
|
||||
LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,
|
||||
h_accessor, true);
|
||||
LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
|
|
@ -352,11 +352,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass,
|
|||
}
|
||||
}
|
||||
|
||||
fieldDescriptor result;
|
||||
LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
|
||||
LinkInfo link_info(_holder->get_instanceKlass(),
|
||||
_name->get_symbol(), _signature->get_symbol(),
|
||||
accessing_klass->get_Klass(), bc, true, false,
|
||||
KILL_COMPILE_ON_FATAL_(false));
|
||||
accessing_klass->get_Klass());
|
||||
fieldDescriptor result;
|
||||
LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false));
|
||||
|
||||
// update the hit-cache, unless there is a problem with memory scoping:
|
||||
if (accessing_klass->is_shared() || !is_shared()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
|
@ -786,6 +786,7 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
|
|||
Symbol* h_name = name()->get_symbol();
|
||||
Symbol* h_signature = signature()->get_symbol();
|
||||
|
||||
LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
methodHandle m;
|
||||
// Only do exact lookup if receiver klass has been linked. Otherwise,
|
||||
// the vtable has not been setup, and the LinkResolver will fail.
|
||||
|
@ -793,9 +794,9 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
|
|||
||
|
||||
InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
|
||||
if (holder()->is_interface()) {
|
||||
m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
m = LinkResolver::resolve_interface_call_or_null(h_recv, link_info);
|
||||
} else {
|
||||
m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
m = LinkResolver::resolve_virtual_call_or_null(h_recv, link_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -839,7 +840,8 @@ int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
|
|||
Symbol* h_name = name()->get_symbol();
|
||||
Symbol* h_signature = signature()->get_symbol();
|
||||
|
||||
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
|
||||
LinkInfo link_info(h_recv, h_name, h_signature, caller_klass);
|
||||
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, link_info);
|
||||
if (vtable_index == Method::nonvirtual_vtable_index) {
|
||||
// A statically bound method. Return "no such index".
|
||||
vtable_index = Method::invalid_vtable_index;
|
||||
|
@ -1285,10 +1287,8 @@ bool ciMethod::check_call(int refinfo_index, bool is_static) const {
|
|||
EXCEPTION_MARK;
|
||||
HandleMark hm(THREAD);
|
||||
constantPoolHandle pool (THREAD, get_Method()->constants());
|
||||
methodHandle spec_method;
|
||||
KlassHandle spec_klass;
|
||||
Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
|
||||
LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD);
|
||||
methodHandle spec_method = LinkResolver::resolve_method_statically(code, pool, refinfo_index, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
return false;
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "services/threadService.hpp"
|
||||
#include "utilities/bytes.hpp"
|
||||
|
||||
#define NOFAILOVER_MAJOR_VERSION 51
|
||||
|
@ -130,6 +132,16 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul
|
|||
return true;
|
||||
}
|
||||
|
||||
// Timer includes any side effects of class verification (resolution,
|
||||
// etc), but not recursive calls to Verifier::verify().
|
||||
JavaThread* jt = (JavaThread*)THREAD;
|
||||
PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
|
||||
ClassLoader::perf_class_verify_selftime(),
|
||||
ClassLoader::perf_classes_verified(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_VERIFY);
|
||||
|
||||
// If the class should be verified, first see if we can use the split
|
||||
// verifier. If not, or if verification fails and FailOverToOldVerifier
|
||||
// is set, then call the inference verifier.
|
||||
|
|
|
@ -254,9 +254,9 @@ void VM_GenCollectFullConcurrent::doit_epilogue() {
|
|||
if (_gc_cause != GCCause::_gc_locker &&
|
||||
gch->total_full_collections_completed() <= _full_gc_count_before) {
|
||||
// maybe we should change the condition to test _gc_cause ==
|
||||
// GCCause::_java_lang_system_gc, instead of
|
||||
// _gc_cause != GCCause::_gc_locker
|
||||
assert(_gc_cause == GCCause::_java_lang_system_gc,
|
||||
// GCCause::_java_lang_system_gc or GCCause::_dcmd_gc_run,
|
||||
// instead of _gc_cause != GCCause::_gc_locker
|
||||
assert(GCCause::is_user_requested_gc(_gc_cause),
|
||||
"the only way to get here if this was a System.gc()-induced GC");
|
||||
assert(ExplicitGCInvokesConcurrent, "Error");
|
||||
// Now, wait for witnessing concurrent gc cycle to complete,
|
||||
|
|
|
@ -43,7 +43,7 @@ GangWorker* YieldingFlexibleWorkGang::allocate_worker(uint which) {
|
|||
}
|
||||
|
||||
// Run a task; returns when the task is done, or the workers yield,
|
||||
// or the task is aborted, or the work gang is terminated via stop().
|
||||
// or the task is aborted.
|
||||
// A task that has been yielded can be continued via this interface
|
||||
// by using the same task repeatedly as the argument to the call.
|
||||
// It is expected that the YieldingFlexibleGangTask carries the appropriate
|
||||
|
@ -297,16 +297,9 @@ void YieldingFlexibleGangWorker::loop() {
|
|||
WorkData data;
|
||||
int id;
|
||||
while (true) {
|
||||
// Check if there is work to do or if we have been asked
|
||||
// to terminate
|
||||
// Check if there is work to do.
|
||||
gang()->internal_worker_poll(&data);
|
||||
if (data.terminate()) {
|
||||
// We have been asked to terminate.
|
||||
assert(gang()->task() == NULL, "No task binding");
|
||||
// set_status(TERMINATED);
|
||||
return;
|
||||
} else if (data.task() != NULL &&
|
||||
data.sequence_number() != previous_sequence_number) {
|
||||
if (data.task() != NULL && data.sequence_number() != previous_sequence_number) {
|
||||
// There is work to be done.
|
||||
// First check if we need to become active or if there
|
||||
// are already the requisite number of workers
|
||||
|
|
|
@ -176,7 +176,7 @@ public:
|
|||
GangWorker* allocate_worker(uint which);
|
||||
|
||||
// Run a task; returns when the task is done, or the workers yield,
|
||||
// or the task is aborted, or the work gang is terminated via stop().
|
||||
// or the task is aborted.
|
||||
// A task that has been yielded can be continued via this same interface
|
||||
// by using the same task repeatedly as the argument to the call.
|
||||
// It is expected that the YieldingFlexibleGangTask carries the appropriate
|
||||
|
|
|
@ -1183,7 +1183,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
|
|||
IsGCActiveMark x;
|
||||
|
||||
// Timing
|
||||
assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant");
|
||||
assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant");
|
||||
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
|
||||
|
||||
{
|
||||
|
@ -2199,6 +2199,7 @@ bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
|
|||
switch (cause) {
|
||||
case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
|
||||
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
|
||||
case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
|
||||
case GCCause::_g1_humongous_allocation: return true;
|
||||
case GCCause::_update_allocation_context_stats_inc: return true;
|
||||
case GCCause::_wb_conc_mark: return true;
|
||||
|
|
|
@ -324,7 +324,8 @@ private:
|
|||
// explicitly started if:
|
||||
// (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or
|
||||
// (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
|
||||
// (c) cause == _g1_humongous_allocation
|
||||
// (c) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
|
||||
// (d) cause == _g1_humongous_allocation
|
||||
bool should_do_concurrent_full_gc(GCCause::Cause cause);
|
||||
|
||||
// Keeps track of how many "old marking cycles" (i.e., Full GCs or
|
||||
|
|
|
@ -168,7 +168,7 @@ void VM_G1IncCollectionPause::doit_epilogue() {
|
|||
// +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
|
||||
// that just started (or maybe one that was already in progress) to
|
||||
// finish.
|
||||
if (_gc_cause == GCCause::_java_lang_system_gc &&
|
||||
if (GCCause::is_user_requested_gc(_gc_cause) &&
|
||||
_should_initiate_conc_mark) {
|
||||
assert(ExplicitGCInvokesConcurrent,
|
||||
"the only way to be here is if ExplicitGCInvokesConcurrent is set");
|
||||
|
|
|
@ -130,7 +130,7 @@ void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live,
|
|||
// Update the pause time.
|
||||
_major_timer.stop();
|
||||
|
||||
if (gc_cause != GCCause::_java_lang_system_gc ||
|
||||
if (!GCCause::is_user_requested_gc(gc_cause) ||
|
||||
UseAdaptiveSizePolicyWithSystemGC) {
|
||||
double major_pause_in_seconds = _major_timer.seconds();
|
||||
double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
|
||||
|
|
|
@ -272,7 +272,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
// Don't check if the size_policy is ready here. Let
|
||||
// the size_policy check that internally.
|
||||
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
|
||||
((gc_cause != GCCause::_java_lang_system_gc) ||
|
||||
(!GCCause::is_user_requested_gc(gc_cause) ||
|
||||
UseAdaptiveSizePolicyWithSystemGC)) {
|
||||
// Swap the survivor spaces if from_space is empty. The
|
||||
// resize_young_gen() called below is normally used after
|
||||
|
|
|
@ -2053,7 +2053,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
|
|||
marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer);
|
||||
|
||||
bool max_on_system_gc = UseMaximumCompactionOnSystemGC
|
||||
&& gc_cause == GCCause::_java_lang_system_gc;
|
||||
&& GCCause::is_user_requested_gc(gc_cause);
|
||||
summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
|
||||
|
||||
COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
|
||||
|
@ -2089,7 +2089,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
|
|||
// Don't check if the size_policy is ready here. Let
|
||||
// the size_policy check that internally.
|
||||
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
|
||||
((gc_cause != GCCause::_java_lang_system_gc) ||
|
||||
(!GCCause::is_user_requested_gc(gc_cause) ||
|
||||
UseAdaptiveSizePolicyWithSystemGC)) {
|
||||
// Swap the survivor spaces if from_space is empty. The
|
||||
// resize_young_gen() called below is normally used after
|
||||
|
|
|
@ -290,7 +290,7 @@ bool PSScavenge::invoke_no_policy() {
|
|||
|
||||
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
|
||||
|
||||
if ((gc_cause != GCCause::_java_lang_system_gc) ||
|
||||
if (!GCCause::is_user_requested_gc(gc_cause) ||
|
||||
UseAdaptiveSizePolicyWithSystemGC) {
|
||||
// Gather the feedback data for eden occupancy.
|
||||
young_gen->eden_space()->accumulate_statistics();
|
||||
|
|
|
@ -960,7 +960,7 @@ void DefNewGeneration::gc_epilogue(bool full) {
|
|||
GCCause::to_string(gch->gc_cause()));
|
||||
}
|
||||
assert(gch->gc_cause() == GCCause::_scavenge_alot ||
|
||||
(gch->gc_cause() == GCCause::_java_lang_system_gc && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
|
||||
(GCCause::is_user_requested_gc(gch->gc_cause()) && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
|
||||
!gch->incremental_collection_failed(),
|
||||
"Twice in a row");
|
||||
seen_incremental_collection_failed = false;
|
||||
|
|
|
@ -244,7 +244,7 @@ void AdaptiveSizePolicy::minor_collection_end(GCCause::Cause gc_cause) {
|
|||
// Update the pause time.
|
||||
_minor_timer.stop();
|
||||
|
||||
if (gc_cause != GCCause::_java_lang_system_gc ||
|
||||
if (!GCCause::is_user_requested_gc(gc_cause) ||
|
||||
UseAdaptiveSizePolicyWithSystemGC) {
|
||||
double minor_pause_in_seconds = _minor_timer.seconds();
|
||||
double minor_pause_in_ms = minor_pause_in_seconds * MILLIUNITS;
|
||||
|
|
|
@ -103,6 +103,9 @@ const char* GCCause::to_string(GCCause::Cause cause) {
|
|||
case _last_ditch_collection:
|
||||
return "Last ditch collection";
|
||||
|
||||
case _dcmd_gc_run:
|
||||
return "Diagnostic Command";
|
||||
|
||||
case _last_gc_cause:
|
||||
return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
|
||||
|
||||
|
|
|
@ -74,12 +74,15 @@ class GCCause : public AllStatic {
|
|||
_g1_humongous_allocation,
|
||||
|
||||
_last_ditch_collection,
|
||||
|
||||
_dcmd_gc_run,
|
||||
|
||||
_last_gc_cause
|
||||
};
|
||||
|
||||
inline static bool is_user_requested_gc(GCCause::Cause cause) {
|
||||
return (cause == GCCause::_java_lang_system_gc ||
|
||||
cause == GCCause::_jvmti_force_gc);
|
||||
cause == GCCause::_dcmd_gc_run);
|
||||
}
|
||||
|
||||
inline static bool is_serviceability_requested_gc(GCCause::Cause
|
||||
|
|
|
@ -304,9 +304,16 @@ bool GenCollectedHeap::must_clear_all_soft_refs() {
|
|||
}
|
||||
|
||||
bool GenCollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
|
||||
return UseConcMarkSweepGC &&
|
||||
((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
|
||||
(cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent));
|
||||
if (!UseConcMarkSweepGC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (cause) {
|
||||
case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
|
||||
case GCCause::_java_lang_system_gc:
|
||||
case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t size,
|
||||
|
|
|
@ -47,7 +47,6 @@ AbstractWorkGang::AbstractWorkGang(const char* name,
|
|||
/* allow_vm_block */ are_GC_task_threads,
|
||||
Monitor::_safepoint_check_sometimes);
|
||||
assert(monitor() != NULL, "Failed to allocate monitor");
|
||||
_terminate = false;
|
||||
_task = NULL;
|
||||
_sequence_number = 0;
|
||||
_started_workers = 0;
|
||||
|
@ -106,18 +105,6 @@ bool WorkGang::initialize_workers() {
|
|||
return true;
|
||||
}
|
||||
|
||||
AbstractWorkGang::~AbstractWorkGang() {
|
||||
if (TraceWorkGang) {
|
||||
tty->print_cr("Destructing work gang %s", name());
|
||||
}
|
||||
stop(); // stop all the workers
|
||||
for (uint worker = 0; worker < total_workers(); worker += 1) {
|
||||
delete gang_worker(worker);
|
||||
}
|
||||
delete gang_workers();
|
||||
delete monitor();
|
||||
}
|
||||
|
||||
GangWorker* AbstractWorkGang::gang_worker(uint i) const {
|
||||
// Array index bounds checking.
|
||||
GangWorker* result = NULL;
|
||||
|
@ -175,28 +162,9 @@ void FlexibleWorkGang::run_task(AbstractGangTask* task) {
|
|||
WorkGang::run_task(task, (uint) active_workers());
|
||||
}
|
||||
|
||||
void AbstractWorkGang::stop() {
|
||||
// Tell all workers to terminate, then wait for them to become inactive.
|
||||
MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
|
||||
if (TraceWorkGang) {
|
||||
tty->print_cr("Stopping work gang %s task %s", name(), task()->name());
|
||||
}
|
||||
_task = NULL;
|
||||
_terminate = true;
|
||||
monitor()->notify_all();
|
||||
while (finished_workers() < active_workers()) {
|
||||
if (TraceWorkGang) {
|
||||
tty->print_cr("Waiting in work gang %s: %u/%u finished",
|
||||
name(), finished_workers(), active_workers());
|
||||
}
|
||||
monitor()->wait(/* no_safepoint_check */ true);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
|
||||
assert(monitor()->owned_by_self(), "worker_poll is an internal method");
|
||||
assert(data != NULL, "worker data is null");
|
||||
data->set_terminate(terminate());
|
||||
data->set_task(task());
|
||||
data->set_sequence_number(sequence_number());
|
||||
}
|
||||
|
@ -259,7 +227,7 @@ void GangWorker::initialize() {
|
|||
void GangWorker::loop() {
|
||||
int previous_sequence_number = 0;
|
||||
Monitor* gang_monitor = gang()->monitor();
|
||||
for ( ; /* !terminate() */; ) {
|
||||
for ( ; ; ) {
|
||||
WorkData data;
|
||||
int part; // Initialized below.
|
||||
{
|
||||
|
@ -272,8 +240,6 @@ void GangWorker::loop() {
|
|||
if (TraceWorkGang) {
|
||||
tty->print("Polled outside for work in gang %s worker %u",
|
||||
gang()->name(), id());
|
||||
tty->print(" terminate: %s",
|
||||
data.terminate() ? "true" : "false");
|
||||
tty->print(" sequence: %d (prev: %d)",
|
||||
data.sequence_number(), previous_sequence_number);
|
||||
if (data.task() != NULL) {
|
||||
|
@ -283,13 +249,7 @@ void GangWorker::loop() {
|
|||
}
|
||||
tty->cr();
|
||||
}
|
||||
for ( ; /* break or return */; ) {
|
||||
// Terminate if requested.
|
||||
if (data.terminate()) {
|
||||
gang()->internal_note_finish();
|
||||
gang_monitor->notify_all();
|
||||
return;
|
||||
}
|
||||
for ( ; /* break */; ) {
|
||||
// Check for new work.
|
||||
if ((data.task() != NULL) &&
|
||||
(data.sequence_number() != previous_sequence_number)) {
|
||||
|
@ -306,8 +266,6 @@ void GangWorker::loop() {
|
|||
if (TraceWorkGang) {
|
||||
tty->print("Polled inside for work in gang %s worker %u",
|
||||
gang()->name(), id());
|
||||
tty->print(" terminate: %s",
|
||||
data.terminate() ? "true" : "false");
|
||||
tty->print(" sequence: %d (prev: %d)",
|
||||
data.sequence_number(), previous_sequence_number);
|
||||
if (data.task() != NULL) {
|
||||
|
|
|
@ -103,16 +103,15 @@ class AbstractGangTaskWOopQueues : public AbstractGangTask {
|
|||
// An abstract class representing a gang of workers.
|
||||
// You subclass this to supply an implementation of run_task().
|
||||
class AbstractWorkGang: public CHeapObj<mtInternal> {
|
||||
// Here's the public interface to this class.
|
||||
protected:
|
||||
// Work gangs are never deleted, so no need to cleanup.
|
||||
~AbstractWorkGang() { ShouldNotReachHere(); }
|
||||
public:
|
||||
// Constructor and destructor.
|
||||
// Constructor.
|
||||
AbstractWorkGang(const char* name, bool are_GC_task_threads,
|
||||
bool are_ConcurrentGC_threads);
|
||||
~AbstractWorkGang();
|
||||
// Run a task, returns when the task is done (or terminated).
|
||||
virtual void run_task(AbstractGangTask* task) = 0;
|
||||
// Stop and terminate all workers.
|
||||
virtual void stop();
|
||||
// Return true if more workers should be applied to the task.
|
||||
virtual bool needs_more_workers() const { return true; }
|
||||
public:
|
||||
|
@ -129,8 +128,6 @@ protected:
|
|||
Monitor* _monitor;
|
||||
// The count of the number of workers in the gang.
|
||||
uint _total_workers;
|
||||
// Whether the workers should terminate.
|
||||
bool _terminate;
|
||||
// The array of worker threads for this gang.
|
||||
// This is only needed for cleaning up.
|
||||
GangWorker** _gang_workers;
|
||||
|
@ -153,9 +150,6 @@ public:
|
|||
virtual uint active_workers() const {
|
||||
return _total_workers;
|
||||
}
|
||||
bool terminate() const {
|
||||
return _terminate;
|
||||
}
|
||||
GangWorker** gang_workers() const {
|
||||
return _gang_workers;
|
||||
}
|
||||
|
@ -205,21 +199,16 @@ protected:
|
|||
class WorkData: public StackObj {
|
||||
// This would be a struct, but I want accessor methods.
|
||||
private:
|
||||
bool _terminate;
|
||||
AbstractGangTask* _task;
|
||||
int _sequence_number;
|
||||
public:
|
||||
// Constructor and destructor
|
||||
WorkData() {
|
||||
_terminate = false;
|
||||
_task = NULL;
|
||||
_sequence_number = 0;
|
||||
}
|
||||
~WorkData() {
|
||||
}
|
||||
// Accessors and modifiers
|
||||
bool terminate() const { return _terminate; }
|
||||
void set_terminate(bool value) { _terminate = value; }
|
||||
AbstractGangTask* task() const { return _task; }
|
||||
void set_task(AbstractGangTask* value) { _task = value; }
|
||||
int sequence_number() const { return _sequence_number; }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
|
@ -147,13 +147,10 @@ BasicType Bytecode_member_ref::result_type() const {
|
|||
|
||||
|
||||
methodHandle Bytecode_invoke::static_target(TRAPS) {
|
||||
methodHandle m;
|
||||
KlassHandle resolved_klass;
|
||||
constantPoolHandle constants(THREAD, this->constants());
|
||||
|
||||
Bytecodes::Code bc = invoke_code();
|
||||
LinkResolver::resolve_method_statically(m, resolved_klass, bc, constants, index(), CHECK_(methodHandle()));
|
||||
return m;
|
||||
return LinkResolver::resolve_method_statically(bc, constants, index(), THREAD);
|
||||
}
|
||||
|
||||
Handle Bytecode_invoke::appendix(TRAPS) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
|
@ -36,7 +36,7 @@
|
|||
// that method. If the info is invalid, the link has not been resolved
|
||||
// successfully.
|
||||
|
||||
class CallInfo VALUE_OBJ_CLASS_SPEC {
|
||||
class CallInfo : public StackObj {
|
||||
public:
|
||||
// Ways that a method call might be selected (or not) based on receiver type.
|
||||
// Note that an invokevirtual instruction might be linked with no_dispatch,
|
||||
|
@ -58,11 +58,22 @@ class CallInfo VALUE_OBJ_CLASS_SPEC {
|
|||
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
|
||||
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
|
||||
|
||||
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
|
||||
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||
void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
|
||||
void set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
int itable_index, TRAPS);
|
||||
void set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
int vtable_index, TRAPS);
|
||||
void set_handle(const methodHandle& resolved_method,
|
||||
Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||
void set_common(KlassHandle resolved_klass, KlassHandle selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
CallKind kind,
|
||||
int index, TRAPS);
|
||||
|
||||
friend class LinkResolver;
|
||||
|
||||
|
@ -113,6 +124,37 @@ class CallInfo VALUE_OBJ_CLASS_SPEC {
|
|||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
|
||||
// Condensed information from constant pool to use to resolve the method or field.
|
||||
// resolved_klass = specified class (i.e., static receiver class)
|
||||
// current_klass = sending method holder (i.e., class containing the method
|
||||
// containing the call being resolved)
|
||||
class LinkInfo : public StackObj {
|
||||
Symbol* _name; // extracted from JVM_CONSTANT_NameAndType
|
||||
Symbol* _signature;
|
||||
KlassHandle _resolved_klass; // class that the constant pool entry points to
|
||||
KlassHandle _current_klass; // class that owns the constant pool
|
||||
bool _check_access;
|
||||
public:
|
||||
LinkInfo(constantPoolHandle pool, int index, TRAPS);
|
||||
// Condensed information from other call sites within the vm.
|
||||
LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature,
|
||||
KlassHandle current_klass, bool check_access = true) :
|
||||
_resolved_klass(resolved_klass),
|
||||
_name(name), _signature(signature), _current_klass(current_klass),
|
||||
_check_access(check_access) {}
|
||||
|
||||
// accessors
|
||||
Symbol* name() const { return _name; }
|
||||
Symbol* signature() const { return _signature; }
|
||||
KlassHandle resolved_klass() const { return _resolved_klass; }
|
||||
KlassHandle current_klass() const { return _current_klass; }
|
||||
bool check_access() const { return _check_access; }
|
||||
char* method_string() const;
|
||||
|
||||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
// Link information for getfield/putfield & getstatic/putstatic bytecodes
|
||||
// is represented using a fieldDescriptor.
|
||||
|
||||
|
@ -124,85 +166,136 @@ class LinkResolver: AllStatic {
|
|||
friend class klassItable;
|
||||
|
||||
private:
|
||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS);
|
||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
|
||||
KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
|
||||
|
||||
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static methodHandle lookup_method_in_klasses(const LinkInfo& link_info,
|
||||
bool checkpolymorphism,
|
||||
bool in_imethod_resolve, TRAPS);
|
||||
static methodHandle lookup_method_in_interfaces(const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
Handle *appendix_result_or_null,
|
||||
Handle *method_type_result, TRAPS);
|
||||
// Not Linktime so doesn't take LinkInfo
|
||||
static methodHandle lookup_instance_method_in_klasses (
|
||||
KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
|
||||
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
||||
// Similar loader constraint checking functions that throw
|
||||
// LinkageError with descriptive message.
|
||||
static void check_method_loader_constraints(const LinkInfo& link_info,
|
||||
const methodHandle& resolved_method,
|
||||
const char* method_type, TRAPS);
|
||||
static void check_field_loader_constraints(Symbol* field, Symbol* sig,
|
||||
KlassHandle current_klass,
|
||||
KlassHandle sel_klass, TRAPS);
|
||||
|
||||
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS);
|
||||
static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS);
|
||||
static methodHandle resolve_interface_method(const LinkInfo& link_info, bool nostatics, TRAPS);
|
||||
static methodHandle resolve_method (const LinkInfo& link_info, bool require_methodref, TRAPS);
|
||||
|
||||
static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_special_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_virtual_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
|
||||
|
||||
static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_special_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle current_klass,
|
||||
bool check_access, TRAPS);
|
||||
static void runtime_resolve_virtual_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
Handle recv,
|
||||
KlassHandle recv_klass,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_interface_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
Handle recv,
|
||||
KlassHandle recv_klass,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
|
||||
static void check_field_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, fieldDescriptor& fd, TRAPS);
|
||||
static void check_method_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, methodHandle sel_method, TRAPS);
|
||||
static void check_field_accessability(KlassHandle ref_klass,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle sel_klass,
|
||||
const fieldDescriptor& fd, TRAPS);
|
||||
static void check_method_accessability(KlassHandle ref_klass,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle sel_klass,
|
||||
const methodHandle& sel_method, TRAPS);
|
||||
|
||||
// runtime resolving from constant pool
|
||||
static void resolve_invokestatic (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokespecial (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokevirtual (CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokeinterface(CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokedynamic (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokehandle (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
public:
|
||||
// constant pool resolving
|
||||
static void check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS);
|
||||
|
||||
// static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target
|
||||
static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result,
|
||||
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
|
||||
// static resolving calls (will not run any Java code);
|
||||
// used only from Bytecode_invoke::static_target
|
||||
static methodHandle resolve_method_statically(Bytecodes::Code code,
|
||||
constantPoolHandle pool,
|
||||
int index, TRAPS);
|
||||
|
||||
// runtime/static resolving for fields
|
||||
static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
|
||||
KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
|
||||
static void resolve_field_access(fieldDescriptor& result,
|
||||
constantPoolHandle pool,
|
||||
int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_field(fieldDescriptor& result, const LinkInfo& link_info,
|
||||
Bytecodes::Code access_kind,
|
||||
bool initialize_class, TRAPS);
|
||||
|
||||
// source of access_kind codes:
|
||||
static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
|
||||
return (is_static
|
||||
? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
|
||||
: (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
|
||||
}
|
||||
static void resolve_static_call (CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
bool initialize_klass, TRAPS);
|
||||
static void resolve_special_call (CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
TRAPS);
|
||||
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass,
|
||||
const LinkInfo& link_info,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
|
||||
const LinkInfo& link_info,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_handle_call (CallInfo& result,
|
||||
const LinkInfo& link_info, TRAPS);
|
||||
static void resolve_dynamic_call (CallInfo& result, Handle bootstrap_specifier,
|
||||
Symbol* method_name, Symbol* method_signature,
|
||||
KlassHandle current_klass, TRAPS);
|
||||
|
||||
// runtime resolving:
|
||||
// resolved_klass = specified class (i.e., static receiver class)
|
||||
// current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
|
||||
static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);
|
||||
static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_handle_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
|
||||
static void resolve_dynamic_call (CallInfo& result, Handle bootstrap_specifier, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
|
||||
// same as above for compile-time resolution; but returns null handle instead of throwing
|
||||
// an exception on error also, does not initialize klass (i.e., no side effects)
|
||||
static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
static methodHandle resolve_static_call_or_null (const LinkInfo& link_info);
|
||||
static methodHandle resolve_special_call_or_null (const LinkInfo& link_info);
|
||||
|
||||
// same as above for compile-time resolution; but returns null handle instead of throwing an exception on error
|
||||
// also, does not initialize klass (i.e., no side effects)
|
||||
static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static int vtable_index_of_interface_method(KlassHandle klass, methodHandle resolved_method);
|
||||
static int vtable_index_of_interface_method(KlassHandle klass, const methodHandle& resolved_method);
|
||||
|
||||
// same as above for compile-time resolution; returns vtable_index if current_klass if linked
|
||||
static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||
static int resolve_virtual_vtable_index (KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
|
||||
// static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful)
|
||||
static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||
static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||
static methodHandle linktime_resolve_virtual_method_or_null (const LinkInfo& link_info);
|
||||
static methodHandle linktime_resolve_interface_method_or_null(const LinkInfo& link_info);
|
||||
|
||||
// runtime resolving from constant pool
|
||||
static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokespecial (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokevirtual (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokedynamic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokehandle (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
|
||||
static void resolve_invoke (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_invoke(CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index,
|
||||
Bytecodes::Code byte, TRAPS);
|
||||
private:
|
||||
static void trace_method_resolution(const char* prefix, KlassHandle klass,
|
||||
KlassHandle resolved_klass,
|
||||
const methodHandle& method) PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
|
||||
|
|
|
@ -614,8 +614,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
|||
Metachunk* _chunks_in_use[NumberOfInUseLists];
|
||||
Metachunk* _current_chunk;
|
||||
|
||||
// Number of small chunks to allocate to a manager
|
||||
// If class space manager, small chunks are unlimited
|
||||
// Maximum number of small chunks to allocate to a SpaceManager
|
||||
static uint const _small_chunk_limit;
|
||||
|
||||
// Sum of all space in allocated chunks
|
||||
|
@ -730,6 +729,8 @@ class SpaceManager : public CHeapObj<mtClass> {
|
|||
// Block allocation and deallocation.
|
||||
// Allocates a block from the current chunk
|
||||
MetaWord* allocate(size_t word_size);
|
||||
// Allocates a block from a small chunk
|
||||
MetaWord* get_small_chunk_and_allocate(size_t word_size);
|
||||
|
||||
// Helper for allocations
|
||||
MetaWord* allocate_work(size_t word_size);
|
||||
|
@ -2011,9 +2012,8 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const {
|
|||
size_t SpaceManager::calc_chunk_size(size_t word_size) {
|
||||
|
||||
// Decide between a small chunk and a medium chunk. Up to
|
||||
// _small_chunk_limit small chunks can be allocated but
|
||||
// once a medium chunk has been allocated, no more small
|
||||
// chunks will be allocated.
|
||||
// _small_chunk_limit small chunks can be allocated.
|
||||
// After that a medium chunk is preferred.
|
||||
size_t chunk_word_size;
|
||||
if (chunks_in_use(MediumIndex) == NULL &&
|
||||
sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
|
||||
|
@ -2081,7 +2081,7 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
|
|||
word_size, words_used, words_left);
|
||||
}
|
||||
|
||||
// Get another chunk out of the virtual space
|
||||
// Get another chunk
|
||||
size_t grow_chunks_by_words = calc_chunk_size(word_size);
|
||||
Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
|
||||
|
||||
|
@ -2412,6 +2412,43 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size,
|
|||
return next;
|
||||
}
|
||||
|
||||
/*
|
||||
* The policy is to allocate up to _small_chunk_limit small chunks
|
||||
* after which only medium chunks are allocated. This is done to
|
||||
* reduce fragmentation. In some cases, this can result in a lot
|
||||
* of small chunks being allocated to the point where it's not
|
||||
* possible to expand. If this happens, there may be no medium chunks
|
||||
* available and OOME would be thrown. Instead of doing that,
|
||||
* if the allocation request size fits in a small chunk, an attempt
|
||||
* will be made to allocate a small chunk.
|
||||
*/
|
||||
MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) {
|
||||
if (word_size + Metachunk::overhead() > small_chunk_size()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
|
||||
MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag);
|
||||
|
||||
Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size());
|
||||
|
||||
MetaWord* mem = NULL;
|
||||
|
||||
if (chunk != NULL) {
|
||||
// Add chunk to the in-use chunk list and do an allocation from it.
|
||||
// Add to this manager's list of chunks in use.
|
||||
add_chunk(chunk, false);
|
||||
mem = chunk->allocate(word_size);
|
||||
|
||||
inc_used_metrics(word_size);
|
||||
|
||||
// Track metaspace memory usage statistic.
|
||||
track_metaspace_memory_usage();
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
MetaWord* SpaceManager::allocate(size_t word_size) {
|
||||
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
|
||||
|
||||
|
@ -3559,9 +3596,20 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
|
|||
}
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
SpaceManager* sm;
|
||||
if (is_class_space_allocation(mdtype)) {
|
||||
sm = loader_data->metaspace_non_null()->class_vsm();
|
||||
} else {
|
||||
sm = loader_data->metaspace_non_null()->vsm();
|
||||
}
|
||||
|
||||
result = sm->get_small_chunk_and_allocate(word_size);
|
||||
|
||||
if (result == NULL) {
|
||||
report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Zero initialize.
|
||||
Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
|
||||
|
|
|
@ -622,14 +622,6 @@ bool InstanceKlass::link_class_impl(
|
|||
if (!this_k->is_linked()) {
|
||||
if (!this_k->is_rewritten()) {
|
||||
{
|
||||
// Timer includes any side effects of class verification (resolution,
|
||||
// etc), but not recursive entry into verify_code().
|
||||
PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
|
||||
ClassLoader::perf_class_verify_selftime(),
|
||||
ClassLoader::perf_classes_verified(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_VERIFY);
|
||||
bool verify_ok = verify_code(this_k, throw_verifyerror, THREAD);
|
||||
if (!verify_ok) {
|
||||
return false;
|
||||
|
|
|
@ -1136,7 +1136,7 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
|||
if (m->has_itable_index()) {
|
||||
// This search must match the runtime resolution, i.e. selection search for invokeinterface
|
||||
// to correctly enforce loader constraints for interface method inheritance
|
||||
LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
|
||||
target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
|
||||
}
|
||||
if (target == NULL || !target->is_public() || target->is_abstract()) {
|
||||
// Entry does not resolve. Leave it empty for AbstractMethodError.
|
||||
|
|
|
@ -1126,13 +1126,14 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
|
|||
Method* m = Method::resolve_jmethod_id(method_id);
|
||||
number_of_parameters = m->size_of_parameters();
|
||||
Klass* holder = m->method_holder();
|
||||
if (!(holder)->is_interface()) {
|
||||
if (call_type != JNI_VIRTUAL) {
|
||||
selected_method = m;
|
||||
} else if (!m->has_itable_index()) {
|
||||
// non-interface call -- for that little speed boost, don't handlize
|
||||
debug_only(No_Safepoint_Verifier nosafepoint;)
|
||||
if (call_type == JNI_VIRTUAL) {
|
||||
// jni_GetMethodID makes sure class is linked and initialized
|
||||
// so m should have a valid vtable index.
|
||||
assert(!m->has_itable_index(), "");
|
||||
assert(m->valid_vtable_index(), "no valid vtable index");
|
||||
int vtbl_index = m->vtable_index();
|
||||
if (vtbl_index != Method::nonvirtual_vtable_index) {
|
||||
Klass* k = h_recv->klass();
|
||||
|
@ -1144,21 +1145,13 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
|
|||
// final method
|
||||
selected_method = m;
|
||||
}
|
||||
} else {
|
||||
// JNI_NONVIRTUAL call
|
||||
selected_method = m;
|
||||
}
|
||||
} else {
|
||||
// interface call
|
||||
KlassHandle h_holder(THREAD, holder);
|
||||
|
||||
if (call_type == JNI_VIRTUAL) {
|
||||
int itbl_index = m->itable_index();
|
||||
Klass* k = h_recv->klass();
|
||||
selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
|
||||
} else {
|
||||
selected_method = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -842,7 +842,7 @@ JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
|
|||
// optimize to limit the number of times that java_sender() is called
|
||||
javaVFrame *jvf_cursor = jvf;
|
||||
javaVFrame *jvf_prev = NULL;
|
||||
javaVFrame *jvf_prev_prev;
|
||||
javaVFrame *jvf_prev_prev = NULL;
|
||||
int j = 0;
|
||||
while (jvf_cursor != NULL) {
|
||||
jvf_prev_prev = jvf_prev;
|
||||
|
|
|
@ -677,24 +677,24 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
|||
case IS_METHOD:
|
||||
{
|
||||
CallInfo result;
|
||||
LinkInfo link_info(defc, name, type, caller, caller.not_null());
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
if (ref_kind == JVM_REF_invokeStatic) {
|
||||
LinkResolver::resolve_static_call(result,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeInterface) {
|
||||
LinkResolver::resolve_interface_call(result, Handle(), defc,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else if (mh_invoke_id != vmIntrinsics::_none) {
|
||||
assert(!is_signature_polymorphic_static(mh_invoke_id), "");
|
||||
LinkResolver::resolve_handle_call(result,
|
||||
defc, name, type, caller, THREAD);
|
||||
LinkResolver::resolve_handle_call(result, link_info, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeSpecial) {
|
||||
LinkResolver::resolve_special_call(result,
|
||||
defc, name, type, caller, caller.not_null(), THREAD);
|
||||
link_info, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeVirtual) {
|
||||
LinkResolver::resolve_virtual_call(result, Handle(), defc,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else {
|
||||
assert(false, err_msg("ref_kind=%d", ref_kind));
|
||||
}
|
||||
|
@ -714,11 +714,11 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
|||
case IS_CONSTRUCTOR:
|
||||
{
|
||||
CallInfo result;
|
||||
LinkInfo link_info(defc, name, type, caller, caller.not_null());
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
if (name == vmSymbols::object_initializer_name()) {
|
||||
LinkResolver::resolve_special_call(result,
|
||||
defc, name, type, caller, caller.not_null(), THREAD);
|
||||
LinkResolver::resolve_special_call(result, link_info, THREAD);
|
||||
} else {
|
||||
break; // will throw after end of switch
|
||||
}
|
||||
|
@ -735,7 +735,8 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
|||
fieldDescriptor result; // find_field initializes fd if found
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD);
|
||||
LinkInfo link_info(defc, name, type, caller, /*check_access*/false);
|
||||
LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
return empty;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
|
@ -179,9 +179,9 @@ void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol*
|
|||
CallInfo callinfo;
|
||||
Handle receiver = args->receiver();
|
||||
KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
|
||||
LinkInfo link_info(spec_klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_virtual_call(
|
||||
callinfo, receiver, recvrKlass, spec_klass, name, signature,
|
||||
KlassHandle(), false, true, CHECK);
|
||||
callinfo, receiver, recvrKlass, link_info, true, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
|
@ -216,7 +216,8 @@ void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spe
|
|||
|
||||
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
|
||||
CallInfo callinfo;
|
||||
LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK);
|
||||
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_special_call(callinfo, link_info, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
|
@ -250,7 +251,8 @@ void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle kla
|
|||
|
||||
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
|
||||
CallInfo callinfo;
|
||||
LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
|
||||
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
|
|
|
@ -775,6 +775,10 @@ void os::start_thread(Thread* thread) {
|
|||
pd_start_thread(thread);
|
||||
}
|
||||
|
||||
void os::abort(bool dump_core) {
|
||||
abort(dump_core && CreateCoredumpOnCrash, NULL, NULL);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Helper functions for fatal error handler
|
||||
|
||||
|
|
|
@ -831,9 +831,9 @@ methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, metho
|
|||
CallInfo info;
|
||||
Symbol* signature = method->signature();
|
||||
Symbol* name = method->name();
|
||||
LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
|
||||
name, signature,
|
||||
KlassHandle(), false, true,
|
||||
LinkResolver::resolve_interface_call(info, receiver, recv_klass,
|
||||
LinkInfo(klass, name, signature, KlassHandle(), false),
|
||||
true,
|
||||
CHECK_(methodHandle()));
|
||||
return info.selected_method();
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ int VMUptimeDCmd::num_arguments() {
|
|||
|
||||
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
|
||||
if (!DisableExplicitGC) {
|
||||
Universe::heap()->collect(GCCause::_java_lang_system_gc);
|
||||
Universe::heap()->collect(GCCause::_dcmd_gc_run);
|
||||
} else {
|
||||
output()->print_cr("Explicit GC is disabled, no GC has been performed.");
|
||||
}
|
||||
|
|
|
@ -89,11 +89,11 @@ private:
|
|||
return ((uintx)1) << validate_tag(tag);
|
||||
}
|
||||
|
||||
static TagType validate_tag(uintx tag) {
|
||||
// Type of tag is not TagType to dodge useless MacOSX compiler warning.
|
||||
assert(tag < (sizeof(uintx) * BitsPerByte),
|
||||
err_msg("Tag " UINTX_FORMAT " is too large", tag));
|
||||
return static_cast<TagType>(tag);
|
||||
static TagType validate_tag(TagType tag) {
|
||||
assert(0 <= tag, err_msg("Tag " INTX_FORMAT " is negative", (intx)tag));
|
||||
assert(tag < BitsPerWord,
|
||||
err_msg("Tag " UINTX_FORMAT " is too large", (uintx)tag));
|
||||
return tag;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @requires vm.gc=="null"
|
||||
* @requires (vm.opt.AggressiveOpts=="null") | (vm.opt.AggressiveOpts=="false")
|
||||
* @requires vm.compMode != "Xcomp"
|
||||
* @requires vm.opt.UseCompressedOops != false
|
||||
* @summary Verify that starting the VM with a small heap works
|
||||
* @library /testlibrary /../../test/lib
|
||||
* @modules java.management/sun.management
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of InterfaceWithToString.
|
||||
*/
|
||||
public class ImplementationOfWithToString implements InterfaceWithToString {
|
||||
|
||||
/**
|
||||
* @see InterfaceWithToString#someMethod()
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void someMethod() {
|
||||
// May do something here.
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "toString() from " + getClass().getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface with toString declared.
|
||||
*/
|
||||
public interface InterfaceWithToString {
|
||||
|
||||
void someMethod();
|
||||
|
||||
/**
|
||||
* Same as Object.toString().
|
||||
*
|
||||
* @return some custom string.
|
||||
*/
|
||||
String toString();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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 8072588
|
||||
* @build InterfaceWithToString
|
||||
* @build ImplementationOfWithToString
|
||||
* @run main/native ToStringTest
|
||||
*/
|
||||
public final class ToStringTest {
|
||||
|
||||
static {
|
||||
System.loadLibrary("ToStringTest");
|
||||
}
|
||||
|
||||
native static void nTest();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
nTest();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Native test for ToStringInInterfaceTest.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#define checkException(env) if ((*env)->ExceptionCheck(env)) { return; }
|
||||
|
||||
jstring callStringMethod(JNIEnv* env, jobject jobj, jmethodID id, ...)
|
||||
{
|
||||
jstring value;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, id);
|
||||
value = (jstring)(*env)->CallObjectMethodV(env, jobj, id, ap);
|
||||
va_end(ap);
|
||||
return value;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_ToStringTest_nTest(JNIEnv* env, jclass jclazz)
|
||||
{
|
||||
jclass classOfInterfaceWithToString;
|
||||
jclass classOfImplementationOfWithToString;
|
||||
jmethodID constructorOfImplementationOfWithToString;
|
||||
jobject instanceOfImplementationOfWithToString;
|
||||
jmethodID toStringOfInterfaceWithToString;
|
||||
jmethodID toStringOfImplementationOfWithToString;
|
||||
jstring jstr;
|
||||
const char *chars;
|
||||
|
||||
classOfInterfaceWithToString = (*env)->FindClass(env, "InterfaceWithToString");
|
||||
checkException(env);
|
||||
classOfImplementationOfWithToString = (*env)->FindClass(env, "ImplementationOfWithToString");
|
||||
checkException(env);
|
||||
|
||||
constructorOfImplementationOfWithToString = (*env)->GetMethodID(env, classOfImplementationOfWithToString, "<init>", "()V");
|
||||
checkException(env);
|
||||
|
||||
instanceOfImplementationOfWithToString = (*env)->NewObject(env, classOfImplementationOfWithToString, constructorOfImplementationOfWithToString);
|
||||
checkException(env);
|
||||
|
||||
toStringOfInterfaceWithToString = (*env)->GetMethodID(env, classOfInterfaceWithToString, "toString", "()Ljava/lang/String;");
|
||||
checkException(env);
|
||||
|
||||
toStringOfImplementationOfWithToString = (*env)->GetMethodID(env, classOfImplementationOfWithToString, "toString", "()Ljava/lang/String;");
|
||||
checkException(env);
|
||||
|
||||
jstr = callStringMethod(env, instanceOfImplementationOfWithToString, toStringOfImplementationOfWithToString);
|
||||
checkException(env);
|
||||
|
||||
chars = (*env)->GetStringUTFChars(env, jstr, NULL);
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, chars);
|
||||
|
||||
jstr = callStringMethod(env, instanceOfImplementationOfWithToString, toStringOfInterfaceWithToString);
|
||||
checkException(env);
|
||||
|
||||
chars = (*env)->GetStringUTFChars(env, jstr, NULL);
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, chars);
|
||||
}
|
|
@ -59,7 +59,7 @@ public class RunGCTest {
|
|||
}
|
||||
|
||||
OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
|
||||
output.shouldMatch(".*\\[Full GC \\(System(\\.gc\\(\\))?.*");
|
||||
output.shouldContain("[Full GC (Diagnostic Command)");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.ProcessTools;
|
||||
import jdk.test.lib.OutputAnalyzer;
|
||||
import jdk.test.lib.apps.LingeredApp;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /../../test/lib/share/classes
|
||||
* @library /testlibrary
|
||||
* @build jdk.test.lib.*
|
||||
* @build jdk.test.lib.apps.*
|
||||
* @run main TestClassLoaderStats
|
||||
*/
|
||||
public class TestClassLoaderStats {
|
||||
|
@ -39,10 +42,15 @@ public class TestClassLoaderStats {
|
|||
return;
|
||||
}
|
||||
|
||||
LingeredApp app = null;
|
||||
try {
|
||||
app = LingeredApp.startApp();
|
||||
|
||||
System.out.println("Attaching sun.jvm.hotspot.tools.ClassLoaderStats to " + app.getPid());
|
||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+UsePerfData",
|
||||
"sun.jvm.hotspot.tools.ClassLoaderStats",
|
||||
Integer.toString(ProcessTools.getProcessId()));
|
||||
Long.toString(app.getPid()));
|
||||
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
|
||||
System.out.println(output.getOutput());
|
||||
|
||||
|
@ -52,6 +60,9 @@ public class TestClassLoaderStats {
|
|||
output.shouldMatch("class_loader\\W+classes\\W+bytes\\W+parent_loader\\W+alive?\\W+type");
|
||||
output.stderrShouldNotMatch("[E|e]xception");
|
||||
output.stderrShouldNotMatch("[E|e]rror");
|
||||
} finally {
|
||||
app.stopApp();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
import jdk.test.lib.OutputAnalyzer;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.ProcessTools;
|
||||
import jdk.test.lib.apps.LingeredApp;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /../../test/lib/share/classes
|
||||
* @library /testlibrary
|
||||
* @build jdk.test.lib.*
|
||||
* @build jdk.test.lib.apps.*
|
||||
* @run main TestStackTrace
|
||||
*/
|
||||
public class TestStackTrace {
|
||||
|
@ -39,10 +42,15 @@ public class TestStackTrace {
|
|||
return;
|
||||
}
|
||||
|
||||
LingeredApp app = null;
|
||||
try {
|
||||
app = LingeredApp.startApp();
|
||||
|
||||
System.out.println("Attaching sun.jvm.hotspot.tools.StackTrace to " + app.getPid());
|
||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+UsePerfData",
|
||||
"sun.jvm.hotspot.tools.StackTrace",
|
||||
Integer.toString(ProcessTools.getProcessId()));
|
||||
Long.toString(app.getPid()));
|
||||
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
|
||||
System.out.println(output.getOutput());
|
||||
|
||||
|
@ -50,6 +58,9 @@ public class TestStackTrace {
|
|||
output.shouldContain("Debugger attached successfully.");
|
||||
output.stderrShouldNotMatch("[E|e]xception");
|
||||
output.stderrShouldNotMatch("[E|e]rror");
|
||||
} finally {
|
||||
app.stopApp();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue