This commit is contained in:
Vladimir Kozlov 2015-06-04 12:52:30 -07:00
commit fcd7686431
50 changed files with 1008 additions and 767 deletions

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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();
}

View file

@ -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()) {

View file

@ -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;

View file

@ -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.

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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");

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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";

View file

@ -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

View file

@ -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,

View file

@ -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) {

View file

@ -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; }

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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.

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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");

View file

@ -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

View file

@ -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();
}

View file

@ -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.");
}

View file

@ -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;
}
};

View file

@ -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

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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();
}
}
}

View file

@ -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();
}
}
}